1 00:00:00,000 --> 00:00:02,730 [Powered by Google Translate] [BAGIAN 5: KURANG NYAMAN] 2 00:00:02,730 --> 00:00:05,180 [Nate Hardison, Universitas Harvard] 3 00:00:05,180 --> 00:00:08,260 [Ini adalah CS50.] [CS50.TV] 4 00:00:08,260 --> 00:00:11,690 Jadi selamat datang kembali, guys. 5 00:00:11,690 --> 00:00:16,320 Selamat datang ke bagian 5. 6 00:00:16,320 --> 00:00:20,220 Pada titik ini, setelah menyelesaikan kuis 0 dan setelah melihat bagaimana Anda lakukan, 7 00:00:20,220 --> 00:00:25,770 mudah-mudahan Anda merasa benar-benar baik karena saya sangat terkesan dengan nilai di bagian ini. 8 00:00:25,770 --> 00:00:28,050 Untuk pemirsa online kami, kami telah memiliki beberapa pertanyaan 9 00:00:28,050 --> 00:00:33,680 tentang dua masalah terakhir di sejumlah masalah - atau kuis, bukan. 10 00:00:33,680 --> 00:00:39,690 Jadi kita akan pergi ke orang-orang benar-benar cepat sehingga semua orang melihat apa yang terjadi 11 00:00:39,690 --> 00:00:45,060 dan bagaimana untuk pergi melalui solusi yang sebenarnya bukan hanya melihat solusi itu sendiri. 12 00:00:45,060 --> 00:00:50,330 Kita akan pergi selama beberapa masalah sangat cepat, 32 dan 33. 13 00:00:50,330 --> 00:00:53,240 Hanya, sekali lagi, sehingga pemirsa online dapat melihat ini. 14 00:00:53,240 --> 00:00:59,080 >> Jika Anda beralih ke masalah, Anda 32 yang pada halaman 13, 15 00:00:59,080 --> 00:01:02,730 13 dari 16, 32 masalah adalah semua tentang swap. 16 00:01:02,730 --> 00:01:05,010 Itu semua tentang swapping dua bilangan bulat. 17 00:01:05,010 --> 00:01:08,740 Ini adalah masalah yang kita pergi selama beberapa kali dalam kuliah. 18 00:01:08,740 --> 00:01:13,590 Dan di sini, apa yang kita minta Anda lakukan adalah jejak memori cepat. 19 00:01:13,590 --> 00:01:17,000 Untuk mengisi nilai dari variabel karena mereka di stack 20 00:01:17,000 --> 00:01:20,250 sebagai kode berjalan melalui fungsi swap. 21 00:01:20,250 --> 00:01:24,500 Secara khusus, apa yang kita sedang melihat - saya akan menempatkan iPad ini turun - 22 00:01:24,500 --> 00:01:29,650 khususnya, apa yang kita lihat adalah baris ini berjumlah 6 di sini. 23 00:01:29,650 --> 00:01:36,740 Dan itu nomor 6 hanya kedekatan dengan masalah sebelumnya. 24 00:01:36,740 --> 00:01:41,720 Apa yang ingin kita lakukan adalah menampilkan label atau keadaan memori 25 00:01:41,720 --> 00:01:46,090 karena pada saat kita menjalankan ini nomor baris 6, 26 00:01:46,090 --> 00:01:52,540 yang efektif kembali dari fungsi swap kita di sini. 27 00:01:52,540 --> 00:01:59,450 Jika kita scroll ke bawah sini, kita melihat bahwa alamat dari segala sesuatu dalam memori yang disediakan bagi kita. 28 00:01:59,450 --> 00:02:02,540 Ini sangat penting, kami akan kembali ke sana hanya dalam beberapa saat. 29 00:02:02,540 --> 00:02:09,240 Dan kemudian di sini di bagian bawah, kami memiliki diagram memori kecil yang kita akan lihat. 30 00:02:09,240 --> 00:02:12,490 Saya telah benar-benar melakukan hal ini di iPad saya. 31 00:02:12,490 --> 00:02:20,720 Jadi aku akan bergantian bolak-balik antara iPad dan kode ini hanya untuk referensi. 32 00:02:20,720 --> 00:02:26,540 >> Mari kita mulai. Pertama, mari kita fokus pada beberapa pertama baris utama di sini. 33 00:02:26,540 --> 00:02:30,220 Untuk memulai, kita akan menginisialisasi x ke 1 dan ke 2 y. 34 00:02:30,220 --> 00:02:33,040 Jadi kita memiliki dua variabel integer, mereka berdua akan ditempatkan di stack. 35 00:02:33,040 --> 00:02:36,050 Kita akan menempatkan 1 dan 2 di dalamnya. 36 00:02:36,050 --> 00:02:43,150 Jadi jika saya flip ke iPad saya, mudah-mudahan, mari kita lihat - 37 00:02:43,150 --> 00:02:48,660 Apple TV mirroring, dan di sana kami pergi. Oke. 38 00:02:48,660 --> 00:02:51,670 Jadi jika saya flip ke iPad saya, 39 00:02:51,670 --> 00:02:56,220 Saya ingin menginisialisasi x ke 1 dan ke 2 y. 40 00:02:56,220 --> 00:03:00,580 Kami melakukan itu cukup hanya dengan menulis di kotak 1 x ditandai 41 00:03:00,580 --> 00:03:07,730 dan 2 di kotak bertanda y. Cukup sederhana. 42 00:03:07,730 --> 00:03:11,620 Jadi sekarang mari kita kembali ke laptop, melihat apa yang terjadi selanjutnya. 43 00:03:11,620 --> 00:03:15,810 Jadi ini baris berikutnya adalah di mana segala sesuatunya menjadi rumit. 44 00:03:15,810 --> 00:03:28,110 Kami melewati alamat x dan alamat y sebagai parameter a dan b untuk fungsi swap. 45 00:03:28,110 --> 00:03:32,380 Alamat dari x dan alamat y hal-hal yang kita tidak dapat menghitung 46 00:03:32,380 --> 00:03:36,360 tanpa mengacu pada peluru tersebut menunjukkan sampai di sini. 47 00:03:36,360 --> 00:03:39,750 Dan untungnya, dua yang pertama poin-poin memberitahu kita apa jawaban. 48 00:03:39,750 --> 00:03:44,740 Alamat x dalam memori adalah 10, dan alamat y dalam memori adalah 14. 49 00:03:44,740 --> 00:03:51,870 Jadi mereka adalah nilai-nilai yang bisa lulus sebagai a dan b bagian atas dalam fungsi swap kita. 50 00:03:51,870 --> 00:04:00,760 Jadi sekali lagi, beralih kembali ke diagram kita, saya bisa menulis 10 dalam 51 00:04:00,760 --> 00:04:07,400 dan 14 di b. 52 00:04:07,400 --> 00:04:11,610 Sekarang, saat ini adalah di mana kita lanjutkan dengan swap. 53 00:04:11,610 --> 00:04:14,520 Jadi membalik kembali ke laptop lagi, 54 00:04:14,520 --> 00:04:21,079 kita melihat bahwa cara swap kerjanya adalah I dereference pertama dan toko menghasilkan tmp. 55 00:04:21,079 --> 00:04:27,650 Jadi operator dereference mengatakan, "Hei. Perlakukan isi dari variabel sebagai alamat. 56 00:04:27,650 --> 00:04:33,830 Pergi ke apa pun yang disimpan di alamat itu, dan beban itu. " 57 00:04:33,830 --> 00:04:41,720 Apa yang Anda beban keluar dari variabel akan disimpan ke dalam variabel tmp kami. 58 00:04:41,720 --> 00:04:45,150 Membalik kembali ke iPad. 59 00:04:45,150 --> 00:04:51,690 Jika kita pergi ke alamat 10, kita tahu bahwa alamat 10 adalah x varible 60 00:04:51,690 --> 00:04:55,480 karena kami diberitahu oleh poin-poin kami bahwa alamat dari x dalam memori adalah 10. 61 00:04:55,480 --> 00:05:00,180 Jadi kita bisa pergi ke sana, mendapatkan nilai dari itu, yaitu 1, seperti yang kita lihat di iPad kami, 62 00:05:00,180 --> 00:05:06,300 dan beban itu ke tmp. 63 00:05:06,300 --> 00:05:08,250 Sekali lagi, ini bukan isi akhir. 64 00:05:08,250 --> 00:05:14,350 Kita akan berjalan melalui dan kami akan sampai ke keadaan akhir kami program di akhir. 65 00:05:14,350 --> 00:05:17,210 Tapi sekarang, kita memiliki nilai 1 yang disimpan dalam tmp. 66 00:05:17,210 --> 00:05:19,210 >> Dan ada pertanyaan singkat di sini. 67 00:05:19,210 --> 00:05:23,980 [Alexander] Apakah operator dereference - itu hanya tepat di depan bintang variabel? 68 00:05:23,980 --> 00:05:27,600 >> Ya. Jadi operator dereference, seperti yang kita flip kembali ke laptop kita sekali lagi, 69 00:05:27,600 --> 00:05:33,780 adalah bintang ini tepat di depan. 70 00:05:33,780 --> 00:05:37,460 Dalam hal ini, itu adalah - Anda kontras dengan operator perkalian 71 00:05:37,460 --> 00:05:42,400 yang membutuhkan dua hal, operator dereference adalah operator unary. 72 00:05:42,400 --> 00:05:46,130 Hanya diterapkan pada satu nilai yang bertentangan dengan operator biner, 73 00:05:46,130 --> 00:05:48,810 di mana Anda berlaku untuk dua nilai yang berbeda. 74 00:05:48,810 --> 00:05:52,080 Jadi itulah yang terjadi di baris ini. 75 00:05:52,080 --> 00:05:58,390 Kami dimuat nilai 1 dan disimpan ke dalam variabel sementara bilangan bulat kami. 76 00:05:58,390 --> 00:06:05,800 Baris berikutnya, kita menyimpan isi b ke - 77 00:06:05,800 --> 00:06:12,630 atau, lebih tepatnya, kita menyimpan isi yang b menunjuk ke ke tempat di mana menunjuk ke. 78 00:06:12,630 --> 00:06:17,690 Jika kita menganalisis ini dari kanan ke kiri, kita akan b dereference, 79 00:06:17,690 --> 00:06:23,580 kita akan membahas 14, kita akan ambil integer yang ada, 80 00:06:23,580 --> 00:06:26,900 dan kemudian kami akan pergi ke alamat 10, 81 00:06:26,900 --> 00:06:34,240 dan kita akan membuang hasil dereference kami b ke ruang itu. 82 00:06:34,240 --> 00:06:40,080 Membalik kembali ke iPad kita, di mana kita dapat membuat ini sedikit lebih konkrit, 83 00:06:40,080 --> 00:06:44,070 mungkin membantu jika saya menulis angka-angka pada semua alamat di sini. 84 00:06:44,070 --> 00:06:53,820 Jadi kita tahu bahwa pada y, kita berada di alamat 14, x adalah di alamat 10. 85 00:06:53,820 --> 00:07:00,180 Ketika kita mulai b, kita dereference b, kita akan ambil nilai 2. 86 00:07:00,180 --> 00:07:08,320 Kami akan ambil nilai ini karena itu adalah nilai yang hidup di alamat 14. 87 00:07:08,320 --> 00:07:15,700 Dan kita akan memasukkannya ke dalam variabel yang tinggal di alamat 10, 88 00:07:15,700 --> 00:07:19,160 yang di sana, sesuai dengan variabel x kami. 89 00:07:19,160 --> 00:07:21,810 Jadi kita bisa melakukan sedikit Timpa sini 90 00:07:21,810 --> 00:07:35,380 di mana kita menyingkirkan 1 kami dan sebaliknya kita menulis 2. 91 00:07:35,380 --> 00:07:39,560 Jadi semua yang baik dan bagus di dunia, meskipun kita sudah x ditimpa sekarang. 92 00:07:39,560 --> 00:07:44,890 Kami telah menyimpan nilai lama x dalam variabel tmp kami. 93 00:07:44,890 --> 00:07:50,210 Jadi kita dapat menyelesaikan swap dengan baris berikutnya. 94 00:07:50,210 --> 00:07:53,030 Membalik kembali ke laptop kita. 95 00:07:53,030 --> 00:07:58,150 Sekarang yang tersisa adalah untuk mengambil isi dari variabel sementara bilangan bulat kami 96 00:07:58,150 --> 00:08:05,630 dan menyimpannya ke dalam variabel yang tinggal di alamat yang b memegang. 97 00:08:05,630 --> 00:08:10,230 Jadi kita akan efektif b dereference untuk mendapatkan akses ke variabel 98 00:08:10,230 --> 00:08:14,340 yang berada di alamat yang b memegang di dalamnya, 99 00:08:14,340 --> 00:08:19,190 dan kita akan hal-hal nilai yang tmp memegang ke dalamnya. 100 00:08:19,190 --> 00:08:23,280 Membalik kembali ke iPad sekali lagi. 101 00:08:23,280 --> 00:08:31,290 Saya dapat menghapus nilai ini di sini, 2, 102 00:08:31,290 --> 00:08:41,010 dan sebaliknya kita akan menyalin hak 1 ke dalamnya. 103 00:08:41,010 --> 00:08:43,059 Kemudian baris berikutnya yang mengeksekusi, tentu saja - 104 00:08:43,059 --> 00:08:47,150 jika kita flip kembali ke laptop - ini 6 poin, 105 00:08:47,150 --> 00:08:52,500 yang merupakan titik di mana kami ingin memiliki diagram kita benar-benar diisi. 106 00:08:52,500 --> 00:08:58,940 Jadi membalik kembali ke iPad sekali lagi, hanya sehingga Anda dapat melihat diagram selesai, 107 00:08:58,940 --> 00:09:06,610 Anda dapat melihat bahwa kita memiliki 10 dalam, 14 di b, 1 dalam tmp, 2 di x, dan 1 di y. 108 00:09:06,610 --> 00:09:11,000 Apakah ada pertanyaan tentang hal ini? 109 00:09:11,000 --> 00:09:14,640 Apakah ini masuk akal, setelah berjalan melalui itu? 110 00:09:14,640 --> 00:09:24,850 Membuat logika yang lebih sedikit? Mudah-mudahan tidak. Oke. 111 00:09:24,850 --> 00:09:28,230 >> Pointer adalah topik yang sangat rumit. 112 00:09:28,230 --> 00:09:33,420 Salah satu dari orang-orang kami bekerja dengan memiliki pepatah yang sangat umum: 113 00:09:33,420 --> 00:09:36,590 "Untuk memahami pointer, Anda harus terlebih dahulu memahami petunjuk." 114 00:09:36,590 --> 00:09:40,530 Yang saya pikir sangat benar. Ini tidak mengambil beberapa saat untuk mendapatkan digunakan untuk itu. 115 00:09:40,530 --> 00:09:45,360 Menggambar banyak gambar, menggambar diagram banyak memori seperti ini sangat membantu, 116 00:09:45,360 --> 00:09:49,480 dan setelah Anda berjalan melalui contoh setelah contoh demi contoh, 117 00:09:49,480 --> 00:09:54,450 itu akan mulai masuk akal sedikit lebih dan rasa sedikit lebih dan arti yang lebih sedikit. 118 00:09:54,450 --> 00:10:01,560 Akhirnya, suatu hari, Anda akan memiliki semua itu benar-benar menguasainya. 119 00:10:01,560 --> 00:10:13,800 Ada pertanyaan sebelum kita beralih ke masalah berikutnya? Baiklah. 120 00:10:13,800 --> 00:10:18,840 Jadi flip kembali ke laptop. 121 00:10:18,840 --> 00:10:23,300 Masalah berikutnya yang kita miliki adalah masalah nomor 33 pada file I / O. 122 00:10:23,300 --> 00:10:26,350 Memperbesar ini sedikit. 123 00:10:26,350 --> 00:10:28,710 Soal 33 - Ya? 124 00:10:28,710 --> 00:10:32,110 >> [Daniel] Saya hanya punya pertanyaan singkat. Bintang ini, atau tanda bintang, 125 00:10:32,110 --> 00:10:35,590 itu disebut dereferencing ketika Anda menggunakan tanda bintang sebelum. 126 00:10:35,590 --> 00:10:38,820 Apa itu disebut ketika Anda menggunakan ampersand sebelum? 127 00:10:38,820 --> 00:10:43,140 >> Ampersand ini sebelumnya adalah alamat-operator. 128 00:10:43,140 --> 00:10:45,880 Jadi mari kita gulir kembali. 129 00:10:45,880 --> 00:10:49,310 Ups. Saya dalam mode zoom jadi saya tidak bisa benar-benar gulir. 130 00:10:49,310 --> 00:10:52,780 Jika kita melihat kode ini benar-benar cepat di sini, 131 00:10:52,780 --> 00:10:54,980 lagi, hal yang sama terjadi. 132 00:10:54,980 --> 00:10:59,180 Jika kita melihat kode ini di sini, pada baris ini di mana kita membuat panggilan untuk swap, 133 00:10:59,180 --> 00:11:10,460 ampersand ini hanya mengatakan "mendapatkan alamat di mana kehidupan variabel x." 134 00:11:10,460 --> 00:11:14,460 Ketika Anda mengkompilasi compiler kode Anda, 135 00:11:14,460 --> 00:11:20,590 itu untuk benar-benar secara fisik menandai tempat di memori untuk semua variabel Anda untuk hidup. 136 00:11:20,590 --> 00:11:24,910 Dan jadi apa compiler kemudian dapat lakukan setelah itu dikompilasi segalanya, 137 00:11:24,910 --> 00:11:31,110 ia tahu, "Oh, saya menempatkan x di alamat 10 Aku meletakkan y di alamat 14.." 138 00:11:31,110 --> 00:11:34,640 Hal ini kemudian dapat mengisi nilai-nilai untuk Anda. 139 00:11:34,640 --> 00:11:44,740 Jadi Anda kemudian dapat - dapat kemudian lulus ini dalam dan lulus & y dalam juga. 140 00:11:44,740 --> 00:11:50,730 Orang-orang ini mendapatkan alamat, tetapi mereka juga, ketika Anda melewati mereka ke fungsi swap, 141 00:11:50,730 --> 00:11:55,690 ini jenis informasi, ini * int di sini, memberitahu compiler, 142 00:11:55,690 --> 00:12:01,350 "Oke, kita akan menafsirkan alamat ini sebagai alamat dari sebuah variabel integer." 143 00:12:01,350 --> 00:12:05,900 Sebagai alamat int, yang berbeda dari alamat dari variabel karakter 144 00:12:05,900 --> 00:12:09,930 karena int membutuhkan, pada mesin 32-bit, mengambil 4 byte ruang, 145 00:12:09,930 --> 00:12:13,310 sedangkan karakter hanya membutuhkan 1 byte ruang. 146 00:12:13,310 --> 00:12:17,310 Jadi penting untuk mengetahui juga apa - apa hidup, apa jenis nilai 147 00:12:17,310 --> 00:12:20,340 yang tinggal di alamat yang mendapat berlalu masuk 148 00:12:20,340 --> 00:12:22,020 Atau alamat yang Anda hadapi. 149 00:12:22,020 --> 00:12:29,020 Dengan begitu, Anda tahu berapa banyak byte informasi untuk benar-benar beban keluar dari RAM Anda. 150 00:12:29,020 --> 00:12:31,780 Dan kemudian, ya, ini operator dereference, seperti Anda bertanya, 151 00:12:31,780 --> 00:12:37,200 pergi dan mengakses informasi pada alamat tertentu. 152 00:12:37,200 --> 00:12:42,820 Jadi itu mengatakan, dengan variabel di sini, mengobati isi sebagai alamat, 153 00:12:42,820 --> 00:12:47,880 pergi ke alamat tersebut, dan menarik keluar, load ke prosesor, beban ke register 154 00:12:47,880 --> 00:12:56,340 sebenarnya nilai-nilai atau isi yang tinggal di alamat itu. 155 00:12:56,340 --> 00:12:59,620 Ada pertanyaan lain? Ini adalah pertanyaan yang baik. 156 00:12:59,620 --> 00:13:01,650 Ini banyak istilah baru juga. 157 00:13:01,650 --> 00:13:09,800 Ini juga agak funky, melihat & dan * di tempat yang berbeda. 158 00:13:09,800 --> 00:13:13,180 >> Baiklah. 159 00:13:13,180 --> 00:13:18,530 Jadi kembali ke masalah 33, file I / O. 160 00:13:18,530 --> 00:13:22,540 Ini adalah salah satu masalah yang saya pikir beberapa hal terjadi. 161 00:13:22,540 --> 00:13:25,400 Satu, itu adalah topik yang cukup baru. 162 00:13:25,400 --> 00:13:30,590 Itu disajikan segera sebelum kuis, 163 00:13:30,590 --> 00:13:33,400 dan kemudian saya pikir itu agak seperti salah satu kata dalam masalah matematika 164 00:13:33,400 --> 00:13:39,720 di mana mereka memberi Anda banyak informasi, tetapi Anda benar-benar tidak berakhir harus menggunakan ton itu. 165 00:13:39,720 --> 00:13:44,060 Bagian pertama dari masalah ini adalah menggambarkan apa file CSV. 166 00:13:44,060 --> 00:13:50,620 Sekarang, file CSV, menurut deskripsi, adalah comma-separated values ​​file. 167 00:13:50,620 --> 00:13:55,300 Alasan ini sama sekali menarik, dan alasan Anda pernah menggunakannya, 168 00:13:55,300 --> 00:14:00,800 adalah, karena, berapa banyak dari Anda pernah menggunakan hal-hal seperti Excel? 169 00:14:00,800 --> 00:14:03,240 Gambar sebagian besar dari Anda telah, mungkin, atau akan menggunakan di beberapa titik dalam hidup Anda. 170 00:14:03,240 --> 00:14:06,430 Anda akan menggunakan sesuatu seperti Excel. 171 00:14:06,430 --> 00:14:10,940 Dalam rangka untuk mendapatkan data dari sebuah spreadsheet Excel atau melakukan apapun pengolahan dengan itu, 172 00:14:10,940 --> 00:14:17,240 jika Anda ingin menulis sebuah program C atau program Python, program Java, 173 00:14:17,240 --> 00:14:20,070 untuk menangani data yang telah disimpan di sana, 174 00:14:20,070 --> 00:14:23,170 salah satu cara yang paling umum untuk mendapatkannya keluar dalam sebuah file CSV. 175 00:14:23,170 --> 00:14:26,850 Dan Anda dapat membuka Excel dan ketika Anda pergi ke 'Save As' dialog, 176 00:14:26,850 --> 00:14:32,840 Anda bisa keluar file CSV yang sebenarnya. 177 00:14:32,840 --> 00:14:35,890 >> Berguna untuk mengetahui bagaimana menangani hal-hal ini. 178 00:14:35,890 --> 00:14:42,010 Cara kerjanya adalah bahwa hal itu mirip dengan - Maksudku, itu pada dasarnya meniru spreadsheet, 179 00:14:42,010 --> 00:14:47,590 di mana, seperti yang kita lihat di sini, di bagian yang sangat kiri-paling, 180 00:14:47,590 --> 00:14:49,910 kita memiliki semua nama terakhir. 181 00:14:49,910 --> 00:14:54,670 Jadi kita memiliki Malan, maka Hardison, dan kemudian Bowden, MacWilliam, dan kemudian Chan. 182 00:14:54,670 --> 00:14:59,470 Semua nama terakhir. Dan kemudian koma memisahkan nama terakhir dari nama pertama. 183 00:14:59,470 --> 00:15:02,970 David, Nate, Rob, Tommy, dan Zamyla. 184 00:15:02,970 --> 00:15:06,850 Saya selalu mencampur Robby dan Tom. 185 00:15:06,850 --> 00:15:10,940 Dan kemudian, akhirnya, kolom ketiga adalah alamat email. 186 00:15:10,940 --> 00:15:18,500 Setelah Anda memahami bahwa, sisa dari program ini adalah cukup mudah untuk melaksanakan. 187 00:15:18,500 --> 00:15:23,850 Apa yang kami lakukan dalam rangka untuk meniru struktur yang sama dalam program C kita 188 00:15:23,850 --> 00:15:27,510 adalah kita telah menggunakan struktur. 189 00:15:27,510 --> 00:15:30,520 Kami akan mulai bermain dengan sedikit lebih juga. 190 00:15:30,520 --> 00:15:35,790 Kami melihat mereka untuk sedikit pertama di set, masalah 3 ketika kami berhadapan dengan kamus. 191 00:15:35,790 --> 00:15:40,290 Tapi ini struct staf menyimpan nama belakang, nama pertama, dan email. 192 00:15:40,290 --> 00:15:44,500 Sama seperti file CSV kami menyimpan. 193 00:15:44,500 --> 00:15:47,950 Jadi ini hanya mengkonversi dari satu format yang lain. 194 00:15:47,950 --> 00:15:54,630 Kita harus mengkonversi, dalam hal ini, sebuah struct staf ke garis, 195 00:15:54,630 --> 00:15:59,060 garis dipisahkan koma, begitu saja. 196 00:15:59,060 --> 00:16:01,500 Apakah itu masuk akal? Kalian semua telah mengambil kuis, 197 00:16:01,500 --> 00:16:07,680 jadi saya bayangkan Anda memiliki setidaknya memiliki beberapa waktu untuk berpikir tentang hal ini. 198 00:16:07,680 --> 00:16:16,410 >> Dalam fungsi menyewa, masalah meminta kita untuk mengambil di - zoom in pada Kita akan ini sedikit - 199 00:16:16,410 --> 00:16:22,480 mengambil dalam struktur staf, struct staf, dengan nama s, 200 00:16:22,480 --> 00:16:30,900 dan menambahkan isinya ke file staff.csv kami. 201 00:16:30,900 --> 00:16:34,230 Ternyata ini cukup mudah untuk digunakan. 202 00:16:34,230 --> 00:16:37,430 Kami akan jenis bermain-main dengan fungsi-fungsi sedikit lebih hari ini. 203 00:16:37,430 --> 00:16:44,510 Tapi dalam kasus ini, fungsi fprintf benar-benar kunci. 204 00:16:44,510 --> 00:16:51,960 Jadi dengan fprintf, kita dapat mencetak, seperti kalian telah menggunakan printf istilah keseluruhan. 205 00:16:51,960 --> 00:16:55,050 Anda dapat printf baris ke file. 206 00:16:55,050 --> 00:16:59,030 Jadi bukan hanya membuat panggilan printf biasa di mana Anda memberikan format string 207 00:16:59,030 --> 00:17:05,380 dan kemudian Anda mengganti semua variabel dengan argumen berikut, 208 00:17:05,380 --> 00:17:11,290 dengan fprintf, argumen pertama Anda adalah bukan file yang Anda ingin menulis ke. 209 00:17:11,290 --> 00:17:21,170 Jika kita melihat ini dalam alat, misalnya, pria fprintf, 210 00:17:21,170 --> 00:17:25,980 kita bisa melihat perbedaan antara printf dan fprintf. 211 00:17:25,980 --> 00:17:28,960 Saya akan tampilannya di sini sedikit. 212 00:17:28,960 --> 00:17:33,140 Jadi dengan printf, kami memberikan format string, dan kemudian argumen berikutnya 213 00:17:33,140 --> 00:17:37,580 semua variabel untuk penggantian atau substitusi ke dalam format string kami. 214 00:17:37,580 --> 00:17:47,310 Sedangkan dengan fprintf, argumen pertama memang ini * file bernama sungai. 215 00:17:47,310 --> 00:17:51,800 >> Pindah kembali ke sini untuk kami menyewa, 216 00:17:51,800 --> 00:17:54,550 kita sudah punya file streaming * kami membuka bagi kita. 217 00:17:54,550 --> 00:17:57,810 Itulah yang ini baris pertama tidak, melainkan membuka file staff.csv, 218 00:17:57,810 --> 00:18:01,690 itu membuka dalam modus append, dan semua yang tersisa untuk kita lakukan adalah 219 00:18:01,690 --> 00:18:08,640 menulis struktur staf untuk file. 220 00:18:08,640 --> 00:18:10,870 Dan, mari kita lihat, apakah saya ingin menggunakan iPad? 221 00:18:10,870 --> 00:18:17,900 Saya akan menggunakan iPad. Kami memiliki kekosongan - mari kita menempatkan ini di atas meja sehingga aku bisa menulis sedikit lebih baik - 222 00:18:17,900 --> 00:18:33,680 membatalkan menyewa dan dibutuhkan dalam satu argumen, struktur staf yang disebut s. 223 00:18:33,680 --> 00:18:44,120 Punya kawat gigi kita, kita punya file * kami disebut file, 224 00:18:44,120 --> 00:18:48,380 kami memiliki lini fopen kami diberikan kepada kita, 225 00:18:48,380 --> 00:18:51,890 dan aku hanya akan menuliskannya sebagai titik karena itu sudah di pedia tersebut. 226 00:18:51,890 --> 00:19:00,530 Dan kemudian pada baris berikutnya kita, kita akan membuat panggilan ke fprintf 227 00:19:00,530 --> 00:19:03,700 dan kita akan lulus dalam file yang kita ingin mencetak ke, 228 00:19:03,700 --> 00:19:10,290 dan kemudian kami format string, yang - 229 00:19:10,290 --> 00:19:14,300 Aku akan membiarkan kalian ceritakan seperti apa. 230 00:19:14,300 --> 00:19:20,500 Bagaimana dengan Anda, Stella? Apakah Anda tahu apa bagian pertama dari format string seperti? 231 00:19:20,500 --> 00:19:24,270 [Stella] Saya tidak yakin. >> Jangan ragu untuk bertanya Jimmy. 232 00:19:24,270 --> 00:19:27,690 Apakah Anda tahu, Jimmy? 233 00:19:27,690 --> 00:19:31,000 [Jimmy] Apakah itu hanya menjadi yang terakhir? Saya tidak tahu. Saya tidak sepenuhnya yakin. 234 00:19:31,000 --> 00:19:39,020 Oke >>. Bagaimana, apakah ada yang mendapatkan ini benar pada ujian? 235 00:19:39,020 --> 00:19:41,770 Tidak Baiklah. 236 00:19:41,770 --> 00:19:47,920 Ternyata bahwa di sini yang harus kita lakukan adalah kita ingin setiap bagian dari struktur staf kami 237 00:19:47,920 --> 00:19:53,290 yang akan dicetak sebagai string ke dalam file kami. 238 00:19:53,290 --> 00:19:59,900 Kami hanya menggunakan karakter penempatan string tiga waktu yang berbeda karena kami memiliki nama belakang 239 00:19:59,900 --> 00:20:07,160 diikuti dengan koma, maka nama pertama diikuti dengan koma, 240 00:20:07,160 --> 00:20:12,430 dan akhirnya alamat email yang diikuti - yang tidak 241 00:20:12,430 --> 00:20:15,140 pas di layar saya - tapi itu diikuti oleh karakter baris baru. 242 00:20:15,140 --> 00:20:20,060 Jadi aku akan menulis hanya di sana. 243 00:20:20,060 --> 00:20:23,560 Dan kemudian mengikuti format string kami, 244 00:20:23,560 --> 00:20:27,880 kita hanya memiliki substitusi, yang kita mengakses menggunakan notasi dot 245 00:20:27,880 --> 00:20:31,370 yang kami lihat di sejumlah masalah 3. 246 00:20:31,370 --> 00:20:48,820 Kita dapat menggunakan s.last, s.first, dan s.email 247 00:20:48,820 --> 00:20:58,990 untuk menggantikan di tiga nilai-nilai ke format string kami. 248 00:20:58,990 --> 00:21:06,190 Jadi bagaimana itu pergi? Masuk akal? 249 00:21:06,190 --> 00:21:09,700 Ya? Tidak ada? Mungkin? Oke. 250 00:21:09,700 --> 00:21:14,180 >> Hal terakhir yang kita lakukan setelah kita dicetak dan setelah kita membuka file kami: 251 00:21:14,180 --> 00:21:17,370 setiap kali kita membuka file, kita harus selalu ingat untuk menutupnya. 252 00:21:17,370 --> 00:21:19,430 Karena kalau tidak kita akan berakhir bocor memori, 253 00:21:19,430 --> 00:21:22,500 menggunakan up file deskriptor. 254 00:21:22,500 --> 00:21:25,950 Jadi untuk menutupnya, yang fungsinya yang kita gunakan? Daniel? 255 00:21:25,950 --> 00:21:30,120 [Daniel] fclose? >> Fclose, tepatnya. 256 00:21:30,120 --> 00:21:37,520 Jadi bagian terakhir dari masalah ini adalah untuk benar menutup file, menggunakan fungsi fclose, 257 00:21:37,520 --> 00:21:40,370 yang hanya terlihat seperti itu. 258 00:21:40,370 --> 00:21:43,880 Tidak terlalu gila. 259 00:21:43,880 --> 00:21:46,990 Cool. 260 00:21:46,990 --> 00:21:49,520 Jadi itulah masalahnya 33 pada kuis. 261 00:21:49,520 --> 00:21:52,480 Kami akan memiliki file pasti lebih I / O datang. 262 00:21:52,480 --> 00:21:55,130 Kami akan melakukan sedikit lebih dalam kuliah ini, atau di bagian hari ini, 263 00:21:55,130 --> 00:22:01,710 karena itulah apa yang akan membentuk sebagian besar dari ini pset mendatang. 264 00:22:01,710 --> 00:22:05,020 Mari kita beralih dari kuis pada saat ini. Ya? 265 00:22:05,020 --> 00:22:10,880 >> [Charlotte]] Mengapa fclose (file) bukan fclose (staff.csv)? 266 00:22:10,880 --> 00:22:19,100 >> Ah. Karena ternyata - jadi pertanyaan, yang adalah salah besar, 267 00:22:19,100 --> 00:22:27,800 adalah mengapa, ketika kita menulis fclose, kita menulis fclose (file) variabel Bintang 268 00:22:27,800 --> 00:22:33,680 sebagai lawan dari nama file, staff.csv? Apakah itu benar? Ya. 269 00:22:33,680 --> 00:22:39,570 Jadi mari kita lihat. Jika saya beralih kembali ke laptop saya, 270 00:22:39,570 --> 00:22:45,040 dan mari kita lihat fungsi fclose. 271 00:22:45,040 --> 00:22:51,460 Jadi fungsi fclose menutup sungai dan dibutuhkan dalam pointer ke sungai yang kita ingin menutup, 272 00:22:51,460 --> 00:22:57,010 yang bertentangan dengan nama file yang sebenarnya yang ingin kita tutup. 273 00:22:57,010 --> 00:23:01,620 Dan ini adalah karena di balik layar, ketika Anda membuat panggilan ke fopen, 274 00:23:01,620 --> 00:23:12,020 ketika Anda membuka file, Anda benar-benar mengalokasikan memori untuk menyimpan informasi tentang file. 275 00:23:12,020 --> 00:23:16,380 Jadi Anda memiliki pointer file yang memiliki informasi tentang file tersebut, 276 00:23:16,380 --> 00:23:23,080 seperti itu terbuka, ukurannya, di mana Anda berada saat ini dalam file, 277 00:23:23,080 --> 00:23:29,100 sehingga Anda dapat membuat membaca dan menulis panggilan ke tempat tertentu dalam file. 278 00:23:29,100 --> 00:23:38,060 Anda akhirnya menutup pointer bukan menutup nama file. 279 00:23:38,060 --> 00:23:48,990 >> Ya? [Daniel] Jadi untuk menggunakan menyewa, akan Anda katakan - bagaimana cara mendapatkan input pengguna? 280 00:23:48,990 --> 00:23:53,830 Apakah fprintf bertindak seperti GetString dalam arti bahwa hal itu hanya akan menunggu input pengguna 281 00:23:53,830 --> 00:23:57,180 dan meminta Anda untuk mengetik ini - atau menunggu bagi Anda untuk mengetik tiga hal dalam? 282 00:23:57,180 --> 00:24:00,480 Atau apakah Anda harus menggunakan sesuatu untuk melaksanakan menyewa? 283 00:24:00,480 --> 00:24:04,100 >> Ya. Jadi kita tidak - pertanyaan itu, bagaimana kita mendapatkan input pengguna 284 00:24:04,100 --> 00:24:09,220 dalam rangka melaksanakan menyewa? Dan apa yang kita miliki di sini adalah pemanggil menyewa, 285 00:24:09,220 --> 00:24:17,690 lulus dalam struct staf dengan semua data yang tersimpan dalam struct sudah. 286 00:24:17,690 --> 00:24:22,990 Jadi fprintf mampu hanya menulis bahwa data langsung ke file. 287 00:24:22,990 --> 00:24:25,690 Tidak ada menunggu input pengguna. 288 00:24:25,690 --> 00:24:32,110 Pengguna sudah diberikan input dengan benar memasukkannya dalam struct staf. 289 00:24:32,110 --> 00:24:36,510 Dan hal, tentu saja, akan pecah jika salah satu dari mereka pointer adalah null, 290 00:24:36,510 --> 00:24:40,370 jadi kita gulir kembali ke sini dan kami melihat struct kami. 291 00:24:40,370 --> 00:24:43,640 Kami memiliki string terakhir, string pertama, email string. 292 00:24:43,640 --> 00:24:48,530 Kita sekarang tahu bahwa semua orang benar-benar, di bawah tenda, adalah variabel char *. 293 00:24:48,530 --> 00:24:53,470 Yang mungkin atau tidak mungkin menunjuk ke null. 294 00:24:53,470 --> 00:24:55,800 Mereka mungkin menunjuk ke memori di heap, 295 00:24:55,800 --> 00:24:59,650 mungkin memori pada stack. 296 00:24:59,650 --> 00:25:04,580 Kami tidak benar-benar tahu, tetapi jika salah satu pointer adalah null, atau tidak valid, 297 00:25:04,580 --> 00:25:08,120 bahwa yang pasti akan kecelakaan fungsi kami menyewa. 298 00:25:08,120 --> 00:25:11,050 Itu adalah sesuatu yang agak luar cakupan ujian. 299 00:25:11,050 --> 00:25:16,440 Kami tidak khawatir tentang hal itu. 300 00:25:16,440 --> 00:25:22,170 Besar. Oke. Jadi pindah dari kuis. 301 00:25:22,170 --> 00:25:25,760 >> Mari kita tutup pria ini, dan kita akan melihat pset 4. 302 00:25:25,760 --> 00:25:34,700 Jadi jika kalian melihat spec pset, setelah Anda dapat mengaksesnya, cs50.net/quizzes, 303 00:25:34,700 --> 00:25:42,730 kita akan pergi melalui beberapa masalah saat bagian. 304 00:25:42,730 --> 00:25:52,240 Aku bergulir ke bawah - bagian pertanyaan dimulai pada halaman ketiga dari spec pset. 305 00:25:52,240 --> 00:25:57,800 Dan bagian pertama meminta Anda untuk pergi dan menonton pendek pada mengarahkan dan pipa. 306 00:25:57,800 --> 00:26:02,820 Yang agak pendek dingin, menunjukkan beberapa, trik baru baris perintah yang keren yang dapat Anda gunakan. 307 00:26:02,820 --> 00:26:06,050 Dan kemudian kita punya beberapa pertanyaan untuk Anda juga. 308 00:26:06,050 --> 00:26:10,860 Ini pertanyaan pertama tentang aliran, yang printf menulis secara default, 309 00:26:10,860 --> 00:26:15,920 kami jenis menyentuh hanya sedikit beberapa saat yang lalu. 310 00:26:15,920 --> 00:26:22,380 Ini fprintf bahwa kita hanya membahas berlangsung dalam aliran * file sebagai argumen. 311 00:26:22,380 --> 00:26:26,580 fclose mengambil dalam aliran * file juga, 312 00:26:26,580 --> 00:26:32,660 dan nilai kembali dari fopen memberikan aliran * file juga. 313 00:26:32,660 --> 00:26:36,060 Alasan kami belum melihat mereka sebelumnya ketika kita sudah berurusan dengan printf 314 00:26:36,060 --> 00:26:39,450 karena printf memiliki aliran standar. 315 00:26:39,450 --> 00:26:41,810 Dan aliran default yang menulis 316 00:26:41,810 --> 00:26:45,190 Anda akan mengetahui dalam jangka pendek. 317 00:26:45,190 --> 00:26:50,080 Jadi jelas kita lihat itu. 318 00:26:50,080 --> 00:26:53,010 >> Pada bagian hari ini, kita akan berbicara sedikit tentang GDB, 319 00:26:53,010 --> 00:26:57,720 sejak lebih akrab Anda dengan itu, praktik yang Anda dapatkan dengan itu, 320 00:26:57,720 --> 00:27:01,390 yang lebih mampu Anda akan benar-benar memburu bug dalam kode Anda sendiri. 321 00:27:01,390 --> 00:27:05,540 Hal ini mempercepat proses debugging dengan dahsyat. 322 00:27:05,540 --> 00:27:09,230 Jadi dengan menggunakan printf, setiap kali Anda melakukan itu Anda harus mengkompilasi ulang kode Anda, 323 00:27:09,230 --> 00:27:13,000 Anda harus menjalankan lagi, kadang-kadang Anda harus memindahkan panggilan printf sekitar, 324 00:27:13,000 --> 00:27:17,100 komentar keluar kode, itu hanya membutuhkan beberapa saat. 325 00:27:17,100 --> 00:27:20,850 Tujuan kami adalah untuk mencoba dan meyakinkan Anda bahwa dengan GDB, Anda pada dasarnya dapat 326 00:27:20,850 --> 00:27:26,810 printf apapun pada setiap titik dalam kode Anda dan Anda tidak perlu mengkompilasi ulang. 327 00:27:26,810 --> 00:27:35,120 Anda tidak perlu untuk memulai dan terus menebak-nebak mana printf berikutnya. 328 00:27:35,120 --> 00:27:40,910 Hal pertama yang harus dilakukan adalah untuk menyalin baris ini dan mendapatkan kode bagian off dari web. 329 00:27:40,910 --> 00:27:47,530 Saya menyalin baris kode yang mengatakan, "http://cdn.cs50.net wget". 330 00:27:47,530 --> 00:27:49,510 Aku akan menyalinnya. 331 00:27:49,510 --> 00:27:55,950 Aku akan pergi ke alat saya, zoom out sehingga Anda dapat melihat apa yang saya lakukan, 332 00:27:55,950 --> 00:28:01,890 paste di sana, dan ketika saya tekan Enter, perintah ini wget harfiah adalah web mendapatkan. 333 00:28:01,890 --> 00:28:06,210 Ini akan pull down file ini dari Internet, 334 00:28:06,210 --> 00:28:11,790 dan itu akan menyimpannya ke direktori saat ini. 335 00:28:11,790 --> 00:28:21,630 Sekarang jika saya daftar direktori saat ini saya Anda dapat melihat bahwa aku punya file ini section5.zip tepat di sana. 336 00:28:21,630 --> 00:28:25,260 Cara untuk berurusan dengan pria itu adalah untuk unzip, 337 00:28:25,260 --> 00:28:27,650 yang dapat Anda lakukan pada command line, seperti ini. 338 00:28:27,650 --> 00:28:31,880 Section5.zip. 339 00:28:31,880 --> 00:28:36,980 Itu akan unzip, membuat folder untuk saya, 340 00:28:36,980 --> 00:28:40,410 mengembang semua isi, menempatkan mereka di sana. 341 00:28:40,410 --> 00:28:47,410 Jadi sekarang saya bisa masuk ke direktori 5 bagian saya menggunakan perintah cd. 342 00:28:47,410 --> 00:28:58,310 Bersihkan layar dengan menggunakan jelas. Jadi jelas layar. 343 00:28:58,310 --> 00:29:02,280 Sekarang saya punya terminal bersih yang bagus untuk menangani. 344 00:29:02,280 --> 00:29:06,200 >> Sekarang jika saya daftar semua file yang saya lihat di direktori ini, 345 00:29:06,200 --> 00:29:12,270 Anda melihat bahwa aku punya empat file: buggy1, buggy2, buggy3, dan buggy4. 346 00:29:12,270 --> 00:29:16,180 Saya juga punya file yang sesuai. Mereka c. 347 00:29:16,180 --> 00:29:20,400 Kita tidak akan melihat file c. Untuk saat ini. 348 00:29:20,400 --> 00:29:24,140 Sebaliknya, kita akan menggunakannya ketika kita membuka GDB. 349 00:29:24,140 --> 00:29:28,220 Kami telah membuat mereka sekitar sehingga kita memiliki akses ke kode sumber yang sebenarnya ketika kita menggunakan GDB, 350 00:29:28,220 --> 00:29:32,740 tetapi tujuan ini bagian dari bagian ini adalah untuk bermain-main-main dengan GDB 351 00:29:32,740 --> 00:29:40,370 dan melihat bagaimana kita dapat menggunakannya untuk mencari tahu apa yang salah dengan masing-masing dari keempat program kereta. 352 00:29:40,370 --> 00:29:43,380 Jadi kita hanya akan sekitar ruangan sangat cepat, 353 00:29:43,380 --> 00:29:47,000 dan aku akan meminta seseorang untuk menjalankan salah satu program kereta, 354 00:29:47,000 --> 00:29:54,730 dan kemudian kami akan pergi sebagai kelompok melalui GDB, dan kita akan melihat apa yang bisa kita lakukan untuk memperbaiki program ini, 355 00:29:54,730 --> 00:29:58,460 atau setidaknya mengidentifikasi apa yang salah di masing-masing dari mereka. 356 00:29:58,460 --> 00:30:04,760 Mari kita mulai di sini dengan Daniel. Apakah Anda menjalankan buggy1? Mari kita lihat apa yang terjadi. 357 00:30:04,760 --> 00:30:09,470 [Daniel] Ia mengatakan ada sebuah kesalahan aplikasi. >> Ya. Tepat. 358 00:30:09,470 --> 00:30:12,460 Jadi jika saya menjalankan buggy1, saya mendapatkan kesalahan seg. 359 00:30:12,460 --> 00:30:16,210 Pada titik ini, saya bisa pergi dan membuka buggy1.c, 360 00:30:16,210 --> 00:30:19,450 mencoba dan mencari tahu apa yang salah, 361 00:30:19,450 --> 00:30:22,000 tapi salah satu hal yang paling menjengkelkan tentang kesalahan kesalahan seg 362 00:30:22,000 --> 00:30:27,610 adalah bahwa hal itu tidak memberitahu Anda tentang apa baris hal program yang benar-benar pergi salah dan pecah. 363 00:30:27,610 --> 00:30:29,880 Anda semacam harus melihat kode 364 00:30:29,880 --> 00:30:33,990 dan mencari tahu menggunakan menebak dan memeriksa atau printf untuk melihat apa yang salah. 365 00:30:33,990 --> 00:30:37,840 Salah satu hal keren tentang GDB adalah bahwa itu benar-benar, benar-benar mudah 366 00:30:37,840 --> 00:30:42,170 untuk mengetahui garis di mana crash program anda. 367 00:30:42,170 --> 00:30:46,160 Ini benar-benar layak untuk menggunakannya, bahkan jika hanya untuk itu. 368 00:30:46,160 --> 00:30:56,190 Jadi untuk boot GDB, saya ketik GDB, dan kemudian saya memberikan path ke executable yang saya ingin menjalankan. 369 00:30:56,190 --> 00:31:01,960 Di sini saya sedang mengetik gdb ./buggy1. 370 00:31:01,960 --> 00:31:06,600 Tekan Enter. Memberi saya semua informasi hak cipta, 371 00:31:06,600 --> 00:31:13,000 dan di sini Anda akan melihat baris ini yang mengatakan, "simbol Membaca dari / home / 372 00:31:13,000 --> 00:31:17,680 jharvard/section5/buggy1. " 373 00:31:17,680 --> 00:31:22,060 Dan jika semuanya berjalan dengan baik, Anda akan melihatnya mencetak pesan yang terlihat seperti ini. 374 00:31:22,060 --> 00:31:25,500 Ini akan membaca simbol, itu akan mengatakan "Saya membaca simbol dari file eksekusi," 375 00:31:25,500 --> 00:31:29,900 dan kemudian akan memiliki "dilakukan" pesan di sini. 376 00:31:29,900 --> 00:31:35,410 Jika Anda melihat beberapa variasi lain dari ini, atau Anda melihatnya tidak bisa menemukan simbol 377 00:31:35,410 --> 00:31:41,460 atau sesuatu seperti itu, apa artinya adalah bahwa Anda hanya belum dikompilasi executable Anda dengan benar. 378 00:31:41,460 --> 00:31:49,980 Ketika kita mengkompilasi program untuk digunakan dengan GDB, kita harus menggunakan bendera khusus-g, 379 00:31:49,980 --> 00:31:54,540 dan itu dilakukan secara default jika Anda mengkompilasi program Anda, hanya dengan mengetik membuat 380 00:31:54,540 --> 00:31:59,320 atau membuat kereta atau membuat sembuh, salah satu dari mereka. 381 00:31:59,320 --> 00:32:07,800 Tetapi jika Anda kompilasi secara manual dengan dentang, maka Anda akan harus pergi dalam dan termasuk bahwa-g bendera. 382 00:32:07,800 --> 00:32:10,310 >> Pada titik ini, sekarang bahwa kami telah kami GDB prompt, 383 00:32:10,310 --> 00:32:12,310 itu cukup sederhana untuk menjalankan program. 384 00:32:12,310 --> 00:32:19,740 Kita bisa mengetik lari, atau kita hanya bisa mengetik r. 385 00:32:19,740 --> 00:32:22,820 Perintah GDB Kebanyakan bisa disingkat. 386 00:32:22,820 --> 00:32:25,940 Biasanya hanya satu atau beberapa surat, yang cukup bagus. 387 00:32:25,940 --> 00:32:30,980 Jadi Saad, jika Anda ketik r dan tekan Enter, apa yang terjadi? 388 00:32:30,980 --> 00:32:39,390 [Saad] aku SIGSEGV, kesalahan segmentasi, dan kemudian semua omong kosong ini. 389 00:32:39,390 --> 00:32:43,650 >> Ya. 390 00:32:43,650 --> 00:32:47,990 Seperti yang kita lihat pada layar sekarang, dan seperti Saad mengatakan, 391 00:32:47,990 --> 00:32:53,430 ketika kita mengetik run atau r dan tekan Enter, kita masih mendapatkan kesalahan yang sama seg. 392 00:32:53,430 --> 00:32:55,830 Jadi menggunakan GDB tidak memecahkan masalah kita. 393 00:32:55,830 --> 00:32:59,120 Tapi itu memberi kita sulit dipahami beberapa, dan ternyata sulit dipahami ini 394 00:32:59,120 --> 00:33:03,080 sebenarnya memberitahu kita di mana hal itu terjadi. 395 00:33:03,080 --> 00:33:10,680 Untuk mengurai ini sedikit, ini sedikit pertama adalah fungsi di mana segala sesuatu yang salah. 396 00:33:10,680 --> 00:33:20,270 Ada ini __ strcmp_sse4_2, dan memberitahu kita bahwa itu terjadi di file ini 397 00:33:20,270 --> 00:33:29,450 disebut sysdeps/i386, semua ini, sekali lagi, agak berantakan - tapi garis 254. 398 00:33:29,450 --> 00:33:31,670 Itu agak sulit untuk mengurai. Biasanya ketika Anda melihat hal-hal seperti ini, 399 00:33:31,670 --> 00:33:38,770 yang berarti bahwa itu seg faulting di salah satu perpustakaan sistem. 400 00:33:38,770 --> 00:33:43,220 Jadi ada hubungannya dengan strcmp. Kalian telah melihat strcmp sebelumnya. 401 00:33:43,220 --> 00:33:52,730 Tidak terlalu gila, tapi apakah ini berarti bahwa strcmp rusak atau ada masalah dengan strcmp? 402 00:33:52,730 --> 00:33:57,110 Apa yang Anda pikirkan, Alexander? 403 00:33:57,110 --> 00:34:04,890 [Alexander] Apakah itu - adalah 254 baris? Dan - tidak biner, tapi tidak langit-langit mereka, 404 00:34:04,890 --> 00:34:10,590 dan kemudian ada bahasa lain untuk setiap fungsi. Apakah itu 254 dalam fungsi itu, atau -? 405 00:34:10,590 --> 00:34:21,460 >> Ini baris 254. Sepertinya dalam file ini s., Sehingga itu perakitan kode mungkin. 406 00:34:21,460 --> 00:34:25,949 >> Tapi, saya kira hal yang lebih mendesak adalah, karena kita sudah kesalahan seg, 407 00:34:25,949 --> 00:34:29,960 dan sepertinya itu datang dari fungsi strcmp, 408 00:34:29,960 --> 00:34:38,030 hal ini menyiratkan, maka, strcmp yang rusak? 409 00:34:38,030 --> 00:34:42,290 Ini tidak boleh, mudah-mudahan. Jadi hanya karena Anda memiliki kesalahan segmentasi 410 00:34:42,290 --> 00:34:49,480 di salah satu fungsi sistem, biasanya itu berarti bahwa Anda hanya belum menyebutnya dengan benar. 411 00:34:49,480 --> 00:34:52,440 Hal tercepat yang harus dilakukan untuk mencari tahu apa yang sebenarnya terjadi 412 00:34:52,440 --> 00:34:55,500 ketika Anda melihat sesuatu yang gila seperti ini, setiap kali Anda melihat kesalahan seg, 413 00:34:55,500 --> 00:34:59,800 terutama jika Anda memiliki program yang menggunakan lebih dari sekedar main, 414 00:34:59,800 --> 00:35:03,570 adalah dengan menggunakan backtrace. 415 00:35:03,570 --> 00:35:13,080 Saya menyingkat Backtrace dengan menulis bt, sebagai lawan dari kata backtrace penuh. 416 00:35:13,080 --> 00:35:16,510 Tapi Charlotte, apa yang terjadi ketika Anda mengetik bt dan tekan Enter? 417 00:35:16,510 --> 00:35:23,200 [Charlotte] Ini menunjukkan saya dua baris, baris 0 dan baris 1. 418 00:35:23,200 --> 00:35:26,150 >> Ya. Jadi baris 0 dan baris 1. 419 00:35:26,150 --> 00:35:34,560 Ini adalah frame tumpukan aktual yang saat ini dalam bermain ketika program anda jatuh. 420 00:35:34,560 --> 00:35:42,230 Mulai dari frame paling atas, frame 0, dan pergi ke paling bawah, yaitu frame 1. 421 00:35:42,230 --> 00:35:45,140 Bingkai paling atas kami adalah bingkai strcmp. 422 00:35:45,140 --> 00:35:50,080 Anda dapat menganggap ini sebagai mirip dengan masalah kami hanya lakukan pada kuis dengan pointer, 423 00:35:50,080 --> 00:35:54,890 di mana kami telah bertukar stack frame di atas stack frame utama, 424 00:35:54,890 --> 00:35:59,700 dan kami memiliki variabel yang menggunakan swap di atas variabel yang utama menggunakan. 425 00:35:59,700 --> 00:36:08,440 Di sini kami kecelakaan terjadi dalam fungsi strcmp kami, yang dipanggil oleh fungsi utama kami, 426 00:36:08,440 --> 00:36:14,370 dan backtrace memberikan kita tidak hanya fungsi di mana hal-hal yang gagal, 427 00:36:14,370 --> 00:36:16,440 tapi itu juga memberitahu kita di mana semuanya dipanggil dari. 428 00:36:16,440 --> 00:36:18,830 Jadi jika saya gulir lebih sedikit lebih ke kanan, 429 00:36:18,830 --> 00:36:26,110 kita dapat melihat bahwa ya, kami berada di jalur 254 dari file ini strcmp-sse4.s. 430 00:36:26,110 --> 00:36:32,540 Tapi panggilan itu dibuat di buggy1.c, baris 6. 431 00:36:32,540 --> 00:36:35,960 Jadi itu berarti bisa kita lakukan - adalah kita hanya bisa pergi memeriksa dan melihat apa yang sedang terjadi 432 00:36:35,960 --> 00:36:39,930 di buggy1.c, baris 6. 433 00:36:39,930 --> 00:36:43,780 Sekali lagi, ada beberapa cara untuk melakukan hal ini. Salah satunya adalah untuk keluar dari GDB 434 00:36:43,780 --> 00:36:49,460 atau memiliki kode Anda terbuka di jendela lain dan referensi silang. 435 00:36:49,460 --> 00:36:54,740 Bahwa, dalam dan dari dirinya sendiri, cukup berguna karena sekarang jika Anda berada di jam kantor 436 00:36:54,740 --> 00:36:57,220 dan Anda punya kesalahan seg dan TF Anda bertanya-tanya di mana semuanya melanggar, 437 00:36:57,220 --> 00:36:59,710 Anda hanya bisa mengatakan, "Oh, baris 6. Aku tidak tahu apa yang terjadi, 438 00:36:59,710 --> 00:37:03,670 tapi sesuatu tentang jalur 6 yang menyebabkan program saya untuk istirahat. " 439 00:37:03,670 --> 00:37:10,430 Cara lain untuk melakukannya adalah Anda dapat menggunakan perintah ini disebut daftar di GDB. 440 00:37:10,430 --> 00:37:13,650 Anda juga dapat menyingkatnya dengan l. 441 00:37:13,650 --> 00:37:18,910 Jadi jika kita memukul l, apa yang kita dapatkan di sini? 442 00:37:18,910 --> 00:37:21,160 Kami mendapatkan sejumlah besar hal-hal aneh. 443 00:37:21,160 --> 00:37:26,030 Ini adalah kode assembly aktual 444 00:37:26,030 --> 00:37:29,860 yang ada di strcmp_sse4_2. 445 00:37:29,860 --> 00:37:32,440 Hal ini terlihat agak funky, 446 00:37:32,440 --> 00:37:36,520 dan alasan kita mendapatkan ini karena sekarang, 447 00:37:36,520 --> 00:37:40,160 GDB memiliki kita di frame 0. 448 00:37:40,160 --> 00:37:43,070 >> Jadi kapan saja kita melihat variabel, setiap kali kita melihat kode sumber, 449 00:37:43,070 --> 00:37:50,530 kita sedang melihat kode sumber yang berhubungan dengan stack frame kita saat ini masuk 450 00:37:50,530 --> 00:37:53,200 Jadi untuk mendapatkan sesuatu yang berarti, kita harus 451 00:37:53,200 --> 00:37:57,070 pindah ke stack frame yang lebih masuk akal. 452 00:37:57,070 --> 00:38:00,180 Dalam hal ini, stack frame utama akan masuk akal sedikit lebih, 453 00:38:00,180 --> 00:38:02,680 karena itu benar-benar kode yang kita tulis. 454 00:38:02,680 --> 00:38:05,330 Bukan kode strcmp. 455 00:38:05,330 --> 00:38:08,650 Cara Anda dapat bergerak di antara frame, dalam hal ini, karena kita memiliki dua, 456 00:38:08,650 --> 00:38:10,430 kita memiliki 0 dan 1, 457 00:38:10,430 --> 00:38:13,650 Anda melakukannya dengan atas dan bawah perintah. 458 00:38:13,650 --> 00:38:18,480 Jika saya naik satu frame, 459 00:38:18,480 --> 00:38:21,770 sekarang aku di stack frame utama. 460 00:38:21,770 --> 00:38:24,330 Aku bisa bergerak turun untuk kembali ke tempat saya, 461 00:38:24,330 --> 00:38:32,830 naik lagi, turun lagi, dan naik lagi. 462 00:38:32,830 --> 00:38:39,750 Jika Anda pernah melakukan program Anda di GDB, Anda mendapatkan kecelakaan, Anda mendapatkan backtrace, 463 00:38:39,750 --> 00:38:42,380 dan Anda melihat bahwa itu dalam beberapa file yang Anda tidak tahu apa yang terjadi. 464 00:38:42,380 --> 00:38:45,460 Anda mencoba daftar, kode tidak tampak akrab bagi Anda, 465 00:38:45,460 --> 00:38:48,150 lihatlah frame Anda dan mencari tahu di mana Anda berada. 466 00:38:48,150 --> 00:38:51,010 Kau mungkin di stack frame yang salah. 467 00:38:51,010 --> 00:38:58,760 Atau setidaknya Anda berada dalam stack frame yang tidak salah satu yang Anda benar-benar dapat men-debug. 468 00:38:58,760 --> 00:39:03,110 Sekarang kita berada di stack frame yang tepat, kita berada di utama, 469 00:39:03,110 --> 00:39:08,100 sekarang kita dapat menggunakan perintah list untuk mencari tahu apa jalur ini. 470 00:39:08,100 --> 00:39:13,590 Dan Anda bisa melihatnya, itu dicetak untuk kami di sini. 471 00:39:13,590 --> 00:39:19,470 Tapi kita dapat menekan daftar semua sama, dan daftar ini memberi kita printout bagus 472 00:39:19,470 --> 00:39:23,920 dari kode sumber yang sebenarnya yang terjadi di sini. 473 00:39:23,920 --> 00:39:26,420 >> Secara khusus, kita dapat melihat pada baris 6. 474 00:39:26,420 --> 00:39:29,330 Kita bisa melihat apa yang terjadi di sini. 475 00:39:29,330 --> 00:39:31,250 Dan sepertinya kita sedang membuat perbandingan string 476 00:39:31,250 --> 00:39:41,050 antara string "CS50 batu" dan argv [1]. 477 00:39:41,050 --> 00:39:45,700 Sesuatu tentang hal ini menerjang. 478 00:39:45,700 --> 00:39:54,120 Jadi Missy, apakah Anda memiliki pemikiran tentang apa yang mungkin terjadi di sini? 479 00:39:54,120 --> 00:39:59,400 [Missy] Saya tidak tahu mengapa hal itu menerjang. >> Anda tidak tahu mengapa hal itu menerjang? 480 00:39:59,400 --> 00:40:02,700 Jimmy, setiap pikiran? 481 00:40:02,700 --> 00:40:06,240 [Jimmy] Saya tidak sepenuhnya yakin, tapi terakhir kali kami menggunakan tali membandingkan, 482 00:40:06,240 --> 00:40:10,260 atau strcmp, kami punya seperti tiga kasus yang berbeda di bawahnya. 483 00:40:10,260 --> 00:40:12,800 Kami tidak memiliki ==, saya tidak berpikir, itu tepat di baris pertama. 484 00:40:12,800 --> 00:40:16,700 Sebaliknya itu dipisahkan menjadi tiga, dan satu adalah == 0, 485 00:40:16,700 --> 00:40:19,910 salah satu adalah <0, saya pikir, dan satu> 0. 486 00:40:19,910 --> 00:40:22,590 Jadi mungkin sesuatu seperti itu? >> Ya. Jadi ada masalah ini 487 00:40:22,590 --> 00:40:27,200 dari kita melakukan perbandingan dengan benar? 488 00:40:27,200 --> 00:40:31,660 Stella? Setiap pikiran? 489 00:40:31,660 --> 00:40:38,110 [Stella] Saya tidak yakin. >> Tidak yakin. Daniel? Pikiran? Oke. 490 00:40:38,110 --> 00:40:44,770 Ternyata apa yang terjadi di sini adalah ketika kami berlari program 491 00:40:44,770 --> 00:40:48,370 dan kami mendapat kesalahan seg, ketika Anda menjalankan program untuk pertama kalinya, Daniel, 492 00:40:48,370 --> 00:40:50,800 kau memberikan argumen baris perintah apapun? 493 00:40:50,800 --> 00:40:58,420 [Daniel] No >> No Dalam hal ini, berapakah nilai dari argv [1]? 494 00:40:58,420 --> 00:41:00,920 >> Ada nilai tidak ada. >> Kanan. 495 00:41:00,920 --> 00:41:06,120 Nah, tidak ada nilai string yang sesuai. 496 00:41:06,120 --> 00:41:10,780 Tapi ada beberapa nilai. Apa nilai yang akan disimpan di sana? 497 00:41:10,780 --> 00:41:15,130 >> Sebuah nilai sampah? >> Ini baik nilai sampah atau, dalam hal ini, 498 00:41:15,130 --> 00:41:19,930 akhir dari array argv selalu diakhiri dengan null. 499 00:41:19,930 --> 00:41:26,050 Jadi apa yang benar-benar mendapat disimpan di sana adalah nol. 500 00:41:26,050 --> 00:41:30,810 Cara lain untuk memecahkan masalah ini, daripada berpikir melalui, 501 00:41:30,810 --> 00:41:33,420 adalah untuk mencoba mencetak keluar. 502 00:41:33,420 --> 00:41:35,880 Di sinilah saya katakan bahwa menggunakan GDB besar, 503 00:41:35,880 --> 00:41:40,640 karena Anda bisa mencetak semua variabel, semua nilai-nilai yang Anda inginkan 504 00:41:40,640 --> 00:41:43,230 menggunakan perintah ini berguna dandy-p. 505 00:41:43,230 --> 00:41:48,520 Jadi jika saya ketik p dan kemudian saya ketik nilai dari suatu variabel atau nama variabel, 506 00:41:48,520 --> 00:41:55,320 mengatakan, argc, saya melihat bahwa argc adalah 1. 507 00:41:55,320 --> 00:42:01,830 Jika saya ingin mencetak argv [0], saya bisa melakukannya begitu saja. 508 00:42:01,830 --> 00:42:04,840 Dan seperti yang kita lihat, argv [0] selalu nama program Anda, 509 00:42:04,840 --> 00:42:06,910 selalu nama executable. 510 00:42:06,910 --> 00:42:09,740 Disini anda melihat itu punya nama path lengkap. 511 00:42:09,740 --> 00:42:15,920 Saya juga dapat mencetak argv [1] dan lihat apa yang terjadi. 512 00:42:15,920 --> 00:42:20,890 >> Di sini kami mendapat semacam ini nilai mistis. 513 00:42:20,890 --> 00:42:23,890 Kami punya 0x0 ini. 514 00:42:23,890 --> 00:42:27,850 Ingat pada awal istilah ketika kita berbicara tentang angka heksadesimal? 515 00:42:27,850 --> 00:42:34,680 Atau bahwa sedikit pertanyaan pada akhir pset 0 tentang bagaimana untuk mewakili 50 di hex? 516 00:42:34,680 --> 00:42:39,410 Cara kita menulis angka hex di CS, hanya untuk tidak membingungkan diri kita sendiri 517 00:42:39,410 --> 00:42:46,080 dengan angka desimal, adalah kita selalu awalan mereka dengan 0x. 518 00:42:46,080 --> 00:42:51,420 Jadi ini awalan 0x selalu hanya berarti menafsirkan nomor berikut sebagai angka heksadesimal, 519 00:42:51,420 --> 00:42:57,400 bukan sebagai string, bukan sebagai angka desimal, bukan sebagai bilangan biner. 520 00:42:57,400 --> 00:43:02,820 Karena jumlah 5-0 adalah angka yang benar dalam heksadesimal. 521 00:43:02,820 --> 00:43:06,240 Dan itu adalah nomor dalam desimal, 50. 522 00:43:06,240 --> 00:43:10,050 Jadi ini hanya bagaimana kita disambiguate. 523 00:43:10,050 --> 00:43:14,860 Jadi 0x0 berarti 0 heksadesimal, yang juga desimal 0, biner 0. 524 00:43:14,860 --> 00:43:17,030 Hanya saja nilai 0. 525 00:43:17,030 --> 00:43:22,630 Ternyata bahwa ini adalah apa yang null adalah, sebenarnya, dalam memori. 526 00:43:22,630 --> 00:43:25,940 Null hanya 0. 527 00:43:25,940 --> 00:43:37,010 Di sini, elemen disimpan di argv [1] adalah null. 528 00:43:37,010 --> 00:43:45,220 Jadi kita mencoba untuk membandingkan kami "batu CS50" string ke string null. 529 00:43:45,220 --> 00:43:48,130 Jadi dereferencing null, mencoba untuk mengakses hal-hal di nol, 530 00:43:48,130 --> 00:43:55,050 mereka biasanya akan menyebabkan beberapa jenis kesalahan segmentasi atau hal-hal buruk lainnya terjadi. 531 00:43:55,050 --> 00:43:59,350 Dan ternyata strcmp tidak memeriksa untuk melihat 532 00:43:59,350 --> 00:44:04,340 apakah Anda telah lulus dalam nilai yang null. 533 00:44:04,340 --> 00:44:06,370 Sebaliknya, ia hanya berjalan ke depan, mencoba untuk melakukan hal tersebut, 534 00:44:06,370 --> 00:44:14,640 dan jika seg kesalahan, itu seg kesalahan, dan itu masalah Anda. Anda harus pergi memperbaikinya. 535 00:44:14,640 --> 00:44:19,730 Benar-benar cepat, bagaimana mungkin kita memperbaiki masalah ini? Charlotte? 536 00:44:19,730 --> 00:44:23,540 [Charlotte] Anda dapat memeriksa menggunakan jika. 537 00:44:23,540 --> 00:44:32,240 Jadi jika argv [1] adalah null, == 0, kemudian kembali 1, atau sesuatu [dipahami]. 538 00:44:32,240 --> 00:44:34,590 >> Ya. Jadi itu salah satu cara yang bagus untuk melakukannya, karena kita dapat memeriksa untuk melihat, 539 00:44:34,590 --> 00:44:39,230 nilai kita akan masuk ke strcmp, argv [1], apakah nol? 540 00:44:39,230 --> 00:44:45,830 Jika nol itu, maka kita dapat mengatakan apa-apa, batalkan. 541 00:44:45,830 --> 00:44:49,450 >> Sebuah cara yang lebih umum untuk melakukan ini adalah dengan menggunakan nilai argc. 542 00:44:49,450 --> 00:44:52,040 Anda dapat melihat di sini pada awal main, 543 00:44:52,040 --> 00:44:58,040 kita menghilangkan bahwa tes pertama yang kita lakukan ketika kita biasanya menggunakan argumen baris perintah, 544 00:44:58,040 --> 00:45:05,240 yaitu untuk menguji apakah atau tidak nilai argc kita adalah apa yang kita harapkan. 545 00:45:05,240 --> 00:45:10,290 Dalam kasus ini, kami mengharapkan setidaknya dua argumen, 546 00:45:10,290 --> 00:45:13,660 nama program ditambah satu lainnya. 547 00:45:13,660 --> 00:45:17,140 Karena kita akan menggunakan argumen kedua di sini. 548 00:45:17,140 --> 00:45:21,350 Jadi memiliki beberapa jenis tes terlebih dahulu, sebelum panggilan strcmp kami 549 00:45:21,350 --> 00:45:37,390 bahwa tes apakah atau tidak argv setidaknya 2, juga akan melakukan hal yang sama. 550 00:45:37,390 --> 00:45:40,620 Kita bisa melihat apakah yang bekerja dengan menjalankan program lagi. 551 00:45:40,620 --> 00:45:45,610 Anda selalu dapat me-restart program anda dalam GDB, yang benar-benar bagus. 552 00:45:45,610 --> 00:45:49,310 Anda dapat menjalankan, dan ketika Anda lulus dalam argumen untuk program anda, 553 00:45:49,310 --> 00:45:53,060 Anda melewati mereka di saat Anda menelepon dijalankan, bukan ketika anda boot up GDB. 554 00:45:53,060 --> 00:45:57,120 Dengan cara itu Anda dapat menyimpan invoking program anda dengan argumen yang berbeda setiap kali. 555 00:45:57,120 --> 00:46:08,080 Jadi jalankan, atau lagi, saya bisa mengetik r, dan mari kita lihat apa yang terjadi jika kita ketik "halo". 556 00:46:08,080 --> 00:46:11,140 Ini akan selalu menanyakan apakah Anda ingin memulainya dari awal lagi. 557 00:46:11,140 --> 00:46:17,490 Biasanya, Anda ingin memulainya dari awal lagi. 558 00:46:17,490 --> 00:46:25,010 Dan pada titik ini, restart lagi, ia akan mencetak 559 00:46:25,010 --> 00:46:28,920 program yang kita jalankan, buggy1, dengan argumen halo, 560 00:46:28,920 --> 00:46:32,720 dan mencetak ini keluar standar, ia mengatakan, "Anda mendapatkan D," wajah sedih. 561 00:46:32,720 --> 00:46:37,610 Tapi kita tidak seg kesalahan. Dikatakan proses yang keluar normal. 562 00:46:37,610 --> 00:46:39,900 Sehingga terlihat cukup bagus. 563 00:46:39,900 --> 00:46:43,050 Tidak ada kesalahan yang lebih seg, kami berhasil melewati, 564 00:46:43,050 --> 00:46:48,190 sehingga terlihat seperti itu memang bug kesalahan seg bahwa kita mendapatkan. 565 00:46:48,190 --> 00:46:51,540 Sayangnya, ia memberitahu kita bahwa kita mendapatkan D. 566 00:46:51,540 --> 00:46:54,090 >> Kita bisa kembali dan melihat kode dan melihat apa yang terjadi di sana 567 00:46:54,090 --> 00:46:57,980 untuk mencari tahu apa itu - mengapa hal itu mengatakan kepada kita bahwa kita mendapat D. 568 00:46:57,980 --> 00:47:03,690 Mari kita lihat, di sini adalah ini printf mengatakan bahwa Anda mendapat D. 569 00:47:03,690 --> 00:47:08,540 Jika kita ketik daftar, Anda tetap daftar mengetik, itu terus iterasi turun melalui program anda, 570 00:47:08,540 --> 00:47:10,940 sehingga akan menunjukkan beberapa baris pertama dari program Anda. 571 00:47:10,940 --> 00:47:15,450 Kemudian akan menunjukkan beberapa baris berikutnya, dan berikutnya dan potongan potongan berikutnya. 572 00:47:15,450 --> 00:47:18,240 Dan itu akan terus mencoba untuk turun. 573 00:47:18,240 --> 00:47:21,180 Dan sekarang kita akan sampai ke "garis nomor 16 adalah di luar jangkauan." 574 00:47:21,180 --> 00:47:23,940 Karena hanya memiliki 15 baris. 575 00:47:23,940 --> 00:47:30,310 Jika Anda sampai ke titik ini dan Anda bertanya-tanya, "Apa yang harus saya lakukan?" Anda dapat menggunakan perintah bantuan. 576 00:47:30,310 --> 00:47:34,340 Gunakan bantuan dan kemudian memberikan nama perintah. 577 00:47:34,340 --> 00:47:36,460 Dan Anda melihat GDB memberi kita semua hal semacam ini. 578 00:47:36,460 --> 00:47:43,870 Ia mengatakan, "Dengan tidak ada argumen, daftar sepuluh baris lagi setelah atau sekitar listing sebelumnya. 579 00:47:43,870 --> 00:47:47,920 Daftar - daftar sepuluh baris sebelum - " 580 00:47:47,920 --> 00:47:52,960 Jadi mari kita coba gunakan dikurangi daftar. 581 00:47:52,960 --> 00:47:57,000 Dan itu daftar 10 baris sebelumnya, Anda dapat bermain-main dengan daftar sedikit. 582 00:47:57,000 --> 00:48:02,330 Anda dapat melakukan daftar, daftar -, Anda bahkan dapat memberikan daftar nomor, seperti daftar 8, 583 00:48:02,330 --> 00:48:07,500 dan itu akan mencantumkan 10 baris sekitar baris 8. 584 00:48:07,500 --> 00:48:10,290 Dan Anda dapat melihat apa yang terjadi di sini adalah Anda punya sederhana jika yang lain. 585 00:48:10,290 --> 00:48:13,980 Jika Anda mengetik CS50 batu, ia akan mencetak "Anda mendapatkan nilai A." 586 00:48:13,980 --> 00:48:16,530 Kalau tidak mencetak "Anda mendapatkan D." 587 00:48:16,530 --> 00:48:23,770 Nyebelin kota. Baiklah. Ya? 588 00:48:23,770 --> 00:48:26,730 >> [Daniel] Jadi ketika saya mencoba melakukan CS50 batu tanpa tanda kutip, 589 00:48:26,730 --> 00:48:29,290 ia mengatakan "Anda mendapatkan D." 590 00:48:29,290 --> 00:48:32,560 Aku butuh tanda kutip untuk mendapatkannya bekerja, kenapa begitu? 591 00:48:32,560 --> 00:48:38,490 >> Ya. Ternyata bahwa ketika - ini merupakan berita gembira kecil yang menyenangkan - 592 00:48:38,490 --> 00:48:47,900 ketika Anda menjalankan program, jika kita menjalankannya dan kita ketik di CS50 batu, 593 00:48:47,900 --> 00:48:50,800 seperti Daniel mengatakan dia lakukan, dan Anda tekan Enter, 594 00:48:50,800 --> 00:48:52,870 masih mengatakan kita mendapatkan D. 595 00:48:52,870 --> 00:48:55,580 Dan pertanyaannya adalah, mengapa ini? 596 00:48:55,580 --> 00:49:02,120 Dan ternyata bahwa baik terminal dan GDB mengurai ini sebagai dua argumen yang terpisah. 597 00:49:02,120 --> 00:49:04,800 Karena ketika ada ruang, yang menyiratkan 598 00:49:04,800 --> 00:49:08,730 argumen pertama berakhir, argumen berikutnya akan dimulai. 599 00:49:08,730 --> 00:49:13,260 Cara untuk menggabungkan mereka menjadi dua, atau maaf, menjadi satu argumen, 600 00:49:13,260 --> 00:49:18,510 adalah dengan menggunakan tanda kutip. 601 00:49:18,510 --> 00:49:29,560 Jadi sekarang, jika kita memasukkannya ke dalam tanda kutip dan menjalankannya lagi, kita mendapatkan nilai A. 602 00:49:29,560 --> 00:49:38,780 Jadi hanya untuk rekap, tanpa tanda kutip, CS50 dan batu diurai sebagai dua argumen yang terpisah. 603 00:49:38,780 --> 00:49:45,320 Dengan tanda kutip, itu diuraikan sebagai satu argumen sama sekali. 604 00:49:45,320 --> 00:49:53,070 >> Kita bisa melihat ini dengan breakpoint. 605 00:49:53,070 --> 00:49:54,920 Sejauh ini kita sudah menjalankan program kami, dan itu sudah berjalan 606 00:49:54,920 --> 00:49:58,230 sampai baik itu seg kesalahan atau hits kesalahan 607 00:49:58,230 --> 00:50:05,930 atau sampai telah keluar dan semua telah benar-benar baik-baik saja. 608 00:50:05,930 --> 00:50:08,360 Ini tidak selalu hal yang paling membantu, karena kadang-kadang 609 00:50:08,360 --> 00:50:11,840 Anda memiliki kesalahan dalam program Anda, tapi itu tidak menyebabkan kesalahan segmentasi. 610 00:50:11,840 --> 00:50:16,950 Ini tidak menyebabkan program Anda untuk berhenti atau sesuatu seperti itu. 611 00:50:16,950 --> 00:50:20,730 Cara untuk mendapatkan GDB untuk menghentikan program Anda pada titik tertentu 612 00:50:20,730 --> 00:50:23,260 adalah untuk mengatur breakpoint. 613 00:50:23,260 --> 00:50:26,520 Anda dapat melakukan ini dengan menetapkan breakpoint pada nama fungsi 614 00:50:26,520 --> 00:50:30,770 atau Anda dapat mengatur breakpoint pada baris tertentu dari kode. 615 00:50:30,770 --> 00:50:34,450 Saya ingin mengatur breakpoint pada nama fungsi, karena - mudah diingat, 616 00:50:34,450 --> 00:50:37,700 dan jika Anda benar-benar masuk dan mengubah kode sumber Anda naik sedikit, 617 00:50:37,700 --> 00:50:42,020 maka breakpoint Anda benar-benar akan tinggal di tempat yang sama dalam kode Anda. 618 00:50:42,020 --> 00:50:44,760 Sedangkan jika Anda menggunakan nomor baris, dan nomor baris berubah 619 00:50:44,760 --> 00:50:51,740 karena Anda menambahkan atau menghapus beberapa kode, maka breakpoints Anda semua benar-benar kacau. 620 00:50:51,740 --> 00:50:58,590 Salah satu hal yang paling umum yang saya lakukan adalah mengatur breakpoint pada fungsi utama. 621 00:50:58,590 --> 00:51:05,300 Sering saya akan boot GDB, saya akan ketik b utama, tekan Enter, dan itu akan mengatur breakpoint 622 00:51:05,300 --> 00:51:10,630 pada fungsi utama yang hanya mengatakan, "Jeda program segera setelah Anda mulai berjalan," 623 00:51:10,630 --> 00:51:17,960 dan dengan cara itu, ketika saya menjalankan program saya dengan, katakanlah, CS50 batu sebagai dua argumen 624 00:51:17,960 --> 00:51:24,830 dan tekan Enter, sampai ke fungsi utama dan berhenti tepat di baris pertama, 625 00:51:24,830 --> 00:51:30,620 tepat sebelum mengevaluasi fungsi strcmp. 626 00:51:30,620 --> 00:51:34,940 >> Karena aku berhenti, sekarang saya bisa mulai penyia-nyiaan waktu dan melihat apa yang terjadi 627 00:51:34,940 --> 00:51:40,250 dengan semua variabel yang berbeda yang masuk ke program saya. 628 00:51:40,250 --> 00:51:43,670 Di sini saya bisa mencetak argc dan melihat apa yang terjadi. 629 00:51:43,670 --> 00:51:50,030 Lihat bahwa argc adalah 3, karena itu punya 3 nilai yang berbeda di dalamnya. 630 00:51:50,030 --> 00:51:54,060 Itu punya nama program, itu punya argumen pertama dan argumen kedua. 631 00:51:54,060 --> 00:52:09,330 Kami dapat mencetak mereka keluar dengan melihat argv [0], argv [1], dan argv [2]. 632 00:52:09,330 --> 00:52:12,030 Jadi sekarang Anda juga dapat melihat mengapa ini panggilan strcmp akan gagal, 633 00:52:12,030 --> 00:52:21,650 karena Anda melihat bahwa hal itu berpisah CS50 dan batu-batu menjadi dua argumen terpisah. 634 00:52:21,650 --> 00:52:27,250 Pada titik ini, setelah Anda menekan breakpoint, Anda dapat terus melangkah melalui program anda 635 00:52:27,250 --> 00:52:32,920 baris demi baris, sebagai lawan memulai program Anda lagi. 636 00:52:32,920 --> 00:52:35,520 Jadi jika Anda tidak ingin untuk memulai program Anda lagi dan hanya melanjutkan dari sini, 637 00:52:35,520 --> 00:52:41,970 Anda dapat menggunakan perintah berlanjut dan terus akan menjalankan program sampai akhir. 638 00:52:41,970 --> 00:52:45,010 Sama seperti itu di sini. 639 00:52:45,010 --> 00:52:54,880 Namun, jika saya restart program, CS50 batu, hits breakpoint saya lagi, 640 00:52:54,880 --> 00:52:59,670 dan kali ini, jika saya tidak ingin hanya pergi semua jalan melalui sisa program, 641 00:52:59,670 --> 00:53:08,040 Saya dapat menggunakan perintah selanjutnya, yang saya juga menyingkat dengan n. 642 00:53:08,040 --> 00:53:12,960 Dan ini akan melangkah melalui program baris demi baris. 643 00:53:12,960 --> 00:53:17,530 Sehingga Anda dapat menonton sebagai hal-hal mengeksekusi, sebagai perubahan variabel, sebagai hal-hal bisa diperbarui. 644 00:53:17,530 --> 00:53:21,550 Yang cukup bagus. 645 00:53:21,550 --> 00:53:26,570 Hal menarik lainnya adalah daripada mengulangi perintah yang sama berulang-ulang, 646 00:53:26,570 --> 00:53:30,670 jika Anda hanya tekan Enter - jadi di sini Anda melihat saya tidak diketik dalam segala hal - 647 00:53:30,670 --> 00:53:33,780 jika saya hanya tekan Enter, maka akan mengulang perintah sebelumnya, 648 00:53:33,780 --> 00:53:36,900 atau perintah GDB sebelumnya yang saya hanya menaruh masuk 649 00:53:36,900 --> 00:53:56,000 Aku bisa terus menekan Enter dan akan terus melangkah melalui baris kode saya demi baris. 650 00:53:56,000 --> 00:53:59,310 Saya akan mendorong kalian untuk pergi memeriksa program kereta lain juga. 651 00:53:59,310 --> 00:54:01,330 Kami tidak punya waktu untuk melewati semua dari mereka hari ini di bagian. 652 00:54:01,330 --> 00:54:05,890 Kode sumber yang ada, sehingga Anda dapat melihat jenis apa yang terjadi 653 00:54:05,890 --> 00:54:07,730 di balik layar jika Anda benar-benar terjebak, 654 00:54:07,730 --> 00:54:11,940 tapi setidaknya, hanya berlatih boot up GDB, 655 00:54:11,940 --> 00:54:13,940 menjalankan program sampai rusak pada Anda, 656 00:54:13,940 --> 00:54:18,260 mendapatkan backtrace, mencari tahu apa fungsi kecelakaan itu di, 657 00:54:18,260 --> 00:54:24,450 apa garis itu pada, mencetak beberapa nilai variabel, 658 00:54:24,450 --> 00:54:30,140 hanya sehingga Anda bisa merasakan hal itu, karena itu benar-benar akan membantu Anda maju. 659 00:54:30,140 --> 00:54:36,340 Pada titik ini, kita akan berhenti keluar dari GDB, yang Anda lakukan dengan menggunakan berhenti atau hanya q. 660 00:54:36,340 --> 00:54:40,460 Jika program Anda adalah di tengah-tengah berjalan masih, dan belum keluar, 661 00:54:40,460 --> 00:54:43,510 selalu akan meminta Anda, "Apakah Anda yakin Anda benar-benar ingin berhenti?" 662 00:54:43,510 --> 00:54:48,770 Anda hanya dapat menekan yes. 663 00:54:48,770 --> 00:54:55,250 >> Sekarang kita akan melihat masalah berikutnya yang kita miliki, yang merupakan program kucing. 664 00:54:55,250 --> 00:54:59,880 Jika Anda menonton pendek pada mengarahkan dan pipa, Anda akan melihat bahwa Tommy menggunakan program ini 665 00:54:59,880 --> 00:55:07,540 yang pada dasarnya mencetak semua output dari file ke layar. 666 00:55:07,540 --> 00:55:12,660 Jadi jika saya menjalankan kucing, ini sebenarnya adalah sebuah program built-in untuk alat, 667 00:55:12,660 --> 00:55:16,860 dan jika Anda memiliki Mac Anda dapat melakukan ini pada Mac Anda juga, jika Anda membuka terminal. 668 00:55:16,860 --> 00:55:25,630 Dan kita - kucing, katakanlah, cp.c, dan tekan Enter. 669 00:55:25,630 --> 00:55:29,640 Apa ini lakukan, jika kita gulir ke atas sedikit dan melihat di mana kita berlari garis, 670 00:55:29,640 --> 00:55:40,440 atau di mana kita menjalankan perintah cat, itu benar-benar hanya dicetak isi cp.c ke layar kami. 671 00:55:40,440 --> 00:55:44,140 Kita bisa menjalankannya lagi dan Anda dapat dimasukkan ke dalam beberapa file bersama-sama. 672 00:55:44,140 --> 00:55:49,880 Sehingga Anda dapat melakukan cp.c kucing, dan kemudian kita juga dapat menggabungkan file cat.c, 673 00:55:49,880 --> 00:55:53,250 yang merupakan program kita akan menulis, 674 00:55:53,250 --> 00:55:58,140 dan itu akan mencetak kedua file kembali untuk kembali ke layar kami. 675 00:55:58,140 --> 00:56:05,490 Jadi jika kita gulir ke atas sedikit, kita melihat bahwa ketika kita berlari ini cp.c kucing, cat.c, 676 00:56:05,490 --> 00:56:17,110 pertama dicetak file cp, dan kemudian di bawahnya, itu dicetak file cat.c sampai di sini. 677 00:56:17,110 --> 00:56:19,650 Kita akan menggunakan ini untuk hanya mendapatkan kaki kami basah. 678 00:56:19,650 --> 00:56:25,930 Bermain-main dengan pencetakan sederhana untuk terminal, melihat bagaimana yang bekerja. 679 00:56:25,930 --> 00:56:39,170 Jika kalian membuka dengan gedit cat.c, tekan Enter, 680 00:56:39,170 --> 00:56:43,760 Anda dapat melihat program yang kita akan menulis. 681 00:56:43,760 --> 00:56:48,980 Kami telah menyertakan ini piring boiler yang bagus, sehingga kita tidak perlu menghabiskan waktu mengetik semua bahwa. 682 00:56:48,980 --> 00:56:52,310 Kami juga memeriksa jumlah argumen berlalu masuk 683 00:56:52,310 --> 00:56:56,910 Kami mencetak pesan penggunaan yang bagus. 684 00:56:56,910 --> 00:57:00,950 >> Ini adalah semacam hal yang, sekali lagi, seperti yang telah kita bicarakan, 685 00:57:00,950 --> 00:57:04,490 itu hampir seperti memori otot. 686 00:57:04,490 --> 00:57:07,190 Tapi ingatlah untuk terus melakukan jenis yang sama hal-hal 687 00:57:07,190 --> 00:57:11,310 dan selalu mencetak semacam pesan membantu 688 00:57:11,310 --> 00:57:17,670 sehingga orang tahu bagaimana untuk menjalankan program Anda. 689 00:57:17,670 --> 00:57:21,630 Dengan kucing, itu cukup sederhana, kita hanya akan pergi melalui semua argumen yang berbeda 690 00:57:21,630 --> 00:57:24,300 yang dikirimkan ke program kami, dan kami akan mencetak 691 00:57:24,300 --> 00:57:29,950 mereka isinya keluar ke layar satu per satu. 692 00:57:29,950 --> 00:57:35,670 Dalam rangka untuk mencetak file ke layar, kita akan melakukan sesuatu yang sangat mirip 693 00:57:35,670 --> 00:57:38,120 dengan apa yang kita lakukan pada akhir kuis. 694 00:57:38,120 --> 00:57:45,350 Pada akhir kuis, yang mempekerjakan program, kami harus membuka file, 695 00:57:45,350 --> 00:57:48,490 dan kemudian kami harus mencetak. 696 00:57:48,490 --> 00:57:54,660 Dalam kasus ini, kita akan membuka file, dan kita akan membaca dari itu sebagai gantinya. 697 00:57:54,660 --> 00:58:00,630 Kemudian kita akan mencetak, bukan ke file, kita akan mencetak ke layar. 698 00:58:00,630 --> 00:58:05,830 Jadi mencetak ke layar Anda semua telah dilakukan sebelumnya dengan printf. 699 00:58:05,830 --> 00:58:08,290 Sehingga tidak terlalu gila. 700 00:58:08,290 --> 00:58:12,190 Tapi membaca file agak aneh. 701 00:58:12,190 --> 00:58:17,300 Kita akan pergi melalui sedikit pada suatu waktu. 702 00:58:17,300 --> 00:58:20,560 Jika kalian kembali ke masalah terakhir pada kuis Anda, masalah 33, 703 00:58:20,560 --> 00:58:27,280 baris pertama yang akan kita lakukan di sini, membuka file, sangat mirip dengan apa yang kita lakukan di sana. 704 00:58:27,280 --> 00:58:36,370 Jadi Stella, apa yang terlihat baris seperti, ketika kita membuka file? 705 00:58:36,370 --> 00:58:47,510 [Stella] Capital FILE *, file - >> Oke. >> - Sama dengan fopen. >> Yup. 706 00:58:47,510 --> 00:58:55,980 Yang dalam hal ini? Ada dalam komentar. 707 00:58:55,980 --> 00:59:06,930 >> Ada dalam komentar? argv [i] dan r? 708 00:59:06,930 --> 00:59:11,300 >> Tepat. Tepat. Jadi Stella yang benar-benar benar. 709 00:59:11,300 --> 00:59:13,720 Ini adalah apa yang akan tampak seperti ini. 710 00:59:13,720 --> 00:59:19,670 Kita akan mendapatkan variabel file stream, menyimpannya dalam sebuah * FILE, sehingga semua topi, 711 00:59:19,670 --> 00:59:25,720 FILE, *, dan nama variabel ini akan menjadi file. 712 00:59:25,720 --> 00:59:32,250 Kita bisa menyebutnya apa saja yang kita sukai. Kita bisa menyebutnya first_file, atau file_i, apa pun yang kita ingin. 713 00:59:32,250 --> 00:59:37,590 Dan kemudian nama file disahkan dalam pada baris perintah untuk program ini. 714 00:59:37,590 --> 00:59:44,450 Jadi itu disimpan di argv [i,] dan kemudian kita akan membuka file ini dalam mode baca. 715 00:59:44,450 --> 00:59:48,100 Sekarang kami telah membuka file tersebut, apa hal yang kita harus selalu ingat untuk melakukan 716 00:59:48,100 --> 00:59:52,230 setiap kali kita telah membuka file? Menutupnya. 717 00:59:52,230 --> 00:59:57,220 Jadi Missy, bagaimana kita menutup file? 718 00:59:57,220 --> 01:00:01,020 [Missy] fclose (file) >> fclose (file). Tepat. 719 01:00:01,020 --> 01:00:05,340 Besar. Oke. Jika kita melihat ini untuk melakukan komentar di sini, 720 01:00:05,340 --> 01:00:11,940 ia mengatakan, "Buka argv [i] dan mencetak isinya ke stdout." 721 01:00:11,940 --> 01:00:15,460 >> Keluar standar adalah nama yang aneh. Stdout hanyalah cara kami mengatakan 722 01:00:15,460 --> 01:00:22,880 kita ingin mencetak ke terminal, kami ingin mencetak ke output stream standar. 723 01:00:22,880 --> 01:00:26,450 Kami benar-benar bisa menyingkirkan komentar ini di sini. 724 01:00:26,450 --> 01:00:36,480 Aku akan menyalinnya dan tempel karena itulah apa yang kami lakukan. 725 01:00:36,480 --> 01:00:41,290 Pada titik ini, sekarang kita harus membaca bit file dengan bit. 726 01:00:41,290 --> 01:00:46,300 Kami telah membahas beberapa cara membaca file. 727 01:00:46,300 --> 01:00:51,830 Mana yang favorit Anda sejauh ini? 728 01:00:51,830 --> 01:00:57,960 Yang cara yang telah Anda lihat atau apakah Anda ingat, untuk membaca file? 729 01:00:57,960 --> 01:01:04,870 [Daniel] fread? >> Fread? Jadi fread adalah satu. Jimmy, kau tahu orang lain? 730 01:01:04,870 --> 01:01:12,150 [Jimmy] No >> Oke. Nope. Charlotte? Alexander? Setiap orang lain? Oke. 731 01:01:12,150 --> 01:01:20,740 Jadi yang lain fgetc, adalah salah satu yang akan kita gunakan banyak. 732 01:01:20,740 --> 01:01:26,410 Ada juga fscanf, kalian melihat pola di sini? 733 01:01:26,410 --> 01:01:29,170 Mereka semua dimulai dengan f. Ada hubungannya dengan file. 734 01:01:29,170 --> 01:01:35,260 Ada fread, fgetc, fscanf. Ini adalah semua fungsi membaca. 735 01:01:35,260 --> 01:01:49,120 Untuk menulis kita memiliki fwrite, kita memiliki fputc bukan fgetc. 736 01:01:49,120 --> 01:01:58,250 Kami juga telah fprintf seperti kita lihat pada kuis. 737 01:01:58,250 --> 01:02:01,680 Karena ini adalah masalah yang melibatkan membaca dari sebuah file, 738 01:02:01,680 --> 01:02:04,940 kita akan menggunakan salah satu dari tiga fungsi. 739 01:02:04,940 --> 01:02:10,890 Kami tidak akan menggunakan fungsi-fungsi di sini. 740 01:02:10,890 --> 01:02:14,880 Fungsi-fungsi ini yang ditemukan di perpustakaan I / O standar. 741 01:02:14,880 --> 01:02:17,510 Jadi jika Anda melihat di bagian atas program ini, 742 01:02:17,510 --> 01:02:24,110 Anda dapat melihat bahwa kita sudah termasuk file header untuk perpustakaan I / O standar. 743 01:02:24,110 --> 01:02:27,120 Jika kita ingin mencari tahu mana yang kita ingin gunakan, 744 01:02:27,120 --> 01:02:29,690 kita selalu dapat membuka halaman manual. 745 01:02:29,690 --> 01:02:34,350 Jadi kita bisa mengetik stdio man 746 01:02:34,350 --> 01:02:43,180 dan membaca semua tentang input dan output fungsi stdio di C. 747 01:02:43,180 --> 01:02:49,870 Dan kita sudah bisa melihat oh, lihat. Ini menyebutkan fgetc, itu menyebutkan fputc. 748 01:02:49,870 --> 01:02:57,220 Jadi, Anda dapat menelusuri sedikit dan melihat, katakanlah, fgetc 749 01:02:57,220 --> 01:03:00,060 dan melihat halaman manual. 750 01:03:00,060 --> 01:03:03,430 Anda dapat melihat bahwa ia pergi bersama dengan sejumlah fungsi lainnya: 751 01:03:03,430 --> 01:03:12,640 fgetc, fgets, getc, getchar, mendapat, ungetc, dan input karakter dan string. 752 01:03:12,640 --> 01:03:19,180 Jadi ini adalah bagaimana kita membaca dalam karakter dan string dari file dari input standar, 753 01:03:19,180 --> 01:03:21,990 yang pada dasarnya dari pengguna. 754 01:03:21,990 --> 01:03:24,780 Dan ini adalah bagaimana kita melakukannya di C. aktual 755 01:03:24,780 --> 01:03:30,850 Jadi ini tidak menggunakan GetString dan fungsi getchar 756 01:03:30,850 --> 01:03:36,840 yang kita gunakan dari perpustakaan CS50. 757 01:03:36,840 --> 01:03:39,710 Kami akan melakukan masalah ini dalam beberapa cara 758 01:03:39,710 --> 01:03:43,430 sehingga Anda dapat melihat dua cara yang berbeda untuk melakukannya. 759 01:03:43,430 --> 01:03:48,490 Kedua fungsi fread bahwa Daniel disebutkan dan fgetc adalah cara yang baik untuk melakukannya. 760 01:03:48,490 --> 01:03:53,790 Saya pikir fgetc adalah sedikit lebih mudah, karena hanya memiliki, seperti yang Anda lihat, 761 01:03:53,790 --> 01:03:59,660 satu argumen, satu * FILE yang kita mencoba membaca karakter dari, 762 01:03:59,660 --> 01:04:02,740 dan nilai kembalinya adalah int. 763 01:04:02,740 --> 01:04:05,610 Dan ini adalah sedikit membingungkan, bukan? 764 01:04:05,610 --> 01:04:11,450 >> Karena kita sedang mendapatkan karakter, jadi mengapa tidak kembali ini char? 765 01:04:11,450 --> 01:04:18,700 Kalian punya ide tentang mengapa hal ini tidak mungkin kembali char? 766 01:04:18,700 --> 01:04:25,510 [Missy jawaban, tidak dapat dipahami] >> Ya. Jadi Missy yang benar-benar benar. 767 01:04:25,510 --> 01:04:31,570 Jika itu ASCII, maka bilangan bulat ini dapat dipetakan ke sebuah char yang sebenarnya. 768 01:04:31,570 --> 01:04:33,520 Bisa jadi karakter ASCII, dan itu benar. 769 01:04:33,520 --> 01:04:36,220 Itulah apa yang terjadi. 770 01:04:36,220 --> 01:04:39,190 Kami menggunakan int hanya karena memiliki lebih banyak bit. 771 01:04:39,190 --> 01:04:44,750 Ini lebih besar dari char, Char kami hanya memiliki 8 bit, bahwa 1 byte pada 32-bit mesin kami. 772 01:04:44,750 --> 01:04:48,520 Dan int memiliki nilai semua 4 byte 'ruang. 773 01:04:48,520 --> 01:04:50,940 Dan ternyata jalan fgetc bekerja, 774 01:04:50,940 --> 01:04:53,940 jika kita scroll ke bawah dalam sinopsis kami di halaman manual sedikit, 775 01:04:53,940 --> 01:05:05,000 gulir semua jalan ke bawah. Ternyata bahwa mereka menggunakan nilai khusus yang disebut EOF. 776 01:05:05,000 --> 01:05:09,640 Ini adalah konstanta khusus sebagai nilai kembali dari fungsi fgetc 777 01:05:09,640 --> 01:05:14,570 setiap kali anda menekan akhir file atau jika Anda mendapatkan pesan kesalahan. 778 01:05:14,570 --> 01:05:18,170 Dan ternyata untuk melakukan perbandingan ini dengan EOF benar, 779 01:05:18,170 --> 01:05:24,060 Anda ingin memiliki jumlah tambahan informasi yang Anda miliki dalam sebuah int 780 01:05:24,060 --> 01:05:28,420 sebagai lawan menggunakan variabel char. 781 01:05:28,420 --> 01:05:32,130 Meskipun fgetc secara efektif mendapatkan karakter dari sebuah file, 782 01:05:32,130 --> 01:05:38,450 Anda ingin mengingat bahwa itu adalah kembali sesuatu yang bertipe int untuk Anda. 783 01:05:38,450 --> 01:05:41,360 Yang mengatakan, itu cukup mudah digunakan. 784 01:05:41,360 --> 01:05:44,960 Ini akan memberi kita sebuah karakter, maka yang harus kita lakukan adalah terus bertanya file, 785 01:05:44,960 --> 01:05:48,440 "Berikan karakter berikutnya, memberi saya karakter berikutnya, memberi saya karakter berikutnya," 786 01:05:48,440 --> 01:05:51,400 sampai kita sampai ke akhir file. 787 01:05:51,400 --> 01:05:54,730 Dan itu akan menarik salah satu karakter pada satu waktu dari file kami, 788 01:05:54,730 --> 01:05:56,250 dan kemudian kita bisa melakukan apapun yang kita suka dengan itu. 789 01:05:56,250 --> 01:06:00,160 Kita bisa menyimpannya, kita dapat menambahkannya ke string, kita bisa mencetaknya. 790 01:06:00,160 --> 01:06:04,630 Melakukan semua itu. 791 01:06:04,630 --> 01:06:09,600 >> Zooming kembali dan akan kembali ke program cat.c kami, 792 01:06:09,600 --> 01:06:16,170 jika kita akan menggunakan fgetc, 793 01:06:16,170 --> 01:06:21,710 bagaimana mungkin kita mendekati baris berikutnya kode? 794 01:06:21,710 --> 01:06:26,020 Kita akan menggunakan - fread akan melakukan sesuatu yang sedikit berbeda. 795 01:06:26,020 --> 01:06:32,600 Dan kali ini, kita hanya akan menggunakan fgetc untuk mendapatkan satu karakter pada satu waktu. 796 01:06:32,600 --> 01:06:40,910 Untuk memproses seluruh file, apa yang mungkin harus kita lakukan? 797 01:06:40,910 --> 01:06:44,030 Berapa banyak karakter yang ada di file? 798 01:06:44,030 --> 01:06:47,390 Ada banyak. Jadi Anda mungkin ingin mendapatkan satu 799 01:06:47,390 --> 01:06:49,860 dan kemudian mendapatkan lain dan mendapatkan lain dan mendapatkan lain. 800 01:06:49,860 --> 01:06:53,330 Apa jenis algoritma yang Anda pikir kita mungkin harus menggunakan di sini? 801 01:06:53,330 --> 01:06:55,470 Apa jenis -? [Alexander] A untuk loop? >> Tepat. 802 01:06:55,470 --> 01:06:57,500 Beberapa jenis loop. 803 01:06:57,500 --> 01:07:03,380 Sebuah untuk loop sebenarnya besar, dalam kasus ini. 804 01:07:03,380 --> 01:07:08,620 Dan seperti yang Anda katakan, kedengarannya seperti Anda ingin loop atas seluruh file, 805 01:07:08,620 --> 01:07:11,820 mendapatkan karakter pada satu waktu. 806 01:07:11,820 --> 01:07:13,850 Ada saran tentang apa yang mungkin terlihat seperti? 807 01:07:13,850 --> 01:07:22,090 [Alexander, tidak dapat dipahami] 808 01:07:22,090 --> 01:07:30,050 >> Oke, katakan saja padaku dalam bahasa Inggris apa yang Anda coba lakukan? [Alexander, tidak dapat dipahami] 809 01:07:30,050 --> 01:07:36,270 Jadi dalam hal ini, kedengarannya seperti kami hanya mencoba untuk loop atas seluruh file. 810 01:07:36,270 --> 01:07:45,330 [Alexander] Jadi i > Ukuran -? 811 01:07:45,330 --> 01:07:49,290 Saya kira ukuran file, kan? Ukuran - kami hanya menulis seperti ini. 812 01:07:49,290 --> 01:07:57,470 Ukuran file untuk saat ini, i + +. 813 01:07:57,470 --> 01:08:04,610 Jadi ternyata bahwa cara Anda melakukan hal ini menggunakan fgetc, dan ini baru, 814 01:08:04,610 --> 01:08:10,460 adalah bahwa tidak ada cara mudah untuk hanya mendapatkan ukuran file 815 01:08:10,460 --> 01:08:16,979 dengan tipe "sizeof" dari membangun yang telah Anda lihat sebelumnya. 816 01:08:16,979 --> 01:08:20,910 Ketika kita menggunakan fungsi fgetc, kami memperkenalkan beberapa jenis 817 01:08:20,910 --> 01:08:29,069 baru sintaks, funky ini untuk loop, di mana bukan hanya menggunakan counter dasar 818 01:08:29,069 --> 01:08:33,920 untuk pergi karakter demi karakter, kita akan menarik salah satu karakter pada satu waktu, 819 01:08:33,920 --> 01:08:37,120 satu karakter pada satu waktu, dan cara kita tahu bahwa kita berada di akhir 820 01:08:37,120 --> 01:08:41,290 tidak ketika kita telah menghitung sejumlah karakter, 821 01:08:41,290 --> 01:08:49,939 tetapi ketika karakter kita tarik keluar adalah bahwa akhir khusus karakter file. 822 01:08:49,939 --> 01:08:58,689 Jadi kita bisa melakukan ini dengan - saya sebut ch ini, dan kita akan menginisialisasi 823 01:08:58,689 --> 01:09:08,050 dengan panggilan pertama kami untuk mendapatkan karakter pertama dari file tersebut. 824 01:09:08,050 --> 01:09:14,979 Jadi bagian ini di sini, ini akan mendapatkan karakter keluar dari file 825 01:09:14,979 --> 01:09:20,840 dan menyimpannya ke dalam variabel ch. 826 01:09:20,840 --> 01:09:25,420 Kita akan terus melakukan hal ini sampai kita sampai ke akhir file, 827 01:09:25,420 --> 01:09:41,170 yang kita lakukan dengan tes karakter tidak menjadi sama dengan karakter EOF khusus. 828 01:09:41,170 --> 01:09:48,750 Dan kemudian bukannya melakukan ch + +, yang hanya akan kenaikan nilai, 829 01:09:48,750 --> 01:09:52,710 jadi jika kita membaca keluar Sebuah file, modal A, katakanlah, 830 01:09:52,710 --> 01:09:56,810 ch + + akan memberi kita b, dan kemudian kita akan mendapatkan c dan kemudian d. 831 01:09:56,810 --> 01:09:59,310 Itu jelas bukan apa yang kita inginkan. Apa yang kita inginkan di sini 832 01:09:59,310 --> 01:10:05,830 dalam bit terakhir ini kita ingin mendapatkan karakter berikutnya dari file tersebut. 833 01:10:05,830 --> 01:10:09,500 >> Jadi bagaimana mungkin kita mendapatkan karakter berikutnya dari file tersebut? 834 01:10:09,500 --> 01:10:13,470 Bagaimana kita mendapatkan karakter pertama dari file tersebut? 835 01:10:13,470 --> 01:10:17,200 [Mahasiswa] fgetfile? >> Fgetc, atau, maaf, kau benar-benar benar. 836 01:10:17,200 --> 01:10:20,470 Saya salah eja itu di sana. Jadi ya. 837 01:10:20,470 --> 01:10:26,240 Di sini bukannya melakukan ch + +, 838 01:10:26,240 --> 01:10:29,560 kami hanya akan memanggil fgetc (file) lagi 839 01:10:29,560 --> 01:10:39,180 dan menyimpan hasilnya dalam variabel ch yang sama kami. 840 01:10:39,180 --> 01:10:43,730 [Pertanyaan Mahasiswa, dipahami] 841 01:10:43,730 --> 01:10:52,390 >> Sinilah orang FILE * ini adalah khusus. 842 01:10:52,390 --> 01:10:59,070 Cara mereka bekerja adalah mereka - ketika Anda pertama kali membuka - ketika Anda pertama kali membuat panggilan fopen, 843 01:10:59,070 --> 01:11:04,260 * FILE yang efektif berfungsi sebagai pointer ke awal file. 844 01:11:04,260 --> 01:11:12,830 Dan kemudian setiap kali Anda menelepon fgetc, bergerak satu karakter melalui file. 845 01:11:12,830 --> 01:11:23,280 Jadi setiap kali Anda menyebutnya, Anda incrementing pointer file dengan satu karakter. 846 01:11:23,280 --> 01:11:26,210 Dan ketika Anda fgetc lagi, Anda bergerak karakter lain 847 01:11:26,210 --> 01:11:28,910 dan lain karakter dan karakter lain dan karakter lain. 848 01:11:28,910 --> 01:11:32,030 [Pertanyaan Mahasiswa, dipahami] >> Dan ltu - ya. 849 01:11:32,030 --> 01:11:34,810 Ini semacam sihir ini di bawah tenda. 850 01:11:34,810 --> 01:11:37,930 Anda hanya terus incrementing melalui. 851 01:11:37,930 --> 01:11:46,510 Pada titik ini, Anda dapat benar-benar bekerja dengan karakter. 852 01:11:46,510 --> 01:11:52,150 Jadi bagaimana mungkin kita mencetak ini ke layar, sekarang? 853 01:11:52,150 --> 01:11:58,340 Kita dapat menggunakan hal printf sama yang kita gunakan sebelumnya. 854 01:11:58,340 --> 01:12:00,330 Bahwa kita telah menggunakan semua semester. 855 01:12:00,330 --> 01:12:05,450 Kita dapat memanggil printf, 856 01:12:05,450 --> 01:12:21,300 dan kita bisa lulus dalam karakter seperti itu. 857 01:12:21,300 --> 01:12:27,430 Cara lain untuk melakukannya adalah daripada menggunakan printf dan harus melakukan hal ini format string, 858 01:12:27,430 --> 01:12:29,490 kita juga dapat menggunakan salah satu fungsi lainnya. 859 01:12:29,490 --> 01:12:40,090 Kita dapat menggunakan fputc, yang mencetak karakter ke layar, 860 01:12:40,090 --> 01:12:52,580 kecuali jika kita melihat fputc - biarkan aku tampilannya keluar sedikit. 861 01:12:52,580 --> 01:12:56,430 Kami melihat apa yang baik adalah yang dibutuhkan dalam karakter yang kita baca dengan menggunakan fgetc, 862 01:12:56,430 --> 01:13:05,100 tapi kemudian kita harus memberikan aliran untuk mencetak ke. 863 01:13:05,100 --> 01:13:11,850 Kita juga bisa menggunakan fungsi putchar, yang akan dimasukkan langsung ke luar standar. 864 01:13:11,850 --> 01:13:16,070 Jadi ada sejumlah pilihan yang berbeda yang dapat kita gunakan untuk mencetak. 865 01:13:16,070 --> 01:13:19,580 Mereka semua di perpustakaan I / O standar. 866 01:13:19,580 --> 01:13:25,150 Setiap kali Anda ingin mencetak - sehingga printf, secara default, akan mencetak dengan standar khusus keluar sungai, 867 01:13:25,150 --> 01:13:27,910 yang stdout itu. 868 01:13:27,910 --> 01:13:41,300 Jadi kita hanya bisa menyebutnya sebagai semacam ini nilai sihir, stdout di sini. 869 01:13:41,300 --> 01:13:48,410 Ups. Menempatkan koma luar. 870 01:13:48,410 --> 01:13:52,790 >> Ini adalah banyak yang baru, informasi yang funky di sini. 871 01:13:52,790 --> 01:13:58,600 Banyak ini sangat idiomatic, dalam arti bahwa ini adalah kode 872 01:13:58,600 --> 01:14:05,700 yang ditulis dengan cara ini hanya karena bersih untuk membaca, mudah dibaca. 873 01:14:05,700 --> 01:14:11,520 Ada banyak cara yang berbeda untuk melakukannya, fungsi yang berbeda yang dapat Anda gunakan, 874 01:14:11,520 --> 01:14:14,680 tetapi kita cenderung hanya mengikuti pola-pola yang sama berulang-ulang. 875 01:14:14,680 --> 01:14:20,180 Jadi jangan heran jika Anda melihat kode seperti ini datang lagi dan lagi. 876 01:14:20,180 --> 01:14:25,690 Baiklah. Pada titik ini, kita perlu istirahat untuk hari. 877 01:14:25,690 --> 01:14:31,300 Terima kasih untuk datang. Terima kasih untuk menonton jika Anda sedang online. Dan kita akan melihat Anda minggu depan. 878 01:14:31,300 --> 01:14:33,890 [CS50.TV]