[Powered by Google Translate] [Seksyen 5 - Lebih Selesa]
[Rob Bowden - Universiti Harvard]
[Ini adalah CS50. - CS50.TV]
>> Seperti yang saya katakan dalam e-mel saya, terdapat banyak perkara yang anda boleh menggunakan
selain daripada perkakas untuk benar-benar melakukan set masalah.
Kami mengesyorkan anda melakukannya dalam perkakas hanya kerana maka kita lebih mudah boleh membantu anda
dan kita tahu bagaimana segala-galanya akan untuk bekerja.
Tetapi sebagai salah satu contoh di mana anda boleh melakukan perkara-perkara yang jika, katakan, anda tidak mempunyai akses
perkakas atau anda mahu bekerja di bawah tanah Pusat Sains -
yang sebenarnya mereka mempunyai perkakas terlalu -
jika anda mahu bekerja di mana-mana.
Satu contoh anda telah melihat / mendengar SSH?
SSH pada asasnya seperti menyambung kepada sesuatu.
Sebenarnya, sekarang saya SSHed ke dalam perkakas.
Saya tidak pernah bekerja secara langsung di dalam perkakas.
Berikut adalah perkakas, dan jika anda melihat ke sini anda melihat ini alamat IP.
Saya tidak pernah bekerja dalam perkakas sendiri;
Saya sentiasa datang ke tetingkap iTerm2 tetingkap / terminal.
Anda boleh SSH ke alamat IP, jharvard@192.168.129.128 ssh.
Saya masih ingat nombor itu sangat mudah kerana ia adalah seperti corak yang bagus.
Tetapi yang akan bertanya kepada saya untuk kata laluan saya, dan sekarang saya dalam perkakas.
Pada asasnya, pada masa ini, jika anda membuka terminal di dalam perkakas itu sendiri,
antara muka ini, tetapi anda akan menggunakan ia, adalah sama
sebagai antara muka saya menggunakan lebih di sini tetapi kini anda SSHed.
Anda tidak perlu SSH untuk perkakas.
Satu contoh tempat lain anda boleh SSH untuk Saya agak pasti anda mempunyai secara lalai -
Oh. Yang lebih besar.
Semua anda perlu mempunyai oleh akaun FAS lalai pada pelayan FAS.
Bagi saya, saya akan SSH kepada rbowden@nice.fas.harvard.edu.
Ia akan meminta anda bahawa kali pertama, dan anda mengatakan ya.
Password saya hanya akan menjadi kata laluan FAS saya.
Dan jadi sekarang, saya SSHed pelayan bagus, dan saya boleh melakukan apa sahaja yang saya mahu di sini.
Banyak kelas anda mungkin mengambil masa, seperti 124, akan mempunyai anda memuat naik barangan ke sini
sebenarnya mengemukakan set masalah anda.
Tetapi mengatakan anda tidak mempunyai akses kepada perkakas anda.
Kemudian anda boleh melakukan perkara-perkara, seperti di sini ia akan berkata -
Ini adalah hanya bahagian soalan.
Ia akan meminta anda untuk melakukan ini di dalam perkakas.
Sebaliknya saya hanya akan melakukannya pada pelayan.
Saya akan untuk unzip bahawa.
Masalah ini akan menjadi bahawa anda digunakan untuk menggunakan sesuatu seperti gedit
atau apa-apa bahagian dalam perkakas.
Anda tidak akan mempunyai bahawa pada pelayan FAS.
Itu semua hanya akan menjadi antara muka teks.
Jadi, anda boleh sama ada satu, cuba untuk belajar editor teks yang mereka tidak mempunyai.
Mereka mempunyai Nano.
Nano biasanya agak mudah untuk digunakan.
Anda boleh menggunakan anak panah anda dan menaip biasanya.
Supaya tidak sukar.
Jika anda ingin mendapatkan benar-benar mewah anda boleh menggunakan Emacs,
yang saya mungkin tidak sepatutnya dibuka kerana saya tidak tahu bagaimana untuk menutup Emacs.
Kawalan X, Kawalan C? Yeah.
Atau anda boleh menggunakan Vim, yang adalah apa yang saya gunakan.
Dan supaya mereka adalah pilihan anda.
Jika anda tidak mahu berbuat demikian, anda boleh juga, jika anda melihat manual.cs50.net -
Oh.
Pada PC, anda boleh SSH menggunakan dempul,
yang anda akan perlu untuk memuat turun secara berasingan.
Pada Mac, anda boleh hanya dengan penggunaan Terminal lalai atau anda boleh memuat turun iTerm2,
yang seperti Terminal bagus, mewah.
Jika anda pergi untuk manual.cs50.net anda akan melihat pautan ke Notepad + +,
yang adalah apa yang anda boleh gunakan pada PC.
Ia membolehkan anda SFTP dari Notepad + +, yang pada asasnya SSH.
Apakah ini akan membiarkan anda lakukan adalah mengedit fail anda tempatan,
dan kemudian apabila anda mahu untuk menyelamatkan mereka, ia akan menjimatkan nice.fas,
di mana anda boleh menjalankan mereka.
Dan bersamaan pada Mac akan menjadi TextWrangler.
Jadi ia membolehkan anda melakukan perkara yang sama.
Ia membolehkan anda mengedit fail tempatan dan menyelamatkan mereka untuk nice.fas,
di mana anda boleh menjalankan mereka.
Jadi, jika anda pernah terjebak tanpa perkakas, anda mempunyai pilihan ini
masih melakukan set masalah anda.
Satu masaalah yang akan menjadi bahawa anda tidak akan mempunyai perpustakaan CS50
kerana nice.fas tidak secara lalai mempunyai bahawa.
Anda boleh sama ada memuat turun perpustakaan CS50 -
Saya tidak fikir saya perlu bahawa pada ketika ini.
Anda boleh sama ada memuat turun perpustakaan CS50 dan salinan ke nice.fas,
atau saya fikir pada ketika ini kita tidak menggunakan lagi anyway.
Atau jika kita lakukan, anda boleh pada masa itu menggantikannya dengan
pelaksanaan fungsi di perpustakaan CS50 anyway.
Jadi yang tidak perlu yang banyak sekatan.
Dan itulah yang.
>> Saya akan kembali kepada perkakas sekarang; kami akan melakukan segala-galanya di dalam perkakas.
Melihat seksyen kami soalan, pada permulaan, seperti yang saya katakan dalam e-mel saya,
kita perlu bercakap tentang satu pendek anda sepatutnya untuk menonton.
Kami mempunyai Dialihkan & Paip dan ketiga-tiga soalan.
>> Aliran yang tidak fungsi seperti printf menulis secara lalai?
Jadi aliran. Apakah aliran?
Aliran adalah pada dasarnya seperti ia hanya beberapa -
Ia bukan walaupun sumber 1s dan 0-an.
Aliran ia meminta sini adalah keluar standard.
Dan keluar begitu standard adalah sungai yang apabila anda menulis kepada,
ia muncul pada skrin.
Keluar Standard, oleh aliran, ia bermakna anda hanya menulis 1s dan 0s kepadanya,
dan hujung yang lain daripada standard hanya membaca daripada aliran itu.
Ia hanya rentetan 1s dan 0-an.
Anda boleh menulis kepada aliran atau anda boleh membaca daripada aliran
bergantung kepada apa aliran sebenarnya.
Dua lagi aliran lalai adalah standard dalam kesesatan dan standard.
Standard dalam apabila anda GetString, ia menunggu untuk anda barangan input.
Jadi ia menunggu untuk anda, ia sebenarnya menunggu standard dalam,
yang benar-benar apa yang anda dapat apabila anda menaip di keyboard.
Anda sedang menaip menjadi standard masuk
Ralat piawai adalah pada dasarnya setara dengan standard keluar,
tetapi ia adalah khusus dalam bahawa apabila anda mencetak ralat piawai,
anda sepatutnya hanya mencetak mesej ralat bahawa
jadi anda boleh membezakan antara mesej biasa dicetak untuk skrin
berbanding mesej ralat bergantung pada sama ada mereka pergi ke keluar standard atau ralat piawai.
Fail juga.
Keluar standard, standard dalam, dan ralat piawai beberapa aliran yang hanya khas,
tetapi benar-benar apa-apa fail, apabila anda membuka fail, ia menjadi satu aliran bait
mana anda hanya boleh membaca daripada aliran itu.
Anda, bagi sebahagian besar, hanya boleh berfikir fail sebagai aliran bait.
Jadi aliran apa yang mereka menulis secara lalai? Keluar standard.
>> Apakah perbezaan antara> dan >>?
Adakah sesiapa menonton video terlebih dahulu? Okay.
> Akan menjadi bagaimana anda redirect ke dalam fail,
dan >> juga akan redirect output ke dalam fail,
tetapi ia sebaliknya akan untuk melampirkan ke fail.
Sebagai contoh, katakan saya berlaku mempunyai Dict di sini,
dan barangan hanya dalam Dict kucing, kucing, anjing, ikan, anjing.
Satu perintah bahawa anda mempunyai sekurang baris arahan adalah kucing,
yang hanya akan mencetak apa dalam fail.
Jadi, apabila saya mengatakan Dict kucing, ia akan mencetak kucing, kucing, anjing, ikan, anjing. Itu semua kucing tidak.
Ini bermakna bahawa ia dicetak standard keluar kucing, kucing, anjing, ikan, anjing,.
Jika saya bukannya mahu redirect yang ke fail, saya boleh menggunakan> redirect kepada apa sahaja fail.
Saya akan memanggil fail fail.
Jadi sekarang jika saya ls, saya akan melihat saya mempunyai fail baru yang dipanggil fail.
Dan jika saya membukanya, ia akan mempunyai apa sebenarnya kucing meletakkan pada baris arahan.
Jadi sekarang jika saya berbuat demikian sekali lagi, maka ia akan redirect output ke fail,
dan saya akan mempunyai perkara yang sama.
Jadi secara teknikal, ia benar-benar overrode apa yang kita ada.
Dan kita akan melihat jika saya menukar Dict, saya mengambil anjing.
Sekarang jika kita kucing Dict ke fail sekali lagi, kita akan mempunyai versi baru dengan anjing yang dikeluarkan.
Jadi ia benar-benar mengatasi.
Sebaliknya, jika kita menggunakan >>, ia akan melampirkan fail.
Sekarang, membuka fail, kita lihat kita hanya mempunyai perkara yang sama dicetak dua kali
kerana ia berada di sana sekali, maka kita dilampirkan kepada asal.
Apa supaya> dan >> lakukan.
Adakah yang seterusnya bertanya - Ia tidak bertanya tentang ia.
>> Yang lain yang kita ada adalah <, yang jika> pelencongan keluar standard,
<Akan redirect standard masuk
Mari kita lihat jika kita mempunyai contoh.
Saya boleh menulis satu cepat sebenar.
Mari kita mengambil mana-mana fail, hello.c.
Fail agak mudah.
Saya hanya mendapat tali dan kemudian mencetak "Hello" apa jua rentetan saya hanya memasuki.
Jadi membuat khabar dan kemudian. / Hello.
Kini ia mendorong saya untuk memasukkan sesuatu,
yang bermakna ia menunggu perkara untuk dimasukkan ke dalam standard.
Jadi masukkan apa sahaja yang saya mahu ke standard masuk Kami hanya akan mengatakan Hello, Rob!
Kemudian ia mencetak kepada standard keluar Hello, Rob!
Jika saya lakukan. / Khabar dan kemudian mengalihkan,
buat masa sekarang, anda hanya boleh mengalihkan dari fail.
Jadi jika saya dimasukkan ke dalam beberapa fail, txt, dan saya meletakkan Rob,
jika saya menjalankan hello dan kemudian mengalihkan txt fail ke dalam. / hello, ia akan mengatakan Hello, Rob! serta-merta.
Apabila ia mula-mula mendapat kepada GetString dan ia menunggu standard dalam,
standard dalam tidak lagi menunggu pada keyboard untuk data untuk mendapatkan dimasukkan.
Sebaliknya, kita telah diarahkan standard untuk membaca dari txt file.
Dan sebagainya ia akan untuk membaca daripada txt fail, yang hanya line Rob,
dan kemudian ia akan mencetak Hello, Rob!
Dan jika saya mahu, saya juga boleh melakukan / hello <txt
dan kemudian standard bahawa ia percetakan, yang merupakan Hello, Rob!
Saya boleh mengalihkan ke dalam fail sendiri.
Saya hanya akan memanggil fail hello - tidak, saya tidak akan, kerana itulah yang laku - txt2.
Sekarang, txt2 akan mempunyai output / hello <txt, yang akan menjadi Hello, Rob!
>> Soalan?
>> Okay. Jadi maka di sini kita mempunyai saluran paip.
Paip adalah unit terakhir redirection.
>> Oh. Saya rasa satu unit yang lebih redirection jika bukan> anda lakukan 2>
itu mengalihkan ralat piawai.
Jadi, jika sesuatu yang pergi ke ralat piawai, ia tidak akan mendapat dimasukkan ke dalam txt2.
Tetapi notis jika saya lakukan 2>, maka ia masih percetakan Hello, Rob! baris arahan
kerana saya hanya mengalihkan ralat piawai, saya tidak mengalihkan standard.
Ralat piawai dan standard keluar adalah berbeza.
Jika anda mahu untuk benar-benar menulis kepada ralat piawai,
maka saya boleh menukar ini menjadi fprintf untuk stderr.
Jadi printf, secara lalai, mencetak keluar standard.
Jika saya mahu mencetak ralat piawai manual, maka saya perlu menggunakan fprintf
dan nyatakan apa yang saya mahu untuk mencetak.
Jika sebaliknya saya lakukan stdout fprintf, maka itulah pada dasarnya bersamaan dengan printf.
Tetapi fprintf kesilapan standard.
Jadi sekarang, jika saya redirect ini ke txt2, Hello, Rob! masih mendapat dicetak pada baris arahan
kerana ia mendapat dicetak kesilapan standard dan saya hanya mengalihkan standard keluar.
Jika saya kini mengalihkan ralat piawai, kini ia tidak mendapat dicetak, dan txt2 akan menjadi Hello, Rob!
Jadi sekarang, anda boleh mencetak kesilapan sebenar anda untuk ralat piawai
dan mencetak mesej biasa anda untuk keluar standard.
Dan jadi apabila anda menjalankan program anda, anda boleh menjalankan ia sebagai / hello jenis ini dengan 2>
supaya program anda akan berjalan dengan normal,
tetapi apa-apa mesej ralat bahawa anda mendapatkan anda boleh menyemak kemudian dalam log ralat anda,
supaya kesilapan, dan kemudian melihat kemudian dan fail kesilapan anda akan mempunyai apa-apa kesilapan yang berlaku.
>> Soalan?
>> Yang terakhir adalah paip, yang anda boleh berfikir sebagai mengambil standard keluar dari satu arahan
dan membuat ia standard dalam arahan seterusnya.
Satu contoh di sini echo adalah satu perkara yang baris arahan
yang hanya akan echo apa yang saya meletakkan sebagai hujah. Saya tidak akan meletakkan sebut harga.
Gema blah, blah, blah hanya akan mencetak blah, blah, blah.
Sebelum ini, apabila saya berkata, saya terpaksa meletakkan Rob ke dalam fail txt
kerana saya hanya boleh mengalihkan fail txt, sebaliknya, / jika saya echo Rob
dan kemudian paip ke. / hello, yang juga akan melakukan jenis yang sama perkara.
Ini mengambil output arahan ini, echo Rob,
dan menggunakan ia sebagai input bagi. / hello.
Anda boleh berfikir ia sebagai pertama redirect echo Rob ke dalam fail
dan kemudian input ke dalam fail. / hello bahawa yang hanya outputted.
Tetapi ia mengambil fail sementara keluar gambar.
>> Soalan pada itu?
>> Persoalan seterusnya akan melibatkan ini.
Apakah perancangan yang anda boleh gunakan untuk mencari beberapa nama-nama yang unik dalam fail yang dipanggil names.txt?
Arahan kita akan mahu menggunakan di sini adalah unik, jadi uniq, dan kemudian tandas.
Anda boleh melakukan uniq lelaki untuk benar-benar melihat apa yang tidak,
dan ia hanya akan menapis bersebelahan padanan garisan dari input.
Dan lelaki tandas akan mencetak newline, perkataan, dan tuduhan bait bagi setiap fail.
Dan yang terakhir yang kita akan mahu menggunakan adalah jenis,
yang akan hanya menyusun garisan fail txt.
Jika saya membuat beberapa fail txt, names.txt, dan ia Rob, Tommy, Yusuf, Tommy, Yusuf, RJ, Rob,
apa yang saya mahu lakukan di sini ialah mencari beberapa nama-nama yang unik dalam fail ini.
Jadi apa jawapan yang sepatutnya? >> [Pelajar] 4. >> Yeah.
Ia harus menjadi 4 sejak Rob, Tommy, Joseph, RJ adalah nama-nama yang hanya unik dalam fail ini.
Langkah pertama, jika saya hanya melakukan kiraan perkataan pada names.txt,
ini sebenarnya memberitahu saya segala-galanya.
Ini sebenarnya adalah percetakan - Mari kita lihat, tandas lelaki - baris baru, perkataan, dan kiraan bait.
Jika saya hanya mengambil berat tentang garisan, maka saya hanya boleh melakukan wc-l names.txt.
Jadi itulah langkah 1.
Tetapi saya tidak mahu names.txt wc-l kerana names.txt hanya mengandungi semua nama-nama,
dan saya mahu menapis apa-apa yang bukan unik.
Jadi, jika saya lakukan names.txt uniq, yang tidak cukup memberi saya apa yang saya mahu
kerana nama ulangan masih ada.
Mengapa? Mengapa uniq tidak melakukan apa yang saya mahu?
[Pelajar] salinan tidak [didengar] >> Yeah.
Ingat halaman lelaki untuk uniq mengatakan garisan padanan penapis bersebelahan.
Mereka tidak berada bersebelahan, jadi ia tidak akan menapis mereka.
Jika saya menyelesaikan terlebih dahulu, names.txt apapun akan meletakkan semua garisan salinan bersama-sama.
Jadi kini names.txt apapun.
Saya akan mahu menggunakan bahawa sebagai input kepada uniq, yang | uniq.
Yang memberikan saya Yusuf, RJ, Rob, Tommy,
dan saya mahu menggunakan bahawa sebagai input ke wc-l,
yang akan memberi saya 4.
Seperti ia berkata di sini, apa perancangan yang anda boleh gunakan?
Anda boleh melakukan banyak perkara seperti menggunakan satu siri arahan
di mana anda menggunakan output dari satu arahan sebagai input untuk arahan seterusnya.
Anda boleh melakukan banyak perkara, banyak perkara yang bijak.
>> Soalan?
Okay.
Itulah untuk paip dan redirection.
>> Sekarang kita pergi kepada barangan sebenar, barangan kod.
Dalam PDF ini, anda akan melihat arahan ini,
dan anda akan mahu menjalankan arahan ini di dalam perkakas anda.
wget adalah arahan hanya untuk mendapat sesuatu dari Internet, pada dasarnya,
begitu wget dan URL ini.
Jika anda pergi ke URL ini dalam pelayar anda, ia akan memuat turun fail tersebut.
Saya hanya klik di atasnya, supaya ia turun fail bagi saya.
Tetapi bertulis wget perkara itu di dalam terminal
hanya akan memuat turun ke dalam terminal anda.
Saya mempunyai yang section5.zip, dan anda akan mahu unzip section5.zip,
yang akan memberikan anda folder yang dipanggil section5,
yang akan mempunyai semua fail yang kita akan menggunakan hari ini di dalamnya.
Sebagai mencadangkan nama fail program-program ini, mereka bit buggy,
jadi misi anda adalah untuk memahami mengapa menggunakan Pra-Pemasangan.
Adakah semua orang telah mereka turun / tahu bagaimana untuk mendapatkan mereka turun
ke dalam perkakas mereka? Okay.
>> Running ./buggy1, ia akan mengatakan kesalahan Segmentasi (teras dibuang),
mana-mana masa anda mendapat segfault, ia adalah satu perkara yang buruk.
Dalam keadaan apakah anda mendapat segfault?
[Pelajar] Dereferencing penunjuk nol. >> Yeah. Jadi itu adalah satu contoh.
Dereferencing penunjuk nol anda pergi untuk mendapatkan segfault.
Apa segfault cara anda menyentuh memori anda tidak perlu menyentuh.
Yang Jadi dereferencing penunjuk nol menyentuh alamat 0,
dan pada dasarnya, semua komputer pada masa kini mengatakan bahawa alamat 0 memori anda tidak perlu menyentuh.
Jadi itulah sebabnya dereferencing keputusan yang penunjuk nol dalam segfault.
Apabila anda berlaku untuk tidak memulakan penunjuk, maka ia mempunyai nilai sampah,
dan sebagainya apabila anda cuba untuk dereference ia, dalam semua kemungkinan anda menyentuh memori
yang di tengah-tengah di mana-mana.
Jika anda berlaku untuk mendapatkan bertuah dan nilai sampah
berlaku untuk menunjukkan ke suatu tempat pada timbunan atau sesuatu,
kemudian apabila anda dereference bahawa penunjuk yang anda tidak dimulakan,
tiada apa yang akan pergi salah.
Tetapi jika ia menunjuk ke, katakan, suatu tempat di antara timbunan dan longgokan itu,
atau ia menunjuk hanya untuk tempat yang tidak digunakan oleh program anda lagi,
maka anda menyentuh ingatan anda tidak perlu menyentuh dan anda segfault.
Apabila anda menulis fungsi rekursi dan ia recurses terlalu banyak kali
dan timbunan anda tumbuh terlalu besar dan bertembung timbunan ke dalam perkara-perkara
bahawa ia tidak perlu berlanggar dengan, anda menyentuh memori anda tidak perlu menyentuh,
jadi anda segfault.
Itulah apa segfault.
>> Ia juga merupakan sebab yang sama bahawa jika anda mempunyai rentetan seperti -
mari kita kembali program sebelumnya.
Di hello.c-: saya hanya akan membuat sesuatu yang lain.
char * s = "hello dunia!";
Jika saya menggunakan * s = sesuatu atau s [0] = 'X';
supaya membuat hello, / hello, kenapa bahawa segfault?
Mengapa ini segfault?
Apa yang anda inginkan berlaku?
Jika saya lakukan printf ("% s \ n", s); apa yang anda inginkan untuk dicetak?
[Pelajar] X hello. >> Yeah.
Masalahnya ialah bahawa apabila anda mengisytiharkan rentetan seperti ini,
s adalah penunjuk yang akan pergi pada timbunan,
dan apa yang s menunjuk kepada rentetan ini yang terkandung dalam ingatan baca sahaja.
Jadi hanya dengan nama, ingatan baca sahaja, anda perlu mendapatkan idea
bahawa jika anda cuba untuk menukar apa yang dalam ingatan baca sahaja,
anda sedang melakukan sesuatu yang anda tidak perlu melakukan dengan ingatan dan anda segfault.
Ini sebenarnya adalah satu perbezaan yang besar antara char * s dan char [].
Jadi char s [], kini tali ini akan diletakkan pada timbunan,
dan timbunan tidak baca sahaja, yang bermaksud bahawa ini perlu bekerja dengan sempurna halus.
Dan ia tidak.
Ingatlah bahawa apabila saya melakukan char * s = "hello dunia!", S sendiri pada timbunan
tetapi s mata ke tempat lain, dan tempat lain yang berlaku kepada menjadi baca sahaja.
Tetapi s char [] adalah hanya sesuatu pada timbunan.
Jadi itulah lagi contoh sebuah segfault berlaku.
>> Kami melihat bahawa ./buggy1 mengakibatkan dalam segfault.
Secara teori, anda tidak perlu melihat buggy1.c segera.
Sebaliknya, kita akan melihat ia melalui Pra-Pemasangan.
Perhatikan bahawa apabila anda mendapat kesalahan Segmentasi (teras dibuang),
anda mendapat fail ini lebih teras yang di sini dipanggil.
Jika kita ls-l, kita akan melihat teras yang biasanya fail yang agak besar.
Ini adalah nombor bait fail, jadi ia kelihatan seperti ia adalah 250-sesuatu kilobytes.
Sebab untuk ini adalah bahawa apa yang dump teras sebenarnya adalah
apabila program kemalangan anda, keadaan ingatan program anda
hanya mendapat disalin dan ditampal ke dalam fail ini.
Ia mendapat dibuang ke dalam fail tersebut.
Program ini, ketika ia berlari, yang berlaku kepada mempunyai penggunaan memori sekitar 250 kilobytes,
dan supaya apa yang mendapat dibuang ke fail ini.
Sekarang anda boleh melihat fail yang jika kita lakukan Pra-Pemasangan buggy1 teras.
Kita hanya boleh melakukan Pra-Pemasangan buggy1, dan yang hanya akan memulakan Pra-Pemasangan kerap,
menggunakan buggy1 sebagai fail input.
Tetapi jika anda melakukan Pra-Pemasangan buggy1 teras, maka ia adalah khas akan memulakan Pra-Pemasangan
dengan melihat fail teras yang.
Dan anda berkata buggy1 cara Pra-Pemasangan tahu bahawa fail teras datang dari program buggy1.
Jadi Pra-Pemasangan buggy1 teras akan segera membawa kita
mana program yang berlaku untuk menamatkan.
Kita lihat di sini Program ditamatkan dengan isyarat 11, Segmentasi kesalahan.
Kita berlaku untuk melihat barisan pemasangan, yang mungkin tidak sangat membantu.
Tetapi jika anda menaip bt atau jejakundur, yang akan menjadi fungsi
yang memberikan kami senarai bingkai timbunan semasa kami.
Jadi jejakundur Ia kelihatan seperti kami hanya mempunyai dua bingkai tindanan.
Yang pertama adalah bingkai tindanan utama kami,
dan yang kedua ialah bingkai tindanan untuk fungsi ini bahawa kita berada dalam,
yang kelihatan seperti kita hanya mempunyai kod pemasangan untuk.
Jadi mari kita kembali ke dalam fungsi utama kita,
dan untuk berbuat demikian kita boleh melakukan bingkai 1, dan saya fikir kita juga boleh melakukan turun,
tetapi saya hampir tidak pernah melakukan - atau sehingga. Yeah.
Naik dan turun. Sehingga membawa anda satu timbunan bingkai, turun membawa anda ke bawah bingkai tindanan.
Saya cenderung untuk tidak menggunakan bahawa.
Saya hanya khusus mengatakan frame 1, yang pergi ke bingkai dilabel 1.
Frame 1 akan membawa kita ke dalam bingkai tindanan utama,
dan ia mengatakan di sini baris kod kita berada di.
Jika kita mahu pasangan lebih baris kod, kita boleh mengatakan senarai,
dan itu akan memberikan kita semua baris kod sekelilingnya.
Barisan kita segfaulted pada 6:
jika (strcmp ("CS50 batu", argv [1]) == 0).
Jika ia tidak jelas lagi, anda boleh mendapatkan terus dari sini hanya dengan berfikir mengapa ia segfaulted.
Tetapi kita boleh mengambil ia satu langkah ke hadapan dan berkata, "Mengapa argv [1] segfault?"
Cetak Mari argv [1], dan ia kelihatan seperti 0x0, ia yang merupakan penunjuk nol.
Kami strcmping CS50 batu dan batal, dan sebagainya yang akan segfault.
Dan mengapa argv [1] null?
[Pelajar] Kerana kita tidak memberikan apa-apa hujah baris arahan.
Yeah. Kami tidak memberikan apa-apa hujah baris arahan.
Jadi ./buggy1 hanya akan mempunyai argv [0] ./buggy1.
Ia tidak akan mempunyai argv [1], supaya akan segfault.
Tetapi jika, sebaliknya, yang saya lakukan hanya CS50, ia akan mengatakan Anda mendapatkan D
kerana itulah apa yang ia sepatutnya lakukan.
Melihat di buggy1.c, ia sepatutnya untuk mencetak "Anda mendapat D" -
Jika argv [1] tidak "CS50 batu", "Anda mendapat D", lain "Anda mendapat A!"
Jadi, jika kita mahu A, kita perlu ini untuk membandingkan sebagai benar,
yang bermaksud bahawa ia membandingkan kepada 0.
Jadi argv [1] perlu "CS50 batu".
Jika anda ingin berbuat demikian pada baris arahan, anda perlu menggunakan \ untuk melarikan diri ruang.
Jadi CS50 \ batu dan Anda mendapat A!
Jika anda tidak berbuat backslash, mengapa ini tidak berfungsi?
[Pelajar] Ia adalah dua hujah yang berbeza. >> Yeah.
Argv [1] akan menjadi CS50, dan argv [2] akan menjadi batu. Okay.
>> Sekarang ./buggy2 akan segfault lagi.
Sebaliknya membukanya dengan fail terasnya, kita hanya akan membuka buggy2 langsung,
jadi Pra-Pemasangan buggy2.
Sekarang jika kita hanya menjalankan program kami, maka ia akan berkata Program menerima SIGSEGV isyarat,
yang merupakan segfault isyarat, dan ini adalah di mana ia berlaku berlaku.
Melihat jejakundur kita, kita melihat bahawa kita adalah dalam oh_no fungsi,
yang telah dipanggil oleh Dinky fungsi, yang dipanggil oleh binky fungsi,
yang telah dipanggil oleh utama.
Kita juga boleh melihat hujah-hujah untuk fungsi-fungsi ini.
Hujah untuk Dinky dan binky adalah 1.
Jika kita menyenaraikan fungsi oh_no, kita lihat bahawa oh_no hanya melakukan char ** s = NULL;
* S = "BOOM";
Mengapa yang akan gagal?
[Pelajar] Anda tidak boleh dereference penunjuk nol? >> Yeah.
Ini hanya mengatakan s adalah NULL, tanpa mengira jika ia berlaku untuk menjadi ** char,
yang, bergantung kepada bagaimana anda mentafsir, ia boleh menjadi penunjuk kepada penunjuk kepada rentetan
atau pelbagai rentetan.
Ia s adalah NULL, jadi * s dereferencing penunjuk nol,
dan sebagainya ini akan kemalangan.
Ini adalah salah satu cara paling cepat anda mungkin boleh segfault.
Ia hanya mengisytiharkan penunjuk nol dan segera segfaulting.
Itulah apa yang oh_no lakukan.
Jika kita pergi satu bingkai, maka kita akan masuk ke dalam fungsi yang dipanggil oh_no.
Saya perlu untuk melakukan yang turun.
Jika anda tidak memasukkan arahan dan anda hanya tekan Enter lagi,
ia hanya akan mengulangi arahan sebelumnya yang anda berlari.
Kami dalam bingkai 1.
Penyenaraian bingkai ini, kita lihat sini adalah fungsi kita.
Anda boleh menekan senarai lagi, atau anda boleh melakukan senarai 20 dan ia akan menyenaraikan lebih.
Dinky fungsi mengatakan jika i adalah 1, maka pergi kepada fungsi oh_no,
lain pergi ke fungsi Slinky.
Dan kita tahu i ialah 1 kerana kita berlaku untuk melihat di sini
Dinky yang dipanggil dengan hujah 1.
Atau anda hanya boleh melakukan mencetak i dan ia akan berkata i ialah 1.
Kami sedang dalam Dinky, dan jika kita naik bingkai lain, kita tahu kita akan berakhir di binky.
Up. Sekarang kita berada dalam binky.
Menyenaraikan fungsi ini - senarai dari sebelum separuh memotong saya -
ia bermula seolah-olah i ialah 0, maka kita akan untuk memanggil ia oh_no, lain memanggil Dinky.
Kita tahu i 1, jadi ia dipanggil Dinky.
Dan kini kami kembali utama, dan utama hanya akan menjadi int i = rand ()% 3;
Itu hanya akan memberi anda satu nombor rawak yang sama ada 0, 1, atau 2.
Ia akan memanggil binky dengan nombor itu, dan ia akan kembali 0.
Melihat ini,
hanya berjalan melalui program ini secara manual tanpa berjalan dengan segera,
anda akan menetapkan titik rehat di utama, yang bermaksud bahawa apabila kita menjalankan program
program anda berjalan sehingga ia mencecah titik rehat.
Jadi menjalankan program ini, ia akan berjalan dan kemudian ia akan melanda fungsi utama dan berhenti berjalan.
Sekarang kita berada di dalam utama, dan langkah atau seterusnya akan membawa kita ke baris seterusnya kod.
Anda boleh melakukan langkah atau seterusnya.
Memukul seterusnya, sekarang i telah bersedia untuk rand () 3%, jadi kami boleh mencetak nilai i,
dan ia akan mengatakan i ialah 1.
Sekarang ia tidak kira sama ada kita gunakan seterusnya atau langkah.
Saya rasa ia mattered dalam satu sebelumnya, tetapi kita mahu menggunakan seterusnya.
Jika kita menggunakan langkah, kita melangkah ke fungsi, yang bermakna melihat perkara yang sebenar
yang berlaku di dalam binky.
Jika kita gunakan seterusnya, maka ia bermakna pergi ke fungsi
dan hanya pergi ke baris seterusnya kod dalam fungsi utama kami.
Hak di sini pada baris ini, saya berada di mana ia berkata rand ()% 3;
jika saya lakukan langkah, ia akan pergi ke pelaksanaan rand
dan melihat apa yang berlaku di sana, dan saya boleh melangkah melalui fungsi rand.
Tetapi saya tidak peduli mengenai fungsi rand.
Saya hanya mahu untuk pergi ke baris seterusnya kod utama, jadi saya gunakan seterusnya.
Tetapi kini saya lakukan penjagaan mengenai fungsi binky, jadi saya mahu melangkah ke itu.
Sekarang saya dalam binky.
Baris pertama kod akan mengatakan jika (i == 0), saya mengambil langkah,
kita lihat kita berakhir di Dinky.
Jika perkara senarai kita, kita lihat bahawa ia diperiksa adalah i = 0.
i tidak sama dengan 0, jadi ia pergi ke keadaan yang lain,
yang akan memanggil Dinky (i).
Anda mungkin terkeliru.
Jika anda hanya melihat ayat-ayat ini secara langsung, anda mungkin berfikir jika (i == 0),
okay, maka saya telah mengambil langkah dan kini saya di Dinky (i),
anda mungkin berfikir bahawa mesti bermakna i = 0 atau sesuatu.
Ia hanya bermakna bahawa ia tahu ia boleh melekat terus ke Dinky baris (i).
Kerana saya tidak adalah 0, langkah seterusnya tidak akan berakhir di lain.
Lain tidak adalah selaras ia akan berhenti pada.
Ia hanya akan pergi ke baris berikutnya ia sebenarnya boleh melaksanakan, yang Dinky (i).
Melangkah ke Dinky (i), kita lihat jika (i == 1).
Kita tahu i = 1, jadi apabila kita melangkah, kita tahu kita akan berakhir di oh_no
kerana i = 1 panggilan oh_no fungsi, yang anda boleh melangkah ke,
yang akan menetapkan char ** s = batal dan segera "BOOM".
Dan kemudian sebenarnya melihat pelaksanaan buggy2,
ini, saya hanya mendapat nombor rawak - 0, 1, atau 2 - memanggil binky,
yang jika i adalah 0 ia memerlukan oh_no, jika tidak, ia memerlukan Dinky, yang datang sini.
Jika i 1, panggilan oh_no, lain memanggil Slinky, yang datang sini,
jika i 2, hubungi oh_no.
Saya tidak fikir ada cara -
Adakah sesiapa yang melihat cara membuat ini satu program yang tidak akan segfault?
Kerana melainkan saya hilang sesuatu, jika i ialah 0, anda akan segera segfault,
lain yang anda pergi ke fungsi yang jika i adalah 1 anda segfault,
lain anda pergi untuk fungsi mana jika i 2 anda segfault.
Jadi tidak kira apa yang anda lakukan, anda segfault.
>> Saya rasa salah satu cara menetapkan ia akan menjadi bukannya melakukan char ** s = NULL,
anda boleh malloc ruang untuk rentetan itu.
Kita boleh melakukan malloc (sizeof) - sizeof apa?
[Pelajar] (char) * 5? >> Adakah ini kelihatan betul?
Saya menganggap ini akan bekerja jika saya sebenarnya berlari, tetapi ia bukan apa yang saya cari.
Lihatlah jenis s. Mari kita menambah * int, jadi int * x.
Saya akan lakukan malloc (sizeof (int)).
Atau jika saya mahu pelbagai 5, saya akan lakukan (sizeof (int) * 5);
Bagaimana jika saya mempunyai ** int?
Apa yang akan saya malloc?
[Pelajar] Saiz penunjuk. >> Yeah. (Sizeof (int *));
Perkara yang sama di sini.
Saya mahu (sizeof (char *));
Ini akan untuk memperuntukkan ruang bagi penunjuk bahawa mata untuk "BOOM".
Saya tidak perlu untuk memperuntukkan ruang bagi "BOOM" itu sendiri
kerana ini adalah pada dasarnya bersamaan dengan apa yang saya katakan sebelum ini
char * x = "BOOM".
"BOOM" sudah wujud. Ia berlaku kepada wujud di rantau baca sahaja memori.
Tetapi ia sudah wujud, yang bermakna garis kod ini, jika s adalah ** char,
maka * s * char dan anda menetapkan ini * char untuk menunjukkan "BOOM".
Jika saya mahu menyalin "BOOM" ke dalam s, maka saya akan perlu untuk memperuntukkan ruang untuk s.
Saya akan lakukan * s = malloc (sizeof (char) * 5);
Mengapa 5?
Mengapa not 4? Ia kelihatan seperti "BOOM" adalah 4 aksara. >> [Pelajar] Watak nol.
Yeah. Semua rentetan anda akan memerlukan watak batal.
Sekarang saya boleh melakukan sesuatu seperti strcat - Apakah fungsi untuk menyalin rentetan?
[Pelajar] cpy? >> Strcpy.
strcpy manusia.
Jadi strcpy atau strncpy.
strncpy adalah sedikit lebih selamat kerana anda boleh menentukan dengan tepat berapa banyak aksara,
tetapi di sini ia tidak menjadi masalah kerana kita tahu.
Jadi strcpy dan lihat dalam hujah-hujah.
Hujah pertama adalah destinasi kita.
Hujah kedua adalah sumber kami.
Kami pergi untuk menyalin ke destinasi kita * s penunjuk "BOOM".
Mengapa anda mungkin mahu melakukan ini dengan strcpy bukan hanya apa yang kita sebelum
* s = "BOOM"?
Terdapat satu sebab anda mungkin mahu melakukan ini, tetapi apakah sebab itu?
[Pelajar] Jika anda mahu menukar sesuatu dalam "BOOM". >> Yeah.
Sekarang saya boleh melakukan sesuatu seperti s [0] = 'X';
kerana s mata kepada timbunan dan ruang yang pada timbunan bahawa s menunjuk ke
adalah penunjuk kepada lebih banyak ruang pada timbunan, yang menyimpan "BOOM".
Jadi ini salinan "BOOM" yang disimpan dalam timbunan.
Teknikal Terdapat dua salinan "BOOM" dalam program kami.
Ada yang pertama itu hanya diberikan oleh "BOOM" pemalar rentetan,
dan salinan kedua "BOOM", strcpy mencipta salinan "BOOM".
Tetapi salinan "BOOM" yang disimpan pada timbunan, dan timbunan itu anda bebas untuk menukar.
Timbunan tidak baca sahaja, supaya bermakna bahawa s [0]
akan membiarkan anda menukar nilai "BOOM".
Ia akan membiarkan anda menukar watak-watak mereka.
>> Soalan?
Okay.
>> Beralih kepada buggy3, Pra-Pemasangan buggy3 mari.
Kami hanya menjalankan dan kita lihat kita mendapatkan segfault.
Jika kita jejakundur, terdapat hanya dua fungsi.
Jika kita pergi ke dalam fungsi utama kita, kita lihat bahawa kita segfaulted di garisan ini.
Jadi hanya mencari di garisan ini, untuk (int line = 0; fgets barangan ini tidak NULL tidak sama;
line + +).
Bingkai sebelumnya kami telah dipanggil _IO_fgets.
Anda akan melihat bahawa banyak dengan fungsi terbina dalam C,
bahawa apabila anda mendapat segfault, akan ada nama fungsi yang benar-benar samar
seperti _IO_fgets ini.
Tetapi itu akan berkaitan dengan panggilan fgets ini.
Di suatu tempat di dalam sini, kita segfaulting.
Jika kita melihat hujah-hujah fgets, kita boleh mencetak penampan.
Mari mencetak sebagai - Oh, tidak.
Cetak tidak akan bekerja dengan tepat kerana saya mahu ia.
Mari kita lihat pada program sebenar.
Penimbal adalah pelbagai watak. Ia adalah pelbagai watak 128 aksara.
Jadi, apabila saya mengatakan penampan cetak, ia akan untuk mencetak mereka 128 aksara,
yang saya rasa adalah apa yang diharapkan.
Apa yang saya cari adalah mencetak alamat penampan,
tetapi itu tidak benar-benar memberitahu saya banyak.
Jadi, apabila saya berlaku untuk mengatakan sini x penampan, ia menunjukkan saya 0xbffff090,
yang, jika anda ingat dari awal atau beberapa titik, Oxbffff cenderung untuk menjadi rantau timbunan-ish.
Timbunan cenderung untuk memulakan suatu tempat hanya di bawah 0xc000.
Hanya dengan melihat alamat ini, saya tahu bahawa penampan yang berlaku pada timbunan.
Memulakan semula program saya, berlari, up, penampan yang kita lihat adalah jujukan aksara
yang cukup banyak sia-sia.
Kemudian mencetak fail, apakah fail kelihatan seperti?
[Pelajar] Nol. >> Yeah.
Fail adalah * FILE jenis, jadi ia adalah penunjuk,
dan nilai penunjuk bahawa adalah batal.
Jadi fgets akan cuba untuk membaca daripada penunjuk yang secara tidak langsung,
tetapi dalam usaha untuk mengakses penunjuk bahawa, ia mempunyai dereference ia.
Atau, untuk mengakses apa yang ia harus menunjuk, ia dereferences ia.
Jadi ia dereferencing penunjuk nol dan segfaults ia.
Saya boleh dimulakan semula sana.
Jika kita memecahkan di titik utama kami dan berlari,
baris pertama kod char * filename = "nonexistent.txt";
Yang harus memberi petunjuk yang cukup besar mengapa program ini gagal.
Menaip seterusnya membawa saya kepada baris seterusnya, di mana saya membuka fail ini,
dan kemudian saya segera masuk ke dalam barisan kami, di mana apabila saya memukul seterusnya, ia akan untuk segfault.
Adakah sesiapa yang mahu membuang keluar sebab mengapa kita mungkin segfaulting?
[Pelajar] Fail tidak wujud. >> Yeah.
Ini sepatutnya menjadi petunjuk
bahawa apabila anda membuka fail, anda perlu menyemak bahawa fail itu sebenarnya wujud.
Jadi di sini, "nonexistent.txt";
Apabila kita fopen nama fail untuk membaca, maka kita perlu mengatakan
jika (file == NULL) dan mengatakan printf ("Fail tidak wujud!"
atau - lebih baik lagi - nama fail); pulangan 1;
Jadi sekarang kita memeriksa untuk melihat jika ia adalah NULL
sebelum sebenarnya berterusan dan cuba untuk membaca dari fail itu.
Kita boleh membentuk semula ia hanya untuk melihat bahawa kerja-kerja.
Saya bertujuan untuk memasukkan baris baru.
Jadi sekarang nonexistent.txt tidak wujud.
Anda harus selalu memeriksa untuk menyelesaikan perkara ini.
Anda harus selalu memeriksa untuk melihat jika fopen mengembalikan NULL.
Anda harus selalu memeriksa untuk memastikan bahawa malloc tidak kembali NULL,
atau lain anda segfault.
>> Sekarang buggy4.c.
Berjalan. Saya meneka ini sedang menunggu untuk input atau gelung mungkin terbatas.
Ya, ia adalah gelung tidak terhingga.
Jadi buggy4. Ia kelihatan seperti kami gelung tidak terhingga.
Kita boleh memecahkan di utama, jalankan program kami.
Pra-Pemasangan, selagi singkatan yang anda gunakan adalah jelas
atau singkatan khas bahawa mereka menyediakan untuk anda,
maka anda boleh menggunakan n menggunakan seterusnya bukannya perlu menaip depan, semua cara.
Dan sekarang bahawa saya telah melanda n sekali, saya hanya boleh memukul Enter untuk menyimpan berterusan seterusnya
bukannya perlu untuk memukul n Enter, n Masukkan, n Masukkan.
Ia kelihatan seperti saya dalam beberapa jenis untuk gelung itu menetapkan pelbagai [i] kepada 0.
Ia kelihatan seperti saya pernah memecah keluar ini untuk gelung.
Jika saya hendak mencetak i, jadi saya ialah 2, maka saya akan pergi seterusnya.
Saya akan mencetak i, i 3, maka saya akan pergi seterusnya.
Saya akan mencetak i dan i ialah 3. Seterusnya, mencetak i, i 4.
Sebenarnya, cetak sizeof (pelbagai), jadi saiz array ialah 20.
Tetapi ia kelihatan seperti terdapat beberapa arahan Pra-Pemasangan khas untuk pergi sehingga sesuatu berlaku.
Ia seperti menetapkan keadaan pada nilai pembolehubah. Tetapi saya tidak ingat apa ia adalah.
Jadi, jika kita terus pergi -
Apa yang kau katakan? Apa yang kau membawa?
[Pelajar] Adakah memaparkan i menambah - >> Yeah. Jadi memaparkan i boleh membantu.
Jika kita hanya memaparkan i, ia akan meletakkan di sini apa nilai i adalah
jadi saya tidak perlu untuk mencetak ia keluar setiap kali.
Jika kita hanya menyimpan akan datang, kita lihat 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5.
Sesuatu yang sedang berlaku betul-betul salah, dan saya sedang menetap semula kepada 0.
Melihat di buggy4.c, kita lihat semua yang berlaku adalah pelbagai int [5];
(i = 0; i <= sizeof (pelbagai); i + +)
pelbagai [i] = 0;
Apa yang kita lihat bahawa salah di sini?
Sebagai petunjuk, apabila saya telah melakukan Pra-Pemasangan buggy4 - mari kita memecahkan utama, run -
Saya tidak cetak sizeof (susunan) hanya untuk melihat apa keadaan di mana akhirnya saya harus keluar.
Di mana saya? Adakah saya menjalankan?
Saya tidak mengisytiharkan lagi.
Jadi mencetak sizeof (pelbagai) dan yang adalah 20,
yang dijangka sejak pelbagai saya adalah saiz 5 dan ia sebanyak 5 integer,
jadi keseluruhan perkara harus 5 * sizeof (int) bait, mana sizeof (int) cenderung untuk menjadi 4.
Jadi sizeof (pelbagai) adalah 20.
Apakah ini harus?
[Pelajar] Terbahagi oleh sizeof (int). >> Yeah, / sizeof (int).
Ia kelihatan seperti masih ada masalah di sini. Saya fikir ini hanya perlu menjadi <
kerana ia adalah cukup banyak sentiasa <dan tidak pernah <=.
Sekarang mari kita berfikir tentang mengapa ini sebenarnya pecah.
Adakah sesiapa yang telah tekaan mengapa i menetap semula kepada 0 melalui setiap lelaran gelung?
Satu-satunya perkara di sini yang berlaku adalah bahawa pelbagai [i] sedang disetkan kepada 0.
Jadi, entah bagaimana, baris kod ini menyebabkan int kami i akan disetkan kepada 0.
[Pelajar] Bolehkah ia menjadi kerana ia mengatasi memori bahagian ini i
apabila ia difikirkan ia adalah elemen yang seterusnya pelbagai? >> [Bowden] Ya.
Apabila kita pergi luar akhir pelbagai kami,
entah bagaimana bahawa ruang yang kita sedang mengatasi mengatasi nilai i.
Dan sebagainya jika kita melihat ke buggy4, memecahkan utama, larian,
mari kita mencetak alamat i.
Ia kelihatan seperti ia bffff124.
Sekarang mari kita mencetak alamat array [0]. 110.
Apa kira-kira [1]? 114.
[2], 118.
11c, 120. pelbagai [5] bfff124.
Jadi pelbagai [5] mempunyai alamat yang sama seperti i, yang bermaksud bahawa pelbagai [5] adalah i.
Jika mereka mempunyai alamat yang sama, mereka adalah perkara yang sama.
Jadi apabila kita menetapkan pelbagai [5] kepada 0, kita menetapkan i ke 0.
Dan jika anda berfikir tentang ini dari segi susunan,
int i diisytiharkan pertama, yang bermaksud i mendapat beberapa ruang pada timbunan.
Kemudian pelbagai [5] diperuntukkan, jadi kemudian 20 bytes diperuntukkan pada timbunan.
Jadi saya mendapat diperuntukkan terlebih dahulu, maka ini 20 bytes mendapat diperuntukkan.
Jadi saya berlaku sejurus sebelum array,
dan kerana cara, seperti saya berkata minggu lepas, di mana teknikal timbunan tumbuh ke bawah,
apabila anda indeks ke array, kita dijamin bahawa kedudukan 0 dalam pelbagai
sentiasa berlaku sebelum kedudukan pertama dalam array.
Ini adalah jenis bagaimana saya melukisnya minggu lepas.
Perhatikan bahawa di bawah kita mempunyai alamat 0 dan di atas kita mempunyai Max alamat.
Tindanan sentiasa berkembang.
Mari kita mengatakan bahawa kita memperuntukkan i.
Kami memperuntukkan integer i, yang bermaksud mari kita hanya mengatakan di sini integer i mendapat diperuntukkan.
Kemudian kita memperuntukkan pelbagai kami 5 integer, yang bermaksud bahawa di bawah itu,
sejak timbunan berkembang ke bawah, mereka 5 integer mendapat diperuntukkan.
Tetapi kerana bagaimana array bekerja, kita dijamin bahawa kedudukan pertama dalam pelbagai
sentiasa mempunyai alamat yang kurang daripada perkara yang kedua dalam array.
Jadi pelbagai kedudukan 0 sentiasa berlaku pertama dalam ingatan,
sedangkan pelbagai kedudukan 1 telah berlaku selepas itu
dan pelbagai kedudukan 2 mempunyai berlaku selepas itu,
yang bermaksud bahawa 0 array kedudukan akan berlaku suatu hari nanti di sini,
pelbagai kedudukan 1 akan berlaku atas bahawa
kerana bergerak ke atas bermakna alamat yang lebih tinggi sejak alamat maksimum adalah sehingga di sini.
Jadi [0] array turun sini, array [1] sehingga di sini, pelbagai [2] sehingga di sini, pelbagai [3] di sini.
Notis bagaimana sebelum ini kita memperuntukkan integer i semua cara di sini,
seperti yang kita bergerak lagi dan lagi ke dalam pelbagai kami, kami mendapat lebih dekat dan lebih dekat kepada integer i kami.
Ia hanya kebetulan bahawa pelbagai [5], yang merupakan salah satu kedudukan luar array kami,
sebenarnya mana integer i berlaku diperuntukkan.
Jadi itulah titik di mana kita berada memukul ruang pada timbunan
yang telah diperuntukkan untuk i integer, dan kami menetapkan bahawa kepada 0.
>> Itulah bagaimana ia berfungsi. Soalan? Yeah.
[Pelajar] Jangan sekali-kali fikiran. Okay.
[Pelajar] Bagaimana anda mengelakkan ini jenis kesilapan?
Ini jenis kesilapan? Jangan gunakan C sebagai bahasa pengaturcaraan anda.
Gunakan bahasa yang mempunyai batas pelbagai memeriksa.
Selagi anda berhati-hati, anda hanya perlu untuk mengelakkan pergi lalu batas array anda.
[Pelajar] Jadi di sini apabila kita pergi lalu batas array anda -
[Bowden] Itulah di mana perkara mula tersilap. >> [Pelajar] Oh, okay.
Selagi anda tinggal dalam memori yang diperuntukkan untuk pelbagai anda, anda denda.
Tetapi C tidak ada semakan ralat. Jika saya melakukan pelbagai [1000], ia akan dengan senang hati hanya mengubah apa yang berlaku -
Ia pergi ke permulaan array, maka ia pergi 1000 jawatan selepas dan set kepada 0.
Ia tidak melakukan apa-apa semakan bahawa oh, ini tidak benar-benar mempunyai 1000 perkara di dalamnya.
1000 adalah jauh melebihi apa yang saya harus berubah,
manakala Jawa atau sesuatu anda akan mendapat pelbagai indeks batas
atau indeks daripada batas pengecualian.
Itulah sebabnya banyak bahasa tahap yang lebih tinggi mempunyai perkara-perkara
di mana jika anda melampaui batas array, anda gagal
supaya anda tidak boleh mengubah perkara-perkara dari bawah anda
dan kemudian perkara pergi lebih buruk daripada hanya mendapat pengecualian
mengatakan bahawa anda pergi di luar akhir array.
[Pelajar] Dan sebagainya harus kita telah hanya berubah <= hanya <? >> [Bowden] Yeah.
Ia harus <sizeof (pelbagai) / sizeof (int);
sejak sizeof (array) ialah 20, tetapi kita hanya mahu 5. >> [Pelajar] Hak.
Lebih banyak soalan? Okay.
>> [Pelajar] Saya mempunyai satu soalan. >> Yeah.
[Pelajar] Apakah pembolehubah array sebenar?
[Bowden] Seperti apa yang pelbagai?
Array itu sendiri adalah simbol.
Ia hanya alamat permulaan daripada 20 bait yang kita rujukan.
Anda boleh berfikir ia sebagai penunjuk, tetapi ia adalah penunjuk berterusan.
Secepat perkara mendapatkan disusun, pelbagai pembolehubah tidak lagi wujud.
[Pelajar] Jadi bagaimana ia mencari saiz array?
Saiz pelbagai merujuk kepada saiz blok itu bahawa simbol yang merujuk kepada.
Apabila saya melakukan sesuatu seperti printf ("% p \ n", array);
mari kita jalankan ia.
Apa yang tidak saya hanya zalim?
'Array' Array diisytiharkan di sini.
Oh, di sini.
Dilafaz pandai, dan ia berlaku kepada notis bahawa saya mengisytiharkan array sebagai 5 elemen
tetapi saya mengindeks kepada 1000 kedudukan.
Ia boleh berbuat demikian kerana ini adalah hanya pemalar.
Ia hanya boleh pergi setakat perasan bahawa saya akan melampaui batas array.
Tetapi notis sebelum ini apabila kita terpaksa i tidak betul,
ia tidak mungkin boleh menentukan berapa banyak nilai i boleh mengambil,
jadi ia tidak boleh menentukan bahawa saya telah melampaui akhir array.
Itu hanya dilafaz pandai.
>> Tetapi sekarang membuat buggy4. Jadi apa lagi yang saya lakukan salah?
Tersirat mengisytiharkan fungsi perpustakaan 'printf'.
Saya akan mahu # include .
Okay. Kini berjalan buggy4.
Percetakan nilai array seperti yang saya lakukan di sini, percetakan ia sebagai penunjuk
sesuatu cetakan yang kelihatan seperti ini - bfb8805c - yang beberapa alamat
itu di rantau timbunan-ish.
Array itu sendiri adalah seperti penunjuk, tetapi ia tidak merupakan penunjuk sebenar,
sejak penunjuk tetap kita boleh berubah.
Tatasusunan adalah hanya beberapa berterusan. 20 blok memori bermula pada 0xbfb8805c alamat.
Jadi bfb8805c melalui alamat ini +20--atau saya rasa -20 -
semua memori yang diperuntukkan untuk pelbagai ini.
Array, pembolehubah itu sendiri tidak disimpan di mana-mana.
Apabila anda menyusun, pengkompil - gelombang tangan di dalamnya -
tetapi pengkompil hanya akan menggunakan mana ia tahu pelbagai untuk menjadi.
Ia tahu di mana pelbagai yang bermula,
dan supaya ia boleh sentiasa hanya melakukan perkara-perkara dari segi ofset dari awal bahawa.
Ia tidak memerlukan satu pemboleh ubah sendiri untuk mewakili pelbagai.
Tetapi apabila saya melakukan sesuatu seperti int * p = array; kini p ialah penunjuk yang menunjukkan kepada pelbagai itu,
dan kini p sebenarnya tidak wujud pada timbunan.
Saya bebas untuk menukar p. Boleh saya lakukan p = malloc.
Jadi ia asalnya menunjukkan pelbagai, kini ia menjurus kepada beberapa ruang pada timbunan.
Saya tidak boleh melakukan pelbagai malloc =.
Jika dilafaz pandai, ia akan menjerit pada saya kanan dari kelawar.
Sebenarnya, saya agak pasti gcc akan melakukan ini terlalu.
Jadi pelbagai jenis 'int [5]' tidak boleh diserahhakkan.
Anda tidak boleh menetapkan sesuatu untuk jenis pelbagai
kerana pelbagai hanya malar.
Ia adalah simbol yang rujukan mereka 20 bytes. Saya tidak boleh menukar.
>> [Pelajar] Dan di mana saiz array yang disimpan?
[Bowden] Ia tidak disimpan di mana-mana. Ia adalah apabila ia menyusun.
Jadi di mana saiz array yang disimpan?
Anda hanya boleh menggunakan sizeof (pelbagai) di dalam fungsi array diisytiharkan sendiri.
Jadi jika saya melakukan beberapa fungsi, foo, dan saya lakukan (int array [])
printf ("% d \ n", sizeof (array));
dan kemudian turun di sini saya panggil foo (susunan);
dalam fungsi ini - mari kita jalankan ia.
Ini adalah dilafaz pandai lagi.
Ia memberitahu saya bahawa sizeof pada pelbagai parameter fungsi
akan kembali saiz '* int'.
Ini akan menjadi satu kesilapan jika ia tidak apa yang saya mahu berlaku.
Mari kita sebenarnya mematikan Werror.
Amaran. Amaran yang halus.
Ia masih akan menyusun selagi ia mempunyai amaran.
/ A.out akan mencetak 4.
Amaran yang telah dijana adalah petunjuk jelas apa silapnya.
Ini pelbagai int hanya akan mencetak sizeof (int *).
Malah jika saya meletakkan pelbagai [5] di sini, ia masih hanya akan mencetak sizeof (int *).
Demikian secepat anda lulus ia ke dalam fungsi, perbezaan antara tatasusunan dan penunjuk
adalah tidak wujud.
Ini berlaku untuk menjadi pelbagai yang telah diisytiharkan pada timbunan,
tetapi sebaik sahaja kita lulus nilai itu, bahawa 0xbf blah, blah, blah ke dalam fungsi ini,
maka penunjuk ini menunjukkan kepada pelbagai itu pada timbunan.
Supaya bermakna bahawa sizeof hanya terpakai dalam fungsi yang pelbagai telah diisytiharkan,
yang bermaksud bahawa apabila anda menyusun fungsi ini,
apabila dilafaz pergi melalui fungsi ini, ia melihat pelbagai adalah pelbagai int bersaiz 5.
Jadi maka ia melihat sizeof (array). Nah, itu 20.
Itulah sebenarnya bagaimana sizeof pada dasarnya bekerja untuk hampir semua kes.
Sizeof bukan fungsi, ia adalah pengendali.
Anda tidak memanggil fungsi sizeof.
Sizeof (int), pengkompil hanya akan menterjemahkan bahawa ke 4.
Faham? Okay.
>> [Pelajar] Jadi apakah perbezaan antara sizeof (susunan) utama dan dalam foo?
Ini adalah kerana kita mengatakan sizeof (pelbagai), yang merupakan * int jenis,
sedangkan array turun di sini tidak * int jenis, ia adalah pelbagai int.
>> [Pelajar] Jadi jika anda mempunyai parameter dalam pelbagai [] bukannya * array int,
yang akan bermakna bahawa anda masih boleh menukar pelbagai kerana sekarang ia adalah penunjuk?
[Bowden] Seperti ini? >> [Pelajar] Yeah. Anda boleh menukar pelbagai dalam fungsi sekarang?
[Bowden] Anda boleh menukar pelbagai dalam kedua-dua kes.
Dalam kedua-dua kes ini, anda bebas untuk mengatakan pelbagai [4] = 0.
[Pelajar] Tetapi anda boleh membuat pelbagai titik kepada sesuatu yang lain?
[Bowden] Oh. Yeah. Dalam mana-mana kes - >> [pelajar] Yeah.
[Bowden] perbezaan antara pelbagai [] dan * pelbagai int, maka tiada sesiapapun.
Anda juga boleh mendapatkan beberapa pelbagai multidimensi di sini
untuk beberapa sintaks mudah, tetapi ia masih hanya penunjuk.
Ini bermakna bahawa saya bebas untuk melakukan pelbagai = malloc (sizeof (int)); dan kini menunjukkan tempat lain.
Tetapi seperti bagaimana ini berfungsi selama-lamanya dan sentiasa,
perubahan pelbagai ini dengan membuat ia menunjukkan kepada sesuatu yang lain
tidak menukar pelbagai ini ke sini kerana ia adalah satu salinan hujah,
ia bukan penunjuk kepada hujah itu.
Dan sebenarnya, hanya sebagai petunjuk lebih bahawa ia adalah betul-betul sama -
kita sudah melihat apa yang mencetak pelbagai percetakan -
bagaimana jika kita mencetak alamat array atau alamat alamat array
sama ada orang-orang?
Mari kita mengabaikan yang satu ini.
Okay. Ini adalah baik. Ia kini berjalan / a.out.
Pelbagai percetakan, kemudian mencetak alamat array, adalah perkara yang sama.
Array hanya tidak wujud.
Ia tahu apabila anda mencetak pelbagai, anda mencetak simbol yang merujuk kepada orang-orang 20 bytes.
Percetakan alamat array, baik, array tidak wujud.
Ia tidak mempunyai alamat, jadi ia hanya mencetak alamat mereka 20 bytes.
Secepat anda menyusun, seperti dalam buggy4 disusun anda. / A.out,
pelbagai adalah tidak wujud.
Penunjuk wujud. Tatasusunan tidak lakukan.
Blok memori mewakili array masih wujud,
tetapi array berubah-ubah dan pembolehubah jenis itu tidak wujud.
Mereka adalah seperti perbezaan utama di antara barisan dan tunjuk ajar
sebaik sahaja anda membuat panggilan fungsi, terdapat perbezaan tidak.
Tetapi di dalam fungsi yang array sendiri diisytiharkan, sizeof kerja-kerja yang berbeza
kerana anda mencetak saiz blok dan bukannya saiz jenis,
dan anda tidak boleh menukar kerana ia adalah simbol.
Percetakan perkara dan alamat benda yang mencetak perkara yang sama.
Dan itulah yang cukup banyak.
[Pelajar] Bolehkah anda mengatakan bahawa salah satu lebih banyak masa?
Saya mungkin telah terlepas sesuatu.
Pelbagai percetakan dan alamat pelbagai mencetak perkara yang sama,
sedangkan jika anda mencetak penunjuk berbanding alamat penunjuk,
satu perkara mencetak alamat apa yang anda menunjuk ke,
yang lain mencetak alamat penunjuk pada timbunan.
Anda boleh menukar penunjuk; anda tidak boleh menukar simbol pelbagai.
Dan penunjuk sizeof akan untuk mencetak saiz jenis penunjuk bahawa.
Jadi int * p sizeof (p) akan mencetak 4,
tetapi int array [5] cetak sizeof (pelbagai) akan mencetak 20.
[Pelajar] Maka int array [5] akan mencetak 20? >> Ya.
Itulah sebabnya di dalam buggy4 apabila ia digunakan untuk menjadi sizeof (susunan)
ini sedang melakukan i <20, yang tidak apa yang kita mahu.
Kami mahu i <5. >> [Pelajar] Okay.
[Bowden] Dan kemudian sebaik sahaja anda mula lulus dalam fungsi,
jika kita lakukan int * p = array;
dalam fungsi ini, kita pada dasarnya boleh menggunakan p dan pelbagai dalam cara yang tepat sama,
kecuali untuk masalah sizeof dan masalah yang berubah-ubah.
Tetapi p [0] = 1; adalah sama seperti mengatakan array [0] = 1;
Dan dengan seberapa segera seperti yang kita katakan foo (pelbagai); atau foo (p);
di dalam fungsi foo, ini adalah panggilan yang sama dua kali.
Tidak terdapat perbezaan antara kedua-dua panggilan.
>> Semua orang yang baik pada itu? Okay.
Kami mempunyai 10 minit.
>> Kami akan cuba untuk mendapatkan melalui program ini Typer Hacker,
laman web ini, yang keluar tahun lepas atau sesuatu.
Ia hanya sepatutnya menjadi seperti anda menaip secara rawak dan ia mencetak keluar -
Apa sahaja fail ia berlaku telah dimuatkan adalah apa ia kelihatan seperti anda sedang menaip.
Ia kelihatan seperti beberapa jenis kod sistem operasi.
Itulah apa yang kita mahu untuk melaksanakan.
Anda harus mempunyai laku binari bernama hacker_typer
yang mengambil dalam hujah tunggal, fail untuk "jenis penggodam."
Running executable perlu mengosongkan skrin
dan kemudian mencetak satu aksara dari fail yang diluluskan dalam setiap kali pengguna menekan kekunci.
Jadi apa jua kekunci yang anda tekan, ia harus buang dan bukannya mencetak watak dari fail
yang hujah.
Saya cukup banyak akan memberitahu anda apa perkara yang kita hendak perlu tahu.
Tetapi kita mahu untuk menyemak perpustakaan termios.
Saya tidak pernah menggunakan perpustakaan ini dalam seluruh hidup saya, jadi ia mempunyai tujuan yang sangat minimum.
Tetapi ini akan menjadi perpustakaan yang boleh kita gunakan untuk buang watak anda memukul
apabila anda menaip menjadi standard.
Jadi hacker_typer.c, dan kita akan mahu # include .
Melihat halaman lelaki untuk termios -: saya meneka terminal ia OS atau sesuatu -
Saya tidak tahu bagaimana untuk membaca.
Melihat ini, ia mengatakan termasuk 2 fail ini, jadi kami akan berbuat demikian.
>> Perkara pertama yang pertama, kami mahu mengambil dalam hujah tunggal, yang kita harus membuka fail.
Jadi, apa yang saya mahu lakukan? Bagaimanakah saya menyemak untuk melihat saya mempunyai hujah tunggal?
[Pelajar] Jika argc sama ia. >> [Bowden] Yeah.
Jadi, jika (argc = 2!) Printf ("Penggunaan:% s [fail untuk membuka]").
Jadi sekarang jika saya menjalankan ini tanpa memberikan hujah kedua - oh, saya memerlukan barisan baru -
anda akan melihat ia mengatakan penggunaan: / hacker_typer,
dan kemudian hujah kedua harus menjadi fail yang saya mahu untuk membuka.
Sekarang apa yang perlu saya lakukan?
Saya mahu membaca dari fail ini. Bagaimanakah saya membaca dari fail?
[Pelajar] Anda membukanya pertama. >> Yeah.
Jadi fopen Apakah fopen kelihatan seperti?
[Pelajar] Filename. >> [Bowden] Filename akan menjadi argv [1].
[Pelajar] Dan kemudian apa yang anda mahu lakukan dengan ia, jadi - >> [Bowden] Yeah.
Jadi jika anda tidak ingat, anda hanya boleh melakukan fopen lelaki,
di mana ia akan menjadi laluan const char * di mana jalan adalah nama fail,
const char * mod.
Jika anda berlaku untuk tidak ingat apa yang mod, maka anda boleh melihat untuk mod.
Dalam muka surat manusia, watak slash adalah apa yang anda boleh gunakan untuk mencari sesuatu.
Jadi saya menaip / mod untuk mencari mod.
n dan N adalah apa yang anda boleh gunakan untuk kitaran melalui perlawanan carian.
Di sini ia berkata mata mod hujah kepada rentetan
bermula dengan salah satu urutan berikut.
Jadi r, fail teks Terbuka untuk membaca. Itulah apa yang kita mahu lakukan.
Untuk membaca, dan saya mahu menyimpan.
Perkara yang akan untuk menjadi * FILE. Sekarang apa yang saya mahu lakukan?
Beri aku satu saat.
Okay. Sekarang apa yang saya mahu lakukan?
[Pelajar] Periksa jika ia NULL. >> [Bowden] Yeah.
Bila-bila masa anda membuka fail, pastikan bahawa anda berjaya dapat untuk membuka.
>> Sekarang saya mahu lakukan bahawa barangan termios di mana saya mahu untuk pertama membaca tetapan semasa saya
dan menyelamatkan mereka ke dalam sesuatu, maka saya ingin untuk mengubah tetapan saya
untuk buang mana-mana watak yang saya menaip,
dan kemudian saya mahu untuk mengemas kini tetapan.
Dan kemudian pada akhir program ini, saya ingin menukar kembali kepada tetapan asal saya.
Jadi struct akan menjadi termios jenis, dan saya akan mahu dua daripada mereka.
Yang pertama akan menjadi current_settings saya,
dan kemudian mereka pergi untuk menjadi hacker_settings saya.
Pertama, saya akan mahu menyimpan tetapan semasa saya,
maka saya akan untuk mahu mengemaskini hacker_settings,
dan kemudian cara pada akhir program saya, saya mahu kembali kepada tetapan semasa.
Jadi menyimpan tetapan semasa, cara yang berfungsi, kita termios lelaki.
Kita melihat bahawa kita mempunyai ini tcsetattr int, int tcgetattr.
Saya lulus dalam struct termios oleh penunjuk.
Cara ini akan kelihatan - I've sudah lupa apa fungsi dipanggil.
Salin dan tampal.
Jadi tcgetattr, maka saya mahu lulus dalam struct itu bahawa saya menyimpan maklumat dalam,
yang akan menjadi current_settings,
dan hujah pertama adalah pemerihal fail untuk perkara yang saya mahu menyimpan sifat-sifat.
Apa pemerihal fail adalah seperti bila-bila masa anda membuka fail, ia mendapat penghurai fail.
Apabila saya fopen argv [1], ia mendapat penghurai fail yang anda rujukan
apabila anda mahu untuk membaca atau menulis kepadanya.
Itu bukan pemerihal fail yang saya mahu menggunakan di sini.
Terdapat tiga perihalan fail anda secara lalai,
yang standard dalam, keluar standard, dan ralat piawai.
Secara lalai, saya fikir ia adalah standard dalam ialah 0, keluar standard 1, dan ralat piawai ialah 2.
Jadi, apa yang saya mahu untuk mengubah tetapan?
Saya ingin menukar tetapan apabila saya mencecah watak,
Saya mahu ia untuk membuang watak yang jauh bukannya mencetak skrin.
Apa aliran - standard dalam, keluar standard, atau ralat piawai -
respons kepada perkara yang apabila saya menaip di keyboard? >> [Pelajar] Standard masuk >> Yeah.
Jadi saya boleh lakukan 0 atau boleh saya lakukan stdin.
Saya mendapat current_settings standard masuk
>> Sekarang saya mahu mengemas kini tetapan,
jadi pertama saya akan menyalin ke hacker_settings apa current_settings saya.
Dan bagaimana kerja structs ia hanya akan menyalin.
Ini salinan semua bidang, seperti yang anda inginkan.
>> Sekarang saya mahu untuk mengemaskini beberapa bidang.
Melihat di termios, anda perlu membaca melalui banyak ini
hanya untuk melihat apa yang anda mahu untuk mencari,
tetapi bendera yang anda akan mahu untuk mencari adalah gema,
jadi ECHO aksara input Gema.
Pertama saya ingin menetapkan - I've sudah lupa apa bidang.
Ini adalah apa struct kelihatan seperti.
Jadi mod input saya fikir kita mahu kepada perubahan.
Kami akan melihat penyelesaian untuk memastikan bahawa apa yang kita ingin menukar.
Kami mahu menukar lflag untuk mengelakkan perlu untuk melihat melalui semua ini.
Kita mahu untuk menukar mod tempatan.
Anda perlu membaca melalui perkara ini keseluruhan untuk memahami di mana segala-galanya milik
bahawa kita mahu berubah.
Tetapi ia adalah dalam mod tempatan di mana kita akan mahu menukar bahawa.
Jadi hacker_settings.cc_lmode adalah apa ia dipanggil.
c_lflag.
Ini adalah di mana kita masuk ke dalam pengendali bitwise.
Kami jenis keluar masa, tetapi kita akan pergi melalui cepat sebenar.
Ini adalah di mana kita masuk ke dalam pengendali bitwise,
di mana saya fikir saya berkata satu masa dahulu bahawa apabila anda mula berurusan dengan bendera,
anda akan menggunakan bitwise pengendali banyak.
Setiap bit dalam bendera sepadan dengan sejenis tingkah laku.
Jadi di sini, bendera ini mempunyai sekumpulan perkara yang berbeza, di mana mereka semua bermakna sesuatu yang berbeza.
Tetapi apa yang saya mahu lakukan ialah hanya mematikan bit yang sepadan dengan ECHO.
Jadi untuk menjadikan bahawa off I lakukan & = ¬ ECHO.
Sebenarnya, saya fikir ia adalah seperti tECHO atau sesuatu. Saya hanya akan menyemak lagi.
Saya boleh termios. Ia hanya ECHO.
ECHO akan menjadi sedikit tunggal.
¬ ECHO akan bermakna semua bit ditetapkan kepada 1, yang bermakna semua bendera disetkan kepada true
kecuali sedikit ECHO.
Dengan berakhir bendera tempatan saya dengan ini, ia bermakna semua bendera yang sedang disetkan kepada true
masih akan disetkan kepada true.
Jika bendera ECHO saya disetkan kepada true, maka ini semestinya bersedia untuk palsu pada bendera ECHO.
Jadi ini baris kod hanya dimatikan bendera ECHO.
Baris kod lain, saya hanya akan menyalin mereka dalam kepentingan masa dan kemudian menjelaskan mereka.
Dalam penyelesaian, katanya 0.
Ia mungkin lebih baik tegas mengatakan stdin.
>> Notis bahawa saya juga melakukan ECHO | ICANON sini.
ICANON merujuk kepada sesuatu yang berasingan, yang bermaksud mod kanun.
Apa cara mod kanun biasanya apabila anda menaip baris arahan,
standard dalam tidak memproses apa-apa sehingga anda memukul newline.
Jadi apabila anda GetString, anda menaip sekumpulan perkara, maka anda memukul newline.
Itulah apabila ia dihantar kepada standard masuk
Itulah lalai.
Apabila saya mematikan mod kanun, kini setiap watak tunggal anda menekan
adalah apa yang mendapat diproses, yang biasanya jenis buruk kerana ia lambat untuk memproses perkara-perkara ini,
itulah sebabnya ia adalah baik untuk penampan ke dalam barisan keseluruhan.
Tetapi saya mahu setiap aksara akan diproses
kerana saya tidak mahu ia menunggu untuk saya memukul newline
sebelum ia memproses semua watak-watak yang saya telah menaip.
Ini mematikan mod kanun.
Barangan ini hanya bermakna apabila ia sebenarnya proses watak-watak.
Ini bermakna memprosesnya segera; secepat saya menaip mereka, memproses mereka.
Dan ini adalah fungsi yang mengemaskini tetapan saya untuk standard dalam,
dan cara TCSA melakukannya sekarang.
Pilihan lain menunggu sehingga segala-galanya yang kini di sungai diproses.
Itu tidak benar-benar perkara.
Hanya sekarang mengubah tetapan saya untuk menjadi apa yang kini dalam hacker_typer_settings.
Saya rasa saya dipanggil ia hacker_settings, jadi mari kita mengubah itu.
Tukar segalanya untuk hacker_settings.
>> Kini pada akhir program kami kita akan mahu kembali
apa yang kini di dalam normal_settings,
yang akan hanya kelihatan seperti & normal_settings.
Notis saya tidak mengubah mana-mana normal_settings saya sejak asalnya mendapat ia.
Kemudian hanya menukar mereka kembali, saya lulus mereka kembali pada akhir.
Ini adalah kemas kini. Okay.
>> Sekarang di dalam sini saya hanya akan menjelaskan kod dalam kepentingan masa.
Ia tidak bahawa kod yang banyak.
Kita melihat kita membaca watak dari fail. Kami dipanggil ia f.
Sekarang anda boleh lelaki fgetc, tetapi bagaimana fgetc akan bekerja
hanya ia akan kembali watak yang anda hanya membaca atau EOF,
yang sepadan dengan akhir fail atau beberapa kesilapan berlaku.
Kami menggelung, terus membaca watak tunggal dari fail,
sehingga kita telah kehabisan aksara untuk membaca.
Dan sementara kita berbuat demikian, kita tunggu pada watak tunggal dari standard.
Setiap kali tunggal anda menaip sesuatu pada baris arahan,
yang membaca dalam watak dari standard.
Kemudian putchar hanya akan meletakkan char kita membaca di sini dari fail keluar standard.
Anda boleh lelaki putchar, tetapi ia hanya meletakkan standard keluar, ia mencetak watak itu.
Anda juga boleh hanya melakukan printf ("% c", c), idea Sama.
Itu akan melakukan sebahagian besar kerja kami.
>> Perkara terakhir yang kita akan mahu lakukan adalah hanya fclose fail kami.
Jika anda tidak fclose, itulah kebocoran memori.
Kami mahu fclose fail kita asalnya dibuka, dan saya fikir itulah ia.
Jika kita membuat demikian, saya pun mendapat masalah.
Mari kita lihat.
Apa yang ia mengadu tentang?
Dijangka 'int' tetapi hujah adalah jenis 'struct _IO_FILE *'.
Kita akan melihat jika yang berfungsi.
Hanya dibenarkan di C99. Augh. Okay, membuat hacker_typer.
Sekarang kita mendapat penerangan yang lebih berguna.
Jadi menggunakan pengecam tidak diisytiharkan 'normal_settings'.
Saya tidak memanggil ia normal_settings. Saya dipanggil ia current_settings.
Jadi mari kita mengubah semua itu.
Sekarang lulus hujah.
Saya akan membuat 0 ini untuk sekarang.
Okay. . / Hacker_typer cp.c.
Saya juga tidak mengosongkan skrin pada permulaan.
Tetapi anda boleh melihat kembali kepada set masalah terakhir untuk melihat bagaimana anda mengosongkan skrin.
Ia hanya mencetak beberapa watak
manakala ini melakukan apa yang saya mahu lakukan.
Okay.
Dan berfikir tentang mengapa ini diperlukan untuk menjadi 0 bukannya stdin,
yang perlu # define 0,
ini mengadu bahawa -
Sebelum apabila saya berkata bahawa terdapat perihalan fail tetapi kemudian anda juga mempunyai * FILE anda,
penghurai fail hanya integer tunggal,
sedangkan * FILE mempunyai sekumpulan keseluruhan barangan yang dikaitkan dengannya.
Sebab kita perlu untuk mengatakan 0 bukannya stdin
bahawa stdin * FILE yang menunjukkan kepada perkara yang rujukan pemerihal fail 0.
Jadi, walaupun di sini apabila saya melakukan fopen (argv [1], Saya mendapat FILE * kembali.
Tetapi tempat * FILE itu adalah satu perkara yang sepadan dengan huraian fail bagi fail yang.
Jika anda melihat halaman lelaki terbuka, jadi saya fikir anda akan mempunyai untuk melakukan lelaki terbuka 3 - ndak -
lelaki terbuka 2 - yeah.
Jika anda melihat halaman untuk terbuka, terbuka adalah seperti fopen rendah tahap,
dan ia kembali pemerihal fail sebenar.
fopen melakukan sekumpulan barangan di atas terbuka,
yang bukannya kembali hanya bahawa huraian fail mengembalikan FILE keseluruhan penunjuk *
di dalam mana adalah huraian fail kecil kami.
Jadi standard merujuk kepada perkara * FILE,
sedangkan 0 merujuk kepada hanya standard pemerihal fail dalam dirinya.
>> Soalan?
[Ketawa] meniup melalui itu.
Semua hak. Kami sedang dilakukan. [Ketawa]
>> [CS50.TV]