1 00:00:00,000 --> 00:00:02,500 [Powered by Google Translate] [Bagian 5 - Lebih Nyaman] 2 00:00:02,500 --> 00:00:04,690 [Rob Bowden - Harvard University] 3 00:00:04,690 --> 00:00:07,250 [Ini adalah CS50. - CS50.TV] 4 00:00:08,990 --> 00:00:14,250 >> Seperti saya katakan dalam email saya, ada banyak hal yang dapat Anda gunakan 5 00:00:14,250 --> 00:00:17,060 selain alat untuk benar-benar melakukan set masalah. 6 00:00:17,060 --> 00:00:19,910 Kami sarankan Anda melakukannya di alat hanya karena dengan begitu kita bisa lebih mudah membantu Anda 7 00:00:19,910 --> 00:00:22,070 dan kita tahu bagaimana semuanya akan bekerja. 8 00:00:22,070 --> 00:00:26,950 Tapi sebagai salah satu contoh di mana Anda dapat melakukan hal-hal jika, katakanlah, Anda tidak memiliki akses 9 00:00:26,950 --> 00:00:31,570 pada alat atau Anda ingin bekerja di ruang bawah tanah Science Center - 10 00:00:31,570 --> 00:00:33,090 yang sebenarnya mereka memiliki alat terlalu - 11 00:00:33,090 --> 00:00:35,150 jika Anda ingin bekerja di mana saja. 12 00:00:35,150 --> 00:00:42,370 Salah satu contoh adalah apakah Anda melihat / mendengar tentang SSH? 13 00:00:44,380 --> 00:00:47,780 SSH pada dasarnya hanya seperti terhubung ke sesuatu. 14 00:00:47,780 --> 00:00:51,340 Sebenarnya, sekarang saya SSHed ke dalam alat. 15 00:00:51,340 --> 00:00:54,290 Saya pernah bekerja langsung di alat. 16 00:00:55,930 --> 00:01:01,060 Berikut adalah alat, dan jika Anda melihat di sini Anda melihat alamat IP ini. 17 00:01:01,060 --> 00:01:03,650 Saya pernah bekerja di alat itu sendiri; 18 00:01:03,650 --> 00:01:08,840 Aku selalu datang ke jendela jendela / terminal iTerm2. 19 00:01:08,840 --> 00:01:15,910 Anda bisa SSH ke alamat IP, ssh jharvard@192.168.129.128. 20 00:01:15,910 --> 00:01:20,390 Saya ingat nomor yang sangat mudah karena seperti pola yang bagus. 21 00:01:20,390 --> 00:01:24,920 Tapi itu akan meminta saya untuk password saya, dan sekarang aku di alat. 22 00:01:24,920 --> 00:01:33,060 Pada dasarnya, pada titik ini, jika Anda membuka terminal dalam alat itu sendiri, 23 00:01:33,060 --> 00:01:36,350 antarmuka ini, namun Anda akan menggunakannya, persis sama 24 00:01:36,350 --> 00:01:40,010 sebagai antarmuka saya menggunakan di sini tapi sekarang Anda SSHed. 25 00:01:42,240 --> 00:01:44,920 Anda tidak perlu SSH ke alat. 26 00:01:44,920 --> 00:01:52,360 Salah satu contoh dari tempat lain Anda bisa SSH pesan adalah Aku cukup yakin Anda memiliki secara default - 27 00:01:52,360 --> 00:01:55,020 Oh. Bigger. 28 00:01:55,020 --> 00:02:01,130 Semua Anda harus memiliki account dengan FAS default pada server FAS. 29 00:02:01,130 --> 00:02:06,840 Bagi saya, saya akan SSH ke rbowden@nice.fas.harvard.edu. 30 00:02:06,840 --> 00:02:11,610 Ini akan meminta Anda yang pertama kali, dan Anda mengatakan ya. 31 00:02:11,610 --> 00:02:15,840 Password saya hanya akan menjadi sandi FAS saya. 32 00:02:15,840 --> 00:02:22,650 Dan sekarang, aku SSHed ke server yang bagus, dan saya bisa melakukan apapun yang saya mau di sini. 33 00:02:22,650 --> 00:02:28,560 Banyak kelas Anda mungkin mengambil, seperti 124, akan memiliki Anda meng-upload barang-barang ke sini 34 00:02:28,560 --> 00:02:30,950 untuk benar-benar menyerahkan set masalah Anda. 35 00:02:30,950 --> 00:02:34,100 Tapi mengatakan Anda tidak memiliki akses ke alat Anda. 36 00:02:34,100 --> 00:02:37,910 Kemudian Anda dapat melakukan hal-hal, seperti di sini akan mengatakan - 37 00:02:37,910 --> 00:02:42,160 Ini hanya bagian kami pertanyaan. 38 00:02:42,160 --> 00:02:45,070 Ini akan meminta Anda untuk melakukan hal ini dalam alat. 39 00:02:45,070 --> 00:02:47,790 Sebaliknya saya hanya akan melakukannya pada server. 40 00:02:47,790 --> 00:02:50,560 Aku akan unzip itu. 41 00:02:50,560 --> 00:02:55,670 Masalahnya akan menjadi bahwa Anda terbiasa menggunakan sesuatu seperti gedit 42 00:02:55,670 --> 00:02:58,160 atau apa pun dalam alat. 43 00:02:58,160 --> 00:03:01,830 Anda tidak akan memiliki pada server FAS. 44 00:03:01,830 --> 00:03:04,110 Ini semua hanya akan menjadi interface ini tekstual. 45 00:03:04,110 --> 00:03:09,180 Jadi Anda bisa salah satu, cobalah untuk belajar editor teks yang mereka miliki. 46 00:03:09,180 --> 00:03:12,130 Mereka memiliki Nano. 47 00:03:12,130 --> 00:03:14,990 Nano biasanya cukup mudah digunakan. 48 00:03:14,990 --> 00:03:19,470 Anda dapat menggunakan panah Anda dan ketik normal. 49 00:03:19,470 --> 00:03:21,250 Jadi itu tidak sulit. 50 00:03:21,250 --> 00:03:24,720 Jika Anda ingin benar-benar mewah Anda dapat menggunakan Emacs, 51 00:03:24,720 --> 00:03:29,850 yang saya mungkin tidak seharusnya dibuka karena saya bahkan tidak tahu bagaimana menutup Emacs. 52 00:03:29,850 --> 00:03:32,760 Kontrol X, Kontrol C? Ya. 53 00:03:32,760 --> 00:03:35,310 Atau Anda bisa menggunakan Vim, yang adalah apa yang saya gunakan. 54 00:03:35,310 --> 00:03:37,800 Dan sehingga mereka adalah pilihan Anda. 55 00:03:37,800 --> 00:03:43,830 Jika Anda tidak ingin melakukan itu, Anda juga bisa, jika Anda melihat-manual.cs50.net - 56 00:03:43,830 --> 00:03:45,410 Oh. 57 00:03:45,410 --> 00:03:49,920 Pada PC, Anda dapat menggunakan SSH Putty, 58 00:03:49,920 --> 00:03:51,940 yang Anda akan harus men-download secara terpisah. 59 00:03:51,940 --> 00:03:55,460 Pada Mac, Anda bisa hanya dengan menggunakan Terminal standar atau Anda dapat men-download iTerm2, 60 00:03:55,460 --> 00:03:58,490 yang seperti Terminal, baik mewah. 61 00:03:58,490 --> 00:04:03,780 Jika Anda pergi ke manual.cs50.net Anda akan melihat link ke Notepad + +, 62 00:04:03,780 --> 00:04:07,120 yang adalah apa yang dapat Anda gunakan pada PC. 63 00:04:07,120 --> 00:04:13,340 Ini memungkinkan Anda SFTP dari Notepad + +, yang pada dasarnya SSH. 64 00:04:13,340 --> 00:04:17,750 Apa ini akan membiarkan Anda lakukan adalah mengedit file secara lokal, 65 00:04:17,750 --> 00:04:20,670 dan kemudian setiap kali Anda ingin menyimpannya, maka akan menyimpan ke nice.fas, 66 00:04:20,670 --> 00:04:23,670 di mana Anda kemudian dapat menjalankannya. 67 00:04:23,670 --> 00:04:26,880 Dan setara pada Mac akan menjadi TextWrangler. 68 00:04:26,880 --> 00:04:28,760 Jadi memungkinkan Anda melakukan hal yang sama. 69 00:04:28,760 --> 00:04:32,800 Ini memungkinkan Anda mengedit file secara lokal dan menyimpannya ke nice.fas, 70 00:04:32,800 --> 00:04:35,730 di mana Anda kemudian dapat menjalankannya. 71 00:04:35,730 --> 00:04:40,400 Jadi jika Anda pernah terjebak tanpa sebuah alat, Anda memiliki pilihan ini 72 00:04:40,400 --> 00:04:44,230 masih melakukan set masalah Anda. 73 00:04:44,230 --> 00:04:48,250 Masalah yang akan menjadi bahwa Anda tidak akan memiliki perpustakaan CS50 74 00:04:48,250 --> 00:04:51,580 karena nice.fas tidak secara default memiliki. 75 00:04:51,580 --> 00:04:55,970 Anda dapat men-download perpustakaan CS50 - 76 00:04:55,970 --> 00:04:58,470 Saya tidak berpikir saya perlu bahwa pada saat ini. 77 00:04:58,470 --> 00:05:03,270 Anda dapat men-download perpustakaan CS50 dan salin ke nice.fas, 78 00:05:03,270 --> 00:05:07,450 atau saya pikir pada saat ini kita tidak menggunakannya lagi pula. 79 00:05:07,450 --> 00:05:12,720 Atau jika kita lakukan, Anda dapat untuk sementara waktu menggantinya dengan 80 00:05:12,720 --> 00:05:18,480 implementasi dari fungsi di perpustakaan CS50 pula. 81 00:05:18,480 --> 00:05:21,370 Sehingga tidak boleh yang banyak pembatasan. 82 00:05:21,370 --> 00:05:23,710 Dan itu itu. 83 00:05:26,460 --> 00:05:29,820 >> Aku akan kembali ke alat sekarang, kami akan melakukan segalanya dalam alat. 84 00:05:29,820 --> 00:05:37,510 Melihat bagian kami pertanyaan, di awal, seperti saya katakan di email saya, 85 00:05:37,510 --> 00:05:43,620 kita harus bicara tentang satu pendek Anda seharusnya untuk menonton. 86 00:05:43,620 --> 00:05:51,980 Kami memiliki mengarahkan & Pipa dan tiga pertanyaan. 87 00:05:51,980 --> 00:05:56,070 >> Untuk yang aliran apakah fungsi seperti printf menulis secara default? 88 00:05:56,070 --> 00:05:59,130 Jadi aliran. Apa sungai? 89 00:06:06,520 --> 00:06:15,100 Sebuah stream adalah pada dasarnya seperti itu hanya beberapa - 90 00:06:15,100 --> 00:06:21,450 Ini bahkan bukan sumber 1s dan 0s. 91 00:06:21,450 --> 00:06:24,920 Aliran itu meminta di sini adalah keluar standar. 92 00:06:24,920 --> 00:06:27,250 Dan sehingga standar aliran bahwa ketika Anda menulis untuk itu, 93 00:06:27,250 --> 00:06:30,940 muncul di layar. 94 00:06:30,940 --> 00:06:36,860 Keluar standar, oleh sungai, itu berarti Anda hanya menulis 1s dan 0s untuk itu, 95 00:06:36,860 --> 00:06:40,220 dan ujung keluar standar hanya membaca dari sungai itu. 96 00:06:40,220 --> 00:06:43,540 Ini hanya serangkaian 1s dan 0s. 97 00:06:43,540 --> 00:06:45,570 Anda dapat menulis ke sungai atau Anda dapat membaca dari stream 98 00:06:45,570 --> 00:06:47,950 tergantung pada apa sungai sebenarnya. 99 00:06:47,950 --> 00:06:52,800 Dua lainnya stream standar adalah standar dalam dan standard error. 100 00:06:52,800 --> 00:06:57,540 Standar adalah setiap kali Anda GetString, itu menunggu Anda untuk barang-barang input. 101 00:06:57,540 --> 00:07:01,570 Jadi menunggu untuk Anda, itu benar-benar menunggu standar, 102 00:07:01,570 --> 00:07:04,880 yang benar-benar apa yang Anda dapatkan ketika Anda mengetik di keyboard. 103 00:07:04,880 --> 00:07:07,530 Anda mengetik ke standar masuk 104 00:07:07,530 --> 00:07:10,050 Standard error pada dasarnya setara dengan keluar standar, 105 00:07:10,050 --> 00:07:13,280 tapi itu khusus dalam bahwa ketika Anda mencetak ke standard error, 106 00:07:13,280 --> 00:07:16,770 Anda seharusnya hanya mencetak pesan kesalahan itu 107 00:07:16,770 --> 00:07:20,200 sehingga Anda dapat membedakan antara pesan reguler dicetak ke layar 108 00:07:20,200 --> 00:07:24,560 dibandingkan pesan kesalahan tergantung pada apakah mereka pergi ke luar standar atau standard error. 109 00:07:24,560 --> 00:07:28,660 File juga. 110 00:07:28,660 --> 00:07:32,440 Keluar standar, standar, dan kesalahan standar aliran hanya khusus, 111 00:07:32,440 --> 00:07:36,810 tapi benar-benar file apapun, ketika Anda membuka file, itu menjadi aliran byte 112 00:07:36,810 --> 00:07:40,740 di mana Anda hanya dapat membaca dari sungai itu. 113 00:07:40,740 --> 00:07:47,770 Anda, untuk sebagian besar, hanya bisa memikirkan sebuah file sebagai aliran byte. 114 00:07:47,770 --> 00:07:51,190 Jadi aliran apa yang mereka tulis untuk secara default? Standar keluar. 115 00:07:51,190 --> 00:07:56,980 >> Apa perbedaan antara> dan >>? 116 00:07:58,140 --> 00:08:03,710 Apakah ada yang menonton video terlebih dahulu? Oke. 117 00:08:03,710 --> 00:08:10,960 > Akan menjadi bagaimana Anda redirect ke file, 118 00:08:10,960 --> 00:08:15,240 dan >> juga akan mengarahkan output ke file, 119 00:08:15,240 --> 00:08:17,820 tapi itu bukan akan menambahkan ke file. 120 00:08:17,820 --> 00:08:23,430 Sebagai contoh, katakanlah saya kebetulan punya dict di sini, 121 00:08:23,430 --> 00:08:27,020 dan hal-hal hanya dalam dict adalah kucing, kucing, anjing, ikan, anjing. 122 00:08:27,020 --> 00:08:31,530 Salah satu perintah yang Anda miliki di baris perintah adalah kucing, 123 00:08:31,530 --> 00:08:34,539 yang hanya akan mencetak apa yang ada di file. 124 00:08:34,539 --> 00:08:40,679 Jadi ketika saya mengatakan dict kucing, itu akan mencetak kucing, kucing, anjing, ikan, anjing. Itu semua kucing tidak. 125 00:08:40,679 --> 00:08:46,280 Itu berarti bahwa itu dicetak untuk keluar standar kucing, anjing, kucing, anjing ikan,. 126 00:08:46,280 --> 00:08:53,240 Jika saya bukan ingin mengarahkan bahwa ke file, saya dapat menggunakan> dan redirect ke file apapun adalah. 127 00:08:53,240 --> 00:08:56,460 Aku akan memanggil file file. 128 00:08:56,460 --> 00:09:00,320 Jadi sekarang jika saya ls, saya akan melihat saya memiliki sebuah file baru yang disebut file. 129 00:09:00,320 --> 00:09:05,700 Dan kalau aku membukanya, itu akan memiliki apa kucing dimasukkan pada baris perintah. 130 00:09:05,700 --> 00:09:11,040 Jadi sekarang jika saya melakukan hal itu lagi, maka itu akan mengarahkan output ke file, 131 00:09:11,040 --> 00:09:13,930 dan aku akan memiliki hal yang persis sama. 132 00:09:13,930 --> 00:09:17,910 Jadi secara teknis, itu benar-benar mengesampingkan apa yang kita miliki. 133 00:09:17,910 --> 00:09:22,970 Dan kita akan melihat apakah saya mengubah dict, saya mengambil anjing. 134 00:09:22,970 --> 00:09:29,980 Sekarang jika kita cat dict ke file lagi, kita akan memiliki versi baru dengan anjing dihapus. 135 00:09:29,980 --> 00:09:32,400 Jadi benar-benar mengabaikan itu. 136 00:09:32,400 --> 00:09:36,640 Sebaliknya, jika kita menggunakan >>, itu akan menambahkan file. 137 00:09:36,640 --> 00:09:40,860 Sekarang, membuka file, kita melihat kita hanya memiliki hal yang sama dua kali dicetak 138 00:09:40,860 --> 00:09:44,920 karena itu ada sekali, maka kita ditambahkan dengan aslinya. 139 00:09:44,920 --> 00:09:48,130 Apa jadi itu> dan >> lakukan. 140 00:09:48,130 --> 00:09:50,580 Apakah yang berikutnya bertanya - Ini tidak bertanya tentang hal itu. 141 00:09:50,580 --> 00:09:59,050 >> Yang lain yang kita miliki adalah <, yang jika> mengarahkan keluar standar, 142 00:09:59,050 --> 00:10:01,970 00:10:12,050 Mari kita lihat jika kita memiliki contoh. 144 00:10:14,750 --> 00:10:16,930 Aku bisa menulis satu cepat. 145 00:10:17,870 --> 00:10:25,700 Mari kita mengambil file, hello.c. 146 00:10:56,060 --> 00:10:59,070 Relatif mudah file. 147 00:10:59,070 --> 00:11:03,570 Aku hanya mendapatkan string dan kemudian mencetak "Hello" apapun string saya hanya masuk itu. 148 00:11:03,570 --> 00:11:07,990 Jadi membuat halo dan kemudian / hello.. 149 00:11:07,990 --> 00:11:10,720 Sekarang itu mendorong saya untuk memasukkan sesuatu, 150 00:11:10,720 --> 00:11:15,070 yang berarti itu menunggu pada hal-hal yang akan dimasukkan ke dalam standar masuk 151 00:11:15,070 --> 00:11:20,450 Jadi apapun yang saya inginkan masuk ke dalam standar masuk Kami hanya akan mengatakan Halo, Rob! 152 00:11:20,450 --> 00:11:23,310 Maka itu mencetak standar keluar Hello, Rob! 153 00:11:23,310 --> 00:11:28,860 Jika saya melakukan / hello. Dan kemudian mengarahkan, 154 00:11:30,740 --> 00:11:34,310 untuk saat ini Anda hanya dapat mengarahkan dari sebuah file. 155 00:11:34,310 --> 00:11:41,720 Jadi jika saya dimasukkan ke dalam beberapa file, txt, dan saya menaruh Rob, 156 00:11:41,720 --> 00:11:52,300 jika saya menjalankan halo dan kemudian mengarahkan ke file txt. / hello, itu akan menyapa, Rob! segera. 157 00:11:52,300 --> 00:11:57,160 Ketika pertama kali sampai ke GetString dan itu menunggu standar, 158 00:11:57,160 --> 00:12:01,730 standar dalam tidak lagi menunggu di keyboard untuk data untuk mendapatkan masuk. 159 00:12:01,730 --> 00:12:05,980 Sebaliknya, kami telah diarahkan standar untuk membaca dari file txt. 160 00:12:05,980 --> 00:12:10,290 Dan sehingga akan membaca dari file txt, yang hanya Rob garis, 161 00:12:10,290 --> 00:12:13,380 dan kemudian akan mencetak Hello, Rob! 162 00:12:13,380 --> 00:12:18,180 Dan jika saya ingin, saya juga bisa melakukan. / Hello 00:12:21,500 dan kemudian standar bahwa itu cetak, yang Hello, Rob!, 164 00:12:21,500 --> 00:12:24,700 Saya bisa mengarahkan itu ke file sendiri. 165 00:12:24,700 --> 00:12:29,790 Aku hanya akan memanggil file halo - tidak, aku tidak akan, karena itulah dieksekusi - txt2. 166 00:12:29,790 --> 00:12:40,150 Sekarang, txt2 akan memiliki output / hello. 00:12:43,520 >> Pertanyaan? 168 00:12:45,900 --> 00:12:49,090 >> Oke. Jadi di sini kita memiliki pipa. 169 00:12:49,090 --> 00:12:53,510 Pipa adalah unit terakhir dari redirection. 170 00:12:53,510 --> 00:12:58,750 >> Oh. Saya kira satu unit lebih redirection adalah jika bukan> Anda lakukan 2>, 171 00:12:58,750 --> 00:13:01,070 yang mengarahkan standard error. 172 00:13:01,070 --> 00:13:06,280 Jadi jika sesuatu pergi ke standard error, itu tidak akan bisa dimasukkan ke dalam txt2. 173 00:13:06,280 --> 00:13:12,480 Tapi perhatikan jika saya lakukan 2>, maka masih mencetak Hello, Rob! ke baris perintah 174 00:13:12,480 --> 00:13:18,600 karena aku hanya mengarahkan standard error, saya tidak mengarahkan keluar standar. 175 00:13:18,600 --> 00:13:22,210 Standard error dan keluar standar yang berbeda. 176 00:13:24,210 --> 00:13:27,080 Jika Anda ingin benar-benar menulis ke standard error, 177 00:13:27,080 --> 00:13:35,080 maka saya bisa mengubah ini menjadi fprintf ke stderr. 178 00:13:35,080 --> 00:13:37,850 Jadi printf, secara default, mencetak untuk keluar standar. 179 00:13:37,850 --> 00:13:41,720 Jika saya ingin mencetak ke standard error secara manual, maka saya harus menggunakan fprintf 180 00:13:41,720 --> 00:13:45,010 dan menentukan apa yang ingin saya mencetak ke. 181 00:13:45,010 --> 00:13:49,720 Jika bukan aku stdout fprintf, maka itu pada dasarnya setara dengan printf. 182 00:13:49,720 --> 00:13:55,530 Tapi fprintf kesalahan standar. 183 00:13:57,790 --> 00:14:03,650 Jadi sekarang, jika saya mengarahkan ini ke txt2, Hello, Rob! masih mendapatkan dicetak pada baris perintah 184 00:14:03,650 --> 00:14:08,270 karena ini mendapatkan dicetak ke standard error dan aku hanya mengarahkan keluar standar. 185 00:14:08,270 --> 00:14:16,420 Jika sekarang saya mengarahkan standard error, sekarang tidak bisa dicetak, dan txt2 akan menjadi Hello, Rob! 186 00:14:16,420 --> 00:14:21,910 Jadi sekarang, Anda dapat mencetak kesalahan yang sebenarnya Anda ke standard error 187 00:14:21,910 --> 00:14:24,720 dan mencetak pesan biasa untuk keluar standar. 188 00:14:24,720 --> 00:14:31,420 Dan jadi ketika Anda menjalankan program Anda, Anda dapat menjalankannya sebagai / hello. Jenis ini dengan 2> 189 00:14:31,420 --> 00:14:33,800 sehingga program Anda akan berjalan normal, 190 00:14:33,800 --> 00:14:38,400 tetapi pesan kesalahan yang Anda dapatkan Anda dapat memeriksa nanti dalam log kesalahan Anda, 191 00:14:38,400 --> 00:14:44,500 sehingga kesalahan, dan kemudian melihat kemudian dan kesalahan file Anda akan memiliki kesalahan yang terjadi. 192 00:14:45,200 --> 00:14:47,540 >> Pertanyaan? 193 00:14:47,540 --> 00:14:58,070 >> Yang terakhir adalah pipa, yang dapat Anda anggap sebagai mengambil standar keluar dari satu perintah 194 00:14:58,070 --> 00:15:01,210 dan membuat standar dalam dari perintah selanjutnya. 195 00:15:01,210 --> 00:15:05,570 Contoh di sini adalah gema adalah hal baris perintah 196 00:15:05,570 --> 00:15:11,840 yang hanya akan echo apa pun yang saya dimasukkan sebagai argumen. Saya tidak akan meletakkan tanda kutip. 197 00:15:11,840 --> 00:15:16,150 Echo bla, bla, bla hanya akan mencetak bla, bla, bla. 198 00:15:16,150 --> 00:15:20,600 Sebelumnya, ketika saya berkata saya harus meletakkan Rob ke dalam sebuah file txt 199 00:15:20,600 --> 00:15:28,830 karena saya hanya bisa mengarahkan file txt, sebagai gantinya, / jika aku echo Rob 200 00:15:28,830 --> 00:15:35,520 dan kemudian pipa ke / halo, yang juga akan melakukan jenis yang sama hal.. 201 00:15:35,520 --> 00:15:39,160 Ini adalah mengambil output dari perintah ini, gema Rob, 202 00:15:39,160 --> 00:15:43,610 dan menggunakannya sebagai masukan untuk / hello.. 203 00:15:44,790 --> 00:15:49,560 Anda dapat menganggapnya sebagai peralihan yang pertama gema Rob ke dalam file 204 00:15:49,560 --> 00:15:54,160 dan kemudian masukan ke / hello. bahwa file yang baru saja outputted. 205 00:15:54,160 --> 00:15:57,850 Tapi itu butuh file sementara keluar dari gambar. 206 00:16:01,890 --> 00:16:04,460 >> Pertanyaan itu? 207 00:16:04,460 --> 00:16:07,150 >> Pertanyaan berikutnya akan melibatkan ini. 208 00:16:07,150 --> 00:16:15,310 Apa yang bisa Anda gunakan pipa untuk menemukan jumlah nama-nama unik dalam sebuah file yang bernama names.txt? 209 00:16:15,310 --> 00:16:24,160 Perintah kita akan ingin menggunakan di sini adalah unik, sehingga uniq, dan kemudian wc. 210 00:16:24,160 --> 00:16:28,840 Anda dapat melakukan uniq manusia untuk benar-benar melihat apa yang tidak, 211 00:16:28,840 --> 00:16:34,840 dan itu hanya akan menyaring garis pencocokan yang berdekatan dari input. 212 00:16:34,840 --> 00:16:40,690 Dan pria wc akan mencetak kata, baris, dan jumlah byte untuk setiap file. 213 00:16:40,690 --> 00:16:43,760 Dan yang terakhir kita akan ingin menggunakan semacam, 214 00:16:43,760 --> 00:16:47,410 yang akan hanya mengurutkan baris file txt. 215 00:16:47,410 --> 00:16:58,080 Jika saya membuat beberapa file txt, names.txt, dan itu Rob, Tommy, Yusuf, Tommy, Yusuf, RJ, Rob, 216 00:16:58,080 --> 00:17:03,910 apa yang ingin saya lakukan di sini adalah menemukan jumlah nama yang unik dalam file ini. 217 00:17:03,910 --> 00:17:08,750 Jadi apa yang harus menjadi jawabannya? >> [Mahasiswa] 4. >> Ya. 218 00:17:08,750 --> 00:17:13,780 Ini harus menjadi 4 sejak Rob, Tommy, Joseph, RJ adalah nama hanya unik dalam file ini. 219 00:17:13,780 --> 00:17:20,180 Langkah pertama, jika saya hanya melakukan jumlah kata pada names.txt, 220 00:17:20,180 --> 00:17:24,290 ini sebenarnya menceritakan segalanya. 221 00:17:24,290 --> 00:17:32,560 Ini sebenarnya pencetakan - mari kita lihat, man wc - baris, kata, dan jumlah byte. 222 00:17:32,560 --> 00:17:38,270 Jika saya hanya peduli tentang garis, maka saya hanya bisa melakukan wc-l names.txt. 223 00:17:41,730 --> 00:17:44,300 Jadi itu langkah 1. 224 00:17:44,300 --> 00:17:50,510 Tapi aku tidak ingin wc-l names.txt karena names.txt hanya berisi semua nama, 225 00:17:50,510 --> 00:17:54,170 dan saya ingin menyaring setiap non-unik yang. 226 00:17:54,170 --> 00:18:01,200 Jadi jika saya melakukan names.txt uniq, yang tidak cukup memberikan apa yang saya inginkan 227 00:18:01,200 --> 00:18:03,760 karena nama digandakan masih ada. 228 00:18:03,760 --> 00:18:07,690 Mengapa demikian? Mengapa uniq tidak melakukan apa yang saya inginkan? 229 00:18:07,690 --> 00:18:10,500 [Mahasiswa] duplikat ini tidak [tak terdengar] >> Ya. 230 00:18:10,500 --> 00:18:16,370 Ingat halaman manual untuk uniq mengatakan garis pencocokan saringan yang berdekatan. 231 00:18:16,370 --> 00:18:19,680 Mereka tidak berdekatan, sehingga tidak akan menyaring mereka. 232 00:18:19,680 --> 00:18:31,100 Jika saya mengurutkan terlebih dahulu, names.txt semacam ini akan menempatkan semua baris duplikat bersama-sama. 233 00:18:31,100 --> 00:18:34,450 Jadi sekarang names.txt semacam adalah bahwa. 234 00:18:34,450 --> 00:18:40,550 Aku akan ingin menggunakannya sebagai masukan untuk uniq, yang | uniq. 235 00:18:40,550 --> 00:18:43,390 Itu memberi saya Joseph, RJ, Rob, Tommy, 236 00:18:43,390 --> 00:18:49,260 dan saya ingin menggunakannya sebagai masukan untuk wc-l, 237 00:18:49,260 --> 00:18:52,740 yang akan memberi saya 4. 238 00:18:52,740 --> 00:18:56,930 Seperti dikatakan di sini, apa yang bisa Anda gunakan pipa? 239 00:18:56,930 --> 00:19:01,390 Anda dapat melakukan banyak hal seperti menggunakan serangkaian perintah 240 00:19:01,390 --> 00:19:05,130 di mana Anda menggunakan output dari satu perintah sebagai masukan untuk perintah selanjutnya. 241 00:19:05,130 --> 00:19:08,780 Anda dapat melakukan banyak hal, banyak hal yang cerdas. 242 00:19:08,780 --> 00:19:11,440 >> Pertanyaan? 243 00:19:12,910 --> 00:19:14,600 Oke. 244 00:19:14,600 --> 00:19:17,880 Itu saja untuk pipa dan pengalihan. 245 00:19:18,370 --> 00:19:24,090 >> Sekarang kita melanjutkan ke hal-hal yang sebenarnya, hal-hal coding. 246 00:19:24,090 --> 00:19:29,100 Di dalam hal ini PDF, Anda akan melihat perintah ini, 247 00:19:29,100 --> 00:19:32,950 dan Anda akan ingin menjalankan perintah ini dalam alat Anda. 248 00:19:36,240 --> 00:19:42,250 wget adalah perintah untuk hanya mendapatkan sesuatu dari internet, pada dasarnya, 249 00:19:42,250 --> 00:19:45,180 sehingga wget dan URL ini. 250 00:19:45,180 --> 00:19:49,110 Jika Anda pergi ke URL ini di browser Anda, itu akan men-download file tersebut. 251 00:19:49,110 --> 00:19:52,510 Saya hanya diklik di atasnya, sehingga download file untuk saya. 252 00:19:52,510 --> 00:19:55,650 Tapi menulis wget hal bahwa di dalam terminal 253 00:19:55,650 --> 00:19:58,620 hanya akan men-download ke dalam terminal. 254 00:19:58,620 --> 00:20:02,750 Saya memiliki section5.zip, dan Anda akan ingin unzip section5.zip, 255 00:20:02,750 --> 00:20:06,520 yang akan memberikan Anda sebuah folder bernama section5, 256 00:20:06,520 --> 00:20:11,550 yang akan memiliki semua file kita akan menggunakan hari ini di dalamnya. 257 00:20:33,380 --> 00:20:37,710 Sebagai nama file program ini 'menunjukkan, mereka sedikit buggy, 258 00:20:37,710 --> 00:20:40,990 sehingga misi Anda adalah untuk mencari tahu mengapa menggunakan gdb. 259 00:20:40,990 --> 00:20:44,560 Apakah setiap orang telah mereka download / tahu bagaimana untuk mendapatkan mereka download 260 00:20:44,560 --> 00:20:47,480 ke dalam alat mereka? Oke. 261 00:20:47,480 --> 00:20:56,400 >> Menjalankan ./buggy1, ia akan berkata Segmentation fault (inti dibuang), 262 00:20:56,400 --> 00:21:00,500 yang setiap kali Anda mendapatkan segfault, itu adalah hal yang buruk. 263 00:21:00,500 --> 00:21:03,810 Dalam keadaan apa yang Anda mendapatkan segfault? 264 00:21:03,810 --> 00:21:08,210 [Mahasiswa] Dereferencing pointer null. >> Ya. Jadi itu adalah salah satu contoh. 265 00:21:08,210 --> 00:21:11,580 Dereferencing null pointer Anda akan mendapatkan segfault. 266 00:21:11,580 --> 00:21:16,720 Apa segfault berarti adalah Anda menyentuh memori Anda tidak boleh menyentuh. 267 00:21:16,720 --> 00:21:21,350 Jadi dereferencing pointer null menyentuh alamat 0, 268 00:21:21,350 --> 00:21:28,060 dan pada dasarnya, semua komputer saat ini mengatakan bahwa 0 adalah alamat memori Anda tidak boleh menyentuh. 269 00:21:28,060 --> 00:21:31,920 Jadi itu sebabnya dereferencing sebuah hasil pointer nol dalam segfault. 270 00:21:31,920 --> 00:21:37,210 Bila Anda kebetulan tidak menginisialisasi pointer, maka ia memiliki nilai sampah, 271 00:21:37,210 --> 00:21:41,520 dan sehingga ketika Anda mencoba untuk dereference itu, kemungkinan besar Anda menyentuh memori 272 00:21:41,520 --> 00:21:43,540 itu di antah berantah. 273 00:21:43,540 --> 00:21:45,650 Jika Anda kebetulan beruntung dan nilai sampah 274 00:21:45,650 --> 00:21:48,440 terjadi untuk menunjuk ke suatu tempat di tumpukan atau sesuatu, 275 00:21:48,440 --> 00:21:50,820 maka ketika Anda dereference pointer yang yang Anda belum diinisialisasi, 276 00:21:50,820 --> 00:21:52,730 tidak akan salah. 277 00:21:52,730 --> 00:21:55,480 Tetapi jika itu menunjuk ke, katakanlah, di suatu tempat antara tumpukan dan tumpukan, 278 00:21:55,480 --> 00:21:59,850 atau itu hanya menunjuk ke suatu tempat yang belum digunakan oleh program anda belum, 279 00:21:59,850 --> 00:22:02,240 maka Anda menyentuh memori Anda tidak boleh menyentuh dan Anda segfault. 280 00:22:02,240 --> 00:22:06,370 Ketika Anda menulis fungsi rekursif dan recurses kali terlalu banyak 281 00:22:06,370 --> 00:22:08,720 dan tumpukan Anda tumbuh terlalu besar dan bertabrakan tumpukan ke hal-hal 282 00:22:08,720 --> 00:22:12,270 bahwa itu tidak boleh bertabrakan dengan, Anda menyentuh memori Anda tidak boleh menyentuh, 283 00:22:12,270 --> 00:22:14,810 sehingga Anda segfault. 284 00:22:14,810 --> 00:22:17,010 Itulah yang segfault ini. 285 00:22:17,010 --> 00:22:21,810 >> Ini juga alasan yang sama bahwa jika Anda memiliki string seperti - 286 00:22:21,810 --> 00:22:23,930 mari kita kembali ke program sebelumnya. 287 00:22:23,930 --> 00:22:28,530 Dalam hello.c--aku hanya akan membuat sesuatu yang lain. 288 00:22:28,530 --> 00:22:33,770 char * s = "hello world!"; 289 00:22:33,770 --> 00:22:42,310 Jika saya menggunakan * s = sesuatu atau s [0] = 'X'; 290 00:22:42,310 --> 00:22:47,290 sehingga membuat halo, / hello., kenapa itu segfault? 291 00:22:48,410 --> 00:22:51,250 Mengapa hal ini segfault? 292 00:22:55,660 --> 00:22:57,890 Apa yang akan Anda harapkan untuk terjadi? 293 00:22:57,890 --> 00:23:06,640 Jika saya melakukan printf ("% s \ n", s); apa yang Anda harapkan untuk dicetak? 294 00:23:06,640 --> 00:23:09,930 [Mahasiswa] X halo. >> Ya. 295 00:23:09,930 --> 00:23:15,140 Masalahnya adalah bahwa ketika Anda mendeklarasikan string seperti ini, 296 00:23:15,140 --> 00:23:18,190 s adalah sebuah pointer yang akan pergi di stack, 297 00:23:18,190 --> 00:23:25,880 dan apa s menunjuk ke string ini adalah yang terkandung dalam read-only memory. 298 00:23:25,880 --> 00:23:30,560 Jadi hanya dengan memori, nama read-only, Anda harus mendapatkan ide 299 00:23:30,560 --> 00:23:33,010 bahwa jika Anda mencoba untuk mengubah apa yang ada di read-only memory, 300 00:23:33,010 --> 00:23:36,670 Anda melakukan sesuatu yang Anda tidak harus melakukan dengan memori dan Anda segfault. 301 00:23:36,670 --> 00:23:45,360 Ini sebenarnya adalah sebuah perbedaan besar antara char * s dan char s []. 302 00:23:45,360 --> 00:23:48,790 Jadi char s [], sekarang string ini akan diletakkan di stack, 303 00:23:48,790 --> 00:23:53,960 dan stack tidak read-only, yang berarti bahwa ini harus bekerja baik-baik saja. 304 00:23:55,500 --> 00:23:57,370 Dan itu tidak. 305 00:23:57,370 --> 00:24:06,250 Ingatlah bahwa ketika saya melakukan char * s = "hello world!", S sendiri pada stack 306 00:24:06,250 --> 00:24:10,390 namun s poin ke tempat lain, dan bahwa di tempat lain terjadi menjadi read-only. 307 00:24:10,390 --> 00:24:15,640 Tapi char s [] hanyalah sesuatu pada stack. 308 00:24:17,560 --> 00:24:21,760 Jadi itu contoh lain dari segfault terjadi. 309 00:24:21,760 --> 00:24:27,820 >> Kami melihat bahwa ./buggy1 menghasilkan segfault. 310 00:24:27,820 --> 00:24:31,810 Secara teori, Anda tidak harus melihat buggy1.c segera. 311 00:24:31,810 --> 00:24:35,170 Sebaliknya, kita akan melihat melalui gdb. 312 00:24:35,170 --> 00:24:37,750 Perhatikan bahwa ketika Anda mendapatkan kesalahan Segmentasi (inti dibuang), 313 00:24:37,750 --> 00:24:40,850 Anda mendapatkan file ini di sini disebut inti. 314 00:24:40,850 --> 00:24:45,200 Jika kita ls-l, kita akan melihat inti yang biasanya file yang cukup besar. 315 00:24:45,200 --> 00:24:51,580 Ini adalah jumlah byte dari file tersebut, sehingga terlihat seperti itu 250-sesuatu kilobyte. 316 00:24:51,580 --> 00:24:56,120 Alasan untuk ini adalah bahwa apa yang core dump sebenarnya 317 00:24:56,120 --> 00:25:01,410 adalah ketika program anda crash, keadaan memori dari program Anda 318 00:25:01,410 --> 00:25:05,230 hanya akan disalin dan disisipkan ke dalam file ini. 319 00:25:05,230 --> 00:25:07,270 Ini akan dibuang ke dalam file tersebut. 320 00:25:07,270 --> 00:25:13,060 Program ini, sementara itu berlari, kebetulan memiliki penggunaan memori sekitar 250 kilobyte, 321 00:25:13,060 --> 00:25:17,040 dan itulah yang mendapat dibuang ke file ini. 322 00:25:17,040 --> 00:25:23,630 Sekarang Anda dapat melihat file yang jika kita lakukan gdb inti buggy1. 323 00:25:23,630 --> 00:25:30,130 Kami hanya bisa melakukan gdb buggy1, dan itu hanya akan start up gdb teratur, 324 00:25:30,130 --> 00:25:33,800 menggunakan buggy1 sebagai file input. 325 00:25:33,800 --> 00:25:38,260 Tapi jika Anda melakukannya gdb inti buggy1, maka itu khusus akan memulai gdb 326 00:25:38,260 --> 00:25:40,330 dengan melihat file inti. 327 00:25:40,330 --> 00:25:45,560 Dan Anda mengatakan buggy1 gdb berarti tahu bahwa file inti berasal dari program buggy1. 328 00:25:45,560 --> 00:25:49,580 Jadi gdb buggy1 inti akan segera membawa kita 329 00:25:49,580 --> 00:25:52,060 ke mana program terjadi untuk mengakhiri. 330 00:25:57,720 --> 00:26:02,340 Kita lihat di sini Program diakhiri dengan sinyal 11, Segmentation fault. 331 00:26:02,340 --> 00:26:10,110 Kami kebetulan melihat garis perakitan, yang mungkin tidak sangat membantu. 332 00:26:10,110 --> 00:26:15,360 Tetapi jika Anda mengetik bt atau backtrace, yang akan menjadi fungsi 333 00:26:15,360 --> 00:26:19,430 yang memberi kita daftar frame kita saat ini tumpukan. 334 00:26:19,430 --> 00:26:23,150 Jadi backtrace. Sepertinya kita hanya memiliki dua frame stack. 335 00:26:23,150 --> 00:26:26,310 Yang pertama adalah stack frame utama kami, 336 00:26:26,310 --> 00:26:29,810 dan yang kedua adalah stack frame untuk fungsi yang kita kebetulan berada di, 337 00:26:29,810 --> 00:26:34,440 yang sepertinya kita hanya memiliki kode assembly untuk. 338 00:26:34,440 --> 00:26:38,050 Jadi mari kita kembali ke dalam fungsi utama kami, 339 00:26:38,050 --> 00:26:42,300 dan untuk melakukan itu kita dapat melakukan frame 1, dan saya pikir kita juga bisa melakukan turun, 340 00:26:42,300 --> 00:26:45,160 tapi aku hampir tidak pernah melakukan turun - atau up. Ya. 341 00:26:45,160 --> 00:26:50,710 Up and down. Up membawa Anda naik satu stack frame, turun membawa Anda ke bawah stack frame. 342 00:26:50,710 --> 00:26:53,240 Saya cenderung untuk tidak pernah menggunakan. 343 00:26:53,240 --> 00:26:59,120 Aku hanya khusus mengatakan frame 1, yang pergi ke bingkai berlabel 1. 344 00:26:59,120 --> 00:27:01,750 Bingkai 1 akan membawa kita ke dalam stack frame utama, 345 00:27:01,750 --> 00:27:05,570 dan mengatakan di sini baris kode kita kebetulan berada di. 346 00:27:05,570 --> 00:27:07,950 Jika kita ingin beberapa baris lebih kode, kita dapat mengatakan daftar, 347 00:27:07,950 --> 00:27:11,280 dan itu akan memberi kita semua baris kode di sekitarnya. 348 00:27:11,280 --> 00:27:13,360 Garis kami segfaulted di 6 adalah: 349 00:27:13,360 --> 00:27:17,360 if (strcmp ("CS50 batu", argv [1]) == 0). 350 00:27:17,360 --> 00:27:24,130 Jika tidak jelas belum, Anda bisa mendapatkannya langsung dari sini hanya dengan berpikir mengapa segfaulted. 351 00:27:24,130 --> 00:27:28,800 Tapi kita bisa mengambil satu langkah lebih jauh dan berkata, "Mengapa argv [1] segfault?" 352 00:27:28,800 --> 00:27:38,830 Mari kita cetak argv [1], dan sepertinya 0x0 itu, yang merupakan pointer null. 353 00:27:38,830 --> 00:27:44,750 Kami strcmping CS50 batu dan nol, dan sehingga akan segfault. 354 00:27:44,750 --> 00:27:48,280 Dan mengapa argv [1] nol? 355 00:27:48,640 --> 00:27:51,280 [Mahasiswa] Karena kita tidak memberikan apapun argumen baris perintah. 356 00:27:51,280 --> 00:27:53,390 Ya. Kami tidak memberikan setiap argumen baris perintah. 357 00:27:53,390 --> 00:27:58,460 Jadi ./buggy1 hanya akan memiliki argv [0] menjadi ./buggy1. 358 00:27:58,460 --> 00:28:02,100 Ini tidak akan memiliki argv [1], sehingga akan segfault. 359 00:28:02,100 --> 00:28:07,450 Tapi jika, sebaliknya, saya hanya CS50, itu akan mengatakan Anda mendapatkan D 360 00:28:07,450 --> 00:28:09,950 karena itulah apa yang seharusnya dilakukan. 361 00:28:09,950 --> 00:28:15,240 Melihat buggy1.c, itu seharusnya untuk mencetak "Anda mendapatkan D" - 362 00:28:15,240 --> 00:28:20,820 Jika argv [1] tidak "CS50 batu", "Anda mendapatkan D", yang lain "Anda mendapatkan nilai A!" 363 00:28:20,820 --> 00:28:25,660 Jadi jika kita ingin A, kita perlu ini untuk membandingkan sebagai benar, 364 00:28:25,660 --> 00:28:28,710 yang berarti bahwa dibandingkan dengan 0. 365 00:28:28,710 --> 00:28:31,100 Jadi argv [1] perlu "CS50 batu". 366 00:28:31,100 --> 00:28:35,660 Jika Anda ingin melakukan itu pada baris perintah, Anda perlu menggunakan \ untuk melarikan diri ruang. 367 00:28:35,660 --> 00:28:41,690 Jadi CS50 \ batu dan Anda mendapatkan nilai A! 368 00:28:41,690 --> 00:28:44,060 Jika Anda tidak melakukan backslash, mengapa hal ini tidak bekerja? 369 00:28:44,060 --> 00:28:47,190 [Mahasiswa] Ini dua argumen yang berbeda. >> Ya. 370 00:28:47,190 --> 00:28:52,540 Argv [1] akan menjadi CS50, dan argv [2] akan menjadi batu. Oke. 371 00:28:52,540 --> 00:28:56,470 >> Sekarang ./buggy2 akan segfault lagi. 372 00:28:56,470 --> 00:29:01,880 Alih-alih membukanya dengan file intinya, kami hanya akan membuka buggy2 secara langsung, 373 00:29:01,880 --> 00:29:05,000 sehingga gdb buggy2. 374 00:29:05,000 --> 00:29:09,590 Sekarang jika kita hanya menjalankan program kami, maka itu akan mengatakan Program menerima sinyal SIGSEGV, 375 00:29:09,590 --> 00:29:15,530 yang merupakan segfault sinyal, dan ini adalah di mana hal itu terjadi terjadi. 376 00:29:15,530 --> 00:29:21,250 Melihat backtrace kami, kami melihat bahwa kami berada di oh_no fungsi, 377 00:29:21,250 --> 00:29:23,900 yang disebut oleh mungil fungsi, yang disebut oleh binky fungsi, 378 00:29:23,900 --> 00:29:26,460 yang disebut oleh utama. 379 00:29:26,460 --> 00:29:31,680 Kita juga bisa melihat argumen untuk fungsi tersebut. 380 00:29:31,680 --> 00:29:34,680 Argumen ke mungil dan binky adalah 1. 381 00:29:34,680 --> 00:29:44,390 Jika kita daftar fungsi oh_no, kita melihat bahwa oh_no hanya melakukan char ** s = NULL; 382 00:29:44,390 --> 00:29:47,410 * S = "BOOM"; 383 00:29:47,410 --> 00:29:50,330 Mengapa yang gagal? 384 00:29:54,330 --> 00:29:58,380 [Mahasiswa] Anda tidak dapat dereference pointer nol? >> Ya. 385 00:29:58,380 --> 00:30:06,090 Ini hanya mengatakan s adalah NULL, tidak peduli apakah itu terjadi menjadi char **, 386 00:30:06,090 --> 00:30:12,070 yang, tergantung pada bagaimana Anda menafsirkannya, itu bisa menjadi pointer ke pointer ke string 387 00:30:12,070 --> 00:30:15,550 atau array string. 388 00:30:15,550 --> 00:30:21,430 Ini s adalah NULL, maka * s dereferencing null pointer, 389 00:30:21,430 --> 00:30:24,800 dan jadi ini akan kecelakaan. 390 00:30:24,800 --> 00:30:27,540 Ini adalah salah satu cara tercepat yang bisa Anda segfault. 391 00:30:27,540 --> 00:30:31,300 Hanya saja mendeklarasikan pointer nol dan segera segfault. 392 00:30:31,300 --> 00:30:34,570 Itulah yang oh_no lakukan. 393 00:30:34,570 --> 00:30:43,400 Jika kita naik satu frame, maka kita akan masuk ke fungsi yang disebut oh_no. 394 00:30:43,400 --> 00:30:44,830 Saya perlu melakukan itu turun. 395 00:30:44,830 --> 00:30:48,610 Jika Anda tidak memasukkan perintah dan Anda hanya tekan Enter lagi, 396 00:30:48,610 --> 00:30:52,350 itu hanya akan mengulang perintah sebelumnya yang Anda berlari. 397 00:30:52,350 --> 00:30:56,610 Kami berada di frame 1. 398 00:30:56,610 --> 00:31:04,650 Listing frame ini, kita lihat di sini adalah fungsi kita. 399 00:31:04,650 --> 00:31:08,520 Anda dapat menekan daftar lagi, atau Anda dapat melakukan daftar 20 dan akan daftar lebih. 400 00:31:08,520 --> 00:31:13,640 The mungil Fungsi mengatakan jika saya adalah 1, kemudian pergi ke fungsi oh_no, 401 00:31:13,640 --> 00:31:15,960 lain pergi ke fungsi Slinky. 402 00:31:15,960 --> 00:31:18,700 Dan kita tahu i adalah 1 karena kita kebetulan melihat di sini 403 00:31:18,700 --> 00:31:22,560 mungil yang disebut dengan argumen 1. 404 00:31:22,560 --> 00:31:27,560 Atau Anda hanya dapat melakukan print saya dan akan mengatakan saya adalah 1. 405 00:31:27,560 --> 00:31:33,770 Kami sedang dalam mungil, dan jika kita naik frame lain, kita tahu bahwa kita akan berakhir di binky. 406 00:31:33,770 --> 00:31:36,600 Up. Sekarang kita berada di binky. 407 00:31:36,600 --> 00:31:41,340 Listing fungsi ini - daftar dari sebelum setengah memotong saya - 408 00:31:41,340 --> 00:31:52,670 itu dimulai seolah-olah saya adalah 0, maka kita akan menyebutnya oh_no, yang lain menghubungi mungil. 409 00:31:52,670 --> 00:31:57,000 Kita tahu i adalah 1, sehingga disebut mungil. 410 00:31:57,000 --> 00:32:05,030 Dan sekarang kita kembali main, dan main hanya akan menjadi int i = rand ()% 3; 411 00:32:05,030 --> 00:32:08,790 Itu hanya akan memberikan nomor acak yang baik 0, 1, atau 2. 412 00:32:08,790 --> 00:32:12,780 Ini akan menelepon binky dengan nomor itu, dan itu akan kembali 0. 413 00:32:12,780 --> 00:32:16,700 Melihat hal ini, 414 00:32:16,700 --> 00:32:19,880 hanya berjalan melalui program secara manual tanpa menjalankan segera, 415 00:32:19,880 --> 00:32:25,400 Anda akan menetapkan titik istirahat di utama, yang berarti bahwa ketika kita menjalankan program 416 00:32:25,400 --> 00:32:31,020 program anda berjalan sampai hits titik istirahat. 417 00:32:31,020 --> 00:32:35,450 Jadi menjalankan program, itu akan berjalan dan kemudian akan menekan fungsi utama dan berhenti berjalan. 418 00:32:35,450 --> 00:32:44,700 Sekarang kita dalam utama, dan langkah atau selanjutnya akan membawa kita ke baris berikutnya kode. 419 00:32:44,700 --> 00:32:47,050 Anda dapat melakukan langkah atau berikutnya. 420 00:32:47,050 --> 00:32:51,800 Menekan selanjutnya, sekarang saya telah diatur untuk rand ()% 3, jadi kita bisa mencetak nilai i, 421 00:32:51,800 --> 00:32:55,280 dan akan mengatakan saya adalah 1. 422 00:32:55,280 --> 00:32:58,110 Sekarang itu tidak peduli apakah kita menggunakan berikutnya atau langkah. 423 00:32:58,110 --> 00:33:01,000 Saya kira itu penting dalam satu sebelumnya, tapi kami ingin menggunakan selanjutnya. 424 00:33:01,000 --> 00:33:06,000 Jika kita menggunakan langkah, kita masuk ke fungsi, yang berarti melihat hal yang sebenarnya 425 00:33:06,000 --> 00:33:07,940 yang terjadi dalam binky. 426 00:33:07,940 --> 00:33:10,510 Jika kita menggunakan berikutnya, maka itu berarti pergi ke fungsi 427 00:33:10,510 --> 00:33:14,070 dan hanya pergi ke baris berikutnya kode dalam fungsi utama kami. 428 00:33:14,070 --> 00:33:17,900 Di sini pada baris ini, aku berada di mana dikatakan rand ()% 3; 429 00:33:17,900 --> 00:33:21,320 jika aku langkah, itu akan masuk ke pelaksanaan rand 430 00:33:21,320 --> 00:33:25,110 dan melihat apa yang terjadi di sana, dan aku bisa melangkah melalui fungsi rand. 431 00:33:25,110 --> 00:33:26,920 Tapi aku tidak peduli tentang fungsi rand. 432 00:33:26,920 --> 00:33:30,190 Aku hanya ingin pergi ke baris berikutnya kode di main, jadi saya menggunakan berikutnya. 433 00:33:30,190 --> 00:33:35,800 Tapi sekarang aku peduli fungsi binky, jadi saya ingin melangkah ke dalam. 434 00:33:35,800 --> 00:33:37,730 Sekarang aku di binky. 435 00:33:37,730 --> 00:33:42,040 Baris pertama dari kode yang akan mengatakan jika (i == 0), saya mengambil langkah, 436 00:33:42,040 --> 00:33:44,930 kita melihat kita berakhir di mungil. 437 00:33:44,930 --> 00:33:51,620 Jika kita hal daftar, kita melihat bahwa itu diperiksa adalah i = 0. 438 00:33:51,620 --> 00:33:55,470 i tidak sama dengan 0, sehingga pergi ke kondisi yang lain, 439 00:33:55,470 --> 00:33:59,540 yang akan menelepon mungil (i). 440 00:33:59,540 --> 00:34:04,030 Anda mungkin bingung. 441 00:34:04,030 --> 00:34:07,380 Jika Anda hanya melihat garis-garis secara langsung, Anda mungkin berpikir jika (i == 0), 442 00:34:07,380 --> 00:34:10,800 oke, maka saya mengambil langkah dan sekarang aku di mungil (i), 443 00:34:10,800 --> 00:34:14,120 Anda mungkin berpikir bahwa harus berarti i = 0 atau sesuatu. 444 00:34:14,120 --> 00:34:18,980 No Ini hanya berarti bahwa ia tahu itu dapat menempel langsung ke mungil line (i). 445 00:34:18,980 --> 00:34:23,300 Karena saya tidak 0, langkah berikutnya tidak akan berakhir di lain tersebut. 446 00:34:23,300 --> 00:34:26,239 Lain bukanlah garis itu akan berhenti di. 447 00:34:26,239 --> 00:34:31,570 Ini hanya akan pergi ke baris berikutnya itu benar-benar bisa mengeksekusi, yang mungil (i). 448 00:34:31,570 --> 00:34:36,090 Melangkah ke mungil (i), kita lihat apakah (i == 1). 449 00:34:36,090 --> 00:34:42,670 Kami tahu i = 1, jadi ketika kita melangkah, kita tahu kita akan berakhir di oh_no 450 00:34:42,670 --> 00:34:46,489 karena i = 1 panggilan oh_no fungsi, yang Anda dapat melangkah ke, 451 00:34:46,489 --> 00:34:52,969 yang akan mengatur char ** s = NULL dan segera "BOOM". 452 00:34:54,270 --> 00:34:59,690 Dan kemudian benar-benar melihat pelaksanaan buggy2, 453 00:34:59,690 --> 00:35:04,590 ini, saya hanya mendapatkan nomor acak - 0, 1, atau 2 - panggilan binky, 454 00:35:04,590 --> 00:35:10,610 yang jika i adalah 0 itu panggilan oh_no, yang lain itu panggilan mungil, yang muncul di sini. 455 00:35:10,610 --> 00:35:18,100 Jika i adalah 1, panggilan oh_no, yang lain memanggil Slinky, yang datang ke sini, 456 00:35:18,100 --> 00:35:20,460 jika saya adalah 2, sebut oh_no. 457 00:35:20,460 --> 00:35:24,720 Aku bahkan tidak berpikir ada cara - 458 00:35:24,720 --> 00:35:30,030 Apakah ada yang melihat cara untuk membuat ini sebuah program yang tidak akan segfault? 459 00:35:30,030 --> 00:35:37,530 Karena kecuali aku kehilangan sesuatu, jika i adalah 0, Anda segera akan segfault, 460 00:35:37,530 --> 00:35:41,250 pun Anda pergi ke fungsi yang jika i adalah 1 Anda segfault, 461 00:35:41,250 --> 00:35:44,540 pun Anda pergi ke fungsi di mana jika saya adalah 2 Anda segfault. 462 00:35:44,540 --> 00:35:46,810 Jadi tidak peduli apa yang Anda lakukan, Anda segfault. 463 00:35:46,810 --> 00:35:52,380 >> Saya kira salah satu cara untuk memperbaiki itu akan bukannya melakukan char ** s = NULL, 464 00:35:52,380 --> 00:35:55,610 Anda bisa malloc ruang untuk string yang. 465 00:35:55,610 --> 00:36:04,230 Kita bisa melakukan malloc (sizeof) - sizeof apa? 466 00:36:09,910 --> 00:36:15,190 [Mahasiswa] (char) * 5? >> Apakah ini tampaknya benar? 467 00:36:15,190 --> 00:36:21,060 Aku menduga ini akan bekerja jika saya benar-benar berlari, tapi itu bukan apa yang saya cari. 468 00:36:24,400 --> 00:36:32,940 Lihatlah jenis s. Mari kita tambahkan * int, sehingga int * x. 469 00:36:32,940 --> 00:36:35,600 Saya akan melakukan malloc (sizeof (int)). 470 00:36:35,600 --> 00:36:40,490 Atau jika saya ingin sebuah array dari 5, saya akan lakukan (sizeof (int) * 5); 471 00:36:40,490 --> 00:36:44,210 Bagaimana jika saya memiliki ** int? 472 00:36:46,260 --> 00:36:49,140 Apa yang akan aku malloc? 473 00:36:49,140 --> 00:36:53,510 [Mahasiswa] Ukuran dari pointer. >> Ya. (Sizeof (int *)); 474 00:36:53,510 --> 00:36:56,960 Hal yang sama di sini. 475 00:36:56,960 --> 00:37:01,280 Saya ingin (sizeof (char *)); 476 00:37:06,170 --> 00:37:12,840 Ini akan mengalokasikan ruang untuk pointer yang menunjuk "BOOM". 477 00:37:12,840 --> 00:37:15,330 Saya tidak perlu mengalokasikan ruang untuk "BOOM" itu sendiri 478 00:37:15,330 --> 00:37:17,210 karena ini pada dasarnya setara dengan apa yang saya katakan sebelumnya 479 00:37:17,210 --> 00:37:20,870 char * x = "BOOM". 480 00:37:20,870 --> 00:37:27,950 "BOOM" sudah ada. Hal ini terjadi untuk ada di wilayah read-only memori. 481 00:37:27,950 --> 00:37:35,200 Tapi itu sudah ada, yang berarti baris kode ini, jika s adalah char **, 482 00:37:35,200 --> 00:37:43,900 maka * s adalah char * dan Anda menetapkan ini char * untuk menunjuk ke "BOOM". 483 00:37:43,900 --> 00:37:50,040 Jika saya ingin menyalin "BOOM" ke s, maka saya akan perlu untuk mengalokasikan ruang untuk s. 484 00:37:55,170 --> 00:38:03,900 Saya akan melakukan * s = malloc (sizeof (char) * 5); 485 00:38:03,900 --> 00:38:06,210 Kenapa 5? 486 00:38:06,210 --> 00:38:10,860 Mengapa tidak 4? Sepertinya "BOOM" adalah 4 karakter. >> [Mahasiswa] Karakter null. 487 00:38:10,860 --> 00:38:14,580 Ya. Semua string Anda akan membutuhkan karakter null. 488 00:38:14,580 --> 00:38:23,590 Sekarang aku bisa melakukan sesuatu seperti strcat - Apa fungsi untuk menyalin string? 489 00:38:23,590 --> 00:38:28,520 [Mahasiswa] cpy? >> Strcpy. 490 00:38:28,520 --> 00:38:32,700 man strcpy. 491 00:38:36,120 --> 00:38:39,590 Jadi strcpy atau strncpy. 492 00:38:39,590 --> 00:38:43,410 strncpy sedikit lebih aman karena Anda dapat menentukan dengan tepat berapa banyak karakter, 493 00:38:43,410 --> 00:38:46,190 tapi di sini tidak masalah karena kita tahu. 494 00:38:46,190 --> 00:38:50,340 Jadi strcpy dan terlihat dalam argumen. 495 00:38:50,340 --> 00:38:53,100 Argumen pertama adalah tujuan kami. 496 00:38:53,100 --> 00:38:56,770 Argumen kedua adalah sumber kami. 497 00:38:56,770 --> 00:39:10,310 Kita akan menyalin ke * tujuan kami s pointer "BOOM". 498 00:39:10,310 --> 00:39:19,820 Mengapa Anda ingin melakukan hal ini dengan strcpy bukan hanya apa yang kita miliki sebelumnya 499 00:39:19,820 --> 00:39:22,800 dari * s = "BOOM"? 500 00:39:22,800 --> 00:39:28,630 Ada alasan Anda mungkin ingin melakukan hal ini, tetapi apa alasan itu? 501 00:39:28,630 --> 00:39:31,940 [Mahasiswa] Jika Anda ingin mengubah sesuatu di "BOOM". >> Ya. 502 00:39:31,940 --> 00:39:37,950 Sekarang aku bisa melakukan sesuatu seperti s [0] = 'X'; 503 00:39:37,950 --> 00:39:48,190 karena poin s ke tumpukan dan ruang yang di heap bahwa s menunjuk ke 504 00:39:48,190 --> 00:39:52,320 adalah pointer ke lebih banyak ruang pada tumpukan, yang menyimpan "BOOM". 505 00:39:52,320 --> 00:39:55,150 Jadi ini salinan "BOOM" sedang disimpan di heap. 506 00:39:55,150 --> 00:39:58,780 Ada teknis dua salinan "BOOM" dalam program kami. 507 00:39:58,780 --> 00:40:03,500 Ada yang pertama yang baru saja diberikan oleh konstanta "BOOM" string, 508 00:40:03,500 --> 00:40:09,250 dan salinan kedua "BOOM", strcpy menciptakan salinan "BOOM". 509 00:40:09,250 --> 00:40:13,100 Namun salinan "BOOM" sedang disimpan di heap, dan tumpukan Anda bebas untuk mengubah. 510 00:40:13,100 --> 00:40:17,250 Tumpukan tidak read-only, sehingga berarti bahwa s [0] 511 00:40:17,250 --> 00:40:20,500 akan membiarkan Anda mengubah nilai "BOOM". 512 00:40:20,500 --> 00:40:23,130 Ini akan membiarkan Anda mengubah karakter tersebut. 513 00:40:23,130 --> 00:40:26,640 >> Pertanyaan? 514 00:40:27,740 --> 00:40:29,290 Oke. 515 00:40:29,290 --> 00:40:35,500 >> Pindah ke buggy3, mari kita gdb buggy3. 516 00:40:35,500 --> 00:40:39,840 Kami hanya menjalankannya dan kita melihat kita mendapatkan segfault. 517 00:40:39,840 --> 00:40:46,550 Jika kita backtrace, hanya ada dua fungsi. 518 00:40:46,550 --> 00:40:52,970 Jika kita naik ke fungsi utama kita, kita melihat bahwa kita segfaulted pada baris ini. 519 00:40:52,970 --> 00:41:00,180 Jadi hanya melihat baris ini, for (int baris = 0; fgets hal ini tidak NULL tidak sama; 520 00:41:00,180 --> 00:41:03,770 baris + +). 521 00:41:03,770 --> 00:41:08,010 Frame sebelumnya kami disebut _IO_fgets. 522 00:41:08,010 --> 00:41:10,720 Anda akan melihat bahwa banyak dengan built-in fungsi C, 523 00:41:10,720 --> 00:41:15,350 bahwa ketika Anda mendapatkan segfault, akan ada nama fungsi benar-benar samar 524 00:41:15,350 --> 00:41:18,090 seperti ini _IO_fgets. 525 00:41:18,090 --> 00:41:21,770 Tapi itu akan berhubungan dengan ini panggilan fgets. 526 00:41:21,770 --> 00:41:25,850 Suatu tempat di dalam sini, kita segfault. 527 00:41:25,850 --> 00:41:30,340 Jika kita melihat argumen untuk fgets, kita dapat mencetak penyangga. 528 00:41:30,340 --> 00:41:41,180 Mari kita cetak sebagai - Oh, tidak. 529 00:41:48,980 --> 00:41:51,900 Cetak tidak akan bekerja persis seperti yang saya inginkan. 530 00:41:55,460 --> 00:41:58,000 Mari kita lihat program yang sebenarnya. 531 00:42:02,200 --> 00:42:09,640 Buffer adalah array karakter. Ini adalah array karakter dari 128 karakter. 532 00:42:09,640 --> 00:42:14,980 Jadi ketika saya mengatakan buffer cetak, itu akan mencetak mereka 128 karakter, 533 00:42:14,980 --> 00:42:18,300 yang kurasa adalah apa yang diharapkan. 534 00:42:18,300 --> 00:42:21,390 Apa yang saya cari adalah mencetak alamat buffer, 535 00:42:21,390 --> 00:42:23,680 tapi itu tidak benar-benar memberitahu saya banyak. 536 00:42:23,680 --> 00:42:30,770 Jadi ketika saya kebetulan mengatakan di sini x penyangga, itu menunjukkan saya 0xbffff090, 537 00:42:30,770 --> 00:42:38,690 yang, jika Anda ingat dari sebelumnya atau beberapa titik, Oxbffff cenderung menjadi wilayah tumpukan-ish. 538 00:42:38,690 --> 00:42:46,020 Tumpukan cenderung untuk memulai suatu tempat hanya di bawah 0xc000. 539 00:42:46,020 --> 00:42:51,890 Hanya dengan melihat alamat ini, saya tahu bahwa buffer yang terjadi pada stack. 540 00:42:51,890 --> 00:43:04,500 Restart program saya, berlari, naik, penyangga kita lihat adalah ini urutan karakter 541 00:43:04,500 --> 00:43:06,530 yang cukup banyak berarti. 542 00:43:06,530 --> 00:43:12,270 Kemudian mencetak file, apakah file yang terlihat seperti? 543 00:43:15,120 --> 00:43:17,310 [Mahasiswa] Null. >> Ya. 544 00:43:17,310 --> 00:43:22,610 File adalah dari jenis * FILE, sehingga pointer, 545 00:43:22,610 --> 00:43:26,610 dan nilai dari pointer itu adalah nol. 546 00:43:26,610 --> 00:43:33,240 Jadi fgets akan mencoba untuk membaca dari pointer yang secara tidak langsung, 547 00:43:33,240 --> 00:43:37,320 tetapi untuk mengakses pointer itu, harus dereference itu. 548 00:43:37,320 --> 00:43:40,550 Atau, untuk mengakses apa yang harus menunjuk ke, itu dereferences itu. 549 00:43:40,550 --> 00:43:43,810 Jadi itu dereferencing pointer null dan segfaults. 550 00:43:46,600 --> 00:43:48,730 Saya bisa restart sana. 551 00:43:48,730 --> 00:43:52,170 Jika kita istirahat di titik utama kami dan menjalankan, 552 00:43:52,170 --> 00:43:57,320 baris pertama dari kode adalah char * filename = "nonexistent.txt"; 553 00:43:57,320 --> 00:44:00,870 Yang seharusnya memberikan petunjuk yang cukup besar seperti mengapa program ini gagal. 554 00:44:00,870 --> 00:44:06,080 Mengetik berikutnya membawa saya ke baris berikutnya, di mana saya membuka file ini, 555 00:44:06,080 --> 00:44:11,140 dan kemudian saya langsung masuk ke baris kami, di mana setelah saya tekan berikutnya, itu akan segfault. 556 00:44:11,140 --> 00:44:16,880 Apakah ada yang ingin membuang alasan mengapa kita mungkin segfault? 557 00:44:16,880 --> 00:44:19,130 [Mahasiswa] File tidak ada. >> Ya. 558 00:44:19,130 --> 00:44:22,250 Hal ini seharusnya menjadi petunjuk 559 00:44:22,250 --> 00:44:29,570 bahwa setiap kali Anda membuka file Anda perlu memeriksa bahwa file tersebut benar-benar ada. 560 00:44:29,570 --> 00:44:31,510 Jadi di sini, "nonexistent.txt"; 561 00:44:31,510 --> 00:44:34,700 Ketika kita fopen nama file untuk membaca, maka kita perlu untuk mengatakan 562 00:44:34,700 --> 00:44:45,870 jika (file == NULL) dan mengatakan printf ("File tidak ada!" 563 00:44:45,870 --> 00:44:56,340 atau - lebih baik lagi - filename); return 1; 564 00:44:56,340 --> 00:45:00,300 Jadi sekarang kita periksa untuk melihat apakah itu NULL 565 00:45:00,300 --> 00:45:03,930 sebelum benar-benar melanjutkan dan mencoba untuk membaca dari file tersebut. 566 00:45:03,930 --> 00:45:08,800 Kita bisa remake itu hanya untuk melihat bahwa bekerja. 567 00:45:11,020 --> 00:45:14,970 Saya berniat untuk memasukkan baris baru. 568 00:45:21,090 --> 00:45:25,290 Jadi sekarang nonexistent.txt tidak ada. 569 00:45:26,890 --> 00:45:30,040 Anda harus selalu memeriksa hal semacam ini. 570 00:45:30,040 --> 00:45:33,870 Anda harus selalu memeriksa untuk melihat apakah fopen mengembalikan NULL. 571 00:45:33,870 --> 00:45:38,170 Anda harus selalu memeriksa untuk memastikan bahwa malloc tidak mengembalikan NULL, 572 00:45:38,170 --> 00:45:41,410 atau Anda segfault. 573 00:45:42,200 --> 00:45:45,930 >> Sekarang buggy4.c. 574 00:45:49,190 --> 00:45:58,440 Menjalankan. Saya menduga ini sedang menunggu masukan atau looping kemungkinan tak terbatas. 575 00:45:58,440 --> 00:46:01,870 Ya, itu perulangan tak terbatas. 576 00:46:01,870 --> 00:46:05,560 Jadi buggy4. Sepertinya kita perulangan tak terbatas. 577 00:46:05,560 --> 00:46:12,590 Kita bisa istirahat di utama, menjalankan program kami. 578 00:46:12,590 --> 00:46:20,180 Dalam gdb, asalkan singkatan yang Anda gunakan adalah ambigu 579 00:46:20,180 --> 00:46:23,420 atau singkatan khusus yang mereka berikan untuk Anda, 580 00:46:23,420 --> 00:46:29,020 maka Anda dapat menggunakan n untuk menggunakan berikutnya daripada harus mengetikkan berikutnya sepanjang jalan. 581 00:46:29,020 --> 00:46:33,730 Dan sekarang aku sudah memukul n sekali, saya hanya bisa menekan Enter untuk terus berikutnya 582 00:46:33,730 --> 00:46:36,640 daripada harus memukul n Masukkan, n Masukkan, n Enter. 583 00:46:36,640 --> 00:46:44,630 Sepertinya aku dalam beberapa jenis untuk loop yang menetapkan array [i] ke 0. 584 00:46:44,630 --> 00:46:50,510 Sepertinya saya tidak pernah melanggar keluar dari ini untuk loop. 585 00:46:50,510 --> 00:46:54,780 Jika saya mencetak i, jadi saya adalah 2, maka saya akan pergi berikutnya. 586 00:46:54,780 --> 00:46:59,250 Saya akan mencetak i, i adalah 3, maka saya akan pergi berikutnya. 587 00:46:59,250 --> 00:47:05,360 Saya akan mencetak i dan i adalah 3. Selanjutnya, cetak i, i adalah 4. 588 00:47:05,360 --> 00:47:14,520 Sebenarnya, cetak sizeof (array), sehingga ukuran dari array adalah 20. 589 00:47:16,310 --> 00:47:32,870 Tapi sepertinya ada beberapa perintah gdb khusus untuk pergi sampai sesuatu terjadi. 590 00:47:32,870 --> 00:47:37,620 Ini seperti pengaturan kondisi pada nilai variabel. Tapi aku tidak ingat apa itu. 591 00:47:37,620 --> 00:47:44,100 Jadi jika kita terus - 592 00:47:44,100 --> 00:47:47,120 Apa yang kau katakan? Apa yang Anda membawa? 593 00:47:47,120 --> 00:47:50,500 [Mahasiswa] Apakah menampilkan saya menambahkan - >> Ya. Jadi menampilkan saya dapat membantu. 594 00:47:50,500 --> 00:47:54,530 Jika kita hanya sekedar menampilkan i, itu akan disiapkan di sini apa nilai i adalah 595 00:47:54,530 --> 00:47:56,470 jadi saya tidak perlu mencetaknya setiap kali. 596 00:47:56,470 --> 00:48:02,930 Jika kita hanya terus berikutnya, kita melihat 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5. 597 00:48:02,930 --> 00:48:08,530 Sesuatu akan beres, dan saya sedang reset ke 0. 598 00:48:13,330 --> 00:48:22,220 Melihat buggy4.c, kita melihat semua yang terjadi adalah array int [5]; 599 00:48:22,220 --> 00:48:26,200 untuk (i = 0; i <= sizeof (array); i + +) 600 00:48:26,200 --> 00:48:28,550 array [i] = 0; 601 00:48:28,550 --> 00:48:31,390 Apa yang kita lihat itu salah di sini? 602 00:48:31,390 --> 00:48:39,480 Sebagai petunjuk, ketika saya sedang melakukan gdb buggy4 - mari kita istirahat utama, run - 603 00:48:39,480 --> 00:48:45,980 Aku cetak sizeof (array) hanya untuk melihat apa kondisi adalah di mana saya akhirnya harus keluar. 604 00:48:47,690 --> 00:48:51,100 Dimana saya? Apakah saya lari? 605 00:48:51,100 --> 00:48:54,280 Saya tidak menyatakan belum. 606 00:48:54,280 --> 00:48:58,680 Jadi mencetak sizeof (array) dan itu 20, 607 00:48:58,680 --> 00:49:06,690 yang diharapkan karena array saya adalah ukuran 5 dan itu dari 5 bilangan bulat, 608 00:49:06,690 --> 00:49:12,410 sehingga seluruh hal harus 5 * sizeof (int) byte, di mana sizeof (int) cenderung 4. 609 00:49:12,410 --> 00:49:14,780 Jadi sizeof (array) adalah 20. 610 00:49:14,780 --> 00:49:17,420 Apa yang harus begini? 611 00:49:17,420 --> 00:49:21,720 [Mahasiswa] Dibagi dengan sizeof (int). >> Ya, / sizeof (int). 612 00:49:21,720 --> 00:49:30,630 Sepertinya masih ada masalah di sini. Saya pikir ini hanya harus < 613 00:49:30,630 --> 00:49:36,960 karena cukup banyak selalu 00:49:44,860 Sekarang mari kita berpikir tentang mengapa ini benar-benar rusak. 615 00:49:44,860 --> 00:49:53,370 Apakah ada yang telah menebak mengapa saya reset ke 0 melalui setiap iterasi dari loop? 616 00:50:01,300 --> 00:50:09,350 Satu-satunya hal dalam sini yang terjadi adalah bahwa array [i] sedang diatur ke 0. 617 00:50:09,350 --> 00:50:15,350 Jadi entah bagaimana, ini baris kode yang menyebabkan int i kami harus diatur ke 0. 618 00:50:16,730 --> 00:50:23,130 [Mahasiswa] Mungkinkah karena itu menimpa memori ini bagian dari saya 619 00:50:23,130 --> 00:50:27,970 ketika berpikir itu adalah elemen berikutnya dari array? >> [Bowden] Ya. 620 00:50:27,970 --> 00:50:33,880 Ketika kita akan melampaui akhir array kita, 621 00:50:33,880 --> 00:50:39,870 entah itu ruang yang kita override adalah mengesampingkan nilai i. 622 00:50:39,870 --> 00:50:48,030 Dan jadi jika kita melihat ke buggy4, istirahat utama, run, 623 00:50:48,030 --> 00:50:53,120 mari kita mencetak alamat dari i. 624 00:50:53,120 --> 00:50:57,280 Sepertinya itu bffff124. 625 00:50:57,280 --> 00:51:03,930 Sekarang mari kita mencetak alamat array [0]. 110. 626 00:51:03,930 --> 00:51:06,290 Bagaimana [1]? 114. 627 00:51:06,290 --> 00:51:07,920 [2], 118. 628 00:51:07,920 --> 00:51:14,530 11c, 120. array [5] adalah bfff124. 629 00:51:14,530 --> 00:51:26,990 Jadi array [5] memiliki alamat yang sama seperti saya, yang berarti bahwa array [5] adalah i. 630 00:51:26,990 --> 00:51:30,720 Jika mereka memiliki alamat yang sama, mereka adalah hal yang sama. 631 00:51:30,720 --> 00:51:38,410 Jadi ketika kita menetapkan array [5] ke 0, kita menetapkan saya ke 0. 632 00:51:38,410 --> 00:51:46,070 Dan jika Anda berpikir tentang hal ini dalam hal stack, 633 00:51:46,070 --> 00:51:55,590 int i dinyatakan pertama, yang berarti saya mendapatkan beberapa ruang pada stack. 634 00:51:55,590 --> 00:52:04,730 Kemudian array [5] dialokasikan, sehingga kemudian 20 byte dialokasikan pada stack. 635 00:52:04,730 --> 00:52:08,400 Jadi saya akan dialokasikan terlebih dahulu, maka 20 byte mendapatkan dialokasikan. 636 00:52:08,400 --> 00:52:11,400 Jadi saya terjadi tepat sebelum array, 637 00:52:11,400 --> 00:52:19,230 dan karena cara, seperti saya katakan pekan lalu, di mana secara teknis stack tumbuh ke bawah, 638 00:52:19,230 --> 00:52:28,520 ketika Anda indeks ke dalam array, kita dijamin bahwa posisi 0 dalam array 639 00:52:28,520 --> 00:52:31,970 selalu terjadi sebelum posisi pertama dalam array. 640 00:52:31,970 --> 00:52:35,900 Ini adalah jenis bagaimana saya menarik minggu lalu. 641 00:52:35,900 --> 00:52:42,210 Perhatikan bahwa di bagian bawah kita memiliki alamat 0 dan di atas kita memiliki alamat Max. 642 00:52:42,210 --> 00:52:44,880 Tumpukan selalu tumbuh ke bawah. 643 00:52:48,100 --> 00:52:53,500 Katakanlah kita mengalokasikan i. 644 00:52:53,500 --> 00:52:59,680 Kami mengalokasikan bilangan bulat i, yang berarti mari kita katakan saja di sini bilangan bulat i akan dialokasikan. 645 00:52:59,680 --> 00:53:06,420 Kemudian kita mengalokasikan array kita dari 5 bilangan bulat, yang berarti bahwa di balik itu, 646 00:53:06,420 --> 00:53:11,230 karena tumpukan tumbuh ke bawah, mereka 5 bilangan bulat mendapatkan dialokasikan. 647 00:53:11,230 --> 00:53:15,900 Tapi karena cara array bekerja, kita dijamin bahwa posisi pertama dalam array 648 00:53:15,900 --> 00:53:22,260 selalu memiliki alamat kurang dari hal kedua dalam array. 649 00:53:22,260 --> 00:53:28,270 Jadi Array 0 posisi selalu terjadi pertama dalam memori, 650 00:53:28,270 --> 00:53:30,700 sedangkan array posisi 1 harus terjadi setelah itu 651 00:53:30,700 --> 00:53:33,310 dan array posisi 2 harus terjadi setelah itu, 652 00:53:33,310 --> 00:53:37,900 yang berarti bahwa 0 posisi array yang akan terjadi di suatu tempat di sini, 653 00:53:37,900 --> 00:53:40,690 array posisi 1 akan terjadi di atas bahwa 654 00:53:40,690 --> 00:53:45,530 karena bergerak naik lebih tinggi berarti alamat karena alamat maksimal di sini. 655 00:53:45,530 --> 00:53:50,490 Jadi array [0] di sini, array [1] di sini, array [2] di sini, array [3] di sini. 656 00:53:50,490 --> 00:53:55,620 Perhatikan bagaimana sebelum kita dialokasikan bulat i semua jalan di sini, 657 00:53:55,620 --> 00:54:01,040 seperti yang kita bergerak semakin jauh ke dalam array kita, kita semakin dekat dan lebih dekat ke integer kami i. 658 00:54:01,040 --> 00:54:07,640 Kebetulan array [5], yang merupakan salah satu posisi di luar array kita, 659 00:54:07,640 --> 00:54:13,010 adalah persis di mana bilangan bulat saya kebetulan dialokasikan. 660 00:54:13,010 --> 00:54:16,920 Jadi itulah titik di mana kita kebetulan memukul ruang pada stack 661 00:54:16,920 --> 00:54:21,680 yang dialokasikan untuk integer i, dan kami sedang menyiapkan bahwa untuk 0. 662 00:54:21,680 --> 00:54:26,160 >> Itulah cara yang bekerja. Pertanyaan? Ya. 663 00:54:26,160 --> 00:54:30,710 [Mahasiswa] Sudahlah. Oke. 664 00:54:30,710 --> 00:54:33,090 [Mahasiswa] Bagaimana Anda menghindari kesalahan semacam ini? 665 00:54:33,090 --> 00:54:41,190 Ini semacam kesalahan? Jangan menggunakan C sebagai bahasa pemrograman Anda. 666 00:54:41,190 --> 00:54:45,840 Gunakan bahasa yang memiliki batas array memeriksa. 667 00:54:45,840 --> 00:54:55,900 Selama Anda berhati-hati, Anda hanya perlu menghindari pergi melewati batas-batas array Anda. 668 00:54:55,900 --> 00:54:58,300 [Mahasiswa] Jadi di sini ketika kami pergi melewati batas-batas array Anda - 669 00:54:58,300 --> 00:55:01,840 [Bowden] situlah sesuatu mulai tidak beres. >> [Mahasiswa] Oh, oke. 670 00:55:01,840 --> 00:55:05,730 Selama Anda tinggal di dalam memori dialokasikan untuk array Anda, Anda baik-baik saja. 671 00:55:05,730 --> 00:55:12,400 Tapi C tidak melakukan pengecekan error. Jika saya melakukan array [1000], dengan senang hati akan hanya memodifikasi apapun yang terjadi - 672 00:55:12,400 --> 00:55:16,500 It goes ke awal array, kemudian pergi setelah posisi 1.000 dan set ke 0. 673 00:55:16,500 --> 00:55:20,000 Ia tidak melakukan pengecekan bahwa oh, ini tidak benar-benar memiliki 1000 hal di dalamnya. 674 00:55:20,000 --> 00:55:22,750 1000 adalah jauh melampaui apa yang saya harus berubah, 675 00:55:22,750 --> 00:55:26,940 sedangkan Jawa atau sesuatu yang Anda akan mendapatkan berbagai keluar dari indeks batas 676 00:55:26,940 --> 00:55:29,820 atau indeks keluar dari pengecualian batas. 677 00:55:29,820 --> 00:55:33,950 Itu sebabnya banyak bahasa tingkat tinggi memiliki hal-hal 678 00:55:33,950 --> 00:55:37,340 di mana jika Anda melampaui batas-batas array, Anda gagal 679 00:55:37,340 --> 00:55:40,070 sehingga Anda tidak bisa mengubah hal-hal dari bawah Anda 680 00:55:40,070 --> 00:55:42,590 dan kemudian hal-hal pergi jauh lebih buruk daripada hanya mendapatkan pengecualian 681 00:55:42,590 --> 00:55:44,940 mengatakan bahwa Anda melampaui akhir array. 682 00:55:44,940 --> 00:55:50,970 [Mahasiswa] Dan harus kita baru saja mengubah <= hanya > [Bowden] Ya. 683 00:55:50,970 --> 00:55:54,800 Ini harus 00:55:59,560 sejak sizeof (array) adalah 20, tapi kami hanya ingin 5. >> [Mahasiswa] Kanan. 685 00:55:59,560 --> 00:56:04,060 Lebih banyak pertanyaan? Oke. 686 00:56:04,060 --> 00:56:07,380 >> [Mahasiswa] Saya punya pertanyaan. >> Ya. 687 00:56:07,380 --> 00:56:16,440 [Mahasiswa] Apa variabel array yang sebenarnya? 688 00:56:16,440 --> 00:56:20,000 [Bowden] Seperti apa adalah array? 689 00:56:20,000 --> 00:56:24,930 Array itu sendiri adalah simbol. 690 00:56:24,930 --> 00:56:31,490 Ini hanya alamat awal 20 byte yang kita referensi. 691 00:56:31,490 --> 00:56:38,070 Anda dapat menganggapnya sebagai pointer, tetapi pointer konstan. 692 00:56:38,070 --> 00:56:44,140 Segera setelah hal mendapatkan dikompilasi, array variabel tidak ada lagi. 693 00:56:44,140 --> 00:56:48,210 [Mahasiswa] Jadi bagaimana cara menemukan ukuran array? 694 00:56:48,210 --> 00:56:54,130 Ukuran array mengacu pada ukuran blok bahwa simbol yang mengacu pada. 695 00:56:54,130 --> 00:57:01,240 Ketika saya melakukan sesuatu seperti printf ("% p \ n", array); 696 00:57:01,240 --> 00:57:05,140 mari kita menjalankannya. 697 00:57:12,960 --> 00:57:15,530 Apa yang saya lakukan salah? 698 00:57:15,530 --> 00:57:19,220 'Array' Array dideklarasikan di sini. 699 00:57:20,820 --> 00:57:23,200 Oh, di sini. 700 00:57:23,200 --> 00:57:31,250 Clang pintar, dan hal itu terjadi untuk melihat bahwa saya menyatakan array sebagai elemen 5 701 00:57:31,250 --> 00:57:34,540 tapi aku mengindeks ke posisi 1000. 702 00:57:34,540 --> 00:57:38,450 Hal ini dapat melakukan hal itu karena ini hanya konstanta. 703 00:57:38,450 --> 00:57:43,370 Ini hanya bisa pergi sejauh ini menyadari bahwa aku akan melampaui batas-batas array. 704 00:57:43,370 --> 00:57:46,880 Tapi perhatikan sebelum ketika kami memiliki saya tidak benar, 705 00:57:46,880 --> 00:57:51,040 itu tidak mungkin menentukan berapa banyak nilai-nilai saya bisa mengambil, 706 00:57:51,040 --> 00:57:55,540 sehingga tidak dapat menentukan bahwa saya akan melampaui akhir array. 707 00:57:55,540 --> 00:57:59,430 Itu hanya dentang menjadi pintar. 708 00:57:59,430 --> 00:58:03,340 >> Tapi sekarang membuat buggy4. Jadi apa lagi yang saya lakukan salah? 709 00:58:03,340 --> 00:58:05,970 Secara implisit menyatakan fungsi perpustakaan 'printf'. 710 00:58:05,970 --> 00:58:14,960 Aku akan ingin # include. 711 00:58:14,960 --> 00:58:18,710 Oke. Sekarang berjalan buggy4. 712 00:58:18,710 --> 00:58:24,840 Mencetak nilai dari array seperti yang kulakukan di sini, mencetaknya sebagai pointer 713 00:58:24,840 --> 00:58:30,060 cetakan sesuatu yang tampak seperti ini - bfb8805c - yang adalah alamat beberapa 714 00:58:30,060 --> 00:58:33,450 itu di wilayah tumpukan-ish. 715 00:58:33,450 --> 00:58:41,820 Array itu sendiri adalah seperti pointer, tetapi bukan merupakan pointer yang sebenarnya, 716 00:58:41,820 --> 00:58:45,410 sejak pointer biasa kita dapat berubah. 717 00:58:45,410 --> 00:58:54,700 Array adalah hanya beberapa konstan. The 20 blok memori mulai dari alamat 0xbfb8805c. 718 00:58:54,700 --> 00:59:09,020 Jadi bfb8805c melalui alamat ini +20--atau saya kira -20 - 719 00:59:09,020 --> 00:59:17,400 adalah semua memori dialokasikan untuk array ini. 720 00:59:17,400 --> 00:59:20,350 Array, variabel itu sendiri tidak disimpan di mana saja. 721 00:59:20,350 --> 00:59:27,660 Bila Anda kompilasi, compiler - tangan gelombang pada itu - 722 00:59:27,660 --> 00:59:33,060 tapi compiler hanya akan menggunakan mana tahu array untuk menjadi. 723 00:59:33,060 --> 00:59:36,090 Ia tahu di mana array dimulai, 724 00:59:36,090 --> 00:59:40,910 dan sehingga dapat selalu saja melakukan hal-hal dalam hal offset dari awal itu. 725 00:59:40,910 --> 00:59:43,960 Itu tidak membutuhkan variabel itu sendiri untuk mewakili array. 726 00:59:43,960 --> 00:59:53,730 Tapi ketika saya melakukan sesuatu seperti int * p = Array, sekarang p adalah pointer yang menunjuk ke array, 727 00:59:53,730 --> 00:59:57,830 dan sekarang p sebenarnya tidak ada di stack. 728 00:59:57,830 --> 01:00:01,950 Aku bebas untuk mengubah p. Aku bisa melakukan p = malloc. 729 01:00:01,950 --> 01:00:06,500 Jadi awalnya menunjuk ke array, sekarang menunjuk ke beberapa ruang di heap. 730 01:00:06,500 --> 01:00:09,620 Saya tidak bisa melakukan berbagai malloc =. 731 01:00:09,620 --> 01:00:13,710 Jika dentang pintar, ia akan berteriak padaku langsung dari kelelawar. 732 01:00:17,000 --> 01:00:21,430 Sebenarnya, aku cukup yakin gcc akan melakukan hal ini juga. 733 01:00:21,430 --> 01:00:25,010 Jadi tipe array 'int [5]' tidak dialihkan. 734 01:00:25,010 --> 01:00:28,040 Anda tidak dapat menetapkan sesuatu ke sebuah tipe array 735 01:00:28,040 --> 01:00:30,500 karena array hanyalah sebuah konstanta. 736 01:00:30,500 --> 01:00:34,760 Ini adalah simbol yang referensi yang 20 byte. Aku tidak bisa mengubahnya. 737 01:00:34,760 --> 01:00:37,690 >> [Mahasiswa] Dan di mana ukuran dari array disimpan? 738 01:00:37,690 --> 01:00:40,670 [Bowden] Ini tidak disimpan di mana saja. Justru ketika itu kompilasi. 739 01:00:40,670 --> 01:00:46,310 Jadi mana ukuran array disimpan? 740 01:00:46,310 --> 01:00:51,870 Anda hanya dapat menggunakan sizeof (array) dalam fungsi yang array dideklarasikan sendiri. 741 01:00:51,870 --> 01:01:03,150 Jadi jika saya melakukan beberapa fungsi, foo, dan saya lakukan (int array []) 742 01:01:03,150 --> 01:01:10,450 printf ("% d \ n", sizeof (array)); 743 01:01:10,450 --> 01:01:21,330 dan kemudian di sini saya sebut foo (array); 744 01:01:21,330 --> 01:01:24,840 dalam fungsi ini - mari kita menjalankannya. 745 01:01:34,200 --> 01:01:36,840 Ini adalah dentang menjadi pintar lagi. 746 01:01:36,840 --> 01:01:43,890 Ia memberi tahu saya bahwa sizeof pada parameter array fungsi 747 01:01:43,890 --> 01:01:46,690 akan kembali ukuran '* int'. 748 01:01:46,690 --> 01:01:55,150 Ini akan menjadi kesalahan jika itu bukan apa yang saya inginkan untuk terjadi. 749 01:01:55,150 --> 01:01:58,960 Mari kita benar-benar mematikan Werror. 750 01:02:14,950 --> 01:02:17,590 Peringatan. Peringatan baik-baik saja. 751 01:02:17,590 --> 01:02:19,960 Ini masih akan mengkompilasi asalkan memiliki peringatan. 752 01:02:19,960 --> 01:02:22,910 . / A.out akan mencetak 4. 753 01:02:22,910 --> 01:02:28,650 Peringatan yang dihasilkan merupakan indikator yang jelas tentang apa yang salah. 754 01:02:28,650 --> 01:02:34,120 Ini array int hanya akan mencetak sizeof (int *). 755 01:02:34,120 --> 01:02:39,790 Bahkan jika saya menempatkan array [5] di sini, itu masih hanya akan mencetak sizeof (int *). 756 01:02:39,790 --> 01:02:47,440 Jadi segera setelah Anda lulus ke fungsi, perbedaan antara array dan pointer 757 01:02:47,440 --> 01:02:49,670 tidak ada. 758 01:02:49,670 --> 01:02:52,640 Hal ini terjadi untuk menjadi sebuah array yang dideklarasikan pada stack, 759 01:02:52,640 --> 01:02:58,300 tetapi segera setelah kami melewati nilai tersebut, bahwa 0xBF bla, bla, bla ke dalam fungsi ini, 760 01:02:58,300 --> 01:03:03,350 maka pointer ini menunjuk ke array di stack. 761 01:03:03,350 --> 01:03:08,310 Jadi itu berarti bahwa sizeof hanya berlaku dalam fungsi yang array dideklarasikan, 762 01:03:08,310 --> 01:03:11,230 yang berarti bahwa ketika Anda melakukan compile fungsi ini, 763 01:03:11,230 --> 01:03:17,330 ketika dentang berjalan melalui fungsi ini, ia melihat array adalah array int ukuran 5. 764 01:03:17,330 --> 01:03:20,640 Jadi itu melihat sizeof (array). Nah, itu 20. 765 01:03:20,640 --> 01:03:26,440 Itu sebenarnya bagaimana sizeof pada dasarnya bekerja untuk hampir semua kasus. 766 01:03:26,440 --> 01:03:31,150 Sizeof bukan fungsi, melainkan operator. 767 01:03:31,150 --> 01:03:33,570 Anda tidak memanggil fungsi sizeof. 768 01:03:33,570 --> 01:03:38,280 Sizeof (int), compiler hanya akan menerjemahkan ke 4. 769 01:03:41,480 --> 01:03:43,700 Got it? Oke. 770 01:03:43,700 --> 01:03:47,520 >> [Mahasiswa] Jadi apa perbedaan antara sizeof (array) di utama dan di foo? 771 01:03:47,520 --> 01:03:52,840 Ini karena kita katakan sizeof (array), yang adalah tipe int *, 772 01:03:52,840 --> 01:03:57,120 sedangkan array di sini adalah bukan dari * tipe int, itu sebuah array int. 773 01:03:57,120 --> 01:04:04,540 >> [Mahasiswa] Jadi jika Anda memiliki parameter dalam array [] bukan array * int, 774 01:04:04,540 --> 01:04:09,230 akan itu berarti bahwa Anda masih bisa mengubah berbagai karena sekarang itu pointer? 775 01:04:09,230 --> 01:04:14,250 [Bowden] Seperti ini? >> [Mahasiswa] Ya. Dapatkah Anda mengubah susunan dalam fungsi sekarang? 776 01:04:14,250 --> 01:04:18,420 [Bowden] Anda bisa mengubah array dalam kedua kasus. 777 01:04:18,420 --> 01:04:23,130 Dalam kedua kasus, Anda bebas untuk mengatakan array [4] = 0. 778 01:04:23,130 --> 01:04:26,590 [Mahasiswa] Tapi Anda bisa membuat titik array ke sesuatu yang lain? 779 01:04:26,590 --> 01:04:30,230 [Bowden] Oh. Ya. Dalam kedua kasus - >> [mahasiswa] Ya. 780 01:04:30,230 --> 01:04:38,410 [Bowden] Perbedaan antara array [] dan sebuah array int *, tidak ada. 781 01:04:38,410 --> 01:04:42,570 Anda juga bisa mendapatkan beberapa array multidimensi di sini 782 01:04:42,570 --> 01:04:47,050 untuk beberapa sintaks yang nyaman, tapi masih hanya pointer. 783 01:04:47,050 --> 01:04:56,400 Ini berarti bahwa saya bebas untuk melakukan array = malloc (sizeof (int)), dan sekarang menunjukkan di tempat lain. 784 01:04:56,400 --> 01:04:59,610 Tapi seperti bagaimana ini bekerja selamanya dan selalu, 785 01:04:59,610 --> 01:05:03,210 mengubah array ini dengan membuatnya menunjuk ke sesuatu yang lain 786 01:05:03,210 --> 01:05:07,570 tidak mengubah array ini di sini karena salinan argumen, 787 01:05:07,570 --> 01:05:10,780 itu bukan pointer ke argumen itu. 788 01:05:10,780 --> 01:05:16,070 Dan sebenarnya, seperti indikasi lagi bahwa itu persis sama - 789 01:05:16,070 --> 01:05:21,100 kita sudah melihat cetakan pencetakan apa yang array - 790 01:05:21,100 --> 01:05:31,410 bagaimana kalau kita mencetak alamat dari array atau alamat dari alamat dari array 791 01:05:31,410 --> 01:05:36,290 ke salah dari mereka? 792 01:05:41,770 --> 01:05:45,220 Mari kita mengabaikan satu ini. 793 01:05:48,140 --> 01:05:51,660 Oke. Ini baik-baik saja. Ini sekarang berjalan / a.out.. 794 01:05:51,660 --> 01:06:00,220 Array Printing, kemudian mencetak alamat dari array, adalah hal yang sama. 795 01:06:00,220 --> 01:06:02,870 Array hanya tidak ada. 796 01:06:02,870 --> 01:06:08,190 Ia tahu ketika Anda mencetak array, Anda mencetak simbol yang mengacu pada 20 byte. 797 01:06:08,190 --> 01:06:11,940 Mencetak alamat array, baik, array tidak ada. 798 01:06:11,940 --> 01:06:17,200 Ia tidak memiliki alamat, sehingga hanya mencetak alamat tersebut 20 byte. 799 01:06:20,820 --> 01:06:28,150 Segera setelah Anda mengkompilasi bawah, seperti di buggy4 Anda dikompilasi / a.out., 800 01:06:28,150 --> 01:06:30,340 array tidak ada. 801 01:06:30,340 --> 01:06:33,640 Pointer ada. Array tidak. 802 01:06:34,300 --> 01:06:38,060 Blok memori yang mewakili array masih ada, 803 01:06:38,060 --> 01:06:43,270 tetapi variabel array dan variabel jenis yang tidak ada. 804 01:06:46,260 --> 01:06:50,270 Mereka adalah seperti perbedaan utama antara array dan pointer 805 01:06:50,270 --> 01:06:55,590 adalah sebagai segera setelah Anda membuat panggilan fungsi, tidak ada perbedaan. 806 01:06:55,590 --> 01:07:00,460 Namun dalam fungsi bahwa array itu sendiri dinyatakan, sizeof bekerja secara berbeda 807 01:07:00,460 --> 01:07:05,190 karena Anda mencetak ukuran blok bukan ukuran jenis, 808 01:07:05,190 --> 01:07:08,950 dan Anda tidak bisa mengubahnya karena itu simbol. 809 01:07:08,950 --> 01:07:14,370 Mencetak hal dan alamat dari hal yang mencetak hal yang sama. 810 01:07:14,370 --> 01:07:18,480 Dan itu cukup banyak itu. 811 01:07:18,480 --> 01:07:20,820 [Mahasiswa] Bisakah Anda mengatakan bahwa sekali lagi? 812 01:07:21,170 --> 01:07:24,170 Saya mungkin telah melewatkan sesuatu. 813 01:07:24,170 --> 01:07:29,260 Percetakan array dan alamat array mencetak hal yang sama, 814 01:07:29,260 --> 01:07:33,180 sedangkan jika Anda mencetak pointer versus alamat pointer, 815 01:07:33,180 --> 01:07:36,010 satu hal mencetak alamat dari apa yang Anda menunjuk ke, 816 01:07:36,010 --> 01:07:40,360 yang lain mencetak alamat dari pointer pada stack. 817 01:07:40,360 --> 01:07:47,040 Anda dapat mengubah pointer, Anda tidak dapat mengubah simbol array. 818 01:07:47,740 --> 01:07:53,270 Dan pointer sizeof akan mencetak ukuran jenis pointer. 819 01:07:53,270 --> 01:07:57,470 Jadi int * p sizeof (p) akan mencetak 4, 820 01:07:57,470 --> 01:08:04,110 tapi int array [5] cetak sizeof (array) akan mencetak 20. 821 01:08:04,110 --> 01:08:07,480 [Mahasiswa] Jadi int array [5] akan mencetak 20? >> Ya. 822 01:08:07,480 --> 01:08:13,300 Itulah sebabnya dalam buggy4 ketika digunakan untuk menjadi sizeof (array) 823 01:08:13,300 --> 01:08:16,660 ini melakukan i <20, yang tidak apa yang kita inginkan. 824 01:08:16,660 --> 01:08:20,880 Kami ingin i <5. >> [Mahasiswa] Oke. 825 01:08:20,880 --> 01:08:25,569 [Bowden] Dan kemudian segera setelah Anda mulai melewati dalam fungsi, 826 01:08:25,569 --> 01:08:34,340 jika kita melakukan int * p = array; 827 01:08:34,340 --> 01:08:39,779 dalam fungsi ini, pada dasarnya kita dapat menggunakan p dan array yang persis dengan cara yang sama, 828 01:08:39,779 --> 01:08:43,710 kecuali untuk masalah sizeof dan masalah perubahan. 829 01:08:43,710 --> 01:08:49,810 Tapi p [0] = 1; adalah sama dengan mengatakan array [0] = 1; 830 01:08:49,810 --> 01:08:55,600 Dan segera setelah kami katakan foo (array), atau foo (p); 831 01:08:55,600 --> 01:08:59,760 dalam fungsi foo, ini adalah panggilan yang sama dua kali. 832 01:08:59,760 --> 01:09:03,350 Tidak ada perbedaan antara kedua panggilan. 833 01:09:07,029 --> 01:09:11,080 >> Baik pada semua orang? Oke. 834 01:09:14,620 --> 01:09:17,950 Kami memiliki 10 menit. 835 01:09:17,950 --> 01:09:28,319 >> Kami akan mencoba untuk mendapatkan melalui program typer Hacker, 836 01:09:28,319 --> 01:09:32,350 website ini, yang keluar tahun lalu atau sesuatu. 837 01:09:34,149 --> 01:09:41,100 Hanya saja seharusnya seperti Anda mengetik secara acak dan mencetak - 838 01:09:41,100 --> 01:09:46,729 Apapun file itu terjadi telah dimuat adalah apa yang tampak seperti Anda sedang mengetik. 839 01:09:46,729 --> 01:09:52,069 Sepertinya semacam kode sistem operasi. 840 01:09:53,760 --> 01:09:56,890 Itu yang kita ingin menerapkan. 841 01:10:08,560 --> 01:10:11,690 Anda harus memiliki executable biner bernama hacker_typer 842 01:10:11,690 --> 01:10:14,350 yang mengambil dalam satu argumen, file tersebut ke "jenis hacker." 843 01:10:14,350 --> 01:10:16,480 Menjalankan eksekusi harus menghapus layar 844 01:10:16,480 --> 01:10:20,850 dan kemudian mencetak satu karakter dari file berlalu-in setiap kali pengguna menekan tombol. 845 01:10:20,850 --> 01:10:24,990 Jadi apapun yang Anda menekan tombol, harus membuang dan bukannya mencetak karakter dari file 846 01:10:24,990 --> 01:10:27,810 itu adalah argumen. 847 01:10:29,880 --> 01:10:34,350 Aku akan cukup banyak memberitahu Anda apa hal-hal yang kita akan perlu tahu adalah. 848 01:10:34,350 --> 01:10:36,440 Tapi kami ingin memeriksa perpustakaan termios. 849 01:10:36,440 --> 01:10:44,840 Saya tidak pernah menggunakan perpustakaan ini sepanjang hidup saya, sehingga memiliki tujuan yang sangat minim. 850 01:10:44,840 --> 01:10:48,610 Tapi ini akan menjadi perpustakaan bisa kita gunakan untuk membuang karakter anda menekan 851 01:10:48,610 --> 01:10:52,390 ketika Anda mengetik ke standar masuk 852 01:10:56,970 --> 01:11:05,840 Jadi hacker_typer.c, dan kita akan ingin # include. 853 01:11:05,840 --> 01:11:12,870 Melihat halaman manual untuk termios - aku menebak terminal itu OS atau sesuatu - 854 01:11:12,870 --> 01:11:16,240 Saya tidak tahu bagaimana membacanya. 855 01:11:16,240 --> 01:11:21,040 Melihat hal ini, ia mengatakan untuk menyertakan 2 file, jadi kita akan melakukan itu. 856 01:11:37,620 --> 01:11:46,820 >> Hal pertama yang pertama, kami ingin mengambil satu argumen, yang merupakan file kita harus membuka. 857 01:11:46,820 --> 01:11:52,420 Jadi apa yang saya ingin lakukan? Bagaimana cara memeriksa untuk melihat saya memiliki satu argumen? 858 01:11:52,420 --> 01:11:56,480 [Mahasiswa] Jika argc sama itu. >> [Bowden] Ya. 859 01:11:56,480 --> 01:12:21,250 Jadi, jika (argc = 2!) Printf ("penggunaan:% s [file untuk membuka]"). 860 01:12:21,250 --> 01:12:32,750 Jadi sekarang jika saya menjalankan ini tanpa memberikan argumen kedua - oh, saya memerlukan baris baru - 861 01:12:32,750 --> 01:12:36,240 Anda akan melihat ia mengatakan penggunaan: / hacker_typer,. 862 01:12:36,240 --> 01:12:39,770 dan kemudian argumen kedua harus file saya ingin membuka. 863 01:12:58,430 --> 01:13:01,260 Sekarang apa yang harus saya lakukan? 864 01:13:01,260 --> 01:13:08,490 Saya ingin membaca dari file ini. Bagaimana cara membaca dari file? 865 01:13:08,490 --> 01:13:11,920 [Mahasiswa] Anda membukanya terlebih dahulu. >> Ya. 866 01:13:11,920 --> 01:13:15,010 Jadi fopen. Apa fopen terlihat seperti? 867 01:13:15,010 --> 01:13:22,980 [Mahasiswa] Filename. >> [Bowden] Nama file akan menjadi argv [1]. 868 01:13:22,980 --> 01:13:26,110 [Mahasiswa] Dan kemudian apa yang ingin Anda lakukan dengan itu, sehingga - >> [Bowden] Ya. 869 01:13:26,110 --> 01:13:28,740 Jadi jika Anda tidak ingat, Anda hanya bisa melakukan fopen man, 870 01:13:28,740 --> 01:13:32,960 di mana itu akan menjadi jalur * const char mana jalan adalah nama file, 871 01:13:32,960 --> 01:13:34,970 const * modus char. 872 01:13:34,970 --> 01:13:38,660 Jika Anda kebetulan tidak ingat apa modus ini, maka Anda dapat mencari modus. 873 01:13:38,660 --> 01:13:44,660 Di dalam halaman manual, karakter garis miring adalah apa yang dapat Anda gunakan untuk mencari sesuatu. 874 01:13:44,660 --> 01:13:49,790 Jadi saya ketik / modus untuk mencari modus. 875 01:13:49,790 --> 01:13:57,130 n dan N adalah apa yang dapat Anda gunakan untuk siklus melalui pertandingan pencarian. 876 01:13:57,130 --> 01:13:59,800 Di sini dikatakan poin argumen mode untuk string 877 01:13:59,800 --> 01:14:01,930 dimulai dengan salah satu urutan berikut. 878 01:14:01,930 --> 01:14:06,480 Jadi r, file teks Terbuka untuk membaca. Itulah yang kami ingin lakukan. 879 01:14:08,930 --> 01:14:13,210 Untuk membaca, dan saya ingin menyimpan itu. 880 01:14:13,210 --> 01:14:18,720 Hal ini akan menjadi * FILE. Sekarang apa yang ingin saya lakukan? 881 01:14:18,720 --> 01:14:21,200 Beri aku detik. 882 01:14:28,140 --> 01:14:30,430 Oke. Sekarang apa yang ingin saya lakukan? 883 01:14:30,430 --> 01:14:32,940 [Mahasiswa] Periksa apakah itu NULL. >> [Bowden] Ya. 884 01:14:32,940 --> 01:14:38,690 Setiap kali Anda membuka file, pastikan bahwa Anda berhasil dapat membukanya. 885 01:14:58,930 --> 01:15:10,460 >> Sekarang saya ingin melakukan hal-hal termios mana saya ingin pertama kali membaca pengaturan saya saat ini 886 01:15:10,460 --> 01:15:14,050 dan menyelamatkan mereka menjadi sesuatu, maka saya ingin mengubah setting saya 887 01:15:14,050 --> 01:15:19,420 membuang setiap karakter yang saya ketik, 888 01:15:19,420 --> 01:15:22,520 dan kemudian saya ingin memperbarui pengaturan tersebut. 889 01:15:22,520 --> 01:15:27,250 Dan kemudian pada akhir program, saya ingin mengubah kembali ke pengaturan asli saya. 890 01:15:27,250 --> 01:15:32,080 Jadi struct akan menjadi termios jenis, dan aku akan ingin dua dari mereka. 891 01:15:32,080 --> 01:15:35,600 Yang pertama akan menjadi current_settings saya, 892 01:15:35,600 --> 01:15:42,010 dan kemudian mereka akan menjadi hacker_settings saya. 893 01:15:42,010 --> 01:15:48,070 Pertama, aku akan ingin menyimpan pengaturan saya saat ini, 894 01:15:48,070 --> 01:15:53,790 maka aku akan ingin memperbarui hacker_settings, 895 01:15:53,790 --> 01:16:01,570 dan kemudian jalan pada akhir program saya, saya ingin kembali ke pengaturan saat ini. 896 01:16:01,570 --> 01:16:08,660 Jadi menyimpan pengaturan saat ini, cara yang bekerja, kita termios manusia. 897 01:16:08,660 --> 01:16:15,810 Kita melihat bahwa kita memiliki tcsetattr int, int tcgetattr. 898 01:16:15,810 --> 01:16:22,960 Saya lulus dalam struct termios oleh pointer. 899 01:16:22,960 --> 01:16:30,640 Cara ini akan terlihat adalah - aku sudah lupa apa fungsi dipanggil. 900 01:16:30,640 --> 01:16:34,930 Salin dan tempel. 901 01:16:39,150 --> 01:16:45,500 Jadi tcgetattr, maka saya ingin lulus dalam struct bahwa aku menyimpan informasi dalam, 902 01:16:45,500 --> 01:16:49,650 yang akan menjadi current_settings, 903 01:16:49,650 --> 01:16:59,120 dan argumen pertama adalah file descriptor untuk hal yang saya ingin menyimpan atribut. 904 01:16:59,120 --> 01:17:04,360 Apa file descriptor adalah seperti setiap kali Anda membuka file, ia mendapat file descriptor. 905 01:17:04,360 --> 01:17:14,560 Ketika saya fopen argv [1], ia mendapat file descriptor yang Anda referensi 906 01:17:14,560 --> 01:17:16,730 setiap kali Anda ingin membaca atau menulis untuk itu. 907 01:17:16,730 --> 01:17:19,220 Itu bukan file descriptor saya ingin gunakan di sini. 908 01:17:19,220 --> 01:17:21,940 Ada tiga deskriptor file yang Anda miliki secara default, 909 01:17:21,940 --> 01:17:24,310 yang standar di, keluar standar, dan standard error. 910 01:17:24,310 --> 01:17:29,960 Secara default, saya pikir itu adalah standar di 0, keluar standar 1, dan kesalahan standar 2. 911 01:17:29,960 --> 01:17:33,980 Jadi apa yang saya ingin mengubah pengaturan? 912 01:17:33,980 --> 01:17:37,370 Saya ingin mengubah pengaturan setiap kali aku memukul karakter, 913 01:17:37,370 --> 01:17:41,590 Aku ingin membuang karakter yang pergi bukannya mencetak ke layar. 914 01:17:41,590 --> 01:17:45,960 Apa aliran - standar dalam, keluar standar, atau standard error - 915 01:17:45,960 --> 01:17:52,050 menanggapi hal-hal ketika saya mengetik di keyboard? >> [Mahasiswa] Standar masuk >> Ya. 916 01:17:52,050 --> 01:17:56,450 Jadi saya dapat melakukan 0 atau aku bisa melakukan stdin. 917 01:17:56,450 --> 01:17:59,380 Saya mendapatkan current_settings standar masuk 918 01:17:59,380 --> 01:18:01,720 >> Sekarang saya ingin memperbarui pengaturan tersebut, 919 01:18:01,720 --> 01:18:07,200 jadi pertama saya akan menyalin ke hacker_settings apa current_settings saya. 920 01:18:07,200 --> 01:18:10,430 Dan bagaimana structs kerja itu hanya akan menyalin. 921 01:18:10,430 --> 01:18:14,510 Ini salinan semua bidang, seperti yang Anda harapkan. 922 01:18:14,510 --> 01:18:17,410 >> Sekarang saya ingin memperbarui beberapa bidang. 923 01:18:17,410 --> 01:18:21,670 Melihat termios, Anda harus membaca banyak ini 924 01:18:21,670 --> 01:18:24,110 hanya untuk melihat apa yang akan Anda ingin mencari, 925 01:18:24,110 --> 01:18:28,210 tapi bendera Anda akan ingin mencari adalah gema, 926 01:18:28,210 --> 01:18:33,110 sehingga ECHO Echo karakter masukan. 927 01:18:33,110 --> 01:18:37,710 Pertama saya ingin mengatur - aku sudah lupa apa bidang yang. 928 01:18:45,040 --> 01:18:47,900 Ini adalah apa yang tampak seperti struct. 929 01:18:47,900 --> 01:18:51,060 Jadi mode masukan saya pikir kita ingin mengubah. 930 01:18:51,060 --> 01:18:54,210 Kita akan melihat solusi untuk memastikan bahwa apa yang ingin kita ubah. 931 01:19:04,060 --> 01:19:12,610 Kami ingin mengubah lflag untuk mencegah perlu untuk melihat melalui semua ini. 932 01:19:12,610 --> 01:19:14,670 Kami ingin mengubah mode lokal. 933 01:19:14,670 --> 01:19:17,710 Anda harus membaca ini seluruh hal untuk memahami di mana segala sesuatu adalah milik 934 01:19:17,710 --> 01:19:19,320 bahwa kita ingin mengubah. 935 01:19:19,320 --> 01:19:24,120 Tapi itu dalam mode lokal di mana kita akan ingin mengubah itu. 936 01:19:27,080 --> 01:19:33,110 Jadi hacker_settings.cc_lmode adalah apa namanya. 937 01:19:39,630 --> 01:19:43,020 c_lflag. 938 01:19:49,060 --> 01:19:52,280 Di sinilah kita masuk ke operator bitwise. 939 01:19:52,280 --> 01:19:54,860 Kami agak kehabisan waktu, tapi kami akan pergi melalui itu cepat. 940 01:19:54,860 --> 01:19:56,600 Di sinilah kita masuk ke operator bitwise, 941 01:19:56,600 --> 01:19:59,950 di mana saya pikir saya mengatakan satu lama bahwa setiap kali Anda mulai berurusan dengan bendera, 942 01:19:59,950 --> 01:20:03,370 Anda akan menggunakan bitwise operator yang banyak. 943 01:20:03,370 --> 01:20:08,240 Setiap bit dalam bendera sesuai dengan semacam perilaku. 944 01:20:08,240 --> 01:20:14,090 Jadi di sini, bendera ini memiliki banyak hal yang berbeda, di mana mereka semua berarti sesuatu yang berbeda. 945 01:20:14,090 --> 01:20:18,690 Tapi apa yang saya ingin lakukan adalah hanya mematikan bit yang sesuai dengan ECHO. 946 01:20:18,690 --> 01:20:25,440 Jadi untuk matikan itu saya lakukan & = ¬ ECHO. 947 01:20:25,440 --> 01:20:30,110 Sebenarnya, saya pikir itu seperti Techo atau sesuatu. Aku hanya akan memeriksa lagi. 948 01:20:30,110 --> 01:20:34,050 Saya bisa termios itu. Hanya saja ECHO. 949 01:20:34,050 --> 01:20:38,440 ECHO akan menjadi satu bit. 950 01:20:38,440 --> 01:20:44,230 ¬ ECHO akan berarti semua bit diatur ke 1, yang berarti semua flag diatur ke true 951 01:20:44,230 --> 01:20:47,140 kecuali untuk bit ECHO. 952 01:20:47,140 --> 01:20:53,830 Dengan mengakhiri bendera lokal saya dengan ini, itu berarti semua bendera yang saat ini diatur ke benar 953 01:20:53,830 --> 01:20:56,520 masih akan diatur ke true. 954 01:20:56,520 --> 01:21:03,240 Jika bendera ECHO saya diatur ke benar, maka ini tentu diatur ke false pada bendera ECHO. 955 01:21:03,240 --> 01:21:07,170 Jadi baris kode ini hanya mematikan bendera ECHO. 956 01:21:07,170 --> 01:21:16,270 Garis lain dari kode, saya hanya akan menyalinnya untuk kepentingan waktu dan kemudian menjelaskan mereka. 957 01:21:27,810 --> 01:21:30,180 Dalam larutan, katanya 0. 958 01:21:30,180 --> 01:21:33,880 Ini mungkin lebih baik untuk secara eksplisit mengatakan stdin. 959 01:21:33,880 --> 01:21:42,100 >> Perhatikan bahwa saya juga melakukan ECHO | ICANON sini. 960 01:21:42,100 --> 01:21:46,650 ICANON mengacu pada sesuatu yang terpisah, yang berarti modus kanonik. 961 01:21:46,650 --> 01:21:50,280 Apa artinya modus kanonik biasanya ketika Anda mengetik baris perintah, 962 01:21:50,280 --> 01:21:54,670 standar tidak memproses apapun sampai Anda mencapai baris baru. 963 01:21:54,670 --> 01:21:58,230 Jadi, ketika Anda GetString, Anda mengetik banyak hal, maka anda menekan baris baru. 964 01:21:58,230 --> 01:22:00,590 Itulah ketika itu dikirim ke standar masuk 965 01:22:00,590 --> 01:22:02,680 Itulah default. 966 01:22:02,680 --> 01:22:05,830 Ketika saya mematikan modus kanonik, sekarang setiap karakter tunggal Anda menekan 967 01:22:05,830 --> 01:22:10,910 adalah apa yang akan diproses, yang biasanya jenis buruk karena itu lambat untuk memproses hal-hal ini, 968 01:22:10,910 --> 01:22:14,330 itulah sebabnya mengapa ada baiknya untuk buffer ke seluruh baris. 969 01:22:14,330 --> 01:22:16,810 Tapi aku ingin setiap karakter untuk diproses 970 01:22:16,810 --> 01:22:18,810 karena saya tidak ingin menunggu saya untuk memukul newline 971 01:22:18,810 --> 01:22:21,280 sebelum memproses semua karakter saya telah mengetik. 972 01:22:21,280 --> 01:22:24,760 Ini akan menonaktifkan modus kanonik. 973 01:22:24,760 --> 01:22:31,320 Hal ini hanya berarti padahal sebenarnya proses karakter. 974 01:22:31,320 --> 01:22:35,830 Ini berarti proses mereka segera, secepat saya mengetik mereka, mengolahnya. 975 01:22:35,830 --> 01:22:42,510 Dan ini adalah fungsi yang memperbarui pengaturan saya untuk standar, 976 01:22:42,510 --> 01:22:45,480 dan sarana TCSA melakukannya sekarang. 977 01:22:45,480 --> 01:22:50,310 Pilihan yang lain menunggu sampai segala sesuatu yang saat ini di sungai diproses. 978 01:22:50,310 --> 01:22:52,030 Itu tidak terlalu penting. 979 01:22:52,030 --> 01:22:56,920 Hanya sekarang mengubah pengaturan saya untuk menjadi apa pun saat ini sedang dalam hacker_typer_settings. 980 01:22:56,920 --> 01:23:02,210 Saya kira saya menyebutnya hacker_settings, jadi mari kita mengubah itu. 981 01:23:09,610 --> 01:23:13,500 Mengubah segalanya untuk hacker_settings. 982 01:23:13,500 --> 01:23:16,870 >> Sekarang di akhir program kami kita akan ingin kembali 983 01:23:16,870 --> 01:23:20,210 untuk apa saat ini dalam normal_settings, 984 01:23:20,210 --> 01:23:26,560 yang akan hanya terlihat seperti & normal_settings. 985 01:23:26,560 --> 01:23:30,650 Perhatikan Aku tidak berubah salah satu normal_settings saya sejak awalnya mendapatkan itu. 986 01:23:30,650 --> 01:23:34,520 Kemudian untuk hanya mengubah mereka kembali, saya melewati mereka kembali di akhir. 987 01:23:34,520 --> 01:23:38,390 Ini adalah pembaruan. Oke. 988 01:23:38,390 --> 01:23:43,900 >> Sekarang dalam sini saya hanya akan menjelaskan kode untuk kepentingan waktu. 989 01:23:43,900 --> 01:23:46,350 Ini bukan bahwa kode banyak. 990 01:23:50,770 --> 01:24:03,750 Kita melihat kita membaca karakter dari file tersebut. Kami menyebutnya f. 991 01:24:03,750 --> 01:24:07,850 Sekarang Anda bisa manusia fgetc, tapi bagaimana fgetc akan bekerja 992 01:24:07,850 --> 01:24:11,910 hanya itu akan mengembalikan karakter yang baru saja Anda baca atau EOF, 993 01:24:11,910 --> 01:24:15,680 yang sesuai dengan akhir file atau beberapa terjadi kesalahan. 994 01:24:15,680 --> 01:24:19,900 Kami looping, terus membaca karakter tunggal dari file tersebut, 995 01:24:19,900 --> 01:24:22,420 sampai kita sudah kehabisan karakter untuk dibaca. 996 01:24:22,420 --> 01:24:26,650 Dan sementara kita melakukan itu, kita menunggu satu karakter dari standar masuk 997 01:24:26,650 --> 01:24:29,090 Setiap kali Anda mengetik sesuatu di baris perintah, 998 01:24:29,090 --> 01:24:32,820 yang membaca karakter dari standar masuk 999 01:24:32,820 --> 01:24:38,330 Kemudian putchar hanya akan menempatkan char kita baca di sini dari file ke luar standar. 1000 01:24:38,330 --> 01:24:42,890 Anda dapat man putchar, tapi itu hanya menempatkan standar keluar, itu mencetak bahwa karakter. 1001 01:24:42,890 --> 01:24:51,600 Anda juga bisa hanya melakukan printf ("% c", c); ide yang sama. 1002 01:24:53,330 --> 01:24:56,670 Itu akan melakukan sebagian besar pekerjaan kami. 1003 01:24:56,670 --> 01:25:00,300 >> Hal terakhir yang kita akan ingin lakukan adalah hanya fclose file kita. 1004 01:25:00,300 --> 01:25:03,310 Jika Anda tidak fclose, itu adalah kebocoran memori. 1005 01:25:03,310 --> 01:25:06,680 Kami ingin fclose file yang kita awalnya dibuka, dan saya pikir itu saja. 1006 01:25:06,680 --> 01:25:13,810 Jika kita membuat itu, saya sudah punya masalah. 1007 01:25:13,810 --> 01:25:17,260 Mari kita lihat. 1008 01:25:17,260 --> 01:25:19,960 Apa itu mengeluh tentang? 1009 01:25:19,960 --> 01:25:30,220 Diharapkan 'int' tapi argumen adalah tipe 'struct _IO_FILE *'. 1010 01:25:36,850 --> 01:25:39,370 Kita akan melihat apakah yang bekerja. 1011 01:25:45,210 --> 01:25:53,540 Hanya diperbolehkan dalam C99. Augh. Oke, membuat hacker_typer. 1012 01:25:53,540 --> 01:25:57,760 Sekarang kita mendapatkan gambaran yang lebih berguna. 1013 01:25:57,760 --> 01:25:59,900 Jadi penggunaan undeclared identifier 'normal_settings'. 1014 01:25:59,900 --> 01:26:04,170 Saya tidak menyebutnya normal_settings. Saya menyebutnya current_settings. 1015 01:26:04,170 --> 01:26:12,090 Jadi mari kita mengubah semua itu. 1016 01:26:17,920 --> 01:26:21,710 Sekarang melewatkan argumen. 1017 01:26:26,290 --> 01:26:29,500 Aku akan membuat 0 ini untuk saat ini. 1018 01:26:29,500 --> 01:26:36,720 Oke. / Hacker_typer. Cp.c. 1019 01:26:36,720 --> 01:26:39,590 Saya juga tidak menghapus layar di awal. 1020 01:26:39,590 --> 01:26:42,960 Tapi Anda bisa melihat kembali ke set masalah terakhir untuk melihat bagaimana Anda membersihkan layar. 1021 01:26:42,960 --> 01:26:45,160 Hanya saja mencetak beberapa karakter 1022 01:26:45,160 --> 01:26:47,210 sementara ini adalah melakukan apa yang ingin saya lakukan. 1023 01:26:47,210 --> 01:26:48,900 Oke. 1024 01:26:48,900 --> 01:26:55,280 Dan berpikir tentang mengapa hal ini perlu 0 bukan stdin, 1025 01:26:55,280 --> 01:27:00,560 yang harus # define 0, 1026 01:27:00,560 --> 01:27:03,890 ini mengeluh bahwa - 1027 01:27:13,150 --> 01:27:19,360 Sebelum ketika saya mengatakan bahwa ada file deskriptor tapi kemudian Anda juga memiliki FILE * Anda, 1028 01:27:19,360 --> 01:27:23,210 file descriptor hanyalah satu bilangan bulat, 1029 01:27:23,210 --> 01:27:26,970 sedangkan * FILE memiliki sejumlah besar barang-barang yang terkait dengannya. 1030 01:27:26,970 --> 01:27:30,380 Alasan kita perlu dikatakan 0 bukan stdin 1031 01:27:30,380 --> 01:27:37,480 adalah stdin itu adalah * FILE yang menunjuk ke hal yang referensi file descriptor 0. 1032 01:27:37,480 --> 01:27:45,070 Jadi bahkan sampai di sini ketika saya melakukan fopen (argv [1], saya mendapatkan * FILE kembali. 1033 01:27:45,070 --> 01:27:51,180 Tapi di suatu tempat dalam * FILE adalah hal yang sesuai dengan file descriptor untuk file itu. 1034 01:27:51,180 --> 01:27:57,430 Jika Anda melihat halaman manual untuk terbuka, jadi saya pikir Anda harus melakukan man 3 terbuka - tidak - 1035 01:27:57,430 --> 01:27:59,380 man 2 terbuka - ya. 1036 01:27:59,380 --> 01:28:06,250 Jika Anda melihat halaman untuk terbuka, terbuka seperti fopen tingkat rendah, 1037 01:28:06,250 --> 01:28:09,350 dan itu mengembalikan descriptor file yang sebenarnya. 1038 01:28:09,350 --> 01:28:12,050 fopen melakukan banyak hal di atas terbuka, 1039 01:28:12,050 --> 01:28:17,640 yang bukannya kembali hanya saja file descriptor mengembalikan seluruh FILE pointer * 1040 01:28:17,640 --> 01:28:20,590 di dalamnya ada file descriptor kecil kami. 1041 01:28:20,590 --> 01:28:25,020 Jadi standar dalam mengacu pada hal * FILE, 1042 01:28:25,020 --> 01:28:29,120 sedangkan 0 mengacu hanya standar file descriptor dalam dirinya sendiri. 1043 01:28:29,120 --> 01:28:32,160 >> Pertanyaan? 1044 01:28:32,160 --> 01:28:35,930 [Tertawa] Meniup melalui itu. 1045 01:28:35,930 --> 01:28:39,140 Baiklah. Kita sudah selesai. [Tertawa] 1046 01:28:39,140 --> 01:28:42,000 >> [CS50.TV]