[Powered by Google Translate] [BAHAGIAN 5: KURANG SELESA]
[Nate Hardison, Universiti Harvard]
[Ini adalah CS50.] [CS50.TV]
Begitu dialu-alukan kembali, guys.
Selamat datang kepada seksyen 5.
Pada ketika ini, setelah selesai kuiz 0 dan setelah melihat bagaimana anda lakukan,
diharapkan anda berasa benar-benar baik kerana saya amat kagum dengan skor dalam seksyen ini.
Bagi penonton talian kami, kami telah mempunyai beberapa soalan
mengenai dua masalah terakhir pada set masalah - atau pada kuiz, sebaliknya.
Jadi kita akan pergi ke atas mereka yang benar-benar cepat supaya semua orang melihat apa yang berlaku
dan bagaimana untuk pergi melalui penyelesaian sebenar dan bukannya hanya melihat penyelesaian itu sendiri.
Kami akan pergi sejak beberapa tahun lepas masalah benar-benar cepat, 32 dan 33.
Adil, sekali lagi, supaya penonton dalam talian boleh melihat ini.
>> Jika anda bertukar kepada 32 masalah anda, yang adalah pada halaman 13,
13 daripada 16 tahun, masalah 32 adalah semua tentang swap.
Ia adalah semua tentang bertukar-tukar dua integer.
Ia adalah masalah yang kita akan pergi ke atas beberapa kali dalam kuliah.
Dan di sini, apa yang kita telah meminta anda lakukan adalah trace memori cepat.
Untuk mengisi nilai pembolehubah kerana mereka pada timbunan
sebagai kod pergi melalui fungsi swap ini.
Khususnya, apa yang kita melihat -: saya akan meletakkan iPad ini turun -
khususnya, apa yang kita sedang melihat garis ini bernombor 6 hak di sini.
Dan ia bernombor 6 untuk persentuhan hanya dengan masalah sebelumnya.
Apa yang kami mahu lakukan adalah memaparkan atau label negeri memori
kerana ia adalah pada masa itu apabila kita melaksanakan ini nombor talian 6,
yang berkesan pulangan daripada fungsi swap kami di sini.
Jika kita tatal ke bawah di sini, kita melihat bahawa alamat segala-galanya dalam ingatan telah disediakan untuk kita.
Ini adalah sangat penting; kita akan kembali kepadanya dalam hanya seketika.
Dan kemudian turun di sini di bawah, kami terpaksa gambarajah memori sedikit bahawa kita akan merujuk kepada.
Saya sebenarnya telah dilakukan ini keluar pada iPad saya.
Jadi saya akan berselang-seli dan berulang-alik antara iPad dan kod ini hanya untuk rujukan.
>> Mari kita mulakan. Pertama, mari kita memberi tumpuan kepada pasangan yang pertama barisan utama di sini.
Untuk memulakan, kita pergi untuk memulakan x 1 dan y ke 2.
Jadi kita mempunyai dua pembolehubah integer, kedua-dua mereka akan diletakkan pada timbunan.
Kami akan meletakkan 1 dan 2 di dalamnya.
Jadi jika saya flip untuk iPad saya, mudah-mudahan, mari kita lihat -
Mencerminkan Apple TV, dan di sana kita pergi. Okay.
Jadi jika saya flip untuk iPad saya,
Saya mahu untuk memulakan x 1 dan y ke 2.
Kami melakukan yang cukup hanya dengan menulis 1 dalam kotak bertanda x
dan 2 dalam kotak bertanda y. Agak mudah.
Jadi sekarang mari kita kembali kepada laptop, lihat apa yang berlaku seterusnya.
Jadi ini selaras seterusnya adalah di mana perkara mendapatkan rumit.
Kami lulus alamat x dan alamat y sebagai parameter a dan b untuk fungsi swap.
Alamat x dan alamat y adalah perkara-perkara yang kita tidak boleh mengira
tanpa merujuk kepada peluru-mata sampai di sini.
Dan mujurlah, dua mata peluru pertama memberitahu kita betul-betul apa jawapan.
Alamat x dalam ingatan ialah 10, dan alamat y dalam ingatan ialah 14.
Jadi mereka adalah nilai yang diluluskan pada sebagai a dan b top up dalam fungsi swap kami.
Jadi sekali lagi, beralih kembali kepada gambarajah kami, saya boleh menulis 10 dalam
dan 14 dalam b.
Sekarang, ketika ini adalah di mana kita teruskan dengan swap.
Jadi Melibas kembali ke laptop lagi,
kita lihat bahawa cara kerja swap saya dereference pertama dan menyimpan hasil dalam tmp.
Jadi pengendali dereference berkata, "Hei Merawat kandungan satu variable sebagai alamat.
Pergi ke apa yang disimpan di alamat itu, dan beban. "
Apa yang anda beban daripada pembolehubah akan disimpan ke dalam pembolehubah tmp kami.
Melibas kembali ke iPad.
Jika kita pergi untuk menangani 10, kita tahu bahawa alamat 10 x varible
kerana kita diberitahu oleh titik peluru kami bahawa alamat x dalam ingatan adalah 10.
Jadi kita boleh pergi ke sana, dapatkan nilai, iaitu 1, seperti yang kita lihat pada iPad kami,
dan beban yang menjadi tmp.
Sekali lagi, ini bukan kandungan akhir.
Kami akan berjalan melalui dan kita akan sampai ke negeri terakhir kami program pada akhir.
Tetapi sekarang, kita mempunyai nilai 1 disimpan di dalam tmp.
>> Dan ada soalan yang lebih cepat sini.
[Alexander] Adakah pengendali dereference - itu hanya hak bintang di hadapan pembolehubah?
>> Ya. Jadi pengendali dereference, seperti yang kita flip kembali untuk komputer riba kami sekali lagi,
adalah bintang ini betul-betul di hadapan.
Dari segi ini, ia adalah - anda bezakan dengan operator pendaraban
yang memerlukan dua perkara; pengendali dereference adalah pengendali unari.
Hanya digunakan untuk satu nilai berbanding pengendali binari,
di mana anda memohon kepada dua nilai yang berbeza.
Jadi itulah apa yang berlaku di dalam bidang ini.
Kami dimuatkan nilai 1 dan disimpan ke dalam pembolehubah integer sementara kami.
Barisan seterusnya, kita menyimpan kandungan b ke -
atau, sebaliknya, kita menyimpan kandungan yang b menunjuk ke ke tempat di mana menunjuk ke.
Jika kita menganalisis ini dari kanan ke kiri, kita akan b dereference,
kita akan untuk menangani 14, kita akan merebut integer yang ada,
dan kemudian kita akan pergi ke alamat 10,
dan kita akan membuang hasil dereference kami b ke dalam ruang itu.
Melibas kembali ke iPad, kita di mana kita boleh membuat ini sedikit lebih konkrit,
ia mungkin membantu jika saya menulis nombor pada semua alamat di sini.
Jadi kita tahu bahawa pada y, kita adalah pada 14 alamat, x ialah pada 10 alamat.
Apabila kita bermula di b, kita dereference b, kita akan merebut nilai 2.
Kami akan merebut nilai ini kerana itu adalah nilai yang tinggal pada 14 alamat.
Dan kita akan meletakkan ia ke dalam pembolehubah yang tinggal alamat pada 10,
yang betul-betul ada, sepadan dengan pembolehubah x kita.
Jadi kita boleh melakukan sedikit penggantian sini
di mana kita menghilangkan daripada 1 kita dan sebaliknya kita menulis 2.
Jadi semua baik dan baik di dunia, walaupun kita telah x ditimpa sekarang.
Kami telah disimpan nilai lama x dalam pembolehubah tmp kami.
Jadi kita boleh melengkapkan swap dengan baris berikutnya.
Melibas kembali ke komputer riba kita.
Sekarang semua yang tinggal adalah untuk mengambil keluar kandungan pembolehubah sementara integer kami
dan menyimpan mereka ke dalam pembolehubah yang tinggal di alamat yang b memegang.
Jadi kita pergi untuk b dereference berkesan untuk mendapatkan akses kepada pembolehubah
yang berada di alamat yang b memegang di dalamnya,
dan kita pergi untuk barangan nilai yang tmp memegang ke dalamnya.
Melibas kembali untuk iPad sekali lagi.
Saya boleh memadam nilai ini di sini, 2,
dan sebaliknya kita akan menyalin hak 1 ke dalamnya.
Kemudian baris seterusnya yang melaksanakan, sudah tentu -
jika kita menyelak kembali ke laptop - adalah ini 6 titik,
yang merupakan titik di mana kita mahu mempunyai gambarajah kami diisi dengan lengkap.
Jadi Melibas kembali ke iPad sekali lagi, hanya jadi anda boleh lihat gambar rajah yang lengkap,
anda dapat melihat bahawa kita mempunyai 10 di, 14 dalam b, 1 dalam tmp, 2 x, dan 1 dalam y.
Adakah terdapat apa-apa soalan tentang perkara ini?
Adakah ini masuk akal yang lebih, setelah berjalan melaluinya?
Kurang akal? Harap-harap tidak. Okay.
>> Petunjuk adalah satu perkara yang amat sukar.
Salah satu lelaki kita bekerja dengan mempunyai satu pepatah yang sangat biasa:
"Untuk memahami petunjuk, pertama anda mesti memahami petunjuk."
Yang saya fikir adalah sangat benar. Ia tidak mengambil sedikit masa untuk mendapatkan digunakan untuk ia.
Lukisan banyak gambar, lukisan banyak gambarajah memori seperti ini sangat membantu,
dan selepas anda berjalan melalui contoh selepas contoh selepas contoh,
ia akan mula masuk akal lebih sedikit dan rasa lebih sedikit dan rasa lebih sedikit.
Akhirnya, satu hari, anda akan mempunyai semua sepenuhnya menguasai.
Apa-apa soalan sebelum kita beralih ke masalah seterusnya? Semua hak.
Jadi menyelak kembali ke laptop.
Masalah seterusnya yang kita ada adalah masalah nombor 33 pada fail I / O.
Zum masuk pada sedikit ini sedikit.
Masalah 33 - Ya?
>> [Daniel] Saya hanya mempunyai satu soalan yang cepat. Ini bintang, atau asterisk,
ia dipanggil dereferencing apabila anda menggunakan asterisk sebelum.
Apakah ia dipanggil apabila anda menggunakan #: glib sebelum?
>> #: Glib sebelum ini alamat pengendali.
Jadi mari kita tatal sandaran.
Oops. Saya dalam mod zum jadi saya tidak boleh benar-benar tatal.
Jika kita melihat kod ini benar-benar cepat di sini,
sekali lagi, perkara yang sama berlaku.
Jika kita melihat kod ini di sini, pada baris ini di mana kita membuat panggilan untuk menukar,
#: glib hanya mengatakan "mendapatkan alamat di mana kehidupan pembolehubah x."
Apabila pengkompil anda menyusun kod anda,
ia sebenarnya mempunyai fizikal menandakan tempat dalam ingatan untuk semua pembolehubah anda untuk hidup.
Dan jadi apa pengkompil maka boleh lakukan apabila ia disusun segala-galanya,
ia tahu, "Oh, saya meletakkan x alamat pada 10 saya meletakkan y alamat pada 14."
Ia kemudian boleh mengisi dalam nilai-nilai ini untuk anda.
Jadi, anda boleh kemudian - ia kemudian boleh lulus ini dalam pas dan & y dalam juga.
Ini lelaki mendapat alamat, tetapi mereka juga, apabila anda lulus mereka ke dalam fungsi swap,
jenis maklumat ini, ini * int di sini, memberitahu pengkompil,
"Baiklah, kita akan mentafsirkan alamat ini sebagai alamat pembolehubah integer."
Sebagai alamat int, yang berbeza daripada alamat pembolehubah watak
kerana int mengambil, pada mesin 32-bit, mengambil masa sehingga 4 bait ruang,
manakala watak hanya mengambil masa sehingga 1 bait ruang.
Jadi ia adalah penting untuk tahu juga apa yang - apa yang tinggal, apa jenis nilai
tinggal di alamat yang mendapat diluluskan.
Atau alamat yang anda berurusan dengan.
Cara itu, anda tahu berapa banyak bait maklumat sebenarnya beban keluar RAM anda.
Dan kemudian, ya, ini pengendali dereference, seperti anda telah bertanya,
pergi dan mengakses maklumat di alamat tertentu.
Jadi ia berkata, dengan pembolehubah ini di sini, merawat kandungan sebagai alamat,
pergi ke alamat tersebut, dan tarik keluar, beban ke dalam pemproses, beban ke dalam daftar
nilai sebenar atau kandungan yang tinggal di alamat itu.
Apa-apa lagi soalan? Ini adalah soalan yang baik.
Ia banyak istilah baru juga.
Ia juga jenis funky, melihat dan * di tempat-tempat yang berbeza.
>> Semua hak.
Jadi kembali kepada 33 masalah, memfailkan I / O.
Ini adalah salah satu masalah yang saya berfikir beberapa perkara yang berlaku.
Satu, ia adalah satu topik yang agak baru.
Ia telah dibentangkan cantik tidak lama lagi sebelum kuiz,
dan kemudian saya fikir ia adalah jenis seperti salah seorang daripada mereka masalah perkataan dalam matematik
di mana mereka memberikan anda banyak maklumat, tetapi anda sebenarnya tidak berakhir sehingga perlu menggunakan tan.
Bahagian pertama masalah ini menggambarkan apa fail CSV.
Kini, fail CSV, menurut keterangan, adalah fail nilai dipisahkan koma.
Sebab ini adalah di semua menarik, dan sebab anda pernah menggunakan mereka,
kerana, berapa ramai daripada anda pernah menggunakan barangan seperti Excel?
Rajah kebanyakan kamu telah, mungkin, atau akan digunakan pada satu ketika dalam hidup anda.
Anda akan menggunakan sesuatu seperti Excel.
Dalam usaha untuk mendapatkan data spreadsheet Excel atau melakukan apa-apa jenis pemprosesan dengan itu,
jika anda mahu untuk menulis program C atau program Python, program Jawa,
untuk berurusan dengan data yang anda telah disimpan di sana,
salah satu cara yang paling biasa untuk mendapatkan ia keluar adalah dalam fail CSV.
Dan anda boleh membuka Excel dan apabila anda pergi ke 'Save As' dialog,
anda boleh mendapatkan fail CSV sebenar.
>> Berguna untuk tahu bagaimana untuk berurusan dengan perkara-perkara ini.
Cara ia berfungsi ialah bahawa ia adalah serupa dengan - Maksud saya, ia dasarnya meniru spreadsheet,
di mana, seperti yang kita lihat di sini, dalam sekeping sangat kiri yang paling,
kita mempunyai semua nama-nama yang lalu.
Jadi kita mempunyai Malan, maka Hardison, dan kemudian Bowden, MacWilliam, dan kemudian Chan.
Semua nama-nama yang lalu. Dan kemudian koma memisahkan nama terakhir dari nama pertama.
David, Nate, Rob, Tommy, dan Zamyla.
Saya sentiasa adukkan Robby dan Tom.
Dan kemudian, akhirnya, lajur ketiga adalah alamat e-mel.
Setelah anda memahami bahawa, seluruh program ini adalah agak mudah untuk melaksanakan.
Apa yang kita telah dilakukan dalam usaha untuk meniru struktur yang sama dalam program C kami
kita telah digunakan struktur.
Kami akan mula bermain dengan lebih sedikit serta.
Kita melihat mereka untuk bit pertama sedikit masalah dalam set 3, apabila kita berurusan dengan kamus.
Tetapi ini struct kakitangan menyimpan nama akhir, nama pertama, dan e-mel.
Sama seperti fail CSV kami telah menyimpan.
Jadi ini hanya menukar dari satu format yang lain.
Kita perlu untuk menukar, dalam kes ini, struct kakitangan ke dalam barisan,
garis dipisahkan dengan koma, seperti itu.
Adakah yang masuk akal? Kalian semua telah mengambil kuiz,
jadi saya bayangkan anda telah sekurang-kurangnya mempunyai sedikit masa untuk berfikir tentang perkara ini.
>> Dalam fungsi sewa, masalah meminta kita untuk mengambil - zoom we'll di atas sedikit ini sedikit -
mengambil struktur kakitangan, struct kakitangan, dengan nama s,
dan melampirkan kandungannya ke fail staff.csv kami.
Ia ternyata bahawa ini adalah agak mudah untuk digunakan.
Kami jenis akan bermain-main dengan fungsi-fungsi lebih sedikit hari ini.
Tetapi dalam kes ini, fungsi fprintf adalah benar-benar kunci.
Jadi dengan fprintf, kita boleh mencetak, seperti anda semua telah printf menggunakan istilah ini keseluruhan.
Anda boleh printf garis ke fail.
Jadi bukan hanya membuat panggilan printf biasa di mana anda memberikan rentetan format
dan kemudian anda menggantikan semua pembolehubah dengan hujah-hujah berikut,
dengan fprintf, hujah anda yang pertama adalah sebaliknya fail yang anda mahu untuk menulis.
Jika kita melihat ini dalam perkakas, sebagai contoh, manusia fprintf,
kita boleh lihat perbezaan antara printf dan fprintf.
Saya akan zum di sini sedikit.
Jadi dengan printf, kita memberikan rentetan format, dan kemudian hujah berikutnya
semua pembolehubah untuk penggantian atau penggantian ke dalam rentetan format kami.
Manakala dengan fprintf, hujah pertama memang * Fail ini dipanggil sungai.
>> Melangkah kembali di sini untuk sewa kami,
kita sudah mendapat aliran fail * kami dibuka untuk kita.
Itulah apa ini baris pertama tidak; ia membuka fail staff.csv,
ia dibuka dalam mod lampiran, dan semua yang tinggal untuk kita lakukan adalah
menulis struktur kakitangan ke fail.
Dan, mari kita lihat, adakah saya mahu menggunakan iPad?
Saya akan menggunakan iPad. Kami mempunyai terbatal - biarkan yang meletakkan ini di atas meja supaya saya boleh menulis sedikit lebih baik -
membatalkan sewa dan ia mengambil masa dalam satu hujah, struktur kakitangan dipanggil s.
Got pendakap kami, kami telah mendapat * fail kami dipanggil fail,
kita mempunyai garis fopen kami yang diberikan kepada kita,
dan saya hanya akan menulis ia sebagai titik kerana ia sudah di pedia.
Dan kemudian pada baris seterusnya kita, kita pergi untuk membuat panggilan kepada fprintf
dan kita akan lulus dalam fail yang kita ingin mencetak,
dan kemudian rentetan format kami, yang -
Saya akan biarkan anda semua beritahu saya apa yang kelihatan seperti.
Bagaimana pula dengan anda, Stella? Adakah anda tahu apa bahagian pertama rentetan format kelihatan seperti?
[Stella] Saya tidak pasti. >> Rasa bebas untuk bertanya Jimmy.
Adakah anda tahu, Jimmy?
[Jimmy] Adakah ia hanya akan bertahan? Saya tidak tahu. Saya tidak pasti sepenuhnya.
>> Okay. Bagaimana pula, adakah sesiapa mendapatkan ini betul pada peperiksaan?
No Baiklah.
Ia ternyata bahawa di sini semua yang perlu kita lakukan ialah kita mahu setiap sebahagian daripada struktur kakitangan kami
akan dicetak sebagai rentetan ke dalam fail kami.
Kami hanya menggunakan watak tali penggantian tiga kali berbeza kerana kita mempunyai nama akhir
diikuti dengan koma, maka nama pertama diikuti oleh koma,
dan akhirnya alamat e-mel yang diikuti - yang tidak
pemasangan pada skrin saya - tetapi ia diikuti oleh watak newline.
Jadi saya akan menulis ia hanya di bawah sana.
Dan kemudian berikutan rentetan format kami,
kita hanya perlu penggantian, yang kita mengakses menggunakan tatatanda dot
yang kita lihat masalah dalam set 3.
Kita boleh menggunakan s.last, s.first, dan s.email
untuk menggantikan dalam ketiga-tiga nilai ke dalam rentetan format kami.
Jadi bagaimana itu pergi? Masuk akal?
Ya? Tidak? Mungkin? Okay.
>> Perkara terakhir yang kita lakukan selepas kita telah dicetak dan selepas kita telah membuka fail kami:
apabila kita telah membuka fail, kita sentiasa perlu ingat untuk menutupnya.
Kerana jika tidak, kita akan berakhir sehingga bocor memori,
menggunakan perihalan fail.
Jadi untuk menutup, fungsi yang tidak kita gunakan? Daniel?
[Daniel] fclose? >> Fclose, betul-betul.
Jadi bahagian terakhir masalah ini adalah untuk menutup fail, menggunakan fungsi fclose,
yang hanya kelihatan seperti itu.
Tidak terlalu gila.
Sejuk.
Jadi itulah masalah 33 pada kuiz.
Kami akan mempunyai fail pasti lebih I / O datang.
Kami akan melakukan sedikit lebih dalam kuliah hari ini, atau dalam seksyen hari ini,
kerana itulah apa yang akan membentuk sebahagian besar daripada pset ini akan datang.
Mari kita bergerak dari kuiz pada ketika ini. Ya?
>> [Charlotte]] Mengapa fclose (fail) bukannya fclose (staff.csv)?
>> Ah. Kerana ia ternyata bahawa - jadi soalan, yang adalah satu besar,
sebabnya, apabila kita menulis fclose, kita menulis bintang pembolehubah fclose (file)
berbanding kepada nama fail, staff.csv? Adakah itu betul? Yeah.
Jadi mari kita lihat. Jika saya menukar kembali ke komputer riba saya,
dan biarkan melihat fungsi fclose.
Jadi fungsi fclose menutup sungai dan ia mengambil penunjuk aliran yang kita mahu untuk menutup,
berbanding dengan nama fail sebenar yang kita mahu menutup.
Dan ini adalah kerana di sebalik tabir, apabila anda membuat panggilan untuk fopen,
apabila anda membuka fail, anda sebenarnya memperuntukkan memori untuk menyimpan maklumat mengenai fail.
Jadi anda mempunyai penunjuk fail yang mempunyai maklumat tentang fail,
seperti ia terbuka, saiznya, di mana anda berada kini dalam fail,
supaya anda boleh membuat membaca dan menulis panggilan ke tempat yang tertentu dalam fail.
Anda akhirnya menutup penunjuk bukannya menutup nama fail.
>> Ya? [Daniel] Jadi untuk menggunakan sewa, anda akan berkata - bagaimana ia mendapatkan input pengguna?
Adakah fprintf bertindak seperti GetString dalam erti kata bahawa ia hanya akan menunggu untuk input pengguna
dan meminta anda untuk menaip ini - atau menunggu untuk anda menaip ketiga-tiga perkara di?
Atau adakah anda perlu untuk menggunakan sesuatu untuk melaksanakan sewa?
>> Yeah. Jadi kita tidak berada - soalan itu, bagaimana kita mendapatkan input pengguna
untuk melaksanakan sewa? Dan apa yang kita ada di sini adalah pemanggil sewa,
diluluskan dalam struct kakitangan ini dengan semua data yang disimpan dalam struct sudah.
Jadi fprintf mampu untuk hanya menulis bahawa data secara langsung ke fail.
Tiada menunggu input pengguna.
Pengguna sudah diberi input dengan betul meletakkan dalam struct kakitangan ini.
Dan perkara, sudah tentu, akan memecahkan jika mana-mana orang-orang penunjuk nol,
jadi kita skrol kembali di sini dan kita melihat struct kami.
Kami mempunyai rentetan lepas, rentetan pertama, tali e-mel.
Kita kini tahu bahawa semua mereka yang benar-benar, di bawah hood, adalah pembolehubah * char.
Yang mungkin atau tidak boleh menunjuk ke menyeimbangkan.
Mereka boleh menunjuk ke memori pada timbunan itu,
mungkin memori pada timbunan.
Kami tidak benar-benar tahu, tetapi jika mana-mana petunjuk ini adalah batal, atau tidak sah,
bahawa yang pasti akan kemalangan fungsi sewa kami.
Itu adalah sesuatu yang adalah jenis di luar skop peperiksaan.
Kami tidak bimbang tentang itu.
Besar. Okay. Jadi bergerak dari kuiz.
>> Mari kita menutup lelaki ini, dan kita akan melihat pada pset 4.
Jadi jika anda semua melihat spec pset, sekali anda boleh mengaksesnya, cs50.net/quizzes,
kita akan pergi melalui beberapa masalah seksyen hari ini.
Saya menatal ke bawah - seksyen soalan bermula pada halaman ketiga spec pset.
Dan bahagian pertama meminta anda untuk pergi dan menonton pendek mengalihkan dan paip.
Yang jenis yang singkat sejuk, menunjukkan anda beberapa baru, selaras helah arahan sejuk yang boleh anda gunakan.
Dan kemudian kami telah mendapat beberapa soalan untuk anda juga.
Ini soalan pertama tentang sungai, yang printf menulis secara lalai,
kita jenis menyentuh hanya sedikit masa lalu.
Ini fprintf bahawa kita hanya membincangkan mengambil dalam aliran * fail sebagai hujah.
fclose mengambil dalam aliran fail * juga,
dan nilai pulangan fopen memberikan anda aliran fail * juga.
Sebab kita tidak melihat orang-orang sebelum apabila kita telah diuruskan dengan printf
adalah kerana printf mempunyai aliran lalai.
Dan aliran lalai yang ia menulis
anda akan mengetahui di pendek.
Jadi pasti mengambil melihat pada ia.
>> Dalam seksyen hari ini, kita akan bercakap sedikit tentang GDB,
sejak lebih mengenali anda dengan itu, amalan yang lebih anda mendapat dengan itu,
lebih mampu anda akan sebenarnya memburu bug dalam kod anda sendiri.
Ini mempercepatkan proses debugging dengan mendadak.
Jadi dengan menggunakan printf, setiap kali anda berbuat demikian anda perlu susun semula kod anda,
anda perlu untuk menjalankan ia lagi, kadang-kadang anda perlu untuk menggerakkan panggilan printf sekitar,
mengulas kod, ia hanya mengambil masa.
Matlamat kami adalah untuk cuba dan meyakinkan anda bahawa dengan GDB, anda boleh asasnya
apa-apa printf pada mana-mana titik dalam kod anda dan anda tidak perlu susun semula ia.
Anda tidak perlu untuk memulakan dan menyimpan meneka di mana untuk printf seterusnya.
Perkara pertama untuk dilakukan ialah untuk menyalin baris ini dan mendapatkan kod seksyen off web.
Saya menyalin ini baris kod yang mengatakan bahawa, "http://cdn.cs50.net wget".
Saya akan menyalin ia.
Saya akan pergi ke perkakas saya, zum keluar supaya anda boleh melihat apa yang saya lakukan,
tampal di sana, dan apabila saya tekan Enter, ini arahan wget literal adalah web mendapatkan.
Ia akan tarik turun fail ini di luar Internet,
dan ia akan menyimpan direktori semasa.
Sekarang, jika saya senarai direktori semasa saya anda boleh lihat bahawa saya telah mendapat fail ini section5.zip betul-betul di sana.
Cara untuk berurusan dengan lelaki itu adalah untuk unzip ia,
yang boleh anda lakukan dalam baris arahan, seperti ini.
Section5.zip.
Yang akan unzip, membuat folder untuk saya,
mengembung semua kandungan, meletakkan mereka di sana.
Jadi sekarang saya boleh pergi ke direktori seksyen saya 5 dengan menggunakan arahan cd.
Kosongkan skrin menggunakan jelas. Jadi mengosongkan skrin.
Sekarang saya telah mendapat terminal baik bersih untuk berurusan dengan.
>> Sekarang, jika saya menyenaraikan semua fail yang saya lihat dalam direktori ini,
anda melihat bahawa saya telah mendapat empat fail: buggy1, buggy2, buggy3, dan buggy4.
Saya juga telah mendapat c fail yang sepadan. Mereka.
Kami tidak akan melihat c fail sekarang.
Sebaliknya, kita akan menggunakannya apabila kita membuka GDB.
Kami telah disimpan mereka di sekitar supaya kita mempunyai akses kepada kod sumber sebenar apabila kita menggunakan GDB,
tetapi matlamat bahagian ini seksyen itu adalah untuk menggerumit sekitar dengan GDB
dan melihat bagaimana kita boleh menggunakan ia untuk mengetahui apa yang berlaku salah dengan setiap empat program buggy.
Jadi kita hanya akan di sekitar bilik benar-benar cepat,
dan saya akan meminta seseorang untuk menjalankan satu program kereta,
dan kemudian kita akan pergi sebagai satu kumpulan melalui GDB, dan kita akan melihat apa yang boleh kita lakukan untuk menetapkan program-program ini,
atau sekurang-kurangnya mengenal pasti apa yang berlaku salah dalam setiap daripada mereka.
Mari kita mulakan di sini dengan Daniel. Anda akan berjalan buggy1? Mari kita lihat apa yang berlaku.
[Daniel] Ia berkata terdapat satu kesalahan permohonan. >> Yeah. Tepat sekali.
Jadi, jika saya menjalankan buggy1, saya mendapat suatu kesalahan seg.
Pada ketika ini, saya boleh pergi dan membuka buggy1.c,
mencuba dan mengetahui apa yang berlaku salah,
tetapi satu perkara yang paling buruk tentang kesilapan kesilapan ini seg
adalah bahawa ia tidak memberitahu anda apa garis perkara program sebenarnya silapnya dan patah.
Anda jenis perlu melihat kod
dan memikirkan menggunakan tekaan dan memeriksa atau printf untuk melihat apa yang berlaku salah.
Salah satu perkara yang paling hebat tentang GDB adalah bahawa ia adalah benar-benar, benar-benar mudah
untuk memikirkan baris di mana kemalangan program anda.
Ia benar-benar berbaloi untuk menggunakannya, walaupun hanya untuk itu.
Jadi untuk boot GDB, saya menaip GDB, dan kemudian saya memberi laluan untuk laksana bahawa saya mahu menjalankan.
Di sini saya menaip Pra-Pemasangan ./buggy1.
Tekan Enter. Memberikan saya semua maklumat ini hak cipta,
dan turun di sini anda akan melihat baris ini yang mengatakan, "Membaca simbol dari rumah / /
jharvard/section5/buggy1. "
Dan jika semua berjalan lancar, anda akan melihat ia mencetak mesej yang kelihatan seperti ini.
Ia akan membaca simbol, ia akan berkata "Saya membaca simbol dari fail boleh laku anda,"
dan kemudian ia akan mempunyai ini "dilakukan" mesej di sini.
Jika anda melihat beberapa perubahan lain ini, atau yang anda lihat, ia tidak dapat mencari simbol
atau sesuatu seperti itu, apa yang bermakna adalah bahawa anda hanya tidak disusun laku anda dengan betul.
Apabila kita menyusun program untuk digunakan dengan GDB, kita perlu untuk menggunakan bahawa bendera khas g,
dan itulah yang dilakukan oleh lalai jika anda menyusun program anda, hanya dengan menaip membuat
atau membuat kereta atau membuat pulih, mana-mana orang.
Tetapi jika anda sedang menyusun secara manual dengan dilafaz, maka anda akan perlu pergi dalam dan termasuk bendera bahawa-g.
>> Pada ketika ini, sekarang bahawa kita mempunyai prompt GDB kami,
ia adalah agak mudah untuk menjalankan program ini.
Sama ada kita boleh menaip jangka, atau kita hanya boleh menaip r.
Kebanyakan arahan GDB boleh disingkatkan.
Biasanya hanya satu atau surat pasangan, yang cukup baik.
Saad Jadi, jika anda menaip r dan tekan Enter, apa yang berlaku?
[Saad] Saya mendapat SIGSEGV, segmentasi kerosakan, dan maka semua gobbledygook ini.
>> Yeah.
Seperti yang kita lihat pada skrin sekarang, dan seperti Saad berkata,
apabila kita menaip jangka atau r dan tekan Enter, kita masih mendapat kesalahan seg yang sama.
Jadi menggunakan GDB tidak menyelesaikan masalah kita.
Tetapi ia memberikan kita beberapa gobbledygook, dan ternyata bahawa gobbledygook ini
sebenarnya memberitahu kita di mana ia berlaku.
Untuk menghuraikan ini sedikit, ini sedikit pertama adalah fungsi di mana segala-galanya akan salah.
Terdapat ini __ strcmp_sse4_2, dan ia memberitahu kita bahawa ia berlaku dalam fail ini
dipanggil sysdeps/i386, semua ini, sekali lagi, jenis kacau-bilau - tetapi line 254.
Itulah jenis sukar untuk menghurai. Biasanya apabila anda melihat hal-hal seperti ini,
yang bermakna bahawa ia seg faulting dalam salah satu sistem perpustakaan.
Jadi sesuatu kaitan dengan strcmp. Kalian telah dilihat strcmp sebelum ini.
Tidak terlalu gila, tetapi adakah ini bermakna bahawa strcmp rosak atau bahawa terdapat masalah dengan strcmp?
Apa yang anda fikir, Alexander?
[Alexander] Adakah bahawa - 254 baris? Dan bukan binari, tetapi ia tidak siling mereka,
dan kemudian ada satu lagi bahasa untuk setiap fungsi. Adalah bahawa 254 dalam fungsi itu, atau -?
>> Ia line 254. Ia kelihatan seperti dalam fail ini s, jadi ia kod pemasangan mungkin.
>> Tetapi, saya rasa perkara yang lebih mendesak, kerana kita telah mendapat bersalah seg,
dan ia kelihatan seperti ia datang dari fungsi strcmp,
adakah ini membayangkan, maka, strcmp yang rosak?
Ia tidak sepatutnya, mudah-mudahan. Jadi hanya kerana anda mempunyai kesalahan segmentasi
dalam salah satu fungsi sistem, biasanya bermakna bahawa anda hanya tidak dipanggil dengan betul.
Perkara yang paling cepat untuk lakukan untuk mengetahui apa yang sebenarnya berlaku di
apabila anda melihat sesuatu yang gila seperti ini, apabila anda melihat kesilapan seg,
terutamanya jika anda mempunyai satu program yang menggunakan lebih daripada sekadar utama,
adalah untuk menggunakan jejakundur.
Saya menyingkatkan jejakundur dengan menulis bt, berbanding perkataan jejakundur penuh.
Tetapi Charlotte, apa yang berlaku apabila anda menaip bt dan tekan Enter?
[Charlotte] Ia menunjukkan saya dua baris, 0 line dan line 1.
>> Yeah. Jadi line 0 dan baris 1.
Ini adalah bingkai tindanan sebenar yang sedang dalam permainan apabila program anda terhempas.
Bermula dari bingkai teratas, bingkai 0, dan pergi ke paling bawah, yang adalah bingkai 1.
Bingkai teratas kami adalah bingkai strcmp.
Anda boleh berfikir ini sebagai serupa dengan masalah yang kita hanya melakukan kuiz dengan petunjuk,
di mana kita telah menukar bingkai tindanan di atas bingkai timbunan utama,
dan kita mempunyai pembolehubah yang swap menggunakan di atas pembolehubah yang utama telah menggunakan.
Berikut kemalangan kami berlaku dalam fungsi strcmp kami, yang telah dipanggil oleh fungsi utama kami,
dan jejakundur memberi kami bukan sahaja fungsi di mana perkara gagal,
tetapi ia juga memberitahu kita di mana segala-galanya telah dipanggil dari.
Jadi jika saya menatal lebih lebih sedikit ke kanan,
kita dapat melihat bahawa yeah, kita berada pada 254 baris fail ini strcmp-sse4.s.
Tetapi panggilan itu dibuat di buggy1.c, baris 6.
Jadi yang bermakna yang boleh kita lakukan - kita hanya boleh pergi menyemak dan melihat apa yang sedang berlaku
di buggy1.c, baris 6.
Sekali lagi, terdapat beberapa cara untuk melakukan ini. Salah satu adalah untuk keluar daripada GDB
atau mempunyai kod anda terbuka dalam tetingkap lain dan rujukan silang.
Itu, di dalam dan dengan sendirinya, adalah agak berguna kerana sekarang jika anda berada pada waktu pejabat
dan anda telah mendapat suatu kesalahan seg dan TF anda tertanya-tanya di mana segala-galanya telah melanggar,
anda hanya boleh mengatakan, "Oh, baris 6. Saya tidak tahu apa yang berlaku,
tetapi sesuatu tentang line 6 menyebabkan program saya untuk memecahkan. "
Cara lain untuk melakukannya ialah anda boleh menggunakan arahan ini dipanggil senarai dalam GDB.
Anda juga boleh menyingkatkan dengan l.
Jadi jika kita memukul l, apa yang kita sampai ke sini?
Kita mendapat sekumpulan keseluruhan barangan pelik.
Ini adalah kod pemasangan sebenar
yang pada strcmp_sse4_2.
Ini kelihatan jenis funky,
dan sebab kita mendapat ini adalah kerana sekarang,
GDB telah kami dalam bingkai 0.
>> Jadi bila-bila masa kita melihat pada pembolehubah, bila-bila masa kita melihat kod sumber,
kita sedang melihat kod sumber yang berkaitan untuk bingkai tindanan kami kini masuk
Jadi dalam usaha untuk mendapatkan apa-apa yang bermakna, kita perlu
bergerak ke bingkai timbunan yang lebih masuk akal.
Dalam kes ini, bingkai tindanan utama akan masuk akal lebih sedikit,
kerana itu adalah sebenarnya kod yang kita menulis.
Bukan kod strcmp.
Cara anda boleh bergerak antara bingkai, dalam kes ini, kerana kita mempunyai dua,
kita mempunyai 0 dan 1,
anda boleh berbuat demikian dengan dan arahan down.
Jika saya bergerak sehingga satu bingkai,
sekarang saya dalam bingkai tindanan utama.
Saya boleh bergerak ke bawah untuk kembali ke mana saya berada,
naik lagi, pergi ke bawah lagi, dan pergi lagi.
Jika anda pernah melakukan program anda dalam GDB, anda akan mendapat kemalangan, anda akan mendapat jejakundur,
dan anda melihat bahawa ia adalah dalam fail beberapa bahawa anda tidak tahu apa yang berlaku.
Anda cuba senarai, kod tidak kelihatan biasa kepada anda,
mengambil melihat bingkai anda dan mengetahui di mana anda berada.
Anda mungkin dalam bingkai tindanan salah.
Atau sekurang-kurangnya anda berada dalam bingkai timbunan yang tidak adalah salah satu yang anda benar-benar boleh debug.
Sekarang kita berada dalam bingkai tindanan sesuai, kita berada di utama,
sekarang kita boleh menggunakan senarai arahan untuk memikirkan apa baris.
Dan anda boleh melihat; ia dicetak untuk kita di sini.
Tetapi kita boleh memukul menyenaraikan semua yang sama, dan senarai memberikan kita ini cetakan yang bagus
kod sumber sebenar yang berlaku di sini.
>> Khususnya, kita boleh melihat pada baris 6.
Kita boleh lihat apa yang berlaku di sini.
Dan ia kelihatan seperti kita membuat perbandingan rentetan
antara rentetan "CS50 batu" dan argv [1].
Sesuatu tentang perkara ini telah terhempas.
Jadi Missy, adakah anda mempunyai apa-apa pemikiran mengenai apa yang mungkin berlaku di sini?
[Missy] Saya tidak tahu kenapa ia terhempas. >> Anda tidak tahu kenapa ia terhempas?
Jimmy, mana-mana pemikiran?
[Jimmy] Saya tak pasti sepenuhnya, tetapi kali terakhir kita digunakan rentetan istimewa,
atau strcmp, kita mempunyai seperti tiga kes yang berbeza di bawahnya.
Kami tidak mempunyai ==, saya tidak berfikir, betul-betul di garis yang pertama.
Sebaliknya, ia telah dipisahkan kepada tiga, dan satu adalah == 0,
satu <0, saya fikir, dan satu> 0.
Jadi mungkin sesuatu seperti itu? >> Yeah. Jadi ada isu ini
kita melakukan perbandingan dengan betul?
Stella? Mana-mana pemikiran?
[Stella] Saya tidak pasti. >> Tidak pasti. Daniel? Pemikiran? Okay.
Ternyata apa yang berlaku di sini ialah apabila kita berlari program
dan kita mendapat bersalah seg, apabila anda berlari program untuk kali pertama, Daniel,
adakah anda memberikan apa-apa hujah baris arahan?
[Daniel] No >> No. Dalam kes itu, apakah nilai argv [1]?
>> Terdapat tiada nilai. >> Hak.
Well, tidak ada nilai rentetan yang sesuai.
Tetapi terdapat beberapa nilai. Apakah nilai yang mendapat disimpan di sana?
>> Satu nilai sampah? >> Ia adalah sama ada nilai sampah atau, dalam kes ini,
akhir array argv sentiasa ditamatkan dengan batal.
Jadi apa sebenarnya yang mendapat disimpan di dalam terdapat null.
Cara lain untuk menyelesaikan masalah ini, bukannya berfikir melalui,
adalah untuk mencuba mencetak ia keluar.
Ini adalah di mana saya telah mengatakan bahawa menggunakan GDB adalah besar,
kerana anda boleh mencetak keluar semua pembolehubah, semua nilai-nilai yang anda mahu
menggunakan perintah ini berguna bagus sekali p.
Jadi jika saya menaip p dan kemudian saya menaip nilai pembolehubah atau nama pembolehubah,
berkata, argc, saya melihat bahawa argc ialah 1.
Jika saya ingin mencetak keluar argv [0], saya boleh berbuat demikian seperti itu.
Dan seperti yang kita lihat, argv [0] sentiasa nama program anda,
sentiasa nama executable.
Di sini anda melihat ia mendapat nama path penuh.
Saya juga boleh mencetak argv [1] dan lihat apa yang berlaku.
>> Di sini kita mendapat jenis ini nilai mistik.
Kami mendapat 0x0 ini.
Ingat pada permulaan penggal apabila kita bercakap tentang nombor perenambelasan?
Atau soalan itu sedikit di akhir-pset 0 tentang bagaimana untuk mewakili 50 dalam hex?
Cara kita menulis nombor hex dalam CS, hanya untuk tidak mengelirukan diri
dengan nombor perpuluhan, adalah kita sentiasa awalan mereka dengan 0x.
Jadi ini awalan 0x sentiasa hanya bermakna mentafsir nombor berikut sebagai nombor perenambelasan,
bukan sebagai rentetan, bukan sebagai nombor perpuluhan, bukan sebagai nombor perduaan.
Sejak nombor 5-0 adalah nombor yang sah dalam perenambelasan.
Dan ia adalah nombor dalam perpuluhan, 50.
Jadi ini adalah hanya bagaimana kita disambiguate.
Jadi 0x0 cara 0 perenambelasan, yang juga perpuluhan 0, binari 0.
Ia hanya nilai 0.
Ia ternyata bahawa ini adalah apa yang batal adalah, sebenarnya, dalam ingatan.
Nol hanya 0.
Di sini, elemen yang disimpan di argv [1] adalah batal.
Jadi kita sedang berusaha untuk membandingkan "CS50 batu" tali untuk kami rentetan nol.
Jadi dereferencing batal, cuba untuk mengakses perkara di null,
mereka biasanya akan menyebabkan beberapa jenis kesalahan segmentasi atau lain-lain perkara-perkara buruk berlaku.
Dan ternyata strcmp tidak memeriksa untuk melihat
sama ada atau tidak anda telah diluluskan dalam nilai yang batal.
Sebaliknya, ia hanya pergi ke hadapan, cuba untuk melakukan perkara,
dan jika ia seg kesilapan, ia seg kesilapan, dan ia adalah masalah anda. Anda perlu pergi membaikinya.
Benar-benar cepat, bagaimana kita boleh menyelesaikan masalah ini? Charlotte?
[Charlotte] Anda boleh menyemak menggunakan jika.
Jadi jika argv [1] adalah batal, == 0, kemudian kembali 1, atau sesuatu [difahami].
>> Yeah. Jadi itulah salah satu cara terbaik untuk melakukannya, seperti yang kita boleh menyemak untuk melihat,
nilai kita kira-kira untuk masuk ke dalam strcmp, argv [1], ia menyeimbangkan?
Jika ia batal, maka kita boleh mengatakan okay, membatalkan.
>> Satu cara yang lebih biasa untuk melakukan ini adalah untuk menggunakan nilai argc.
Anda boleh lihat di sini pada awal utama,
Kami tinggalkan bahawa ujian pertama yang kita biasanya lakukan apabila kita menggunakan hujah baris arahan,
yang adalah untuk menguji sama ada atau tidak nilai argc kita adalah apa yang kita harapkan.
Dalam kes ini, kita menjangkakan sekurang-kurangnya dua hujah,
nama program ditambah satu lagi.
Kerana kita berada kira-kira untuk menggunakan hujah kedua di sini.
Jadi mempunyai beberapa jenis ujian terlebih dahulu, sebelum panggilan strcmp kita
bahawa ujian sama ada atau tidak argv adalah sekurang-kurangnya 2, juga akan melakukan perkara yang sama perkara.
Kita boleh melihat jika ia berfungsi dengan menjalankan program ini sekali lagi.
Anda sentiasa boleh memulakan semula program anda dalam GDB, yang adalah benar-benar baik.
Anda boleh menjalankan, dan apabila anda lulus dalam hujah untuk program anda,
anda lulus mereka dalam apabila anda panggilan berjalan, bukan apabila anda boot GDB.
Dengan cara itu anda boleh terus memohon program anda dengan hujah-hujah yang berbeza setiap kali.
Jadi berlari, atau sekali lagi, saya boleh menaip r, dan mari kita lihat apa yang berlaku jika kita menaip "hello".
Ia sentiasa akan meminta anda jika anda mahu untuk memulakan dari awal lagi.
Biasanya, anda tidak mahu untuk memulakan dari awal lagi.
Dan pada ketika ini, ia mula semula sekali lagi, ia mencetak keluar
program bahawa kita sedang berjalan, buggy1, dengan hujah hello,
dan ia mencetak ini keluar standard, ia berkata, "Anda mendapat D," wajah sedih.
Tetapi kita tidak seg bersalah. Ia berkata proses itu keluar biasanya.
Jadi yang kelihatan agak baik.
Tiada kesalahan lebih seg, kita menjadikan ia lepas,
jadi ia kelihatan seperti yang sememangnya seg pepijat kerosakan yang kita telah mendapat.
Malangnya, ia memberitahu kita bahawa kita sedang mendapat D.
>> Kita boleh kembali dan melihat kod dan lihat apa yang telah berlaku di sana
untuk mengetahui apa - mengapa ia telah memberitahu kita bahawa kita mendapat D.
Mari kita lihat, di sini ini printf mengatakan bahawa anda mendapat D.
Jika kita menaip senarai, kerana anda menyimpan senarai menaip, ia terus iterating turun melalui program anda,
jadi ia akan menunjukkan kepada anda beberapa baris pertama program anda.
Kemudian ia akan menunjukkan kepada anda garis yang akan datang, dan sebahagian seterusnya dan sebahagian seterusnya.
Dan ia akan terus mencuba untuk pergi ke.
Dan sekarang kita akan mendapat "beratur nombor 16 adalah daripada pelbagai."
Kerana ia hanya mempunyai 15 baris.
Jika anda sampai ke tahap ini dan anda tertanya-tanya, "Apa yang saya lakukan?" anda boleh menggunakan arahan bantuan.
Gunakan membantu dan kemudian memberikan ia nama arahan.
Dan anda lihat GDB memberikan kita semua ini jenis barangan.
Ia berkata, "Dengan hujah tiada, menyenaraikan sepuluh lagi baris selepas atau sekitar penyenaraian sebelumnya.
Senarai - senarai sepuluh baris sebelum "
Jadi mari kita cuba menggunakan tolak senarai.
Dan yang menyenaraikan 10 baris sebelumnya; anda boleh bermain-main dengan senarai sedikit.
Anda boleh melakukan senarai, senarai -, anda juga boleh memberi senarai nombor, seperti 8 senarai,
dan ia akan menyenaraikan 10 baris sekitar 8 baris.
Dan anda boleh melihat apa yang berlaku di sini anda telah mendapat mudah jika lain.
Jika anda menaip di CS50 batu, ia mencetak keluar "Anda mendapat A."
Jika tidak, ia mencetak keluar "Anda mendapat D."
Bandar Bummer. Semua hak. Ya?
>> [Daniel] Jadi apabila saya cuba melakukan CS50 batu tanpa pengikat kata,
ia mengatakan "Anda mendapat D."
Saya memerlukan petikan untuk mendapatkannya untuk bekerja, mengapa?
>> Yeah. Ia ternyata bahawa apabila - ini adalah satu lagi berita gembira sedikit menyeronokkan -
apabila anda menjalankan program ini, jika kita menjalankan dan kita menaip CS50 batu,
seperti Daniel mengatakan yang dia lakukan, dan anda menekan Enter,
ia masih mengatakan kita mendapatkan D.
Dan soalan itu, mengapa ini?
Dan ternyata bahawa kedua-dua terminal kami dan GDB menghurai ini sebagai dua hujah yang berasingan.
Kerana apabila ada ruang, itu tersirat sebagai
hujah pertama berakhir pada tarikh tersebut; hujah seterusnya adalah kira-kira untuk memulakan.
Cara untuk menggabungkan mereka kepada dua, atau maaf, ke dalam satu hujah,
adalah dengan menggunakan petikan.
Jadi sekarang, jika kita meletakkan ia dalam petikan dan berjalan sekali lagi, kita akan mendapat A.
Jadi hanya untuk menggulung, tiada sebut, CS50 dan batu dihuraikan sebagai dua hujah berasingan.
Dengan memetik, ia dihuraikan sebagai salah satu hujah sama sekali.
>> Kita dapat lihat ini dengan titik putus.
Setakat ini kita telah menjalankan program kami, dan ia telah berjalan
sehingga sama ada ia seg kesilapan atau hits ralat
atau sehingga ia telah keluar dan semua telah benar-benar halus.
Ini tidak semestinya perkara yang paling berguna, kerana kadang-kadang
anda mempunyai kesilapan dalam program anda, tetapi ia tidak menyebabkan kerosakan segmentasi.
Ia tidak menyebabkan program anda untuk berhenti atau apa-apa seperti itu.
Cara untuk mendapatkan GDB untuk menjedakan program anda pada satu titik tertentu
adalah untuk menetapkan titik putus.
Anda boleh melakukan ini dengan menetapkan titik putus pada nama fungsi
atau anda boleh menetapkan titik putus on-line kod tertentu.
Saya suka untuk menetapkan titik putus pada nama fungsi, kerana - mudah untuk diingati,
dan jika anda benar-benar pergi dan mengubah kod sumber anda sehingga sedikit,
maka titik putus anda sebenarnya akan tinggal di tempat yang sama dalam kod anda.
Manakala jika anda menggunakan nombor baris, dan nombor talian menukar
kerana anda menambah atau memadam beberapa kod, maka titik putus anda semua benar-benar diskrukan sehingga.
Salah satu perkara yang paling biasa saya lakukan adalah menetapkan titik putus pada fungsi utama.
Selalunya saya akan boot GDB, saya akan menaip b utama, tekan Enter, dan yang akan menetapkan titik putus
kepada fungsi utama yang hanya berkata, "Berhenti Seketika program secepat anda mula berjalan,"
dan dengan cara itu, apabila saya menjalankan program saya dengan, katakan, CS50 batu sebagai dua hujah
dan tekan Enter, ia mendapat ke fungsi utama dan ia berhenti betul-betul di baris pertama,
betul sebelum ia menilai fungsi strcmp.
>> Sejak saya dijeda, sekarang saya boleh mula mucking sekitar dan melihat apa yang berlaku di
dengan semua pembolehubah yang berbeza yang diluluskan ke dalam program saya.
Sini saya boleh mencetak argc dan lihat apa yang berlaku.
Lihat bahawa argc ialah 3, kerana ia mendapat 3 nilai-nilai yang berbeza di dalamnya.
Ia mendapat nama program, ia mendapat hujah pertama dan hujah kedua.
Kita boleh mencetak mereka keluar dengan melihat argv [0], argv [1], dan argv [2].
Jadi sekarang anda juga boleh melihat mengapa ini panggilan strcmp akan gagal,
kerana anda melihat bahawa ia tidak berpecah CS50 dan batu kepada dua hujah yang berasingan.
Pada ketika ini, apabila anda telah melanda titik putus satu, anda boleh terus melangkah melalui program anda
baris demi baris, berbanding untuk memulakan program anda sekali lagi.
Jadi jika anda tidak mahu untuk memulakan program anda sekali lagi dan hanya terus dari sini,
anda boleh menggunakan arahan terus dan terus akan menjalankan program hingga akhir.
Sama seperti ia lakukan di sini.
Walau bagaimanapun, jika saya memulakan semula program, CS50 batu, ia mencecah titik putus saya sekali lagi,
dan kali ini, jika saya tidak mahu hanya pergi sepanjang jalan melalui sepanjang program,
Saya boleh menggunakan arahan seterusnya, yang saya juga menyingkatkan dengan n.
Dan ini akan melangkah melalui talian program demi baris.
Jadi, anda boleh menonton sebagai perkara melaksanakan, sebagai perubahan pembolehubah, sebagai perkara mendapatkan dikemaskini.
Yang cukup baik.
Perkara yang sejuk lain adalah bukannya mengulangi arahan yang sama lebih dan lebih dan lebih lagi,
jika anda hanya tekan Enter - jadi di sini anda lihat Saya tidak ditaip dalam apa-apa -
jika saya hanya tekan Enter, ia akan mengulangi arahan sebelumnya,
atau arahan GDB sebelumnya bahawa saya hanya meletakkan masuk
Saya boleh menyimpan memukul Masukkan dan ia akan terus melangkah melalui talian kod saya demi baris.
Saya akan menggalakkan anda semua untuk pergi menyemak program kereta lain juga.
Kami tidak mempunyai masa untuk mendapatkan melalui semua daripada mereka hari ini dalam seksyen.
Kod sumber yang ada, jadi anda boleh jenis lihat apa yang berlaku di
di sebalik tabir jika anda mendapat benar-benar terperangkap,
tetapi sekurang-kurangnya, hanya amalan boot sehingga GDB,
menjalankan program ini sehingga ia pecah pada anda,
mendapatkan jejakundur, memikirkan apa berfungsi kemalangan itu berada di,
apa garis ia berada di atas, mencetak beberapa nilai pembolehubah,
hanya supaya anda mendapatkan rasa untuk itu, kerana yang benar-benar akan membantu anda di masa hadapan.
Pada ketika ini, kita akan berhenti keluar GDB, yang anda lakukan menggunakan berhenti atau hanya q.
Jika program anda adalah di tengah-tengah berjalan masih, dan ia tidak keluar,
ia sentiasa akan bertanya anda, "Adakah anda pasti anda benar-benar mahu berhenti?"
Anda hanya boleh memukul ya.
>> Sekarang kita akan melihat masalah seterusnya yang kita ada, yang merupakan program kucing.
Jika anda menonton pendek mengalihkan dan paip, anda akan melihat bahawa Tommy menggunakan program ini
yang pada asasnya mencetak semua output fail ke skrin.
Jadi jika saya berjalan kucing, ini adalah sebenarnya satu program yang terbina dalam untuk perkakas,
dan jika anda mempunyai Mac, anda boleh lakukan ini pada Mac anda juga, jika anda membuka terminal.
Dan kita - kucing, katakan, cp.c, dan tekan Enter.
Apakah ini lakukan, jika kita tatal ke atas sedikit dan melihat di mana kita berlari baris,
atau di mana kita berlari arahan kucing, ia benar-benar hanya dicetak kandungan cp.c ke skrin kami.
Kita boleh berjalan lagi dan anda boleh dimasukkan ke dalam beberapa fail bersama-sama.
Jadi anda boleh melakukan cp.c kucing, dan kemudian kita juga boleh menyatukan fail cat.c,
yang merupakan program yang kami kira-kira untuk menulis,
dan ia akan mencetak kedua-dua fail kembali untuk kembali ke skrin kami.
Jadi, jika kita tatal sedikit, kita lihat bahawa apabila kita berlari ini cp.c kucing, cat.c,
pertama ia dicetak fail cp, dan kemudian di bawah, ia dicetak keluar fail cat.c sampai di sini.
Kami akan menggunakan ini untuk hanya mendapat kaki kita basah.
Bermain-main dengan percetakan mudah ke terminal, lihat bagaimana ia berfungsi.
Jika anda semua membuka dengan gedit cat.c, tekan Enter,
anda boleh lihat program yang kami kira-kira untuk menulis.
Kami telah dimasukkan ini plat dandang bagus, jadi kita tidak perlu menghabiskan masa menaip semua itu.
Kami juga memeriksa bilangan hujah berlalu masuk
Kami mencetak mesej penggunaan bagus.
>> Ini adalah jenis perkara itu, sekali lagi, seperti yang kita telah bercakap tentang,
ia hampir seperti memori otot.
Hanya ingat untuk terus melakukan perkara yang sama barangan
dan sentiasa mencetak beberapa jenis mesej berguna
supaya orang tahu bagaimana untuk menjalankan program anda.
Dengan kucing, ia agak mudah, kita hanya akan pergi melalui semua hujah-hujah yang berbeza
yang telah diluluskan untuk program kami, dan kita pergi untuk mencetak
kandungannya keluar satu skrin pada satu masa.
Untuk mencetak fail ke skrin, kita akan melakukan sesuatu yang sangat serupa
kepada apa yang kita lakukan pada akhir kuiz.
Pada akhir kuiz, yang mengupah program, kita terpaksa untuk membuka fail,
dan kemudian kita terpaksa untuk mencetak ia.
Dalam kes ini, kami akan membuka fail, dan kita akan membaca dari ia sebaliknya.
Kemudian kita pergi untuk mencetak, bukannya ke fail, kita pergi untuk mencetak skrin.
Jadi percetakan skrin anda semua telah dilakukan sebelum dengan printf.
Supaya tidak terlalu gila.
Tetapi membaca fail adalah jenis pelik.
Kami akan pergi melalui yang sedikit pada satu masa.
Jika anda semua kembali kepada masalah yang terakhir pada kuiz, anda masalah 33,
baris pertama yang kita akan lakukan di sini, membuka fail, adalah amat serupa dengan apa yang kita lakukan di sana.
Jadi Stella, apakah yang kelihatan selaras seperti, apabila kita membuka fail?
[Stella] Modal FILE *, Fail - >> Okay. >> - Adalah sama dengan fopen. >> Yup.
Yang dalam kes ini? Ia adalah dalam komen.
>> Ia adalah dalam komen? argv [i] dan r?
>> Tepat sekali. Right on. Jadi Stella adalah benar-benar betul.
Ini adalah apa yang kelihatan seperti garis.
Kami akan mendapatkan pemboleh ubah fail sungai, menyimpannya * FILE, jadi semua topi,
FILE, *, dan nama pembolehubah ini akan fail.
Kita boleh memanggilnya apa sahaja yang kita suka. Kita boleh memanggil ia first_file, atau file_i, apa sahaja yang kita ingin.
Dan kemudian nama fail telah diluluskan di atas baris arahan untuk program ini.
Jadi ia disimpan di dalam argv [i] dan kemudian kita pergi untuk membuka fail ini dalam mod membaca.
Sekarang kita telah membuka fail, apakah perkara yang kita sentiasa perlu ingat untuk melakukan
apabila kita telah membuka fail? Menutupnya.
Jadi Missy, bagaimana kita menutup fail?
[Missy] fclose (fail) >> fclose (fail). Tepat sekali.
Besar. Okay. Jika kita melihat ini untuk melakukan komen di sini,
ia berkata, "Terbuka argv [i] dan mencetak kandungannya ke stdout."
>> Keluar Standard adalah nama yang pelik. Stdout adalah hanya cara untuk kami mengucapkan
kita ingin mencetak ke terminal; kita ingin mencetak kepada aliran output standard.
Kita sebenarnya boleh menyingkirkan komen ini di sini.
Saya akan salin dan tampalkannya kerana itulah apa yang kita lakukan.
Pada ketika ini, sekarang kita perlu membaca sedikit fail demi sedikit.
Kami telah membincangkan beberapa cara fail membaca.
Yang mana adalah kegemaran anda setakat ini?
Yang cara telah anda dilihat atau adakah anda ingat, untuk membaca fail?
[Daniel] fread? >> Fread? Jadi fread adalah salah. Jimmy, adakah anda tahu mana-mana orang lain?
[Jimmy] No >> Okay. Nope. Charlotte? Alexander? Mana-mana orang lain? Okay.
Jadi yang lain adalah fgetc, salah satu yang kita akan menggunakan banyak.
Terdapat juga fscanf; kalian melihat corak di sini?
Mereka semua bermula dengan f. Apa-apa kaitan dengan fail.
Ada fread, fgetc, fscanf. Ini semua adalah fungsi membaca.
Untuk penulisan kita mempunyai fwrite, kita mempunyai fputc bukannya fgetc.
Kami juga telah fprintf seperti yang kita lihat pada kuiz.
Sejak ini adalah satu masalah yang melibatkan membaca dari fail,
kita akan menggunakan salah satu daripada ketiga-tiga fungsi.
Kami tidak akan menggunakan fungsi-fungsi ini ke sini.
Fungsi-fungsi ini semua didapati di perpustakaan standard I / O.
Jadi, jika anda melihat di atas program ini,
anda boleh melihat bahawa kita sudah termasuk fail header for perpustakaan standard I / O.
Jika kita mahu memikirkan yang mana satu yang kita mahu menggunakan,
kita sentiasa boleh membuka halaman lelaki.
Jadi, kita boleh menaip stdio lelaki
dan membaca semua tentang input stdio dan fungsi output dalam C.
Dan kita sudah boleh lihat oh, melihat. Ia menyebut fgetc, ia menyebut fputc.
Jadi, anda boleh mengesan sedikit dan melihat, berkata, fgetc
dan melihat halaman lelaki.
Anda boleh melihat bahawa ia pergi bersama-sama dengan sekumpulan keseluruhan fungsi-fungsi lain:
fgetc, fgets, getc, getchar, mendapat, ungetc, dan input aksara dan rentetan.
Jadi ini adalah bagaimana kita membaca dalam aksara dan rentetan dari fail daripada input standard,
yang asasnya adalah dari pengguna.
Dan ini ialah bagaimana kita melakukannya dalam C. sebenar
Jadi ini tidak menggunakan GetString dan fungsi GetChar
bahawa kita digunakan dari perpustakaan CS50.
Kami akan melakukan masalah ini dalam beberapa cara
supaya anda boleh melihat dua cara yang berbeza untuk melakukannya.
Kedua-dua fungsi fread bahawa Daniel disebut dan fgetc adalah cara yang baik untuk melakukannya.
Saya fikir fgetc adalah sedikit lebih mudah, kerana ia hanya mempunyai, seperti yang anda lihat,
satu hujah, * FAIL bahawa kita sedang cuba untuk membaca watak dari,
dan nilai pulangan adalah int.
Dan ini adalah sedikit mengelirukan, kanan?
>> Kerana kita sedang mendapat watak, jadi mengapa tidak penyata ini char?
Anda lelaki itu mempunyai apa-apa idea mengapa ini tidak mungkin kembali char?
[Jawapan Missy, difahami] >> Yeah. Jadi Missy adalah benar-benar betul.
Jika ia adalah ASCII, maka integer ini boleh dipetakan kepada char sebenar.
Boleh menjadi aksara ASCII, dan yang betul.
Itulah apa yang berlaku.
Kami menggunakan int semata-mata kerana ia mempunyai lebih bit.
Ia lebih besar daripada char; char kita hanya mempunyai 8 bit, yang 1 bait pada mesin 32-bit kami.
Dan int mempunyai bernilai semua 4 bait ruang.
Dan ternyata bahawa cara fgetc berfungsi,
jika kita tatal ke bawah dalam sinopsis kami di halaman lelaki ini sedikit,
tatal sepanjang jalan ke bawah. Ia ternyata bahawa mereka menggunakan nilai ini khas dipanggil EOF.
Ia adalah satu pemalar istimewa kerana nilai pulangan fungsi fgetc
apabila anda melanda akhir fail atau jika anda mendapat mesej ralat.
Dan ternyata bahawa untuk melakukan perbandingan dengan EOF betul,
anda mahu mempunyai bahawa jumlah tambahan maklumat yang anda ada dalam int
berbanding untuk menggunakan pembolehubah char.
Walaupun fgetc berkesan mendapat watak dari fail,
anda mahu ingat bahawa ia mengembalikan sesuatu yang int jenis kepada anda.
Yang berkata, ia adalah agak mudah untuk digunakan.
Ia akan memberi kita watak, jadi semua yang perlu kita lakukan adalah terus bertanya fail,
"Berikan saya watak seterusnya, memberikan saya watak seterusnya, memberikan saya watak seterusnya,"
sehingga kita sampai ke akhir fail.
Dan yang akan menarik dalam satu aksara pada masa yang daripada fail kita,
dan kemudian kita boleh melakukan apa sahaja yang kita suka dengan ia.
Kami boleh menyimpan, kita boleh menambah kepada rentetan, kita boleh mencetak keluar.
Melakukan apa-apa itu.
>> Zoom kembali keluar dan akan kembali program cat.c kami,
jika kita pergi menggunakan fgetc,
bagaimana kita mungkin pendekatan ini selaras seterusnya kod?
Kami akan menggunakan - fread akan melakukan sesuatu yang sedikit berbeza.
Dan kali ini, kami hanya akan menggunakan fgetc untuk mendapatkan satu aksara pada satu masa.
Untuk memproses fail keseluruhan, apa yang kita perlu lakukan?
Berapa banyak watak-watak yang terdapat dalam satu fail?
Terdapat banyak. Jadi, anda mungkin mahu untuk mendapatkan satu
dan kemudian mendapatkan lain dan mendapat satu lagi dan mendapatkan yang lain.
Apakah jenis algoritma adakah anda fikir kita mungkin perlu menggunakan di sini?
Apakah jenis -? [Alexander] A untuk gelung? >> Tepat sekali.
Beberapa jenis gelung.
A bagi gelung adalah sebenarnya besar, dalam kes ini.
Dan seperti anda berkata, ia kedengaran seperti anda mahu gelung seluruh fail,
mendapatkan watak pada satu-satu masa.
Mana-mana cadangan mengenai apa yang mungkin kelihatan seperti?
[Alexander, difahami]
>> Okay, hanya beritahu saya dalam Bahasa Inggeris apa yang anda cuba lakukan? [Alexander, difahami]
Jadi dalam kes ini, ia kedengaran seperti kita hanya cuba untuk gelung seluruh fail.
[Alexander] Jadi i > Saiz -?
Saya rasa saiz fail, kan? Saiz - we'll hanya menulis seperti ini.
Saiz fail pada masa itu, i + +.
Jadi ia ternyata bahawa cara anda ini menggunakan fgetc, dan ini adalah baru,
adalah bahawa tidak ada cara mudah untuk hanya mendapatkan saiz fail
dengan jenis ini "sizeof" membina bahawa anda telah melihat sebelum ini.
Apabila kita menggunakan bahawa fungsi fgetc, kita memperkenalkan beberapa jenis
baru, sintaksis funky ini untuk gelung, di mana dan bukannya menggunakan hanya kaunter asas
untuk pergi watak oleh watak, kita akan tarik satu aksara pada satu masa,
satu aksara pada satu masa, dan cara kita tahu kita berada di akhir
tidak apabila kita telah dikira bilangan tertentu aksara,
tetapi apabila watak kita tarik keluar adalah bahawa akhir khas watak fail.
Jadi kita boleh lakukan ini dengan - saya panggil ch ini, dan kita akan memulakan
dengan panggilan pertama kami untuk mendapatkan watak pertama daripada fail.
Jadi bahagian ini di sini, ini akan mendapatkan watak keluar fail
dan menyimpannya ke ch pembolehubah.
Kami akan terus berbuat demikian sehingga kita sampai ke akhir fail,
yang kita lakukan dengan ujian untuk watak tidak sama dengan watak EOF yang istimewa.
Dan kemudian bukannya melakukan ch + +, yang hanya akan kenaikan nilai,
jadi jika kita membaca keluar fail, modal A berkata,
ch + + akan memberikan kita b, dan kemudian kita akan mendapatkan c dan kemudian d.
Itu jelas tidak apa yang kita mahu. Apa yang kita mahu di sini
dalam sedikit terakhir ini kita mahu mendapatkan watak seterusnya dari fail.
>> Jadi bagaimana kita boleh mendapatkan watak seterusnya dari fail?
Bagaimana kita mendapatkan watak pertama dari fail?
[Pelajar] fgetfile? Fgetc >>, atau, maaf, anda benar-benar betul.
Saya silap eja betul di sana. Jadi yeah.
Di sini bukannya melakukan ch + +,
kita hanya akan memanggil fgetc (file) sekali lagi
dan menyimpan hasil dalam pembolehubah ch sama kami.
[Pelajar soalan, difahami]
>> Ini adalah di mana lelaki ini * FILE yang istimewa.
Cara mereka bekerja adalah mereka - apabila anda pertama kali membuka - apabila anda mula-mula membuat panggilan fopen,
* FILE berkesan berfungsi sebagai penunjuk kepada permulaan fail.
Dan kemudian setiap kali anda memanggil fgetc, ia bergerak satu watak melalui fail.
Jadi apabila anda memanggil ini, anda incrementing penunjuk fail oleh satu watak.
Dan apabila anda fgetc semula, anda bergerak watak lain
dan satu lagi watak dan satu lagi watak dan watak lain.
[Pelajar soalan, difahami] >> Dan that's - yeah.
Ia adalah jenis sihir ini di bawah hood.
Anda hanya menyimpan incrementing melalui.
Pada ketika ini, anda mampu untuk benar-benar bekerja dengan watak.
Jadi bagaimana kita boleh mencetak ini keluar ke skrin, sekarang?
Kita boleh menggunakan perkara yang sama printf yang kita digunakan sebelum.
Bahawa kita telah menggunakan semua semester.
Kita boleh memanggil printf,
dan kita boleh lulus dalam watak seperti itu.
Satu lagi cara untuk melakukannya adalah bukannya menggunakan printf dan perlu melakukan ini rentetan format,
kita juga boleh menggunakan salah satu daripada fungsi-fungsi lain.
Kita boleh menggunakan fputc, yang mencetak watak skrin,
kecuali jika kita melihat fputc - izinkan saya mengezum keluar sedikit.
Kita lihat apa yang baik ialah ia mengambil watak yang kita baca dengan menggunakan fgetc,
tetapi kemudian kita perlu memberikan aliran untuk mencetak.
Kita juga boleh menggunakan fungsi putchar, yang akan meletakkan terus keluar standard.
Jadi, terdapat sejumlah besar pilihan yang berbeza yang boleh kita gunakan untuk mencetak.
Mereka semua di perpustakaan standard I / O.
Apabila anda mahu mencetak - jadi printf, secara lalai, akan mencetak kepada standard khas keluar aliran,
yang adalah bahawa stdout.
Jadi kita hanya boleh merujuk kepada sebagai jenis nilai ini sihir, stdout di sini.
Oops. Letakkan koma bernoktah di luar.
>> Ini adalah banyak maklumat baru, 'funky' di sini.
Banyak ini adalah sangat simpulan bahasa, dalam erti kata bahawa ini adalah kod
yang ditulis cara ini hanya kerana ia adalah bersih membaca, mudah untuk dibaca.
Terdapat banyak cara yang berbeza untuk melakukannya, banyak fungsi yang berbeza yang anda boleh gunakan,
tetapi kita cenderung untuk hanya mengikuti pola-pola yang sama berulang-ulang.
Jadi jangan terkejut jika anda melihat kod seperti ini datang lagi dan lagi.
Semua hak. Pada ketika ini, kita perlu untuk memecahkan untuk hari tersebut.
Terima kasih kerana datang. Terima kasih untuk menonton jika anda berada dalam talian. Dan kita akan melihat anda minggu depan.
[CS50.TV]