1 00:00:00,000 --> 00:00:02,860 [Powered by Google Translate] [第5週] 2 00:00:02,860 --> 00:00:04,860 [戴維·J·馬蘭 - 哈佛大學] 3 00:00:04,860 --> 00:00:07,260 [這是CS50。 - CS50.TV] 4 00:00:07,260 --> 00:00:09,740 >> 這是CS50,5週。 5 00:00:09,740 --> 00:00:12,900 今天和這個星期,我們介紹了一點點取證的世界 6 00:00:12,900 --> 00:00:14,850 的上下文中的問題設置4。 7 00:00:14,850 --> 00:00:18,480 今天將是一個簡短的演講,因為在這裡有一個特殊的事件後。 8 00:00:18,480 --> 00:00:21,940 因此,我們將採取偷看,逗學生和家長的一致好評今天 9 00:00:21,940 --> 00:00:24,600 一些的東西,是在地平線上。 10 00:00:24,600 --> 00:00:29,050 >> 其中,截至週一,你將有一些更多的同學。 11 00:00:29,050 --> 00:00:32,980 EDX,哈佛大學和麻省理工學院的“開放式課程網頁”多新的網上倡議, 12 00:00:32,980 --> 00:00:36,730 哈佛的校園(星期一),這意味著星期一上推出 13 00:00:36,730 --> 00:00:40,930 最近的一次統計,你將有86,000額外的同學 14 00:00:40,930 --> 00:00:43,680 將跟隨著CS50的講座和部分 15 00:00:43,680 --> 00:00:45,890 和演練和習題集。 16 00:00:45,890 --> 00:00:51,870 作為這項工作的一部分,你將成為成員的就職類的CS50,現在CS50x的。 17 00:00:51,870 --> 00:00:56,150 作為這項工作的一部分,現在,知道會有一些的積極作為。 18 00:00:56,150 --> 00:01:00,620 要為此做好準備,對於數量龐大的學生, 19 00:01:00,620 --> 00:01:03,820 可以肯定地說,即使我們有108個轉錄因子和CA, 20 00:01:03,820 --> 00:01:07,560 它不是最好的學生與教師的比例,一旦我們打80000的學生。 21 00:01:07,560 --> 00:01:09,830 我們不打算分級這麼多問題集手動, 22 00:01:09,830 --> 00:01:13,050 所以本週推出的習題集將是CS50檢查, 23 00:01:13,050 --> 00:01:15,410 這將是一個命令行實用程序在設備 24 00:01:15,410 --> 00:01:17,880 一次,你會得到你以後更新本週末。 25 00:01:17,880 --> 00:01:21,030 您就可以運行命令,check50,你自身的pset, 26 00:01:21,030 --> 00:01:24,770 ,你會得到即時反饋,以您的程序是否正確或不正確 27 00:01:24,770 --> 00:01:27,980 根據不同的設計規格,我們已經提供。 28 00:01:27,980 --> 00:01:30,310 更多的是在問題集規範。 29 00:01:30,310 --> 00:01:34,220 CS50x同學們將利用這一點。 30 00:01:34,220 --> 00:01:36,170 >> 習題集4是所有約取證, 31 00:01:36,170 --> 00:01:38,630 真的,這pset的靈感來自一些真實的東西 32 00:01:38,630 --> 00:01:41,210 因此,當我在讀研究生,我實習一段時間 33 00:01:41,210 --> 00:01:45,270 米德爾塞克斯縣地區檢察官辦公室從事法醫工作 34 00:01:45,270 --> 00:01:47,660 他們的領導取證調查。 35 00:01:47,660 --> 00:01:50,280 這為我想我提到了幾個星期過去, 36 00:01:50,280 --> 00:01:52,720 是質量國家警察或其他人, 37 00:01:52,720 --> 00:01:56,150 他們將放棄硬盤驅動器,CD和軟盤之類的事情,比如, 38 00:01:56,150 --> 00:01:58,770 然後的法醫辦公室的目標是要確定 39 00:01:58,770 --> 00:02:01,470 是否有或沒有某種形式的證據。 40 00:02:01,470 --> 00:02:04,730 這是特別調查組,所以它是白領犯罪。 41 00:02:04,730 --> 00:02:10,949 更令人不安的是什麼形式的犯罪​​,涉及某種數字媒體的。 42 00:02:10,949 --> 00:02:16,450 事實證明,沒有那麼多的人寫一封電子郵件,說,“我做到了。” 43 00:02:16,450 --> 00:02:20,490 所以很多時候,這些法醫學搜索並沒有打開所有的東西,水果, 44 00:02:20,490 --> 00:02:22,820 但有時人們會寫這樣的郵件。 45 00:02:22,820 --> 00:02:25,240 所以有時候,努力得到了回報。 46 00:02:25,240 --> 00:02:31,210 >> 不過,導致這個法醫pset中,我們將介紹在pset4位的圖形。 47 00:02:31,210 --> 00:02:35,410 你可能把這些東西是理所當然的 - JPEG格式,GIF和等 - 這些天。 48 00:02:35,410 --> 00:02:38,320 但如果你真的仔細想想,圖像,就像羅布的臉, 49 00:02:38,320 --> 00:02:41,270 可以作為一個序列的點或像素建模。 50 00:02:41,270 --> 00:02:43,380 在羅布的臉的情況下,有各種顏色, 51 00:02:43,380 --> 00:02:46,760 我們開始看到各個點,否則稱為像素, 52 00:02:46,760 --> 00:02:48,610 一旦我們開始放大。 53 00:02:48,610 --> 00:02:54,660 但是,如果我們簡化了世界了一下,只是說,這是搶在黑色和白色, 54 00:02:54,660 --> 00:02:57,490 代表黑色和白色,我們可以只使用二進制文件。 55 00:02:57,490 --> 00:03:01,660 如果我們要使用二進制的1或0,我們可以表達這種相同的圖像 56 00:03:01,660 --> 00:03:06,140 這種模式的位Rob的笑臉。 57 00:03:06,140 --> 00:03:12,100 11000011代表白,白,黑,黑,黑,黑,白,白。 58 00:03:12,100 --> 00:03:16,150 因此,它不是一個巨大的飛躍,然後開始談論精美圖片, 59 00:03:16,150 --> 00:03:18,600 的東西,你會看到在Facebook或用數碼相機拍攝。 60 00:03:18,600 --> 00:03:21,410 但可以肯定的,當涉及到顏色,你需要更多的比特。 61 00:03:21,410 --> 00:03:25,690 在世界上的照片相當普遍的是使用1位顏色, 62 00:03:25,690 --> 00:03:29,560 因為這建議,但24位色,你實際上得到數百萬種顏色。 63 00:03:29,560 --> 00:03:32,250 因此,作為的情況下,當我們放大羅布的眼睛上, 64 00:03:32,250 --> 00:03:36,370 這是任何數以百萬計的不同顏色的可能性。 65 00:03:36,370 --> 00:03:39,040 因此,我們將介紹本習題集4,以及在演練中, 66 00:03:39,040 --> 00:03:43,370 這將是今天下午3:30,而不是平常的下午2時30分,因為上週五的演講在這裡。 67 00:03:43,370 --> 00:03:46,620 但是,視頻將在網上像往常一樣的明天。 68 00:03:46,620 --> 00:03:48,820 >> 我們還將為您介紹另一種文件格式。 69 00:03:48,820 --> 00:03:51,270 這是故意為了看起來嚇人, 70 00:03:51,270 --> 00:03:55,670 但是,這僅僅是一些文件的C結構。 71 00:03:55,670 --> 00:03:58,940 事實證明,微軟幾年前捧紅這種格式 72 00:03:58,940 --> 00:04:05,150 ,BMP的位圖文件格式,這是一個超級簡單的,豐富多彩的圖形文件格式 73 00:04:05,150 --> 00:04:10,150 用於相當長的一段時間,有時還在桌面上的壁紙。 74 00:04:10,150 --> 00:04:14,760 如果你覺得回到了Windows XP和連綿起伏的丘陵和藍色的天​​空, 75 00:04:14,760 --> 00:04:17,170 這是典型的bmp或位圖圖像。 76 00:04:17,170 --> 00:04:19,959 位圖是我們的樂趣,因為他們有了更多的複雜性。 77 00:04:19,959 --> 00:04:22,610 這是不是很簡單,因為這格的0和1。 78 00:04:22,610 --> 00:04:27,510 相反,你必須像一個頭在一個文件的開始的東西。 79 00:04:27,510 --> 00:04:31,990 因此,在其他的話,裡面的bmp文件是一大堆的0和1, 80 00:04:31,990 --> 00:04:34,910 但在那裡有一些額外的“0”和“1。 81 00:04:34,910 --> 00:04:38,220 而事實證明,我們可能已經多年理所當然的 - 82 00:04:38,220 --> 00:04:45,170 任何文件格式的文件格式,如doc或xls或MP3,MP4, 83 00:04:45,170 --> 00:04:48,480 你是熟悉的 - 它甚至意味著是一種文件格式, 84 00:04:48,480 --> 00:04:52,480 因為在一天結束的時候,所有的這些文件,我們只有“0”和“1。 85 00:04:52,480 --> 00:04:56,810 也許那些“0”和“1代表ABC通過ASCII或類似的, 86 00:04:56,810 --> 00:04:58,820 但在一天結束的時候,它仍然只是“0”和“1。 87 00:04:58,820 --> 00:05:02,100 因此,人類只是偶爾決定發明一種新的文件格式 88 00:05:02,100 --> 00:05:06,420 他們規範的位模式,實際上的意思。 89 00:05:06,420 --> 00:05:09,220 在這種情況下,這裡的人誰設計的位圖文件格式 90 00:05:09,220 --> 00:05:15,620 說的第一個字節中的位圖文件,有表示的偏移量為0, 91 00:05:15,620 --> 00:05:18,940 有一些神秘命名的變量稱為bfType, 92 00:05:18,940 --> 00:05:23,080 這只是代表了位圖文件的類型,這是什麼類型的位圖文件。 93 00:05:23,080 --> 00:05:27,700 你或許可以推斷出從第二行偏移2字節2號, 94 00:05:27,700 --> 00:05:33,740 有圖案的0和1,代表什麼?事物的大小。 95 00:05:33,740 --> 00:05:35,310 它從那裡。 96 00:05:35,310 --> 00:05:37,410 因此,在習題集4,你會走過一些事情。 97 00:05:37,410 --> 00:05:39,520 我們會關心所有的人都沒有好下場。 98 00:05:39,520 --> 00:05:47,510 但是請注意,它開始變得有趣的周圍字節54:rgbtBlue,綠色和紅色。 99 00:05:47,510 --> 00:05:52,110 如果你曾經聽說過的縮寫,RGB - 紅,綠,藍 - 這是一個參考 100 00:05:52,110 --> 00:05:54,610 因為事實證明,你可以畫的彩虹的所有顏色 101 00:05:54,610 --> 00:05:58,180 與紅色,藍色和綠色的某種組合。 102 00:05:58,180 --> 00:06:03,320 而事實上,在房間裡的父母可能還記得最早的投影機。 103 00:06:03,320 --> 00:06:05,890 這些天,你只看到一個明亮的光出來的鏡頭, 104 00:06:05,890 --> 00:06:09,800 但早在一天,你有紅色的鏡片,藍色鏡片,綠色鏡片, 105 00:06:09,800 --> 00:06:13,380 和一起,他們的目的是在屏幕上,並形成了豐富多彩的畫面。 106 00:06:13,380 --> 00:06:16,270 很多時候,中學和高中有那些鏡頭 107 00:06:16,270 --> 00:06:19,720 有一點點歪,所以你看到雙重或三重影像。 108 00:06:19,720 --> 00:06:24,100 但他的想法。你有紅色,綠色和藍色光畫一幅畫。 109 00:06:24,100 --> 00:06:26,590 在電腦上使用相同的原則。 110 00:06:26,590 --> 00:06:30,230 >> 所以之間的挑戰,那麼對你來說,在問題設置都將是幾件事情。 111 00:06:30,230 --> 00:06:34,800 一個是調整圖像的大小,圖案中的0和1, 112 00:06:34,800 --> 00:06:40,200 找出其中的“0”和“1塊代表什麼這樣的結構在, 113 00:06:40,200 --> 00:06:43,630 然後找出如何複製的像素 - 紅軍,藍軍,果嶺 - 114 00:06:43,630 --> 00:06:46,660 內,這樣當最初的圖片看起來是這樣的, 115 00:06:46,660 --> 00:06:49,210 它可能看起來像這樣,而不是之後。 116 00:06:49,210 --> 00:06:53,640 在其他的挑戰將是,你會交由法醫的圖像 117 00:06:53,640 --> 00:06:56,030 一個實際的文件從數碼相機。 118 00:06:56,030 --> 00:06:58,960 該相機,曾幾何時,是一大堆的照片。 119 00:06:58,960 --> 00:07:03,760 問題是我們不小心刪除或已損壞的圖像以某種方式。 120 00:07:03,760 --> 00:07:05,750 不好的事情發生的數碼相機。 121 00:07:05,750 --> 00:07:09,150 所以我們很快就複製了所有為你關閉該卡的“0”和“1, 122 00:07:09,150 --> 00:07:13,610 保存他們都在一個大文件,然後我們會交給你的問題集4 123 00:07:13,610 --> 00:07:19,320 所以,你可以寫一個程序,在C恢復所有的這些JPEG文件,理想。 124 00:07:19,320 --> 00:07:23,330 而事實證明,JPEG文件,即使它們是有點複雜的文件格式 - 125 00:07:23,330 --> 00:07:26,360 他們要複雜得多,這笑臉 - 126 00:07:26,360 --> 00:07:31,160 事實證明,每一個JPEG相同的模式0和1開始。 127 00:07:31,160 --> 00:07:35,630 所以,最終,一個while循環或循環或類似的, 128 00:07:35,630 --> 00:07:38,880 在此法醫圖像,你可以遍歷所有的“0”和“1, 129 00:07:38,880 --> 00:07:43,150 每次你看到的特殊的模式,集規範中定義的問題, 130 00:07:43,150 --> 00:07:47,880 在這裡,你可以假設,具有非常高的概率,開始的JPEG。 131 00:07:47,880 --> 00:07:51,230 而一旦當你發現相同的模式一定數量的字節 132 00:07:51,230 --> 00:07:55,430 或千字節或兆字節後,你可以假設這裡是第二JPEG, 133 00:07:55,430 --> 00:07:57,380 我把照片後的第一個。 134 00:07:57,380 --> 00:08:01,370 讓我停止閱讀,第一個文件,開始寫這個新的, 135 00:08:01,370 --> 00:08:06,310 輸出你的程序pset4的是多達50個JPEG文件。 136 00:08:06,310 --> 00:08:09,270 而且,如果它不是50 JPEG文件,你有一點的循環。 137 00:08:09,270 --> 00:08:12,490 如果你有無限多的JPEG文件,你有一個無限循環。 138 00:08:12,490 --> 00:08:14,910 所以,這也將是一個相當常見的情況。 139 00:08:14,910 --> 00:08:16,600 所以,這就是在地平線上。 140 00:08:16,600 --> 00:08:21,310 >> 測驗0在我們的身後,實現按我的電子郵件,總是有鄉親誰都是幸福的, 141 00:08:21,310 --> 00:08:23,640 排序的中性,悲傷周圍測驗的0時間。 142 00:08:23,640 --> 00:08:26,800 請你伸出我的頭,你自己的TF TF Zamyla, 143 00:08:26,800 --> 00:08:31,180 的CA,你知道,如果你想討論如何去。 144 00:08:31,180 --> 00:08:35,539 >> 因此,要在這裡留下深刻印象的父母在房間裡,什麼是的CS50庫嗎? 145 00:08:36,429 --> 00:08:40,390 [笑聲]好工作。 146 00:08:40,390 --> 00:08:48,340 的CS50庫?是啊。 >> [學生]:這是一個預先寫好的代碼集[聽不清] 147 00:08:48,340 --> 00:08:49,750 好,好。 148 00:08:49,750 --> 00:08:53,240 這是一個預先寫好的代碼集,我們的工作人員寫的,我們提供給你, 149 00:08:53,240 --> 00:08:55,030 提供了一些常用的功能, 150 00:08:55,030 --> 00:08:59,020 這樣的東西讓我一個字符串,給我一個int - 此處列出的所有的功能。 151 00:08:59,020 --> 00:09:02,260 >> 從現在起,我們開始真正把這些訓練車輪。 152 00:09:02,260 --> 00:09:05,050 我們將開始從你帶走一個字符串, 153 00:09:05,050 --> 00:09:08,870 這使人想起什麼實際的數據類型只是一個代名詞? >> [多學生的char *。 154 00:09:08,870 --> 00:09:12,730 CHAR *。對於父母來說,那可能是[呼呼的聲音。這是很好的。 155 00:09:12,730 --> 00:09:17,550 我們將開始看到在屏幕上更因為我們從我們的詞彙中刪除字符串的char *, 156 00:09:17,550 --> 00:09:19,730 至少當涉及到實際編寫代碼。 157 00:09:19,730 --> 00:09:22,840 同樣,我們將停止使用這些功能盡可能多 158 00:09:22,840 --> 00:09:25,280 因為我們的程序將會變得更加複雜。 159 00:09:25,280 --> 00:09:28,480 而不是僅僅寫一個提示,閃爍坐在那裡, 160 00:09:28,480 --> 00:09:31,870 等待用戶輸入一些東西,你會得到你輸入的其他地方。 161 00:09:31,870 --> 00:09:35,490 例如,你會得到他們的本地硬盤驅動器上的一系列位。 162 00:09:35,490 --> 00:09:38,580 相反,你會得到他們在未來的網絡連接, 163 00:09:38,580 --> 00:09:40,230 一些網站的地方。 164 00:09:40,230 --> 00:09:44,110 >> 因此,讓我們剝開這層第一次拉CS50電器 165 00:09:44,110 --> 00:09:49,010 這個文件稱為cs50.h,#你已經包括了幾個星期, 166 00:09:49,010 --> 00:09:51,140 但讓​​我們看到這裡面有什麼。 167 00:09:51,140 --> 00:09:54,430 在藍色的文件的頂部是一大堆的意見: 168 00:09:54,430 --> 00:09:57,050 保修信息和許可。 169 00:09:57,050 --> 00:09:59,050 這是一個共同的範式軟件 170 00:09:59,050 --> 00:10:01,580 這些天,因為很多軟件是所謂的開源的, 171 00:10:01,580 --> 00:10:05,220 這意味著有人已經寫好的代碼和自由 172 00:10:05,220 --> 00:10:10,470 不只是運行和使用,但實際讀取和修改,並融入自己的工作。 173 00:10:10,470 --> 00:10:14,660 所以,這就是你一直在使用開源軟件,儘管在一個非常小的形式。 174 00:10:14,660 --> 00:10:18,560 不過,如果我向下滾動過去的意見,我們將開始看到一些比較熟悉的東西。 175 00:10:18,560 --> 00:10:25,010 在頂部,cs50.h文件包括一大堆的頭文件的通知。 176 00:10:25,010 --> 00:10:28,560 最重要的這些,我們還沒有見過,但一個是熟悉的。 177 00:10:28,560 --> 00:10:32,270 這些我們看到,儘管是短暫的,迄今? >> [學生]標準庫。 178 00:10:32,270 --> 00:10:35,810 是啊,標準庫。 stdlib.h中的malloc。 179 00:10:35,810 --> 00:10:38,320 一旦我們開始談論動態內存分配, 180 00:10:38,320 --> 00:10:41,650 我們會回來下週開始,包括該文件。 181 00:10:41,650 --> 00:10:46,640 事實證明,布爾和真假實際上並不存在在C本身 182 00:10:46,640 --> 00:10:49,440 除非你有這個文件在這裡。 183 00:10:49,440 --> 00:10:52,710 我們已經好幾個星期,得到了包括stdbool.h 184 00:10:52,710 --> 00:10:55,620 這樣,您可以使用這個概念的一個布爾值,true或false。 185 00:10:55,620 --> 00:10:58,620 沒有這一點,你就必須假的排序,並使用int 186 00:10:58,620 --> 00:11:02,610 只是任意假設0是假的,1是真實的。 187 00:11:02,610 --> 00:11:07,150 如果我們進一步向下滾動,在這裡我們定義一個字符串。 188 00:11:07,150 --> 00:11:11,390 事實證明,我們已經說過,這顆星在哪裡並不重要。 189 00:11:11,390 --> 00:11:13,720 你甚至可以有空間的限制。 190 00:11:13,720 --> 00:11:16,740 我們這學期一直在推動它,因為這明確 191 00:11:16,740 --> 00:11:18,620 明星做的類型, 192 00:11:18,620 --> 00:11:21,700 但實現一樣普遍,如果沒有一點更為常見, 193 00:11:21,700 --> 00:11:24,430 是把它放在那裡,但在功能上是一樣的東西。 194 00:11:24,430 --> 00:11:27,720 但現在如果我們進一步讀下來,讓我們來看看在調用getInt 195 00:11:27,720 --> 00:11:32,190 因為我們使用之前,也許別的學期。 196 00:11:32,190 --> 00:11:37,440 下面是調用getInt。這是什麼? >> [學生]的原型。 >>這僅僅是一個原型。 197 00:11:37,440 --> 00:11:41,410 通常情況下,我們的原型在我們的頂部。c文件, 198 00:11:41,410 --> 00:11:46,690 但你也可以把原型的頭文件,。h文件中,像這樣的在這裡 199 00:11:46,690 --> 00:11:50,840 所以,當你寫一些功能,你希望其他人能夠使用, 200 00:11:50,840 --> 00:11:53,550 而這恰恰與CS50庫的情況下, 201 00:11:53,550 --> 00:11:57,040 你不僅實現你的功能的東西像cs50.c, 202 00:11:57,040 --> 00:12:02,790 也把原型不是在該文件的頂部,但在一個頭文件的頂部。 203 00:12:02,790 --> 00:12:07,170 然後,頭文件是什麼樣的朋友和同事,包括 204 00:12:07,170 --> 00:12:09,760 在自己的代碼中使用#include。 205 00:12:09,760 --> 00:12:12,210 所以這個時候,你已經包括所有這些原型, 206 00:12:12,210 --> 00:12:16,580 在文件的開頭,但通過這有效地#include機制, 207 00:12:16,580 --> 00:12:20,070 這基本上是複製和粘貼文件到您自己的。 208 00:12:20,070 --> 00:12:23,070 下面是一些比較詳細的文檔。 209 00:12:23,070 --> 00:12:25,640 我們幾乎是理所當然的調用getInt得到一個int, 210 00:12:25,640 --> 00:12:27,640 但事實證明,有一些角落的情況下。 211 00:12:27,640 --> 00:12:31,810 如果用戶鍵入的數字太大了,一百萬的三次方, 212 00:12:31,810 --> 00:12:35,490 ,只是不能裝進一個int?什麼是預期的行為嗎? 213 00:12:35,490 --> 00:12:38,020 理想的情況下,它是可預測的。 214 00:12:38,020 --> 00:12:40,280 因此,在這種情況下,如果你真正閱讀印刷精美, 215 00:12:40,280 --> 00:12:44,500 實際上,你會看到,如果該行不能被讀取,這將返回INT_MAX。 216 00:12:44,500 --> 00:12:48,320 我們從來沒有提到這一點,但其資本額的基礎上,它可能是什麼? 217 00:12:48,320 --> 00:12:50,640 [學生]恆定的。 >>這是一個常數。 218 00:12:50,640 --> 00:12:54,770 這可能是這些頭文件在一個聲明,它的一些特殊的常量 219 00:12:54,770 --> 00:13:00,090 了更高的文件,並INT_MAX大概就像大約2億美元, 220 00:13:00,090 --> 00:13:04,990 的想法是,因為我們需要以某種方式表明的東西出了問題, 221 00:13:04,990 --> 00:13:10,700 是的,我們有我們所掌握的4十億的數字:-2億元到2億元,給予或採取。 222 00:13:10,700 --> 00:13:14,710 那麼,什麼是常見的編程是你偷的只是這些數字, 223 00:13:14,710 --> 00:13:18,920 也許0,也許2十億,也許-2億元, 224 00:13:18,920 --> 00:13:23,280 所以你用一個可能的值,這樣就可以提交到世界 225 00:13:23,280 --> 00:13:26,820 ,如果出現錯誤,我會回到這個超級大的價值。 226 00:13:26,820 --> 00:13:31,030 但你不希望用戶輸入一些神秘的像234 ...,一個非常大的數字。 227 00:13:31,030 --> 00:13:34,060 您概括它,而不是為一個常數。 228 00:13:34,060 --> 00:13:38,060 所以,真的,如果你是肛門過去幾週裡,任何時候你叫調用getInt, 229 00:13:38,060 --> 00:13:42,900 你應該被檢查,如果條件做了INT_MAX的用戶類型, 230 00:13:42,900 --> 00:13:46,590 或者,更具體地說,調用getInt返回INT_MAX,因為如果它這樣做, 231 00:13:46,590 --> 00:13:51,830 這實際上意味著他們沒有鍵入它。在這種情況下,出現了錯誤。 232 00:13:51,830 --> 00:13:56,080 因此,這是通常被稱為一個標記值,這只是意味著什麼。 233 00:13:56,080 --> 00:13:58,120 >> 現在,讓我們變成的。c文件。 234 00:13:58,120 --> 00:14:01,340 C文件已經存在了一段時間的家電。 235 00:14:01,340 --> 00:14:06,840 而事實上,該設備有預編譯的到的事情,我們稱為目標代碼, 236 00:14:06,840 --> 00:14:09,540 但它只是對你重要,那是因為系統知道 237 00:14:09,540 --> 00:14:11,730 在這種情況下,它是:該設備。 238 00:14:11,730 --> 00:14:17,400 讓我們現在向下滾動到調用getInt,看看如何調用getInt一直致力於這一切。 239 00:14:17,400 --> 00:14:19,460 在這裡,我們從之前也有類似的評論。 240 00:14:19,460 --> 00:14:21,660 讓我放大的代碼部分。 241 00:14:21,660 --> 00:14:23,900 我們調用getInt如下。 242 00:14:23,900 --> 00:14:25,700 它不接受任何輸入。 243 00:14:25,700 --> 00:14:29,510 它返回一個int值,而(真),所以我們有一個故意的無限循環, 244 00:14:29,510 --> 00:14:33,180 但想必大家會打破這個以某種方式或在此返回。 245 00:14:33,180 --> 00:14:34,870 >> 讓我們來看看它是如何工作的。 246 00:14:34,870 --> 00:14:39,240 我們似乎在這個循環內的第一線,使用GetString 166。 247 00:14:39,240 --> 00:14:43,780 現在,這是很好的做法,因為在什麼情況下可能的GetString返回 248 00:14:43,780 --> 00:14:47,660 特殊的關鍵字NULL? >> [學生]如果出現錯誤。 249 00:14:47,660 --> 00:14:51,630 如果出現錯誤。會出什麼差錯,當你調用類似的GetString? 250 00:14:54,960 --> 00:14:57,640 是啊。 >> [學生] malloc失敗給它的整數。 251 00:14:57,640 --> 00:14:59,150 是啊。也許malloc失敗。 252 00:14:59,150 --> 00:15:03,190 引擎蓋下方的某個地方,GetString的調用malloc分配內存, 253 00:15:03,190 --> 00:15:06,020 這使得計算機能夠存儲所有的字符 254 00:15:06,020 --> 00:15:07,750 進入鍵盤的用戶類型。 255 00:15:07,750 --> 00:15:11,590 假設用戶得到了很多的空閒時間,多類型的,例如, 256 00:15:11,590 --> 00:15:16,160 甚至有超過2億美元,比電腦更多的字符的字符RAM。 257 00:15:16,160 --> 00:15:19,250 GetString的是,以表示對你。 258 00:15:19,250 --> 00:15:22,560 即使這是一個超級,超級罕見的角落的情況, 259 00:15:22,560 --> 00:15:24,340 它以某種方式來處理這個問題, 260 00:15:24,340 --> 00:15:28,750 等GetString時,如果我們回去,並閱讀其說明文件,確實在事實上,返回NULL。 261 00:15:28,750 --> 00:15:34,460 所以,現在如果GetString的失敗,返回NULL,調用getInt是要失敗的返回INT_MAX 262 00:15:34,460 --> 00:15:37,690 就像一個哨兵。這些都只是人的約定。 263 00:15:37,690 --> 00:15:41,450 你會知道這是唯一的辦法是通過閱讀文檔。 264 00:15:41,450 --> 00:15:45,040 >> 讓我們向下滾動到其中int實際上是得到了。 265 00:15:45,040 --> 00:15:51,160 如果我向下滾動一些,在170行,我們有上述評論,這些線路。 266 00:15:51,160 --> 00:15:55,100 我們聲明一個int,N,和一個char,C,然後這個新的功能,在172 267 00:15:55,100 --> 00:15:58,930 你們中的一些偶然發現之前,sscanf的。 268 00:15:58,930 --> 00:16:00,870 這代表的字符串scanf函數。 269 00:16:00,870 --> 00:16:05,700 換句話說,給我一個字符串,我將掃描件信息感興趣。 270 00:16:05,700 --> 00:16:07,360 這是什麼意思呢? 271 00:16:07,360 --> 00:16:11,800 假設,我在鍵盤上輸入,從字面上看,123,然後按Enter鍵。 272 00:16:11,800 --> 00:16:16,470 123時,由GetString返回的數據類型是什麼? >> [學生]字符串。 273 00:16:16,470 --> 00:16:18,380 這顯然是一個字符串,對不對?我有一個字符串。 274 00:16:18,380 --> 00:16:23,220 所以123是真的,報價引文結束,123 \ 0在它的結束。 275 00:16:23,220 --> 00:16:27,110 這不是一個整數。這不是一個數字。它看起來像一個數字,但它實際上不是。 276 00:16:27,110 --> 00:16:29,080 那麼,是什麼調用getInt有什麼關係? 277 00:16:29,080 --> 00:16:35,750 從左向右掃描該字符串 - 123 \ 0 - ,並以某種方式轉換成一個實際的整數。 278 00:16:35,750 --> 00:16:37,850 你可以計算出如何做到這一點。 279 00:16:37,850 --> 00:16:41,450 如果你覺得回到了pset2,你大概有點生氣了舒適與凱撒 280 00:16:41,450 --> 00:16:44,820 或維瓊內爾,所以你可以遍歷字符串,你可以轉換為整數的字符。 281 00:16:44,820 --> 00:16:46,710 不過,赫克說,這是一個大量的工作。 282 00:16:46,710 --> 00:16:49,860 sscanf的,做一個這樣的函數,你為什麼不叫? 283 00:16:49,860 --> 00:16:54,230 ,所以sscanf的預計參數 - 在這種情況下,稱為線,它是一個字符串。 284 00:16:54,230 --> 00:17:01,840 然後,您可以指定在引號中,非常類似於printf,你希望看到在這個字符串中。 285 00:17:01,840 --> 00:17:09,000 我在這裡所說的是我希望看到一個十進制數,也許一個字符。 286 00:17:09,000 --> 00:17:12,000 我們會看到為什麼是這樣的情況下,在短短的時刻。 287 00:17:12,000 --> 00:17:15,869 事實證明,這個符號是現在回憶的東西,我們開始談論 288 00:17:15,869 --> 00:17:17,619 只是在一個星期前。 289 00:17:17,619 --> 00:17:21,740 什麼是&N&C為我們做嗎? >> [學生] n和c的地址。 290 00:17:21,740 --> 00:17:25,400 是啊。它給我的地址n和c的地址。為什麼這很重要? 291 00:17:25,400 --> 00:17:30,220 你知道,在C的功能,您可以隨時返回一個值或沒有價值。 292 00:17:30,220 --> 00:17:34,530 您可以返回一個int,一個字符串,一個浮點數,字符,什麼的,或者你可以返回void, 293 00:17:34,530 --> 00:17:38,030 但你可以只返回一件事最大限度。 294 00:17:38,030 --> 00:17:42,760 但在這裡我們要sscanf的我,也許返回一個int,一個十進制數, 295 00:17:42,760 --> 00:17:46,220 和一個字符,在某一時刻,我會解釋為什麼字符。 296 00:17:46,220 --> 00:17:51,460 您可以有效地sscanf函數返回兩件事情,但是這只是不可能在C. 297 00:17:51,460 --> 00:17:55,200 您可以解決的,通過兩個地址 298 00:17:55,200 --> 00:17:57,370 因為只要你交給一個功能的兩個地址, 299 00:17:57,370 --> 00:18:00,470 該函數有什麼可以做呢? >> [學生]發表到這些地址。 300 00:18:00,470 --> 00:18:02,010 它可以寫入到這些地址。 301 00:18:02,010 --> 00:18:05,770 您可以使用恆星運轉,去那裡,每個地址。 302 00:18:05,770 --> 00:18:11,260 用於改變的變量的值,它的排序這個後門的機制,但很常見的 303 00:18:11,260 --> 00:18:14,870 以上只是一個地方 - 在這種情況下,兩個。 304 00:18:14,870 --> 00:18:21,340 請注意,我檢查== 1,然後返回n如果這樣做,其實,計算結果為true。 305 00:18:21,340 --> 00:18:26,170 所以,這是怎麼回事呢?從技術上說,我們真的要發生在調用getInt是這樣的。 306 00:18:26,170 --> 00:18:30,740 我們要分析,可以這麼說,我們要讀取的字符串 - 報價 - 享有的123 - 307 00:18:30,740 --> 00:18:34,560 如果它看起來像有一個數字,則我們告訴sscanf的做 308 00:18:34,560 --> 00:18:38,190 在這個變量n對我來說,這個數字 - 123 - 。 309 00:18:38,190 --> 00:18:42,090 那麼為什麼我居然有這樣的呢? 310 00:18:42,090 --> 00:18:48,220 sscanf的說你可能會得到一個字符在這裡的作用是什麼? 311 00:18:48,220 --> 00:18:53,470 [聽不見的學生反應] >> A小數點實際上可以工作。 312 00:18:53,470 --> 00:18:56,330 讓我們認為,想了一會兒。還有什麼呢? 313 00:18:56,330 --> 00:18:59,270 [學生]:這可能是NULL。 >>良好的思想。這可能是空字符。 314 00:18:59,270 --> 00:19:01,660 在這種情況下,它實際上不是。是啊。 >> [學生] ASCII。 315 00:19:01,660 --> 00:19:04,340 ASCII。還是讓我進一步概括。 316 00:19:04,340 --> 00:19:06,640 %c有錯誤檢查。 317 00:19:06,640 --> 00:19:09,300 我們不希望這是之後的字符數, 318 00:19:09,300 --> 00:19:11,870 但讓​​我做的是以下。 319 00:19:11,870 --> 00:19:18,210 事實證明,sscanf的,除了這裡存儲在n和c的值,在這個例子中, 320 00:19:18,210 --> 00:19:24,890 什麼也沒有返回的變量值英寸 321 00:19:24,890 --> 00:19:30,260 所以,如果你只輸入了123,那麼只有%是怎麼回事相匹配, 322 00:19:30,260 --> 00:19:33,880 只有n個被存儲的值,如123, 323 00:19:33,880 --> 00:19:35,640 沒有東西在c。 324 00:19:35,640 --> 00:19:37,620 C保持一個垃圾值,可以這麼說 - 325 00:19:37,620 --> 00:19:40,730 垃圾,因為它從來沒有被初始化為某個值。 326 00:19:40,730 --> 00:19:45,520 因此,在這種情況下,sscanf函數返回1,因為我填充這些指針, 327 00:19:45,520 --> 00:19:50,190 在這種情況下,偉大的,我有一個int,所以我釋放線釋放內存 328 00:19:50,190 --> 00:19:54,000 實際上,GetString的分配,然後我返回n, 329 00:19:54,000 --> 00:19:58,500 否則,如果你有沒有想過,重試來自​​,它來自這裡。 330 00:19:58,500 --> 00:20:04,390 這樣的話,與此相反,I型123foo - 只是一些隨機序列的文本 - 331 00:20:04,390 --> 00:20:08,490 ,sscanf的是要看到數字,數字,數,f, 332 00:20:08,490 --> 00:20:16,410 和它打算把n的123,它打算把在c在f,然後返回2。 333 00:20:16,410 --> 00:20:20,640 因此,我們有,只是使用的基本定義,sscanf的行為,一個很簡單的方法 - 334 00:20:20,640 --> 00:20:23,900 以及,複雜,乍一看,但在年底的一天相當簡單的機制 - 335 00:20:23,900 --> 00:20:28,320 說的是有一個int,如果是的話,是我發現的唯一嗎? 336 00:20:28,320 --> 00:20:29,860 這裡的空白是故意的。 337 00:20:29,860 --> 00:20:34,000 如果你讀了sscanf的文檔,它會告訴你,如果你有一塊空白 338 00:20:34,000 --> 00:20:38,810 在開端或末端,sscanf的太將允許用戶,無論什麼原因, 339 00:20:38,810 --> 00:20:41,860 按空格鍵123,這將是合法的。 340 00:20:41,860 --> 00:20:44,150 你不會在用戶喊叫,只是因為他們打空格鍵 341 00:20:44,150 --> 00:20:48,640 在開始或結束,這只是一個小更方便用戶使用。 342 00:20:48,640 --> 00:20:52,300 >> 如有任何問題,然後調用getInt?是啊。 >> [學生]如果你只是把一個char是什麼? 343 00:20:52,300 --> 00:20:54,030 這個問題問得好。 344 00:20:54,030 --> 00:20:59,890 如果你剛剛輸入的一個字符像f,並按下回車鍵沒有輸入123,該怎麼辦? 345 00:20:59,890 --> 00:21:02,420 你認為這行代碼的行為將是什麼? 346 00:21:02,420 --> 00:21:04,730 [聽不見的學生反應] 347 00:21:04,730 --> 00:21:08,790 是啊,所以sscanf的可以覆蓋這一點,因為在這種情況下,它不會填寫N或C。 348 00:21:08,790 --> 00:21:15,310 這是怎麼回事,而不是返回0,在這種情況下,我也趕上該方案 349 00:21:15,310 --> 00:21:18,750 我想是因為預期值1。 350 00:21:18,750 --> 00:21:22,000 我只想要一個只有一件事來填補。這個問題問得好。 351 00:21:22,000 --> 00:21:24,290 >> 其他人嗎?好的。 352 00:21:24,290 --> 00:21:26,250 >> 讓我們通過在這裡的所有的功能, 353 00:21:26,250 --> 00:21:29,500 但是,這似乎是可能的剩餘權益的GetString 354 00:21:29,500 --> 00:21:32,790 因為事實證明調用getInt GetFloat,的GetDouble,GetLongLong 355 00:21:32,790 --> 00:21:36,260 所有平底船了很多的功能,GetString的。 356 00:21:36,260 --> 00:21:39,750 因此,讓我們來看看他是如何在這裡實現。 357 00:21:39,750 --> 00:21:43,630 這一個看起來有點複雜,但它使用相同的基本原理 358 00:21:43,630 --> 00:21:45,670 我們開始談論上週。 359 00:21:45,670 --> 00:21:49,490 GetString時,它沒有參數,在這裡每虛空 360 00:21:49,490 --> 00:21:53,730 它返回一個字符串,我顯然我聲明了字符串緩衝。 361 00:21:53,730 --> 00:21:56,270 我真的不知道那是什麼要用於還,但我們會看到。 362 00:21:56,270 --> 00:21:58,390 它看起來像能力是由默認的0。 363 00:21:58,390 --> 00:22:01,350 不太清楚這是怎麼回事,不知道n是要用於還 364 00:22:01,350 --> 00:22:03,590 但現在它變得更有趣一些。 365 00:22:03,590 --> 00:22:06,520 在243行,我們聲明了一個int,C。 366 00:22:06,520 --> 00:22:08,800 這是一個愚蠢的細節。 367 00:22:08,800 --> 00:22:15,820 char是8位,8位可以存儲多少不同的值嗎? >> [學生256。 >> 256。 368 00:22:15,820 --> 00:22:20,730 現在的問題是,如果你想有256個不同的ASCII字符,其中有 369 00:22:20,730 --> 00:22:23,340 如果你認為 - 這是不是記住的東西。 370 00:22:23,340 --> 00:22:25,710 但是,如果你覺得回到了那個大的ASCII圖表,我們有幾個星期前, 371 00:22:25,710 --> 00:22:30,600 在這種情況下,有128或256個ASCII字符。 372 00:22:30,600 --> 00:22:32,940 我們使用所有的模式,“0”和“1了。 373 00:22:32,940 --> 00:22:36,210 這是一個問題,如果你想成為能夠檢測到一個錯誤 374 00:22:36,210 --> 00:22:40,190 因為如果你已經使用了256個值,為你的角色, 375 00:22:40,190 --> 00:22:43,050 你真的不提前計劃,因為現在你也沒有辦法說, 376 00:22:43,050 --> 00:22:46,270 這是不是一個合法的字符,這是一些錯誤的信息。 377 00:22:46,270 --> 00:22:50,270 所以,世界是他們最大的價值,像一個int, 378 00:22:50,270 --> 00:22:54,720 所以,你有一個瘋狂的數字,32位,4億的可能值 379 00:22:54,720 --> 00:22:58,860 所以,你可以簡單的使用基本上是257, 380 00:22:58,860 --> 00:23:01,720 1,其中有一些特殊的含義為錯誤。 381 00:23:01,720 --> 00:23:03,120 >> 因此,讓我們來看看它是如何工作的。 382 00:23:03,120 --> 00:23:07,760 在246行,我有這樣大的while循環,調用fgetc函數, 383 00:23:07,760 --> 00:23:11,090 F含義的文件,所以GETC,然後標準輸入。 384 00:23:11,090 --> 00:23:15,520 事實證明,這僅僅是說從鍵盤讀取輸入更精確的方法。 385 00:23:15,520 --> 00:23:19,300 標準輸入方式鍵盤,標準輸出屏幕, 386 00:23:19,300 --> 00:23:23,310 和標準錯誤,我們會看到pset4的,就是說屏幕 387 00:23:23,310 --> 00:23:27,490 而是一種特殊的屏幕部分,因此,它不是與實際產量混為一談 388 00:23:27,490 --> 00:23:30,750 你打算打印。但更多的是在未來。 389 00:23:30,750 --> 00:23:34,440 因此fgetc函數從鍵盤讀取一個字符,並將其存儲在那裡? 390 00:23:34,440 --> 00:23:37,350 將它保存在c。 391 00:23:37,350 --> 00:23:41,360 然後再檢查 - 所以我只是用一些布爾連詞 - 392 00:23:41,360 --> 00:23:46,000 檢查它不等於“ - \ n,所以在用戶按下回車鍵,我們要停止在這一點上, 393 00:23:46,000 --> 00:23:49,850 循環結束 - 我們還需要檢查的特殊常量EOF, 394 00:23:49,850 --> 00:23:53,610 如果你知道或猜測,什麼是代表? >> [學生]:文件的末尾。 >>末頁的文件。 395 00:23:53,610 --> 00:23:56,560 這是一種荒謬的,因為如果我在鍵盤上打字, 396 00:23:56,560 --> 00:23:58,870 真的沒有參與這一​​文件, 397 00:23:58,870 --> 00:24:01,150 但是,這僅僅是排序的通用術語,用來指 398 00:24:01,150 --> 00:24:04,220 ,沒有別的來自人類的手指。 399 00:24:04,220 --> 00:24:06,460 EOF - 文件結束。 400 00:24:06,460 --> 00:24:09,920 順便說一句,如果你曾經打你的鍵盤控制D,不,你還沒有 - 401 00:24:09,920 --> 00:24:15,230 你按下Control C - D發送控制這個特殊的常數,稱為EOF。 402 00:24:15,230 --> 00:24:19,850 所以,現在我們只是有一些動態內存分配。 403 00:24:19,850 --> 00:24:23,440 >> 所以,如果第(n + 1>容量)。現在我將解釋N。 404 00:24:23,440 --> 00:24:26,100 N是目前究竟有多少字節在緩衝區中, 405 00:24:26,100 --> 00:24:28,620 你目前正在建設的字符串從用戶。 406 00:24:28,620 --> 00:24:33,450 如果你有比你有更多的字符在緩衝區中的緩衝能力, 407 00:24:33,450 --> 00:24:37,410 直觀地,我們需要做的是什麼,然後分配更多的容量。 408 00:24:37,410 --> 00:24:43,330 所以我要掠過這裡的算術只專注於這個功能。 409 00:24:43,330 --> 00:24:46,070 你知道什麼是malloc的,或至少是一般熟悉。 410 00:24:46,070 --> 00:24:48,970 什麼realloc的猜測。 >> [學生]添加內存。 411 00:24:48,970 --> 00:24:52,920 這不是很新增記憶體。它重新分配的內存如下。 412 00:24:52,920 --> 00:24:57,220 如果在字符串的結尾還是有空間,該內存以使您更 413 00:24:57,220 --> 00:25:00,000 比原來給你,然後你會得到額外的內存。 414 00:25:00,000 --> 00:25:03,460 所以,你可以不斷地將字符串的字符背靠背背靠背。 415 00:25:03,460 --> 00:25:05,830 但是,如果是這樣的情況並非如此,因為你等太久 416 00:25:05,830 --> 00:25:07,940 和一些隨機得到了一屁股在內存中 417 00:25:07,940 --> 00:25:10,290 但有額外的內存在這兒,沒關係。 418 00:25:10,290 --> 00:25:13,100 realloc是要為你做所有的繁重, 419 00:25:13,100 --> 00:25:16,750 移動您已經閱讀因而在離這裡不遠的字符串,把它放在那裡, 420 00:25:16,750 --> 00:25:19,460 然後給你一些更多的在這一點上跑道。 421 00:25:19,460 --> 00:25:22,550 >> 因此,一揮手,讓我說,是做什麼的GetString 422 00:25:22,550 --> 00:25:26,330 是它的一個小緩衝區,也許一個單一的字符, 423 00:25:26,330 --> 00:25:30,820 如果兩個字符的用戶類型,GetString的最終調用realloc的,並說 424 00:25:30,820 --> 00:25:33,150 一個字符是不夠的,給我兩個字符。 425 00:25:33,150 --> 00:25:35,950 然後,如果你讀通過邏輯的循環,它會說 426 00:25:35,950 --> 00:25:39,600 用戶輸入3個字符;給我,而不是2 4個字符, 427 00:25:39,600 --> 00:25:42,320 然後給我,然後給我16位和32位。 428 00:25:42,320 --> 00:25:45,000 事實上,我的能力增加一倍 429 00:25:45,000 --> 00:25:48,570 意味著該緩衝區不會生長緩慢,它的超快速增長。 430 00:25:48,570 --> 00:25:51,380 可能是什麼的優勢是什麼? 431 00:25:51,380 --> 00:25:54,600 為什麼我的緩衝區大小增加一倍 432 00:25:54,600 --> 00:25:58,020 即使用戶可能只需要一個額外的字符從鍵盤嗎? 433 00:25:58,020 --> 00:26:01,750 [聽不見的學生回應] >>那是什麼? >> [學生]你不經常必須增加。 434 00:26:01,750 --> 00:26:03,300 沒錯。您不必經常增長。 435 00:26:03,300 --> 00:26:05,510 而這僅僅是種對沖你的賭注在這裡, 436 00:26:05,510 --> 00:26:10,850 的想法是,你不希望調用realloc的有很多,因為它往往是緩慢的。 437 00:26:10,850 --> 00:26:12,910 任何時候,你問的操作系統的內存, 438 00:26:12,910 --> 00:26:16,990 你很快就會看到在未來的習題集,它往往需要一定的時間。 439 00:26:16,990 --> 00:26:20,010 因此,最大限度地減少,大量的時間,即使你浪費了一些空間, 440 00:26:20,010 --> 00:26:21,900 往往是一個很好的事情。 441 00:26:21,900 --> 00:26:24,060 >> 但是,如果我們讀通過的GetString在這裡的最後一部分 - 442 00:26:24,060 --> 00:26:27,950 重新認識這裡的每一行是不那麼重要的今天 - 443 00:26:27,950 --> 00:26:30,530 注意,它最終再次調用malloc 444 00:26:30,530 --> 00:26:33,880 它分配完全一樣,因為它需要多少個字節的字符串 445 00:26:33,880 --> 00:26:38,060 然後扔掉致電免費過大的緩衝區 446 00:26:38,060 --> 00:26:40,080 如果它確實得到了太多的時間翻了一倍。 447 00:26:40,080 --> 00:26:42,730 因此,在短,這是多麼的GetString已工作時間。 448 00:26:42,730 --> 00:26:47,060 它所做的就是讀取一個字符的時候,一而再,再而三, 449 00:26:47,060 --> 00:26:50,750 每次它需要一些額外的內存,它要求操作系統 450 00:26:50,750 --> 00:26:53,670 通過調用realloc的。 451 00:26:53,670 --> 00:26:57,890 >> 有什麼問題嗎?好的。 452 00:26:57,890 --> 00:26:59,270 >> 的攻擊。 453 00:26:59,270 --> 00:27:04,060 現在,我們理解指針,或者至少是越來越熟悉指針, 454 00:27:04,060 --> 00:27:06,700 讓我們考慮如何在整個世界開始崩潰 455 00:27:06,700 --> 00:27:10,030 如果你不太捍衛對對抗性用戶, 456 00:27:10,030 --> 00:27:11,850 人們正試圖攻入你的系統, 457 00:27:11,850 --> 00:27:16,890 人誰是試圖竊取您的軟件繞過一些註冊碼 458 00:27:16,890 --> 00:27:19,090 否則,他們可能有輸入英寸 459 00:27:19,090 --> 00:27:22,990 >> 在這個例子來看看這裡,這是C代碼的底部,有一個main函數的 460 00:27:22,990 --> 00:27:26,380 調用一個函數foo。又是什麼呢傳遞給foo? 461 00:27:26,380 --> 00:27:29,680 [學生]一個參數。 >> [馬蘭]的單個參數。 462 00:27:29,680 --> 00:27:33,450 因此,ARGV [1],這意味著用戶在命令行中輸入的第一個字 463 00:27:33,450 --> 00:27:36,360 後a.out或其他程序調用。 464 00:27:36,360 --> 00:27:41,680 所以foo的頂部需要一個char *。但char *是什麼? >> [學生]一個字符串。 465 00:27:41,680 --> 00:27:43,350 [馬蘭]一個字符串,因此在這裡沒有什麼新東西。 466 00:27:43,350 --> 00:27:45,420 該字符串是任意被稱為酒吧。 467 00:27:45,420 --> 00:27:51,430 在這裡,字符c [12];類的半技術性的英語,這條線是在做什麼? 468 00:27:51,430 --> 00:27:55,220 [學生]的數組 - >>陣? >> [學生]字符。 >>字符。 469 00:27:55,220 --> 00:27:58,870 給我一個陣列為12個字符。因此,我們可以稱之為一個緩衝。 470 00:27:58,870 --> 00:28:02,920 它在技術上被稱為C,但程序中的緩衝區僅僅意味著一堆的空間 471 00:28:02,920 --> 00:28:04,800 你可以把一些東西英寸 472 00:28:04,800 --> 00:28:07,940 然後,最後,memcpy的,我們還沒有使用過的,但你可能已經猜到它做什麼。 473 00:28:07,940 --> 00:28:10,480 它的內存複製。它有什麼作用呢? 474 00:28:10,480 --> 00:28:19,270 顯然複製酒吧,它的輸入,到c的長度吧。 475 00:28:19,270 --> 00:28:24,930 但有一個錯誤在這裡。 >> [學生]您需要的sizeof字符。 “好了。 476 00:28:24,930 --> 00:28:30,860 從技術上講,我們真的應該做的strlen(條)* sizeof(char)的)的。這是正確的。 477 00:28:30,860 --> 00:28:33,930 但是,在這裡的最壞的情況下,讓我們假定that's - 478 00:28:33,930 --> 00:28:35,950 好吧。然後有兩個錯誤。 479 00:28:35,950 --> 00:28:39,160 大小(字符)); 480 00:28:39,160 --> 00:28:41,290 讓我們使這一點更廣泛。 481 00:28:41,290 --> 00:28:44,910 所以現在仍然是一個錯誤,這是什麼? >> [聽不見的學生反應] 482 00:28:44,910 --> 00:28:46,990 檢查什麼呢? >> [學生]檢查是否為NULL。 483 00:28:46,990 --> 00:28:50,270 一般應檢查是否為NULL,因為不好的事情發生 484 00:28:50,270 --> 00:28:53,200 當指針為NULL,因為你可能最終會去那裡, 485 00:28:53,200 --> 00:28:57,630 你應該不會去提領的星算為NULL。 486 00:28:57,630 --> 00:29:01,050 所以這是很好的。而我們做什麼?從邏輯上講,在這裡有一個缺陷。 487 00:29:01,050 --> 00:29:04,450 [學生]檢查,如果argc> = 2。 488 00:29:04,450 --> 00:29:10,550 因此,檢查,如果argc> = 2。好了,所以在這個程序有三個錯誤這裡。 489 00:29:10,550 --> 00:29:16,630 我們現在會檢查,如果用戶實際鍵入任何東西到argv [1]。好。 490 00:29:16,630 --> 00:29:20,950 那麼什麼是第三個錯誤嗎?是啊。 >> [學生] C可能沒有足夠大。 491 00:29:20,950 --> 00:29:23,320 好。我們檢查一個場景。 492 00:29:23,320 --> 00:29:29,520 隱式檢查,請不要複製更多的內存比將超過該長度的酒吧。 493 00:29:29,520 --> 00:29:32,510 因此,如果字符串用戶輸入的長度為10個字符, 494 00:29:32,510 --> 00:29:36,020 這是說只複製10個字符。沒關係。 495 00:29:36,020 --> 00:29:39,940 但是,如果用戶鍵入20個字符的字一個字的​​提示一樣嗎? 496 00:29:39,940 --> 00:29:44,900 這是說拷貝20個字符酒吧變成了什麼? 497 00:29:44,900 --> 00:29:49,750 C,否則被稱為我們的緩衝區,這意味著你只是寫數據 498 00:29:49,750 --> 00:29:52,540 8個字節,你沒有自己的位置, 499 00:29:52,540 --> 00:29:54,870 你並不擁有它們在這個意義上,你永遠不分配。 500 00:29:54,870 --> 00:30:00,370 因此,這是一般人都知道的緩衝區溢出攻擊緩衝區溢出攻擊。 501 00:30:00,370 --> 00:30:05,580 在這個意義上,它是一個攻擊,如果用戶或程序的調用你的函數 502 00:30:05,580 --> 00:30:10,490 這樣做惡意,實際情況下,實際上可能是相當糟糕的。 503 00:30:10,490 --> 00:30:12,450 >> 因此,讓我們來看看這張照片。 504 00:30:12,450 --> 00:30:16,060 此圖片代表你的內存堆棧。 505 00:30:16,060 --> 00:30:19,580 回想一下,每次你調用一個函數,你這個小的堆棧幀 506 00:30:19,580 --> 00:30:21,520 然後另一個,然後另一個和另一個。 507 00:30:21,520 --> 00:30:24,300 因此,到目前為止,我們只是一種抽象的這些矩形 508 00:30:24,300 --> 00:30:26,290 在黑板上,或在屏幕上這裡。 509 00:30:26,290 --> 00:30:30,580 但是,如果我們放大這些矩形,當你調用一個函數foo, 510 00:30:30,580 --> 00:30:35,880 事實證明,更重要的是在棧上,框架內的在該矩形 511 00:30:35,880 --> 00:30:40,060 比是x和y,a和b,就像我們談論交換。 512 00:30:40,060 --> 00:30:44,410 事實證明,有一些低級別的細節,其中包括返回地址。 513 00:30:44,410 --> 00:30:49,550 因此,原來當主調用foo,主要有告知富 514 00:30:49,550 --> 00:30:53,520 main()的地址是在計算機的內存中 515 00:30:53,520 --> 00:30:57,770 因為否則,盡快foo的完成,在這種情況下,在這裡,執行 516 00:30:57,770 --> 00:31:00,830 一旦你達到這個封閉的大括號結束時的foo, 517 00:31:00,830 --> 00:31:05,310 富不知道如何赫克控制的程序是應該去嗎? 518 00:31:05,310 --> 00:31:08,970 事實證明,這個問題的答案是在這個紅色矩形。 519 00:31:08,970 --> 00:31:12,670 這是一個指針,它是電腦臨時存儲 520 00:31:12,670 --> 00:31:17,030 所謂的堆疊上的主地址,以便盡快為foo執行完成, 521 00:31:17,030 --> 00:31:21,120 電腦知道在哪裡和什麼線主要回去。 522 00:31:21,120 --> 00:31:23,940 保存的幀指針涉及此同樣。 523 00:31:23,940 --> 00:31:26,310 CHAR *酒吧代表著什麼? 524 00:31:26,310 --> 00:31:31,350 現在這個藍色的部分是foo的框架。什麼是吧? 525 00:31:31,570 --> 00:31:35,010 酒吧的foo函數的參數。 526 00:31:35,010 --> 00:31:37,500 所以,現在我們又回到熟悉的畫面在排序。 527 00:31:37,500 --> 00:31:39,850 還有更多的東西,並在屏幕上的干擾, 528 00:31:39,850 --> 00:31:43,380 但這種淡藍色的部分恰恰是我們一直在畫在黑板上 529 00:31:43,380 --> 00:31:45,790 類似交換。這是為foo的框架。 530 00:31:45,790 --> 00:31:51,490 唯一在它現在是吧,這是此參數。 531 00:31:51,490 --> 00:31:55,220 還有什麼應該是在堆棧中,根據此代碼在這裡? 532 00:31:55,220 --> 00:31:57,760 [學生]字符c [12]。 >> [馬蘭字符c [12]。 533 00:31:57,760 --> 00:32:02,810 我們也應該看到,12平方的內存分配給一個變量名為c, 534 00:32:02,810 --> 00:32:04,970 而事實上,我們也有在屏幕上。 535 00:32:04,970 --> 00:32:08,480 最頂端的是c [0],然後這張圖的作者 536 00:32:08,480 --> 00:32:11,850 沒有理會繪製所有的平方,但確實有12有 537 00:32:11,850 --> 00:32:16,590 因為,如果你看一下在右下角,C [11]如果從0數是12這樣的字節。 538 00:32:16,590 --> 00:32:18,400 但這裡的問題。 539 00:32:18,400 --> 00:32:22,390 在哪個方向是C成長? 540 00:32:22,390 --> 00:32:27,080 自上而下的,如果它開始的頂部和底部生長的排序。 541 00:32:27,080 --> 00:32:30,110 它看起來並不像我們給自己多跑道在這裡。 542 00:32:30,110 --> 00:32:32,090 我們畫種自己陷入了困境, 543 00:32:32,090 --> 00:32:36,940 C [11]是正確的,對吧,這是對保存的幀指針, 544 00:32:36,940 --> 00:32:39,960 這是正確的,對返回地址。有沒有更多的空間。 545 00:32:39,960 --> 00:32:42,810 那麼,有什麼含義,然後如果你搞砸了 546 00:32:42,810 --> 00:32:46,500 您嘗試讀取20字節到12個字節的緩衝區? 547 00:32:46,500 --> 00:32:50,060 這8個額外的字節哪裡去了? >> [學生]內 - 548 00:32:50,060 --> 00:32:53,200 一切裡面,其中有一些是超級重要的。 549 00:32:53,200 --> 00:32:57,260 和最重要的事情,可能是那裡的​​紅色框,返回地址, 550 00:32:57,260 --> 00:33:03,560 因為假設你是意外或adversarially的覆蓋這4個字節, 551 00:33:03,560 --> 00:33:07,260 該指針的地址,不只是垃圾,但有一些 552 00:33:07,260 --> 00:33:09,810 發生這種情況表示在內存中的實際地址。 553 00:33:09,810 --> 00:33:13,880 有何重要意義,邏輯嗎? >> [學生]函數將返回一個不同的地方。 554 00:33:13,880 --> 00:33:15,250 沒錯。 555 00:33:15,250 --> 00:33:19,170 當foo回報率和點擊率,大括號,程序將繼續進行 556 00:33:19,170 --> 00:33:25,060 返回到主,它會返回的地址是在這紅色框。 557 00:33:25,060 --> 00:33:28,600 >> 在繞過軟件登記的情況下, 558 00:33:28,600 --> 00:33:32,260 什麼如果返回到地址的功能,通常被稱為 559 00:33:32,260 --> 00:33:35,690 後,你支付的軟件,輸入你的註冊碼? 560 00:33:35,690 --> 00:33:39,870 您可以按招的電腦不會在這裡,而是在這裡。 561 00:33:39,870 --> 00:33:45,100 或者,如果你真的很聰明,對手實際上可以輸入在鍵盤上,例如, 562 00:33:45,100 --> 00:33:50,690 而不是實際的單詞,而不是20個字符,但假設他或她居然類型 563 00:33:50,690 --> 00:33:52,770 一些字符表示代碼。 564 00:33:52,770 --> 00:33:55,320 它不會是C代碼,它實際上是字符 565 00:33:55,320 --> 00:33:59,290 代表二進制機器代碼,“0”和“1。 566 00:33:59,290 --> 00:34:01,290 但是,假如他們足夠聰明,要做到這一點, 567 00:34:01,290 --> 00:34:06,500 以某種方式粘貼到GetString的的提示東西,基本上是編譯後的代碼, 568 00:34:06,500 --> 00:34:09,980 最後4個字節,返回地址覆蓋。 569 00:34:09,980 --> 00:34:13,360 請問您的地址,輸入怎麼辦? 570 00:34:13,360 --> 00:34:18,630 它實際上是存儲在這個紅色矩形的緩衝區的第一個字節的地址。 571 00:34:18,630 --> 00:34:23,070 所以,你必須是真聰明,這是一個很大的試驗和錯誤不好的人,在那裡, 572 00:34:23,070 --> 00:34:25,639 但如果你能有多大,這個緩衝區 573 00:34:25,639 --> 00:34:28,820 最後幾個字節的輸入您提供的程序 574 00:34:28,820 --> 00:34:33,540 發生在開始您的緩衝區的地址,你可以做到這一點。 575 00:34:33,540 --> 00:34:39,320 如果我們通常所說的招呼,\ 0,這就是在緩衝區。 576 00:34:39,320 --> 00:34:44,420 但是,如果我們更聰明,我們填補了這一緩衝,我們將統稱叫什麼攻擊代碼 - 577 00:34:44,420 --> 00:34:48,860 AAA,攻擊,攻擊,攻擊 - 這是只是做了一件壞事, 578 00:34:48,860 --> 00:34:51,820 如果你真的很聰明,會發生什麼情況,你可能做到這一點。 579 00:34:51,820 --> 00:34:58,610 在這裡的紅色框是一個數字序列 - 80,C0,35,08。 580 00:34:58,610 --> 00:35:01,610 請注意,相匹配的數字在這裡。 581 00:35:01,610 --> 00:35:04,430 它以相反的順序,但其他一些時間。 582 00:35:04,430 --> 00:35:08,140 請注意,這個返回地址被故意改變 583 00:35:08,140 --> 00:35:12,020 相同的地址,而不是主要的地址。 584 00:35:12,020 --> 00:35:17,500 因此,如果壞傢伙是超級聰明,他或她將要包括在該攻擊代碼 585 00:35:17,500 --> 00:35:20,930 像刪除所有用戶的文件或複製的密碼 586 00:35:20,930 --> 00:35:24,680 或創建一個用戶帳戶,然後我就可以登錄到 - 在所有事情。 587 00:35:24,680 --> 00:35:26,950 >> 這是危險的力量C. 588 00:35:26,950 --> 00:35:29,840 因為你必須通過指針存取記憶體 589 00:35:29,840 --> 00:35:32,520 因此,你可以寫任何你想要到一台計算機的內存中, 590 00:35:32,520 --> 00:35:35,080 你可以讓一台計算機做任何你想要的 591 00:35:35,080 --> 00:35:39,550 簡單的跳躍,在它自己的內存空間。 592 00:35:39,550 --> 00:35:44,650 所以到今天這麼多的程序和這麼多的網站被攻破 593 00:35:44,650 --> 00:35:46,200 歸結到人趁著這個。 594 00:35:46,200 --> 00:35:50,760 這可能看起來像一個超級複雜的攻擊,但它並不總是這種方式開始。 595 00:35:50,760 --> 00:35:53,560 現實情況是,什麼不好的人通常會做的是, 596 00:35:53,560 --> 00:35:58,200 無論它是一個程序,在命令行或GUI程序或網站, 597 00:35:58,200 --> 00:35:59,940 你剛開始提供廢話。 598 00:35:59,940 --> 00:36:03,980 您鍵入一個真正的大詞在搜索字段並按下回車鍵, 599 00:36:03,980 --> 00:36:05,780 你就等著看,如果網站崩潰 600 00:36:05,780 --> 00:36:09,990 或者你就等著看,如果程序體現了一些錯誤信息 601 00:36:09,990 --> 00:36:14,330 因為如果你幸運的壞傢伙,你提供一些瘋狂的輸入 602 00:36:14,330 --> 00:36:18,980 ,導致程序崩潰,這意味著程序員沒有預料到你的錯誤行為, 603 00:36:18,980 --> 00:36:23,630 這意味著你可以有足夠的精力,足夠的試驗和錯誤, 604 00:36:23,630 --> 00:36:26,650 如何發動更精確的攻擊。 605 00:36:26,650 --> 00:36:31,410 因此,安全的一部分,不只是完全避免這些攻擊 606 00:36:31,410 --> 00:36:34,100 但檢測,實際上是在尋找日誌 607 00:36:34,100 --> 00:36:36,780 並看到什麼瘋狂的輸入輸入到你的網站的人, 608 00:36:36,780 --> 00:36:38,960 什麼樣的搜索字詞輸入到您的網站的人 609 00:36:38,960 --> 00:36:42,870 在一定的緩衝溢出的希望。 610 00:36:42,870 --> 00:36:45,500 而這一切都可以歸結為簡單的基礎知識,什麼是一個數組 611 00:36:45,500 --> 00:36:49,080 這是什麼意思,分配和使用內存。 612 00:36:49,080 --> 00:36:51,710 >> 相關的,然後是這樣的。 613 00:36:51,710 --> 00:36:54,280 我們只是看了一眼裡面的硬盤驅動器。 614 00:36:54,280 --> 00:36:58,440 你還記得一兩個星期前,當你將文件拖到回收站或垃圾桶, 615 00:36:58,440 --> 00:37:03,710 發生了什麼? >> [學生]沒有。 “絕對沒有,對不對? 616 00:37:03,710 --> 00:37:05,740 最後,如果你運行的磁盤空間不足, 617 00:37:05,740 --> 00:37:08,190 Windows或Mac OS將開始為您刪除的文件。 618 00:37:08,190 --> 00:37:10,390 但是,如果你拖動的東西在那裡,這不是在所有的安全。 619 00:37:10,390 --> 00:37:13,800 你的室友或朋友或家人做的就是雙擊,瞧, 620 00:37:13,800 --> 00:37:16,310 所有的粗略的,您嘗試刪除的文件。 621 00:37:16,310 --> 00:37:19,590 我們大多數人至少知道,你必須右擊或控制點擊 622 00:37:19,590 --> 00:37:22,310 清空垃圾桶或類似的東西。 623 00:37:22,310 --> 00:37:25,000 但是,即使這樣,它不太做的伎倆 624 00:37:25,000 --> 00:37:28,010 因為當你有你的硬盤驅動器上的文件 625 00:37:28,010 --> 00:37:32,770 一些Word文件或某些JPEG,這代表您的硬盤驅動器, 626 00:37:32,770 --> 00:37:35,350 讓我們說這個條子在這裡表示該文件, 627 00:37:35,350 --> 00:37:38,390 它是由一大堆的0和1。 628 00:37:38,390 --> 00:37:42,470 會發生什麼事時,你不僅該文件拖動到垃圾桶或回收站 629 00:37:42,470 --> 00:37:48,020 但也空嗎?排序無關。 630 00:37:48,020 --> 00:37:49,640 這不是絕對沒有。 631 00:37:49,640 --> 00:37:54,290 現在是不是真的發生在此表的形式,因為少了一些。 632 00:37:54,290 --> 00:37:58,370 因此,有一些種類的數據庫或表內的一台計算機的內存 633 00:37:58,370 --> 00:38:03,850 在本質上具有文件的名稱,一列一列文件的位置, 634 00:38:03,850 --> 00:38:07,720 這可能是123,只是一個隨機位置。 635 00:38:07,720 --> 00:38:14,560 因此,我們可能有一些如x.jpeg和地點123。 636 00:38:14,560 --> 00:38:18,800 然後會發生什麼當你真正清空你的回收站? 637 00:38:18,800 --> 00:38:20,330 這消失。 638 00:38:20,330 --> 00:38:23,610 但不會消失的是0和1。 639 00:38:23,610 --> 00:38:26,270 >> 那麼,有什麼然後連接到pset4的嗎? 640 00:38:26,270 --> 00:38:31,240 好了,與pset4,只是因為我們不小心刪掉了緊湊型閃存卡 641 00:38:31,240 --> 00:38:35,750 所有這些照片,或只是因為它的壞運氣成為損壞 642 00:38:35,750 --> 00:38:38,000 並不意味著“0”和“1”是不是仍然存在。 643 00:38:38,000 --> 00:38:40,410 也許他們幾個人都失去了,因為有東西損壞 644 00:38:40,410 --> 00:38:43,320 在這個意義上,一些“0”變成1秒和1秒變成0。 645 00:38:43,320 --> 00:38:47,240 不好的事情都可能發生,因為軟件bug或有缺陷的硬件。 646 00:38:47,240 --> 00:38:50,370 但許多這些位,也許他們甚至100%,是仍然存在。 647 00:38:50,370 --> 00:38:55,050 這只是電腦或相機,不知道去哪裡JPEG1開始 648 00:38:55,050 --> 00:38:56,910 和JPEG2開始。 649 00:38:56,910 --> 00:39:01,070 但是,如果你作為程序員,知道這些JPEG文件是位精明的 650 00:39:01,070 --> 00:39:06,010 它們看起來像什麼,這樣你就可以分析“0”和“1和JPEG,JPEG, 651 00:39:06,010 --> 00:39:09,440 你可以寫一個程序,基本上只是一個while循環 652 00:39:09,440 --> 00:39:12,820 ,恢復這些文件的每個人。 653 00:39:12,820 --> 00:39:16,030 因此,教訓是安全地刪除您的文件 654 00:39:16,030 --> 00:39:18,340 如果你想完全避免這種情況。是。 655 00:39:18,340 --> 00:39:21,010 >> [學生]為什麼說在您的計算機上 656 00:39:21,010 --> 00:39:23,550 你有更多的內存比你以前嗎? 657 00:39:23,550 --> 00:39:27,820 比你以前有更多的內存 - >> [學生]更多的可用內存。 658 00:39:27,820 --> 00:39:29,630 哦。這個問題問得好。 659 00:39:29,630 --> 00:39:32,360 那麼為什麼你的計算機後清空垃圾桶告訴你 660 00:39:32,360 --> 00:39:34,910 你有更多的自由空間比你以前嗎? 661 00:39:34,910 --> 00:39:36,770 簡單地說,因為它是在撒謊。 662 00:39:36,770 --> 00:39:40,740 技術上,你有更多的空間,因為現在你所說的 663 00:39:40,740 --> 00:39:43,680 該文件一旦你可以把其他的東西。 664 00:39:43,680 --> 00:39:45,450 但是,這並不意味著這些位去, 665 00:39:45,450 --> 00:39:48,590 和,這並不意味著正在被改變的比特都為0,例如, 666 00:39:48,590 --> 00:39:50,150 為保護您的利益。 667 00:39:50,150 --> 00:39:54,640 相反,如果你安全地刪除文件或物理損壞設備, 668 00:39:54,640 --> 00:39:57,300 這確實是有時解決這一問題的唯一途徑。 669 00:39:57,300 --> 00:40:02,020 >> 那麼,為什麼我們不離開上,半嚇人的,我們將看到你在週一。 670 00:40:02,020 --> 00:40:07,000 [掌聲] 671 00:40:07,780 --> 00:40:10,000 >> [CS50.TV]