[MUSIC PLAYING]
>> DAVID J. Malan: Baiklah.
Ini adalah CS50.
Dan ini adalah awal minggu 5.
Dan seperti yang Anda mungkin telah memperhatikan, beberapa materi
semakin sedikit lebih kompleks, padat kecil.
>> Dan itu sangat mudah, terutama jika Anda sudah berada di kebiasaan untuk beberapa waktu,
akan mencoba untuk mencoret-coret turun sebagian apa pun yang kita lakukan, kita katakan di kelas.
Tapi menyadari, bahwa tidak mungkin pendekatan pedagogis yang ideal
untuk belajar jenis bahan, dan bahan yang lebih umum.
Dan jadi kami sangat senang untuk mengumumkan Gheng bahwa CS50 sendiri
Gong telah mulai mempersiapkan satu set kanonik catatan
untuk kursus, harapan yaitu bahwa, satu, ini
tidak hanya berfungsi sebagai referensi dan sumber daya
untuk meninjau materi dan pergi kembali melalui materi yang mungkin
melarikan diri Anda pertama kali sekitar, tapi juga agar kepala Anda bisa lebih
up dari bawah, ketika tiba saatnya untuk kuliah,
sehingga Anda mungkin terlibat lebih serius, seperti
lawan lebih Scribbly.
>> Dengan mengatakan bahwa, apa yang akan anda temukan di website ini dokumen-dokumen seperti ini.
Dan pemberitahuan, di sebelah kiri atas, ada tidak hanya daftar isi,
tapi juga kode waktu itu akan segera melompat Anda
ke bagian yang sesuai dalam video online.
Dan apa Chang sini telah dilakukan adalah, pada dasarnya, didokumentasikan
apa yang terjadi dalam hal ini kuliah tertentu.
Dan banyak dari kuliah adalah sudah online sekarang dengan URL ini.
Dan kami akan terus mengirim sisanya orang-orang pada akhir pekan ini,
jadi jangan mengambil keuntungan dari sumber daya itu.
>> Jadi tanpa basa-basi lagi, kami mulai mengupas
lapisan yang telah tali untuk beberapa waktu.
Dan apa yang kita katakan string sebenarnya minggu lalu?
Bintang Jadi arang.
Dan Bintang char, baik, apa apakah itu benar-benar berarti?
Nah, selama ini, jika kita sudah telah memanggil fungsi,
seperti getString, dan penyimpanan yang disebut pulang
nilai getString dalam variable-- itu disebut
s Jenis string-- kami telah menulis baris kode di atas sana di atas.
Dan itu hanya ketika saya melihat saya tulisan tangan diperbesar sini
apakah saya menyadari betapa mengerikan ini.
>> Namun, mari kita asumsikan bahwa, di sisi kanan
adalah, namun, wajar penggambaran apa
terjadi pada semua ini waktu dengan getString.
getString, tentu saja, mendapatkan string.
Tapi apa yang benar-benar berarti?
Ini berarti mendapat sepotong memori dari sistem operasi
dengan memanggil fungsi, yang disebut malloc.
Tapi lebih pada nanti.
Dan kemudian Mempopulai bahwa sepotong memori
dengan huruf pengguna memiliki mengetik, diikuti oleh, tentu saja,
karakter null, atau backslash nol di akhir.
>> Sementara itu, di sisi kiri dari cerita ini, selama ini,
kami telah menyatakan variabel, seperti s.
Dan variabel itulah yang sekarang akan mulai memanggil pointer.
Ini bukan kotak yang di dalamnya kami menempatkan string, Daven, per se,
melainkan kita masukkan ke dalam kotak yang kotak di sebelah kiri apa sebenarnya?
Ya?
>> AUDIENCE: Alamat di mana itu terletak dalam memori.
>> DAVID J. Malan: Tepat.
Alamat di mana Daven terletak di memori.
Dan tidak di mana semua Daven berada, per se, namun secara khusus alamat
apa?
Ya?
>> AUDIENCE: Karakter pertama.
>> DAVID J. Malan: Karakter pertama di Daven, yang, dalam hal ini,
Saya diusulkan adalah sewenang-wenang dan realistis 1, OX1,
yang hanya berarti angka heksadesimal dari 1.
Tapi itu mungkin akan menjadi jumlah yang jauh lebih besar
bahwa kita mungkin menarik dengan 0x sebagai awalan,
mewakili karakter heksadesimal.
Dan karena kita tidak perlu tahu di mana sisa karakter Daven
adalah, karena apa desain yang sederhana keputusan yang dibuat beberapa tahun yang lalu?
Ya?
>> AUDIENCE: Backslash 0.
DAVID J. Malan: Ya, persis.
Backslash 0 memungkinkan Anda, meskipun dalam waktu linier, untuk melintasi string,
berjalan dari kiri ke kanan, dengan untuk loop, atau beberapa saat
lingkaran, atau sesuatu seperti itu, dan menentukan, oh, di sini
adalah akhir dari string tertentu ini.
Jadi dengan hanya alamat di awal string,
kita dapat mengakses keseluruhan itu, karena selama ini,
string baru saja menjadi bintang arang.
>> Jadi itu pasti baik-baik saja untuk terus menggunakan perpustakaan CS50 dan abstraksi ini,
sehingga untuk berbicara, tapi kita akan mulai untuk melihat secara tepat
apa yang telah terjadi bawah sepanjang waktu ini.
Jadi Anda mungkin ingat contoh ini, juga, dari terakhir kali, bandingkan 0,
yang tidak benar-benar membandingkan.
Tapi kita mulai untuk memecahkan masalah ini.
>> Tapi seperti yang mungkin penyegaran, mungkin saya menarik seseorang
di gajah merah muda hari ini, juga dibuat oleh Chang?
Bagaimana Anda di depan? [Tak terdengar].
Ayo up.
>> Dan sementara itu, Anda datang, mari kita
Pertimbangkan untuk sesaat apa kode ini benar-benar melakukan.
Ini menyatakan dua variabel up atas, dan t, dan memanggil getString.
Ini bukan program sangat user-friendly, karena tidak memberitahu Anda apa yang harus dilakukan.
Tapi mari kita asumsikan kita berfokus pada bagian juicy.
Dan kemudian kita lakukan, jika s sama sama t, itu harus mengatakan printf,
Anda mengetik hal yang sama.
Hello.
Siapa nama Anda?
>> Janelle: Janelle.
DAVID J. Malan: Janelle, Senang bertemu denganmu.
Jadi tantangan di tangan untuk gajah ini
adalah untuk pertama menarik kita gambaran tentang apa yang yang diwakili pada mereka pertama dua
baris.
Jadi s dan t mungkin direpresentasikan bagaimana di layar?
Dan Anda hanya dapat menarik dengan jari Anda pada layar besar ini.
>> Jadi ada dua bagian untuk setiap sisi persamaan itu.
Jadi ada s di sebelah kiri, dan kemudian getString di sebelah kanan.
Dan kemudian ada t di sebelah kiri, dan kemudian getString di sebelah kanan.
Jadi bagaimana mungkin kita mulai menggambar gambar yang
mewakili apa yang terjadi di sini dalam memori, yang akan Anda katakan?
Dan biarkan aku memberitahu Anda menjelaskan apa yang Anda lakukan saat Anda pergi.
>> Janelle: OK.
Yah, pertama, itu akan meminta Anda untuk mendapatkan input string.
Dan itu akan store-- oh, maaf.
DAVID J. Malan: OK.
Baik.
Dan ini disebut apa?
Oh, OK.
Terus.
Aku tidak bermaksud mengganggu.
Janelle: Maaf.
Jadi itu akan menjadi masukan alamat tidak of-- yakin.
Saya tidak ingat persis nomor, tapi saya percaya itu dimulai dengan 0.
>> DAVID J. Malan: Tidak apa-apa, karena saya membuat angka sampai,
jadi tidak ada jawaban yang tepat.
>> Janelle: Dimulai dengan 0 busur.
>> DAVID J. Malan: OK, jadi elemen 0.
Tentu.
>> Janelle: Dan kemudian jika itu seperti hanya dua-letter--
>> DAVID J. Malan: OK, kembali kepada Anda.
>> Janelle: Jadi elemen 0, dan maka elemen 1 atau elemen 2.
DAVID J. Malan: Dan yang sepotong gambar yang Anda menggambar sekarang?
Panggilan untuk getString?
Atau deklarasi s?
>> Janelle: Deklarasi dari s, saya percaya.
Oh, yang getString, karena akan akan diinput ke dalam setiap [? daerah. ?]
>> DAVID J. Malan: Good.
Tepat.
Meskipun ini efektif mengembalikan sebuah array, ingat,
ketika kita kembali string, kita bisa indeks ke string menggunakan 01 dan 2.
Secara teknis, ini mungkin diwakili oleh alamat individu,
tapi itu baik-baik saja.
>> Jadi misalkan, kalau bisa hanya cepat maju ke tempat kami tinggalkan
terakhir kali, jika salah satu dari string adalah g b e,
backslash 0, sehingga mewakili gabe dunia masukan, bagaimana kita mungkin mewakili s sekarang?
Jika ini adalah memori yang dikembalikan oleh getString?
>> Janelle: Apakah akan diwakili oleh busur?
>> DAVID J. Malan: Dengan busur?
Yah, tidak ada.
Mari kita katakan saja, pictorially, saya hanya pergi ke depan
dan mengusulkan bahwa, jika ini adalah s, ini adalah nilai pengembalian getString.
Dan Anda telah ditarik ini sebagai 0, 1, 2, yang adalah sangat masuk akal, karena kita
dapat mengindeks ke dalam string, seperti itu.
Tapi hanya untuk konsisten dengan terakhir kali, biarkan aku pergi ke depan
dan sewenang-wenang mengusulkan bahwa ini adalah alamat 1, ini adalah alamat 2,
ini adalah alamat 3, dan sebagainya.
Jadi, hanya untuk menjadi super jelas, apa yang terjadi
untuk masuk sebagai akibat dari itu baris pertama kode, akan Anda katakan?
>> Janelle: Alamat 1?
>> DAVID J. Malan: Tepat.
Jadi alamat 0x1.
Dan sementara itu, biarkan aku pergi ke depan dan duplikat banyak dari apa yang telah Anda lakukan
dan menambahkan t saya sendiri di sini.
Jika saya mengetikkan gabe lagi, untuk kedua kalinya,
ketika diminta dengan getString, di mana, tentu saja, gabe akan pergi?
Nah, presumably--
>> Janelle: Seperti di sini?
DAVID J. Malan: Ya.
Janelle: Atau itu juga dalam kotak yang sama?
DAVID J. Malan: Biarkan saya mengusulkan, ya, persis, sehingga dalam kotak-kotak tambahan.
Tapi apa kuncinya sekarang adalah bahwa, bahkan meskipun aku sudah ditarik ini cukup dekat
together-- 0x1, ini adalah 0x2-- pada kenyataannya,
ini sekarang mungkin alamat 0x10, misalnya, dan 0x11, 0x12 dan,
dan lain sebagainya.
Jadi, jika itu yang terjadi, apa yang akan berakhir di sini di t?
>> Janelle: 0x10?
DAVID J. Malan: Tepat.
Jadi 0x10.
Dan sekarang, pertanyaan terakhir.
Anda telah, sejauh ini, harus bekerja paling sulit untuk gajah sejauh ini.
Sekarang, jika saya menarik kode lagi, ketika saya lakukan, sejalan tiga,
jika s sama sama t, apa aku benar-benar perbandingan antara bahwa kita telah ditarik di sini?
>> Janelle: Dua alamat?
DAVID J. Malan: Tepat.
Jadi saya katakan adalah s sama sama dengan t?
Dengan kata lain, adalah 1 sama sama dengan 10?
Dan tentu saja, jawaban yang jelas saat ini adalah, tidak ada.
Jadi program ini pada akhirnya akan mencetak apa, akan Anda katakan?
>> Janelle: Apakah akan, Anda mengetik hal yang sama?
>> DAVID J. Malan: Jadi, jika s adalah 1 dan t adalah 10?
>> Janelle: Anda mengetik hal yang berbeda.
>> DAVID J. Malan: Tepat.
Anda mengetik hal yang berbeda.
Baiklah.
Jadi tepuk tangan, jika kita bisa, di sini.
[Tepuk Tangan]
Itu menyakitkan.
Aku tahu.
Bagus sekali.
Jadi sekarang mari kita lihat apakah kita tidak bisa menggoda selain apa memperbaiki itu.
Dan tentu saja, ketika kita tetap ini-- yang saya sekarang akan mewakili di green--
kami melakukan beberapa tambahan di sini.
Pertama, seperti kewarasan cek, aku pertama memeriksa
jika s sama dengan nol dan t sama dengan nol.
Dan hanya harus jelas, ketika mungkin s atau t null dalam kode seperti ini?
Kapan s atau t null.
Ya?
>> AUDIENCE: [Tak terdengar].
>> DAVID J. Malan: Tepat.
Jika string bahwa pengguna mengetik terlalu lama
untuk masuk ke dalam memori, atau aneh sudut kasus seperti itu,
GetString, seperti yang akan kita lihat, secara harfiah hari ini, dalam dokumentasi,
mengatakan akan mengembalikan null sebagai nilai sentinel khusus,
atau hanya semacam simbol khusus itu berarti ada yang tidak beres.
Jadi kami ingin memeriksa itu, karena ternyata
nol itu adalah nilai yang sangat berbahaya.
>> Seringkali, jika Anda mencoba untuk melakukan sesuatu dengan nol melibatkan function-- lewat itu
sebagai masukan, untuk instance-- fungsi yang mungkin sangat akan crash dan, dengan itu,
mencatat seluruh program Anda.
Jadi baris ketiga ini sekarang hanya kewarasan cek, pengecekan error, jika Anda mau.
Itu kebiasaan yang baik sekarang ke kita untuk masuk ke setiap kali kita
mencoba untuk menggunakan nilai yang bisa, berpotensi, null.
>> Sekarang, di baris keempat di sini, "Jika strcmp (s, t)," baik,
apa itu maksud?
Yah, kami mengatakan ini adalah sangat ringkas fungsi bernama untuk perbandingan string.
Dan tujuannya dalam hidup adalah untuk membandingkan argumen pertama menentangnya kedua,
tapi tidak dalam hal alamat mereka, seperti yang kita lakukan tidak sengaja saat
lalu dengan kode merah, tapi bukan untuk membandingkan dua
string dalam manusiawi intuitif cara dengan membandingkan ini, melawan ini,
melawan ini, melawan ini, dan kemudian berhenti jika dan ketika salah satu
atau kedua jari saya hits backslash 0.
Jadi seseorang tahun yang lalu dilaksanakan strcmp untuk menerapkan bagi kita fungsi
bahwa kita berharap kita akan mendapatkan dengan hanya membandingkan dua nilai sederhana.
>> Sekarang terus terang, aku terus menggambar semua ini berbagai nomor.
Tetapi kenyataannya adalah, aku sudah membuat ini up sepanjang waktu.
Jadi biarkan aku hanya pergi ke depan dan mencoret-coret ini keluar
untuk membuat titik itu, di akhir hari dan bergerak maju,
kita tidak benar-benar akan peduli apa alamat hal-hal yang benar-benar
dalam memori.
Jadi aku tidak akan menarik ini jenis nomor begitu banyak lagi,
Aku hanya abstrak ini away sedikit lebih ramah dengan hanya panah.
>> Dengan kata lain, jika s adalah pointer, baik, mari kita menarik itu, secara harfiah,
sebagai pointer, panah menunjuk dari dirinya sendiri untuk sesuatu yang lain,
dan tidak terlalu khawatir tentang minutia alamat ini
yang, sekali lagi, saya dibuat pula.
Tapi kita akan melihat alamat tersebut, kadang-kadang, ketika mencari kesalahan kode.
>> Sekarang sementara itu, program ini di sini perbaikan, tentu saja,
bahwa masalah dengan membandingkan dua string.
Tapi kami berlari ke masalah lain.
Ini adalah dari salinan memprogram terakhir kali,
dimana, saya mencoba untuk memanfaatkan hanya karakter pertama dalam string.
Tapi apa gejala kita melihat terakhir kali ketika
pengguna mengetik nilai, seperti gabe dalam huruf kecil, untuk s,
maka kita ditugaskan s ke t, seperti pada baris ketiga ada,
dan kemudian saya mencoba untuk memanfaatkan t braket 0?
Apa efek mengubah t braket 0 di sini?
>> AUDIENCE: Ini mengubah s.
>> DAVID J. Malan: Ya, Saya mengubah s, juga.
Karena apa yang sebenarnya terjadi?
Nah, biarkan aku melihat apakah saya bisa membersihkan up gambar ini, sebagai berikut.
>> Jika s adalah, sekali lagi, kata g, a, b, e, backslash, 0, dan s
kami akan terus menggambar sebagai kotak di sini, tapi alamat tidak lebih.
Mari kita berhenti membuat segalanya.
Mari kita menggambar untuk menyederhanakan dunia.
>> Ketika saya menyatakan t dengan tali t, yang menciptakan bahwa sepotong memori.
Persegi terjadi menjadi 32 bit di kebanyakan komputer.
Bahkan, jika Anda pernah mendengar tentang komputer memiliki arsitektur 32-bit,
benar-benar mewah-bicara, yang hanya berarti menggunakan alamat 32-bit.
Dan sebagai teknis samping, jika Anda pernah bertanya-tanya
mengapa komputer lama, jika Anda benar-benar mencoba sup mereka dengan banyak RAM,
hanya bisa maksimal empat gigabyte RAM,
baik itu karena, secara harfiah, komputer lama Anda hanya bisa
menghitung setinggi 4 miliar, 4 miliar bytes,
karena itu menggunakan 32-bit angka untuk alamat.
>> Tapi dalam hal apapun, dalam hal ini Misalnya, cerita jauh lebih sederhana.
t hanya pointer lain, atau benar-benar bintang char, string yang aka.
Dan bagaimana saya ingin memperbarui gambar ini sekarang dengan baris kedua kode,
setelah titik, dot, dot?
Ketika saya melakukan tali t sama dengan s koma, bagaimana mengubah gambar ini?
Ya?
>> AUDIENCE: [Tak terdengar].
>> DAVID J. Malan: Ya.
Tepat.
Aku hanya menempatkan panah dari t kotak ke alamat yang sama,
huruf pertama yang sama di berikan.
Atau secara teknis, apakah ini orang masih di 0x1,
itu seolah-olah saya telah 0x1 sini dan 0x1 sini.
Tapi sekali lagi, siapa yang peduli tentang alamat?
Hanya saja gagasan bahwa sekarang penting.
Jadi ini adalah apa yang terjadi di sini.
Jadi tentu saja, jika Anda melakukan t braket 0, yang merupakan notasi array,
dari course-- dan terus terang, tampak seperti ada sebuah array di sini,
tapi sekarang ada hal yang aneh ini.
Ketahuilah bahwa bahasa pemrograman, C, menawarkan fitur ini,
dimana, bahkan jika t adalah pointer, atau s adalah pointer,
Anda masih dapat menggunakan familiar, braket persegi nyaman
notasi untuk pergi ke elemen pertama, atau elemen kedua, atau setiap elemen
bahwa pointer yang menunjuk untuk karena, mungkin, itu
adalah, seperti dalam kasus ini, menunjuk beberapa array.
>> Jadi bagaimana kita mengatasinya?
Terus terang, ini adalah di mana ia mendapat sedikit berlebihan pada pandangan pertama.
Tapi di sini adalah versi baru dan lebih baik.
>> Jadi pertama, saya mendapatkan menyingkirkan perpustakaan CS50,
hanya untuk mengekspos bahwa s memang bintang char, hanya sinonim.
Dan t juga merupakan bintang arang.
Tapi apa yang terjadi pada sisi kanan dari garis yang
dimana t ditugaskan nilai?
>> Apa itu malloc?
Apa itu strlen?
Apa sizeof (char)?
Kenapa sih melakukan hal ini garis terlihat begitu rumit?
Apa itu lakukan pada tingkat tinggi?
Apa itu menyimpan di t?
Ya?
AUDIENCE: Ini mengalokasikan sejumlah ruang memori.
Ini untuk menyimpan, saya kira, surat [Tak terdengar].
>> DAVID J. Malan Perfect.
Sempurna.
Ini mengalokasikan tertentu jumlah ruang memori
untuk menyimpan, mungkin, surat masa depan.
Dan khususnya, malloc Oleh karena itu kembali apa?
>> AUDIENCE: Mengembalikan [Tak terdengar]?
DAVID J. Malan: Tepat.
Kembali alamat memori yang, yang merupakan cara mewah mengatakan,
mengembalikan alamat dari byte pertama memori itu.
Tanggung jawab berada pada saya untuk mengingat berapa banyak memori saya benar-benar
dialokasikan atau meminta malloc untuk.
>> Sekarang berapa banyak itu?
Yah, meskipun ada banyak tanda kurung di sini,
malloc hanya butuh satu argumen.
Dan aku menentukan strlen dari s, sehingga memberikan saya sebagai banyak byte seperti yang ada di s,
tapi menambahkan satu.
Mengapa?
Ya?
>> AUDIENCE: The backslash 0.
DAVID J. Malan: Tepat.
Kami harus melakukan pembenahan sedikit.
Jadi karena ada backslash 0, sebaiknya kita ingat itu.
Jika tidak, kita akan untuk membuat string yang
tidak memiliki terminator khusus.
>> Sementara itu, hanya untuk menjadi super anal, saya memiliki sizeof (char),
hanya dalam kasus seseorang berjalan saya kode tidak pada alat CS50,
tapi mungkin komputer yang berbeda sama sekali di mana karakter
adalah salah satu byte, dengan konvensi, tapi dua byte, atau sesuatu yang lebih besar dari itu.
Hanya saja untuk menjadi super, Super menolak untuk kesalahan.
Meskipun, pada kenyataannya, itu kemungkinan besar akan menjadi 1.
>> Sekarang, sementara itu, aku pergi ke depan dan salin String, t braket i sama dengan t braket s.
Dan saya akan tunduk kepada minggu lalu kode sumber untuk melihat apa yang terjadi.
Tapi takeaway kunci, dan Alasan saya menempatkan kode tersebut sekarang dalam warna hijau,
karena baris terakhir, t braket 0 sama dengan toupper,
memiliki efek Memanfaatkan string mana?
t dan / atau s?
Itu baris terakhir kode.
>> Hanya t, karena apa yang terjadi saat ini,
jika saya sedikit membatalkan langkah terakhir, apa yang terjadi adalah, ketika saya sebut malloc,
Saya pada dasarnya mendapatkan sepotong memori itu adalah ukuran yang sama seperti aslinya,
karena itulah aritmetik saya lakukan.
Aku menyimpan di t alamat itu sepotong memori.
Meskipun ini terlihat bagus dan cantik, bagus dan kosong,
kenyataannya adalah ada, apa yang kita akan terus menelepon, nilai sampah di sini.
Potongan itu dari memori mungkin sangat baik memiliki pernah digunakan sebelumnya,
beberapa detik, beberapa menit yang lalu.
Jadi benar-benar bisa menjadi nomor atau surat sana, hanya kebetulan.
Tapi mereka tidak sah, sampai aku diriku mengisi sepotong ini memori
dengan karakter yang sebenarnya, seperti yang saya dilakukan dalam untuk loop di sana.
Baiklah?
>> Jadi sekarang, klimaks dari tiga contoh
yang tampaknya rusak terakhir kali, contoh Swap ini, fungsi ini
bekerja dalam arti bahwa bertukar a dan b.
Tapi itu tidak berhasil dalam arti lain apa?
Ya?
>> AUDIENCE: [Tak terdengar].
>> DAVID J. Malan: Tepat.
Jika saya harus memanggil fungsi ini dari another-- misalnya,
dari fungsi seperti utama, di mana Saya memiliki variabel, x dan y, seperti yang saya
lakukan minggu lalu, kode yang sama, dan saya lulus dalam x dan y
untuk swap, dan kemudian memanggil Swap-- ini, tentu saja, adalah versi yang benar
adalah apa yang kita akan see-- tidak berhasil.
Jadi apa memperbaiki?
>> Nah, jadi hanya menjadi jelas, biarkan aku pergi ke depan
dan-- Beri aku satu detik di sini, dan melihat jika saya bisa menunjukkan yang terakhir, yang
akan in-- mari kita lihat apakah saya dapat menemukan OK ini fast-- nyata, [Tak terdengar].
OK, itu dia.
Jadi mengabaikan perintah saya hanya mengetik.
Aku ingin mengambil di menit terakhir contoh
dari terakhir kali, yang sekarang disebut tidak Swap.
>> Jadi tidak ada Swap adalah di mana kami tinggalkan terakhir kali,
dimana, saya diinisialisasi x 1 dan y 2.
Saya kemudian menelepon Swap, lewat di 1 dan 2.
Dan kemudian fungsi ini bekerja dalam arti tertentu,
tapi itu tidak ada yang permanen berpengaruh terhadap x dan y.
Jadi pertanyaan di tangan adalah, bagaimana sekarang kita benar-benar memperbaiki masalah ini?
Apa solusi di tangan?
>> Nah, di swap.c, yang baru hari ini, melihat beberapa perbedaan.
x dan y adalah sama.
Tapi apa yang jelas berbeda tentang garis 25?
Apa yang baru di sana, jika Anda ingat apa yang tampak seperti detik yang lalu?
>> AUDIENCE: [Tak terdengar].
>> DAVID J. Malan: Ya.
Jadi ampersands adalah bagian baru sintaksis tidak hanya dalam program ini,
tetapi juga lebih umum di CS50.
Sampai saat ini, saya tidak berpikir kita telah melihat contoh-contoh
atau benar-benar berbicara tentang mereka dalam detail, selain, mungkin, Terlebih Dahulu
dalam bagian, ampersand seperti ini.
Nah, ternyata ampersand adalah salah satu potongan terakhir dari sintaks baru
kita akan belajar.
Semua itu berarti adalah alamat beberapa variabel.
Apa alamat yang x hidup?
Tapi apa alamat yang y hidup?
Karena jika masalah mendasar sebelum
adalah bahwa x dan y sedang berlalu sebagai salinan, apa yang kita ingin lakukan
adalah menyediakan Swap dengan seperti harta peta yang mengarah ke mana x dan y benar-benar
dalam RAM, sehingga Swap dapat mengikuti peta yang
dan pergi ke mana pun x atau y menandai tempat dan mengubah nilai-nilai aktual 1 dan 2
ada.
>> Jadi Swap perlu mengubah sedikit terlalu.
Dan pada pandangan pertama, kekuatan ini tampak sedikit mirip dengan bintang arang.
Dan sesungguhnya adalah.
Jadi adalah pointer ke jenis data, sesuai porsi yang disorot ini?
Jadi itu adalah int.
>> Jadi tidak lagi int, itu adalah alamat dari sebuah int.
Dan sama, b sekarang akan menjadi alamat dari sebuah int.
Jadi ketika saya sekarang memanggil swap dari Main, Aku tidak akan memberikan Swap 1 dan 2.
Aku akan memberikannya seperti Ox-sesuatu dan Ox-sesuatu,
dua alamat yang akan memimpin Swap ke lokasi mereka yang sebenarnya
dalam memori komputer saya.
>> Jadi sekarang, implementasi saya yang tersisa perlu mengubah anak laki-laki.
Apa jelas berbeda sekarang dalam tiga baris kode?
Ada bintang sialan ini semua tempat, oke?
Jadi apa yang terjadi di sini?
Ya?
>> AUDIENCE: Ini jelas [Tak terdengar].
>> DAVID J. Malan: Tepat.
Jadi dalam context-- ini dan ini tidak keputusan desain yang terbaik, diakui,
tahun yang lalu.
Dalam konteks ini, di mana Anda hanya memiliki bintang,
dan Anda tidak memiliki tipe data, seperti int, segera ke kiri,
sebaliknya Anda memiliki tanda yang sama, jelas, dalam konteks ini, ketika Anda mengatakan membintangi sebuah,
itu berarti pergi ke alamat yang di.
Ikuti peta harta karun, sehingga untuk berbicara.
>> Dan sementara itu, sejalan 37, itu berarti hal yang sama.
Pergi ke alamat, dan menempatkan apa ada?
Apapun yang di lokasi yang b menentukan.
Dengan kata lain, pergi ke b.
Dapatkan nilai tersebut.
Pergi ke dan, per sederajat menandatangani, operator penugasan,
menempatkan nilai yang ada.
>> Demikian pula, int temp hanya int.
Tidak perlu mengubah tentang temp.
Ini hanya segelas cadang dari Annenberg untuk beberapa susu atau jus jeruk.
Tapi aku harus mengatakan, pergi ke b.
Pergi ke tujuan itu dan menempatkan nilai dalam suhu di sana.
Jadi apa yang terjadi kemudian?
Ketika saya benar-benar menyebutnya Swap saat ini, jika baki pertama ini di sini mewakili Main,
tray kedua ini merupakan Swap, ketika Saya lulus ampersand x dan y ampersand
dari Main untuk swap, hanya harus jelas, apa frame ini menerima tumpukan?
Ya?
>> AUDIENCE: [Tak terdengar].
DAVID J. Malan: Tepat.
Alamat x dan alamat y.
Dan Anda bisa memikirkan ini seperti alamat pos.
33 Oxford Street dan 35 Oxford Street, dan Anda
ingin memindahkan dua bangunan yang berada di lokasi tersebut.
>> Ini semacam ide konyol, tapi itu semua kita maksud dengan alamat.
Dimana di dunia dapat Anda menemukan dua ints?
Dimana di dunia dapat Anda menemukan dua bangunan?
Jadi, jika akhirnya, setelah sekian lama saya masuk ke kode sumber saat ini dan kompilasi
Swap dan menjalankan ./swap, akhirnya, untuk pertama kalinya kita benar-benar melihat bahwa
nilai-nilai saya memang memiliki telah bertukar berhasil.
Dan sekarang, kita bahkan dapat mengambil catatan ini, katakanlah, gdb.
>> Jadi biarkan aku pergi ke file yang sama.
Biarkan aku pergi ke depan dan menjalankan gdb dari ./swap.
Dan sekarang, di Swap, aku akan pergi depan dan menetapkan titik istirahat di Main.
Dan sekarang aku akan pergi depan dan menjalankan program.
Dan sekarang kita melihat kode saya berhenti di jalur itu.
>> Jika saya pergi ke depan dan mencetak x, apa yang harus saya lihat di sini?
Ini pertanyaan.
Katakanlah lagi?
>> AUDIENCE: [Tak terdengar].
>> DAVID J. Malan: Jadi nomor acak, mungkin.
Mungkin aku beruntung, dan itu bagus dan sederhana, seperti 0.
Tapi mungkin itu beberapa nomor acak.
Dalam hal ini, aku beruntung.
Itu hanya kebetulan 0.
Tapi itu memang keberuntungan, karena tidak sampai aku
ketik berikutnya dan kemudian cetak x memiliki yang baris kode, baris 19, telah dieksekusi.
>> Sementara itu, jika saya ketik berikutnya lagi, dan sekarang mencetak y, aku akan melihat 2.
Sekarang, jika saya ketik selanjutnya, itu akan mendapatkan sedikit membingungkan, karena sekarang,
printf ini akan muncul di layar, seperti yang terjadi. x adalah 1.
>> Mari kita lakukan ini lagi.
Dan sekarang, di sinilah hal-hal menarik.
Sebelum saya sebut Swap atau bahkan langkah ke dalamnya, mari kita sedikit mengintip.
x adalah, sekali lagi, 1.
Y adalah, tentu saja, kewarasan cepat cek, 2, jadi tidak keras di sana.
Tapi apa ampersand x?
Jawaban, itu agak funky mencari.
Tapi bintang int dalam kurung hanya Cara GDP ini mengatakan ini adalah alamat.
Ini bukan sebuah int, itu adalah pointer ke int, atau dikenal sebagai alamat.
>> Apa hal gila ini?
Kami belum pernah melihat sesuatu cukup seperti itu sebelumnya.
Jadi ini adalah alamat di komputer saya memori di mana x kebetulan tinggal.
Ini Ox-sesuatu.
Dan ini, terus terang, mengapa Saya sudah mulai menggambar panah,
bukan angka, karena siapa yang benar-benar peduli
bahwa int Anda berada pada tertentu alamat yang begitu besar.
Tapi bffff0c4, ini semua memang digit heksadesimal,
yang adalah 0 sampai f.
>> Jadi kita tidak akan tinggal terlalu panjang tentang apa hal-hal itu.
Tapi kalau aku mencetak y, tentu saja, saya melihat 2.
Tapi ampersand y, saya melihat alamat ini.
Dan perhatikan, bagi yang penasaran, seberapa jauh adalah x dan y?
Anda dapat mengabaikan sebagian besar alamat.
Empat bytes.
Dan itu konsisten dengan kami sebelumnya mengklaim bahwa seberapa besar adalah int?
Empat bytes.
Jadi sepertinya semuanya berbaris baik, seperti yang mungkin Anda harapkan, dalam memori.
>> Jadi sekarang, mari kita maju cepat sampai akhir cerita ini.
Mari kita pergi ke depan dan ketik langkah, untuk menyelam ke dalam fungsi Swap.
Sekarang perhatikan, jika saya ketik, itu identik dengan alamat x.
Jika saya ketik b, itu identik ke alamat y.
Jadi apa yang harus saya melihat apakah saya mengatakan, pergi ke alamat itu?
Jadi mencetak membintangi sebuah.
Jadi Bintang berarti pergi ke sana, dalam konteks ini.
Ampersand berarti apa alamat.
Jadi membintangi sarana 1.
Dan Bintang cetak b memberi saya 2.
>> Dan biarkan aku berasumsi, untuk saat ini, bahwa setidaknya kode yang
hasil untuk mengeksekusi sekarang dapat beralasan melalui cara itu.
Tapi kita akan kembali ide ini tak lama.
Jadi versi Swap sekarang benar dan memungkinkan
kita untuk menukar jenis data tertentu.
>> Jadi pertanyaan kemudian Swap?
Pada bintang?
Pada alamat?
Dan Anda akan melihat, dengan masalah set 4, semacam,
tapi masalahnya set 5, pasti, bagaimana hal-hal yang berguna dan mendapatkan lebih banyak
nyaman dengan mereka, sebagai hasilnya.
Apa saja?
Baiklah.
Jadi malloc adalah, sekali lagi, fungsi ini yang hanya mengalokasikan memori, memori
alokasi.
Dan mengapa ini berguna?
Nah, selama ini, Anda telah menggunakan malloc.
Jika Anda menganggap sekarang bagaimana GetString bekerja, mungkin, itu
telah meminta seseorang untuk sepotong memori, kapan saja pengguna jenis string
in, karena kita pasti tidak tahu, sebagai staf CS50,
seberapa besar mereka string bahwa manusia akan mengetik mungkin.
>> Jadi mari kita, untuk pertama kalinya, mulai mengupas kembali cara kerja perpustakaan CS50,
dengan cara beberapa contoh yang akan membawa kita ke sana.
Jadi jika saya membuka gedit dan membuka scanf 0,
kita akan melihat kode berikut.
Scanf 0, tersedia di situs web untuk hari ini, relatif sedikit baris kode
di sini, 14 sampai 20.
Dan mari kita lihat apa yang dilakukannya.
Ini menyatakan int, yang disebut x.
Ia mengatakan sesuatu seperti, nomor silakan.
Dan sekarang ia mengatakan, scanf% i, & x.
Jadi ada banyak hal baru di sana.
>> Tapi scanf, Anda dapat jenis berpikir sebagai kebalikan dari printf.
printf, tentu saja, cetakan ke layar.
semacam scanf scan dari pengguna Keyboard sesuatu ia telah diketik.
>> % I adalah seperti printf.
Ini berarti mengharapkan pengguna untuk mengetik int.
Dan sekarang, mengapa kau pikir aku mungkin lewat scanf & x?
Jika tujuan dalam kehidupan scanf adalah untuk mendapatkan sesuatu dari pengguna,
apa arti dari lewat itu, & x, sekarang?
Ya?
>> AUDIENCE: [Tak terdengar].
DAVID J. Malan: Tepat.
Apa pun yang saya, manusia, ketik, masukan saya akan disimpan di lokasi itu.
Ini tidak cukup, ingat, hanya lulus dalam x, karena kita telah melihat sudah,
setiap kali Anda melewati hanya variabel baku, seperti int, beberapa fungsi lain,
yakin, itu bisa mengubah itu variabel, tapi tidak secara permanen.
Hal ini tidak dapat memiliki efek pada Main.
Ini hanya dapat mengubah salinan lokal sendiri.
Tapi jika, sebaliknya, Anda tidak memberi saya int sebenarnya,
tapi Anda memberi saya petunjuk untuk bahwa int, saya sekarang, menjadi scanf,
pasti, saya bisa mengikuti alamat dan menempatkan nomor ada
sehingga Anda memiliki akses ke sana juga.
>> Jadi ketika saya menjalankan program ini, mari kita lihat.
Membuat scanf 0 dot slash, scanf 0.
Dan jika sekarang saya ketik nomor seperti 50, terima kasih atas 50.
Jika sekarang saya mengetik nomor seperti negatif 1, untuk yang negatif 1.
Sekarang saya ketik nomor seperti 1.5, hm.
Mengapa program saya mengabaikan saya?
Nah, karena sederhana, saya mengatakan untuk mengharapkan int saja.
Baiklah.
Jadi itu salah satu versi ini.
Mari kita mengambil hal-hal takik dan mengusulkan bahwa ini tidak baik.
Dan di sinilah letak contoh yang sangat sederhana tentang bagaimana kita dapat mulai menulis kode
bahwa orang lain dapat memanfaatkan atau kompromi dengan melakukan hal-hal buruk.
Jadi baris 16, jadi mirip semangat yang sebelumnya,
tapi aku tidak menyatakannya int saat ini.
Saya menyatakan itu bintang char, alias tali.
>> Tapi apa yang benar-benar berarti?
Jadi jika saya tidak menentukan address-- dan Aku menyebutnya sewenang-wenang, penyangga,
tapi aku bisa menyebutnya s, menjadi simple-- dan kemudian saya melakukan ini, menjelaskan kepada saya,
jika Anda bisa, berdasarkan sebelumnya logika, apa yang scanf lakukan di baris 18,
jika lulus% s dan penyangga, yang merupakan alamat?
Apa scanf, jika Anda menerapkan Logika yang sama persis seperti versi 0,
akan mencoba untuk lakukan di sini, ketika jenis pengguna sesuatu?
Ya?
>> AUDIENCE: [Tak terdengar].
>> DAVID J. Malan: Tepat.
Scanf, berdasarkan logika sebelumnya, akan mengambil string
bahwa diketik manusia in-- itu sekarang string,
itu bukan angka, mungkin, jika ia cooperates--
dan itu akan mencoba untuk menempatkan bahwa string dalam memori pada alamat apapun
penyangga menentukan.
Dan ini besar, karena penyangga memang dimaksudkan untuk menjadi alamat.
>> Tapi saya mengklaim program ini adalah kereta di cara yang sangat serius, karena apa yang nilainya
penyangga secara default?
Apa yang telah saya diinisialisasi ke?
Apa sepotong memori?
Aku belum, kan?
>> Jadi meskipun aku sudah dialokasikan Bintang arang yang tidak lagi disebut s,
itu bukan disebut, buffer-- sehingga mari kita menggambar nama variabel
sekarang seperti buffer-- jika saya belum disebut getString atau malloc sini,
yang secara efektif berarti bahwa buffer hanyalah beberapa nilai sampah.
>> Sekarang apa artinya?
Ini berarti bahwa saya telah mengatakan kepada scanf yang diharapkan string dari pengguna.
Dan kau tahu apa?
Apapun hal ini menunjuk untuk-- dan saya menggambar tanda tanya,
namun pada kenyataannya, itu akan menjadi sesuatu seperti OX1, 2, 3, kan?
Ini beberapa nilai palsu yang hanya kebetulan ada dari sebelumnya.
Jadi dengan kata lain, itu seolah-olah penyangga hanya
menunjuk ke sesuatu dalam memori.
Saya tidak tahu apa.
>> Jadi jika saya ketik di gabe sekarang, itu akan mencoba untuk menempatkan g-a-b-e / 0 sana.
Tapi siapa yang tahu apa itu?
Dan di masa lalu, setiap Waktu kita sudah mencoba untuk menyentuh
memori yang bukan milik kepada kami, apa yang terjadi?
Atau hampir setiap waktu.
Segmentation fault, kan?
>> Panah ini, saya tidak tahu di mana itu menunjuk. itu hanya beberapa nilai acak.
Dan tentu saja, jika Anda menafsirkan nilai acak sebagai alamat,
Anda akan pergi ke beberapa tujuan acak.
Jadi gabe mungkin memang kecelakaan program saya dalam hal ini di sini.
>> Jadi apa yang bisa kita lakukan itu hampir sama buruknya?
Pertimbangkan ini ketiga dan Contoh terakhir dari scanf.
Versi ini lebih baik dalam arti apa?
Jika Anda merasa nyaman dengan soal sebelumnya, ini lebih baik.
Mengapa?
>> AUDIENCE: [Tak terdengar].
DAVID J. Malan: Good.
Jadi hal ini baris 16 lebih baik, dalam arti
bahwa kita secara eksplisit mengalokasikan beberapa memori.
Kami tidak menggunakan malloc, kita menggunakan minggu 2
Pendekatan hanya mendeklarasikan array.
Dan kami telah mengatakan sebelumnya bahwa string hanya sebuah array karakter,
jadi ini benar-benar sah.
Tapi itu, tentu saja, seperti Anda perhatikan, ukuran tetap, 16.
>> Jadi program ini adalah benar-benar aman, jika saya ketik
dalam satu karakter string, dua karakter string, 15 string karakter.
Tapi begitu aku mulai mengetik 16, 17, 18, 1.000 string karakter,
di mana string yang akan berakhir?
Ini akan berakhir sebagian di sini.
Tapi kemudian siapa tahu apa lagi berada di luar batas-batas
array tertentu?
>> Seolah-olah aku sudah menyatakan 16 kotak di sini.
Jadi daripada menarik keluar semua 16, kita akan hanya berpura-pura bahwa saya telah ditarik 16.
Tapi jika saya kemudian mencoba untuk membaca string itu lebih lama, seperti 50 karakter,
Aku akan mulai menempatkan a, b, c, d, x, y, z.
Dan ini mungkin beberapa segmen memori lain
itu, sekali lagi, dapat menyebabkan program saya untuk kecelakaan,
karena saya sudah tidak meminta sesuatu yang lebih dari hanya 16 byte.
>> Jadi siapa yang peduli?
Nah, inilah perpustakaan CS50.
Dan sebagian besar ini hanya seperti petunjuk di bagian atas.
The CS50 perpustakaan, selama ini, memiliki baris ini sejalan 52.
Kami telah melihat typedef, atau Anda akan melihat typedef
di PSET 4, yang hanya menciptakan sinonim dimana bintang arang bisa lebih
hanya disebut sebagai string.
Jadi ini adalah salah satu beberapa roda pelatihan
kami telah digunakan secara diam-diam di bawah tenda.
>> Sementara itu, inilah fungsi, getchar.
Sekarang tampaknya, tidak ada tubuh untuk itu.
Dan pada kenyataannya, jika aku terus bergulir, saya tidak benar-benar
melihat implementasi fungsi ini.
Sebagai sebuah pemeriksaan, kenapa begitu?
>> AUDIENCE: [Tak terdengar].
DAVID J. Malan: Ya.
Jadi ini adalah file header.
Dan file header berisi prototipe, ditambah beberapa hal lain, tampaknya,
seperti typedef.
Tapi di CS50.c, yang kami telah tidak pernah memberi Anda langsung,
namun telah di alat CS50 semua kali ini, jauh di dalam folder tersebut,
melihat bahwa ada seluruh banyak fungsi di sini.
>> Bahkan, mari kita gulir ke bawah.
Mari kita mengabaikan sebagian besar dari mereka, untuk saat ini.
Tapi gulir ke bawah ke getInt dan melihat bagaimana getInt bekerja.
Jadi di sini adalah getInt.
Dan jika Anda pernah benar-benar peduli bagaimana mendapatkan int bekerja, di sini adalah dokumentasinya.
Dan di antara hal-hal yang dikatakannya adalah ia memberitahu Anda
apa rentang nilai dapat kembali.
Ini dasarnya negatif 2 miliar ke positif 2 miliar, memberi atau mengambil.
>> Dan ternyata, semua ini waktu, meskipun kita belum pernah
telah Anda memeriksa untuk itu, jika terjadi kesalahan,
ternyata semua kali ini, getInt memiliki
telah kembali khusus konstan, tidak nol,
melainkan INT_MAX, yang konvensi hanya programmer.
Artinya di sini adalah nilai khusus.
Pastikan untuk memeriksa ini, hanya jika sesuatu berjalan salah.
Tapi kami tidak pernah terganggu dengan bahwa sampai saat ini,
karena lagi-lagi, ini dimaksudkan untuk menyederhanakan.
>> Tapi bagaimana getInt bisa dilaksanakan?
Nah, satu, dibutuhkan tanpa argumen.
Kita tahu bahwa.
Ini mengembalikan sebuah int.
Kita tahu bahwa.
Jadi bagaimana cara kerjanya di bawah tenda?
>> Jadi ada tampaknya tak terbatas lingkaran, setidaknya munculnya satu.
Perhatikan bahwa kita menggunakan getString.
Jadi itu menarik. getInt panggilan fungsi kita sendiri, getString.
Dan sekarang, mengapa hal ini menjadi kasus ini?
Mengapa saya menjadi defensif di sini sejalan 165?
Apa yang bisa terjadi sejalan 164, hanya harus jelas?
Ini jawaban yang sama seperti sebelumnya.
Mungkin saja dari memori.
Sesuatu yang tidak beres dengan getString, kita harus bisa mengatasinya.
Dan alasan saya tidak kembali nol itu, secara teknis, null pointer.
getInt harus mengembalikan int.
Jadi saya sudah sewenang-wenang memutuskan, pada dasarnya,
bahwa 2 miliar, memberi atau mengambil, akan menjadi nilai khusus yang saya tidak pernah bisa
benar-benar mendapatkan dari pengguna.
Hanya saja satu nilai aku akan menyia-nyiakan untuk mewakili kode kesalahan.
>> Jadi sekarang, hal-hal yang sedikit mewah.
Dan itu tidak cukup fungsi yang sama seperti sebelumnya, tapi itu sangat mirip.
Jadi perhatikan, saya menyatakan di sini, sejalan 172, baik sebagai n int dan char c.
Dan kemudian saya menggunakan baris yang funky ini, sscanf, yang ternyata
tidak memindai string dari keyboard.
Ia berdiri string yang sudah ada yang pengguna telah diketik dalam.
Jadi saya sudah menelepon getString, yang berarti saya punya string dalam memori.
sscanf adalah apa yang akan Anda memanggil fungsi parsing.
Ini terlihat pada string saya sudah mengetik, karakter demi karakter,
dan melakukan sesuatu yang bermanfaat.
String yang disimpan dalam antrean.
Dan aku tahu bahwa hanya dengan pergi cadangan sini dan berkata, oh, OK,
Aku menyebutnya tidak s kali ini, tapi garis.
>> Dan sekarang ini sedikit berbeda.
Tapi ini secara efektif berarti, karena alasan kita akan agak gelombang tangan kami di hari ini,
bahwa kita memeriksa untuk melihat apakah pengguna mengetik
dan int dan mungkin karakter lain.
Jika pengguna mengetik int, itu akan disimpan dalam n, karena aku
melewati ini dengan alamat, yang trik baru kita lihat hari ini.
Jika pengguna juga diketik dalam seperti 123x, bahwa x
akan berakhir suatu huruf dalam karakter c.
>> Sekarang ternyata sscanf yang akan saya kirim, cerdas,
berapa banyak variabel yang sscanf berhasil mampu mengisi.
Jadi dengan logika ini, jika fungsi Aku menerapkan adalah getInt,
tapi aku memeriksa, berpotensi, bagi pengguna
telah diketik dalam int diikuti oleh sesuatu yang lain,
apa yang ingin saya sscanf dunia nilai kembali benar-benar menjadi?
Jika tujuannya adalah untuk mendapatkan hanya int dari pengguna?
>> Jadi jika sscanf kembali 2, apa artinya?
Pengguna mengetik sesuatu seperti, secara harfiah,
123x, yang hanya omong kosong.
Ini kondisi kesalahan, dan Saya ingin memeriksa untuk itu.
>> Jadi jika pengguna jenis ini di, berdasarkan logika ini, apa sscanf kembali,
yang akan Anda katakan?
Jadi itu akan kembali 2, karena 123 akan masuk di sini,
dan x yang akan berakhir di sini.
Tapi aku tidak ingin x untuk mendapatkan diisi.
Saya ingin sscanf hanya berhasil dalam mengisi pertama variabel tersebut.
Dan itulah mengapa saya ingin sscanf untuk kembali 1.
>> Dan jika ini adalah sedikit di atas kepala untuk saat ini, itu benar-benar baik-baik saja.
Sadarilah meskipun, bahwa salah satu nilai getInt dan getString
adalah bahwa kita sedang melakukan heck of a banyak pengecekan error seperti ini sehingga
bahwa, sampai saat ini, Anda dapat cukup banyak mengetikkan apapun di keyboard Anda,
dan kami akan menangkapnya.
Dan kita yang pasti, staf, pasti akan tidak
menjadi sumber bug dalam Anda Program, karena kita membela diri
memeriksa semua bodoh hal-hal yang pengguna dapat lakukan,
seperti mengetik string, ketika Anda benar-benar ingin int.
Jadi untuk sekarang-- akan kita datang kembali ke ini sebelum long--
tapi selama ini, getString dan getInt memiliki
pernah di bawah kap menggunakan ini Ide dasar dari alamat memori.
>> Jadi sekarang, mari kita membuat hal-hal sedikit lebih user-friendly.
Seperti yang Anda ingat, dari Binky lalu time-- jika mouse saya akan cooperate-- sehingga
kami memiliki kode ini, yang terus terang, cukup masuk akal.
Kode ini mencapai apa-apa berguna, tapi itu contoh
bahwa profesor Parlante digunakan untuk mewakili
apa yang sedang terjadi di program yang melibatkan memori.
>> Jadi mari kita menyadur ini cerita yang super singkat.
Kedua baris pertama, di Inggris, melakukan apa, akan Anda katakan?
Hanya dalam cukup manusia, tetapi sedikit istilah teknis, mengambil bacokan.
AUDIENCE: [Tak terdengar].
>> DAVID J. Malan: OK, Anda membangun alamat untuk x dan variabel y.
Tidak cukup, karena x dan y tidak variabel dalam arti tradisional.
x dan y adalah alamat atau akan menyimpan alamat.
Jadi mari kita coba ini sekali lagi.
Bukan awal yang buruk, meskipun.
Ya?
>> AUDIENCE: [Tak terdengar].
DAVID J. Malan: Good.
Saya pikir itu sedikit lebih bersih.
Mendeklarasikan dua pointer, dua bilangan bulat.
Dan kami memanggil mereka x dan y.
Atau jika kita menggambar ini sebagai sebuah gambaran, sekali lagi,
ingat cukup sederhana bahwa semua kita lakukan dengan baris pertama
menggambar kotak seperti ini, dengan beberapa nilai sampah di dalamnya,
dan menyebutnya x, dan kemudian kotak yang lain seperti ini,
dengan beberapa nilai sampah di dalamnya, menyebutnya y.
Kami telah menyatakan dua pointer yang pada akhirnya
akan menyimpan alamat dari sebuah int.
Jadi itu semua ada.
>> Jadi ketika Binky melakukan ini, liat hanya tampak seperti ini.
Dan Nick hanya jenis membungkus panah,
seolah-olah mereka tidak menunjuk mana saja khususnya, karena mereka hanya
nilai sampah.
Mereka tidak secara eksplisit diinisialisasi mana saja pada khususnya.
>> Sekarang baris berikutnya kode, ingat, adalah ini.
Jadi cukup user-friendly, tetapi bahasa Inggris agak teknis,
apa baris kode lakukan?
Ya?
>> AUDIENCE: [Tak terdengar].
>> DAVID J. Malan Perfect.
Ini mengalokasikan sepotong dari memori yang ukuran int.
Dan itu setengah jawabannya.
Anda menjawab kanan setengah dari ekspresi.
Apa yang terjadi pada sisi kiri dari tanda sama?
Ya?
AUDIENCE: Dan menugaskan ke variabel x?
>> DAVID J. Malan: Dan menugaskan ke variabel x.
Jadi untuk rekap, kanan mengalokasikan sisi memori yang cukup untuk menyimpan int.
Tapi malloc khusus mengembalikan alamat
itu sepotong memori, yang Anda sudah hanya diusulkan akan disimpan di x.
>> Jadi apa Nick lakukan terakhir kali dengan Binky adalah ia menyeret pointer yang keluar, tanah liat,
untuk menunjuk sekarang di sepotong putih memori yang sama dengan ukuran sebuah int.
Dan memang, yang dimaksudkan untuk mewakili empat byte.
>> Sekarang, baris berikutnya kode melakukan ini, bintang x mendapat 42.
Jadi 42 sangat mudah di sisi kanan, makna hidup.
Sisi kiri, bintang x berarti apa?
Itu juga mungkin memiliki gone-- itu OK.
OK.
>> AUDIENCE: Pada dasarnya, pergi ke [Tak terdengar]
DAVID J. Malan: Good.
AUDIENCE: [Tak terdengar].
DAVID J. Malan: Tepat.
Sisi kiri berarti pergi ke x.
x adalah alamat.
Hal ini seperti 33 Oxford Street, atau OX1.
Dan Bintang x berarti pergi ke yang alamat dan menempatkan apa ada?
42.
>> Jadi memang, itulah yang dilakukan Nick.
Dia mulai dengan oleh, dasarnya, mental
menunjuk jari pada x, berikut panah
ke kotak putih di kanan sisi, dan menempatkan nomor 42 di sana.
Tapi kemudian hal mendapat sedikit berbahaya, kan?
Binky tentang kehilangan kepalanya.
>> Bintang y sama dengan 13, nasib buruk, berarti apa?
Jadi Bintang y cara pergi ke alamat di y.
Tapi apa adalah alamat di y?
Baiklah, itu adalah nilai sampah, kan?
Aku menarik sebagai tanda tanya.
Nick menarik sebagai meringkuk panah.
Dan segera setelah Anda mencoba untuk melakukan star y, mengatakan pergi ke sana,
tapi tidak ada yang sah alamat, itu beberapa lokasi palsu,
program akan crash.
Dan kepala Binky ini akan untuk terbang di sini, seperti yang terjadi.
>> Jadi pada akhirnya, program ini hanya datar keluar cacat.
Itu program kereta.
Dan itu perlu diperbaiki.
Dan satu-satunya cara, benar-benar, untuk memperbaikinya akan, misalnya, baris ini,
yang kita bahkan tidak bisa, karena Program jatuh terlalu cepat.
Tapi jika kita untuk memperbaiki hal ini, apa yang Efek tidak melakukan y sama x miliki?
Yah, pada dasarnya poin y di nilai apa pun x menunjuk.
>> Jadi dalam cerita Nick, atau cerita Binky, baik
x dan y yang menunjuk potongan putih memori,
sehingga, akhirnya, ketika Anda jangan membintangi y sama dengan 13 lagi,
Anda akhirnya menempatkan 13 di lokasi yang sesuai.
Jadi semua lini ini sempurna sah, kecuali untuk yang satu ini,
ketika itu terjadi sebelum Anda sebenarnya ditugaskan y beberapa nilai.
>> Sekarang untungnya, Anda tidak harus melalui semua alasan
jenis-jenis masalah pada Anda sendiri.
Biarkan aku pergi ke depan dan membuka sebuah jendela terminal sini
dan membuka, untuk sesaat, program super pendek yang
juga adalah semacam sia-sia.
Ini jelek.
Itu tidak mencapai sesuatu yang berguna.
Tapi itu menunjukkan masalah memori, jadi mari kita lihat.
>> Main, super sederhana.
Rupanya panggilan fungsi, f, dan kemudian kembali 0.
Ini agak sulit untuk kekacauan ini.
Jadi Main cukup baik, sejauh ini.
>> Jadi f bermasalah.
Dan hanya tidak menempatkan banyak usaha dalam penamaan itu
di sini, untuk menjaga fokus pada kode.
f memiliki dua jalur.
Dan mari kita lihat apa yang sekarang terjadi.
Jadi di satu sisi di sini-dan biarkan aku membuat
ini konsisten dengan sebelumnya example-- di satu sisi,
sisi kiri adalah melakukan apa, dalam bahasa Inggris?
Ini Ini--
AUDIENCE: Menciptakan pointer.
DAVID J. Malan: Membuat pointer ke int dan menyebutnya x.
Jadi itu membuat salah satu kotak Aku terus menggambar pada layar sentuh.
Dan sekarang, di kanan sisi, malloc, tentu saja,
mengalokasikan sepotong memori.
Dan hanya harus jelas, bagaimana banyak memori itu rupanya
mengalokasikan, jika Anda hanya jenis melakukan matematika di sini?
>> Jadi 40 byte.
Dan aku tahu bahwa hanya karena saya tahu suatu int, pada alat CS50, setidaknya,
adalah empat byte.
Jadi 10 kali 4 adalah 40.
Jadi ini adalah menyimpan suatu x, alamat dari keluar pertama dari 40 int yang
telah dialokasikan ruang belakang, ke belakang, ke belakang, ke belakang.
>> Dan itulah yang penting tentang malloc.
Tidak perlu memori kecil di sini, sedikit di sini, sedikit di sini.
Ini memberi Anda satu sepotong memori, contiguously, dari operasi
sistem.
>> Sekarang apa tentang hal ini, x braket 10 sama dengan 0?
Baris Sewenang-wenang kode.
Itu tidak mencapai sesuatu yang berguna.
Tapi itu menarik, karena x braket 10--?
Ya?
>> AUDIENCE: [Tak terdengar]?
>> DAVID J. Malan: x braket 10 tidak harus nol.
Null rinci hanya datang ke dalam bermain dengan string, pada akhir string.
Tapi pikiran yang baik.
>> Seberapa besar adalah array ini, bahkan meskipun aku sudah dialokasikan 40 bytes?
Ini 0 sampai sembilan, kan?
Ini 10 int, jumlah.
40 byte, tetapi 10 int, diindeks dari 0 sampai 0.
>> Jadi apa itu x braket 10?
Ini sebenarnya beberapa nilai sampah yang tidak diketahui.
Ini memori yang bukan milik saya.
Aku tidak boleh menyentuh bahwa byte nomor 41, 42, 43, 44.
Aku akan sedikit terlalu jauh.
>> Dan memang, jika saya menjalankan ini program, mungkin sangat baik kecelakaan.
Tapi kadang-kadang, kita akan beruntung.
Dan jadi hanya untuk menunjukkan ini-- dan terus terang,
Anda tidak pernah tahu sebelum Anda jangan itu-- mari kita jalankan ini.
Itu tidak benar-benar kecelakaan.
>> Tapi jika saya mengubah ini, untuk Misalnya, untuk menjadi seperti 1.000,
untuk membuat ini benar-benar disengaja, mari kita lihat
jika kita bisa mendapatkannya untuk kecelakaan kali ini.
OK, itu tidak crash.
Bagaimana sekitar 100.000?
Mari kita membuat kembali, dan sekarang jalankan kembali itu.
OK.
Fiuh.
Baiklah.
Jadi tampaknya, sekali lagi, ini segmen memori, sehingga untuk berbicara,
yang cukup besar, sehingga kami dapat beruntung lagi dan lagi.
Tapi akhirnya, setelah Anda mendapatkan konyol dan benar-benar pergi jauh keluar di layar,
Anda menyentuh memori yang benar-benar, benar-benar bukan milik Anda.
>> Tapi terus terang, ini jenis bug akan
lebih sulit dan lebih sulit untuk mencari tahu sendiri.
Tapi untungnya, sebagai programmer, kita harus alat yang memungkinkan kita untuk melakukan hal ini untuk kita.
Jadi ini, mungkin, salah satu program paling jelek,
bahkan lebih jelek dari keluaran gdb ini.
Namun selalu memiliki garis atau dua yang super berguna.
>> Valgrind adalah program yang membantu Anda tidak men-debug program, per se,
tetapi menemukan memori terkait masalah, khususnya.
Ini akan otomatis menjalankan kode Anda untuk Anda dan mencari setidaknya dua hal.
Satu, apakah Anda melakukan sesuatu disengaja seperti memori sentuh
yang bukan milik Anda?
Ini akan membantu Anda menemukan kasus-kasus.
>> Dan dua, itu akan membantu Anda menemukan sesuatu yang disebut
kebocoran memori, yang kita miliki benar-benar diabaikan, naif,
untuk beberapa waktu dan bahagia.
Tapi ternyata, semua kali ini, setiap kali
Anda telah disebut getString di begitu banyak program kita,
Anda meminta operasi sistem memori,
tetapi Anda memiliki ingatan apapun dari yang pernah memberikan
kembali, melakukan unalloc, atau bebas, seperti disebut.
Tidak, karena kami belum pernah meminta Anda untuk melakukannya.
>> Tapi selama ini, program-program Anda telah menulis di C
telah bocor memori, meminta operasi
sistem untuk lebih dan lebih memori untuk string dan yang lainnya,
tetapi tidak pernah menyerahkan kembali.
Dan sekarang ini agak sedikit terlalu menyederhanakan sebuah,
tetapi jika Anda sudah pernah menjalankan Mac atau PC Anda untuk beberapa waktu, pembukaan
banyak program, mungkin menutup program,
dan meskipun Anda komputer belum jatuh,
itu semakin jauh lebih lambat, seolah-olah itu benar-benar
menggunakan banyak memori atau sumber daya, meskipun,
jika Anda tidak bahkan menyentuh keyboard,
yang bisa akan-- tapi tidak bisa always-- bahwa program yang Anda jalankan
memiliki sendiri kebocoran memori.
Dan mereka terus bertanya OS untuk lebih dan lebih banyak memori, tetapi melupakan tentang hal itu,
tidak benar-benar menggunakannya, tapi Oleh karena itu mengambil memori menjauhi
dari program lain yang mungkin menginginkannya.
Jadi itulah penjelasan umum.
Sekarang di sinilah Valgrind ini Output benar-benar
mengerikan untuk mereka yang kurang dan lebih mirip nyaman.
Tapi yang menarik hal yang benar di sini.
Hal ini memberitahu saya sebuah menulis tidak valid ukuran empat terjadi dalam program ini,
khususnya, pada baris 21 dari memory.c.
>> Jika saya pergi ke baris 21, hm, memang ada adalah menulis valid ukuran empat.
Mengapa ukuran empat?
Nah, number-- ini dan itu bisa anything-- adalah int.
Jadi empat byte.
Jadi aku menempatkan empat byte di mana mereka tidak termasuk.
Itulah yang Valgrind sebenarnya mengatakan.
Selain itu, juga akan katakan padaku, karena kami akan melihat,
karena Anda menjalankan ini dalam PSET masa depan, jika dan ketika Anda sudah bocor memori, yang memang
Aku punya, karena saya sudah menelepon malloc, tapi aku belum benar-benar
disebut, dalam hal ini, gratis, yang pada akhirnya kita akan melihat
adalah kebalikan dari malloc.
>> Jadi sekarang, saya pikir, contoh terakhir.
Jadi yang satu ini sedikit lebih misterius, tapi itu mungkin
alasan terbesar untuk berhati-hati dengan memori,
dan alasan bahwa banyak program dan / atau server web, bahkan sampai hari ini,
diambil alih oleh orang-orang jahat di suatu tempat di internet yang entah bagaimana
mengirimkan paket palsu ke server Anda mencoba untuk berkompromi account Anda,
atau mengambil data Anda, atau hanya umumnya mengambil alih mesin.
Buffer overflow, sebagai nama menyarankan, berarti
meluap bukan int, tapi penyangga.
Dan buffer adalah cara mewah mengatakan itu adalah sekelompok memori.
>> Dan memang, aku menelepon string sebelum penyangga, bukan s.
Karena jika itu penyangga, seperti dalam arti YouTube,
atau setiap kali Anda sedang menonton video, Anda mungkin telah melihat buffering kata,
dot, dot, dot.
Ini sangat menjengkelkan.
Dan itu hanya berarti bahwa pemutar video Anda
sedang mencoba untuk men-download banyak byte, banyak byte
dari video dari internet.
Tapi itu lambat, sehingga mencoba untuk men-download banyak dari mereka
untuk mengisi buffer, wadah, sehingga Anda memiliki cukup bytes yang kemudian dapat
menampilkan video, tanpa berhenti terus-menerus.
Tapi ternyata, Anda bisa memiliki buffer ini besar.
Tapi cobalah untuk menempatkan banyak data ini dalam itu, dan sangat hal-hal buruk bisa terjadi.
Jadi misalnya, mari kita lihat teaser akhir ini sebuah contoh.
Ini adalah program lain itu, pada pandangan pertama,
tidak melakukan sesuatu yang super berguna.
Itu punya fungsi utama yang memanggil fungsi itu, f.
Dan fungsi itu, f, di sini, memiliki array char, disebut c, ukuran 12.
Dan kemudian ia menggunakan ini fungsi baru yang disebut strncpy.
>> Ternyata, dengan sederhana, baris kode sederhana, hanya dua baris,
kami telah membuat seluruh program saya, dan oleh karena itu, seluruh komputer saya,
dan akun pengguna saya, dan kerasku mendorong berpotensi rentan terhadap siapa pun
yang tahu dan cukup baik untuk menjalankan program ini dengan baris perintah tertentu
argumen.
Dengan kata lain, jika orang jahat ini menempatkan dalam argvargv [1] dengan mengetikkan
pada keyboard sangat khusus dibuat String, tidak abc, 123, tapi pada dasarnya,
simbol biner yang mewakili executable code, sebuah program yang ia menulis,
dengan program sederhana ini, yang perwakilan dari ribuan program
yang sama rentan, berani bilang, ia akhirnya dapat menghapus semua
file di harddisk, mendapatkan berkedip cepat sehingga ia dapat
mengetik perintah sendiri, email semua file untuk diriku sendiri.
Apa pun yang bisa saya lakukan, dia atau dia bisa lakukan dengan kode ini.
>> Kami tidak akan cukup mengatasi ini.
Dan pada kenyataannya, itu akan melibatkan sedikit gambaran
seperti ini, yang kami akan segera datang untuk memahami semua yang lebih baik.
Tapi untuk saat ini, mari kita berakhir pada apa, mudah-mudahan, sedikit lebih
dimengerti XKCD lelucon, sampai kita melanjutkan waktu berikutnya.
Baiklah.
Sampai jumpa pada hari Rabu.
>> [MUSIC PLAYING]
>> SPEAKER: Dan sekarang, dalam pikiran, berdasarkan Daven Farnham.
Memori adalah seperti melompat ke tumpukan daun emas pada hari Minggu sore.
Angin bertiup, melemparkan Anda hair-- oh, aku rindu hari-hari when--
>> [Tertawa]