[音樂播放] ROB BODEN:好吧。 所以,首先第一件事情的視頻, 從一個熟悉的面孔。 [視頻回放] - 所有權利。 這是CS50,這是 本週三開始。 對不起,我不能和你在一起 今天,但請允許我介紹 CS50自己的羅布博登。 [完視頻回放] [掌聲和歡呼聲] ROB BODEN:在本片目 該視頻是太棒了。 好的。 因此,首先,有另一個午餐。 這是明天1:15。 有沒有吃午飯這個星期五​​。 這是與Quora的。 和湯米是一個還沒來,但 那裡的人是前負責人的CF, 湯米McWilliam。 所以他是一個有趣的傢伙。 你應該來。 好的。 所以上週,我們開始分崩離析 什麼字符串確實是。 從一開始我們已經知道, 它是一個字符序列。 但上週,我們深入研究的事實 那什麼是真正的一個序列 字符,好了,我們現在有 字符數組。 而我們知道,一個字符串,它是一個數組 的字符,在最後, 我們有這個特殊的空字節,這 反斜線0,則表示的端 該字符串。 所以一個字符串數組 字符,但我們可以有一個以上 個字符的只是一個數組, 我們可以有任意的陣列 我們想要的東西的類型。 所以,如果你從上週還記得, 大衛介紹了中世紀程序 真的很快。 我們將這樣做第一件事是 要求用戶輸入一個整數,則 人在房號。 一旦我們有一個整數, 我們聲明數組。 請注意這個括號的語法。 你會習慣的。 因此,我們聲明一個整數數組 所謂的年齡,並有n個 整數此數組中。 因此,這種模式就在這裡,這4整型 i等於0,i小於N,I加 再加上,這也將是一個模式 你得到非常習慣。 因為這幾乎是你是如何 總是要遍歷數組。 所以請記住,n是 我們的長陣。 所以在這裡,我們反复詢問 對於人,我在房間裡的年齡。 在此之後,我們要下去,不管是什麼 亂的原因,我們再 打印出他們是如何將老 從現在開始的一年。 並運行該程序,讓我們 讓不同年齡,點斜線青睞。 所以,人在房號, 讓我們說有三種。 並說,第一個人是13, 接下來是26,最後是30。 這樣的話,它會遍歷這三個 人,打印出14,27,和31。 所以請記住,當我們聲明 大小為n的數組,該指數 數組,數組有值和 索引0,1,2,一路 最多n減去1。 因此,當我們說,有三個人 在房間裡,和我們擺在這裡 通過本第一次迭代 循環中,i將是0。 因此,在指數0。 我們正在分配第一 年齡的增長,用戶輸入。 那麼在未來一,我們正在進入 第二n用戶輸入,並且在 接下來的兩個,最後n。 所以請注意大小的數組 3沒有什麼 在索引3。 這是無效的。 好的。 因此,回到這裡。 所以,現在,我們已經處理了數組, 我們有一定的了解。 現在,我們要進入到命令 行參數,這將是 漂亮與此問題相關設置。 所以直到現在,每當你已經 宣告你的main函數,我們已經 說整型主作廢。 所以虛空只是意味著 如果我們沒有任何 參數給這個函數。 現在,我們要看到,主 可以採取一些參數。 在這裡,我們稱他們為整型的argc 和字符串argv的括號內。 在括號中,再次指示 我們正在處理的數組。 所以在這裡,字符串argv的支架,我們 處理字符串數組。 這樣的argc,那將表明 我們有多少爭論已經 通過這一方案。 而看到這意味著什麼, 讓我們關閉這個。 確定。 所以到現在為止,我們已經運行每 程序像點斜線年齡。 我們還可以在命令行中,過去 傳遞參數,從而術語,命令 行參數。 所以第一個參數,你好世界。 所以在這裡,ARGC將三人。 它的參數的數量 在命令行中。 的argc總是至少1中,由於點 斜線的年齡,本身算作一個 命令行參數。 然後招呼是第一個。 如果點斜線歷來是零,那麼 你好是第一位的,世界是 第二個命令行參數。 因此字符串argv的,我們要看到, 包含字符串,點斜線 年齡,你好,和世界。 而且,由大衛的要求,我們將 播放視頻介紹了。 [視頻回放] - 到現在為止在我們已經計劃 寫的,我們已經聲明 主要為INT主要作廢。 而這一切的時候,也有無效 只是被指定的 程序不採取任何 命令行參數。 換句話說,當用戶執行一個 節目中,他或她可以提供命令 寫入額外的行參數 詞或短語後程序的 在提示名稱。 好吧,如果你不想要你的程序 採取命令行參數,一個或 更多的這樣的話,我們需要更換 喪失與一對夫婦的參數。 因此,讓我們做到這一點。 包括CS50.h. 包括標準io.h. 詮釋為主。 而現在,而不是無效的,我要去 指定所謂的argc一個int和一個 數組叫做argv的字符串。 現在,argc和argv是 簡單的約定。 我們可以稱這些論點 大多數我們想要的東西。 但是,什麼是重要的是,是ARGC 一個int,因為按照定義,它是 要包含參數計數, 字數在總數的 用戶在鍵入他或她的提示。 argv的,同時,參數向量,是 會實際上是一個數組存儲 所有的用戶具有的字 在鍵入他或她的提示。 讓我們繼續做一些事情現在 與一個或多個這些 命令行參數。 尤其是,讓我們繼續和打印 不論字的用戶類型 該程序的名稱後 在提示符下。 打開支架。 關閉支架。 printf的百分比s反斜線和逗號。 現在我要告訴printf的價值是什麼 插入到該佔位符。 我想,該用戶具有的第一個字 該程序的名稱後輸入, 所以我要去指定 argv的支架1,接近 括號,分號。 現在,為什麼支架1和支架不是0? 嗯,事實證明,自動存儲 argv中0將是該 程序的實際名稱。 因此,第一個字的用戶類型 之後,該程序的名稱是,由 按慣例,將是 存儲在argv中1。 現在讓我們來編譯和 運行此程序。 做的argv 0,點斜線的argv 0。 現在一個字像打招呼。 輸入。 我們在那裡有它,你好。 [完視頻回放] ROB BODEN:好吧。 關閉了。 因此,採取一看那個程序, 我們只是向我們介紹了,好了,只是 顯示,如果我們打印的argv 0,使得現在 它是什麼,ARGV 0,點斜線的argv 0。 因此,正如所料,它打印出 該程序的名稱,因為ARGV 0 總是會在 該程序的名稱。 但是,讓我們做的東西 更有趣。 所以在這個問題集,你會 介紹了此功能,atoi的。 那麼,我們用什麼atoi的呢? 那將轉換 字符串到整數。 所以,如果我把這個字符串,一二三, 以atoi的,那將是轉換 為整數,一二三。 所以,我們要轉換的第一 命令行參數為整數, 然後只打印該整數。 所以基本上,我們是那種 重新實現調用getInt,只是 輸入整數,在命令 行,而不是在程序 交互。 那麼,做的argv 0,讓我們做 它在這裡,並關閉。 所以運行的argv 0,讓我們進入 整數,一二三四一二。 所以它會打印出整數,1 一二三四一二。 有一些微妙之處給atoi的 它會停下來關心什麼 超出有效數字字符, 但是,這並不重要。 所以,你覺得會發生 如果我這樣做? 分段錯誤。 那麼,為什麼會這樣? 如果你回頭看看我們的計劃,我們 轉換的argv 1,第一個參數 程序名之後,為整數。 但沒有傳遞的參數 程序名後。 所以在這裡,我們看到這是一個越野車 方案,因為如果我們嘗試運行它 不帶任何參數, 它只會崩潰。 所以,你會看到另一個常見模式 是一樣的東西,如果ARGC是少 大於2,表明有不 至少程序名和一 第一個參數,然後我們會做一些事情 如printf,沒有足夠的 命令行參數。 這可能不是一個很好的打印, 它可能是什麼東西,像 你應該輸入一個整數 在命令行中。 我剛剛結束了在那裡。 然後返回1。 所以請記住,在我們的結束 程序,如果我們回到0,諸如此類的 表示成功。 和主也會自動 返回0,如果你不這樣做。 所以在這裡,我們重新調整1來表示 那這是不是成功。 而且你可以返回任何你想要的, 只是,0表示成功, 別的表示失敗。 因此,讓我們運行這個版本的東西。 所以,現在,如果我們不進入命令行 參數,它會正確地告訴 我們沒有足夠的命令行。 沒說完這句話。 否則,如果我們真的把它傳遞的, 它可以完成該程序。 因此,這是你將如何使用的argc在 為了驗證數 命令行參數 實際上通過。 因此,讓我們使這個程序有點多 複雜的,並期待在第二 迭代的事情。 所以,現在,我們不只是打印 第一個命令行參數。 在這裡,我們從int i等於迭代 0,i是小於的argc,我加 再加上,印刷的argv,索引i。 所以此模式下,再次,這是相同的 圖案和以前一樣,除了代替 調用該變量的 N,我們使用的argc。 因此,這是遍歷每個索引 在數組中,並打印每個 元素在數組中。 所以,當我們運行這個程序,那麼, 我沒有輸入任何命令行 參數,所以它只是打印 程序名稱。 如果我輸入了一堆東西,它會 打印一份,每個各佔一行。 確定。 因此,讓我們這一步。 和而不是打印每個參數 在自己的行,讓我們每個打印 每個參數的字符 在自己的行。 所以請記住,argv是 一個字符串數組。 那麼,什麼是一個字符串,但 字符數組? 這樣就意味著argv是一個真正的 字符數組的數組。 因此,採取這種優勢, 讓我們忽略這個現在。 讓我們只考慮字符串的argv 0。 因此,如果我們想帶給每個字符 argv的0在自己的行,那麼我想 做我們已經習慣的模式,​​我是 小於所述陣列的長度, 這這裡,是strlen的,那就是 不是我想做的事情,串 s等於argv的0。 所以我不到我們的長 陣列,在這種情況下是一個數組 人物中,我加再加。 因此,正如我們上週所看到的,它是理想的 如果我們朝那個strlen的外 的條件下,由於n將增加 第每次我們去時的strlen 通過循環,並且它是 不會被改變。 因此,我們將其設置等於n在這裡。 確定。 所以,現在,我們遍歷 每個索引的數組中。 所以,如果我們要打印的每個 字符數組,百分比c是 我們要使用的標誌 對於字符。 現在支架我將是該 字符串索引字符我,所以如果 字符串為你好。 則s 0將是H,S支架 1將通過電子郵件,等等。 所以,現在我們要結合 這兩樣東西。 我們要打印的每個字符 每個命令行參數。 因此,我們將有 一個嵌套的for循環。 與以往,第一計數器 是我,接下來的將是J,N 將是我的argv strlen的,我 小於n,我加再加。 而不是印刷的argv我和現在,所以 argv的支架我打算指數 - 這將是第i個命令行 參數,argv的I,J是要 是第j個字符 第i個說法。 我會擺脫現在這種在這裡 因為我們把它放到這個循環。 這樣就相當於字符串s等於 argv的我,和則S支架Ĵ。 好了,我們不需要聲明 這個變量s。 相反,我們就結合這 兩成我們的曾經,的argv I,J。 揚聲器1:[聽不清]。 ROB BODEN:良好的通話。 所以這是破碎。 如果我真的跑了,我們就 已經意識到這一點。 所以,我所關心的計數器 在這個特定的供 環為j,迭代器。 所以,你會遇到的問題, 可能是一個無限循環,如果我們 沒有固定的。 這就是為什麼我們還在談 有關調試今天。 確定。 因此,讓我們運行這個程序。 而且,我們實際上添加一個單獨的printf的 在這裡,將剛剛打印 另一條線,因為這意味著,當我們 運行該程序,就會有一個空白 在每個字符之間的行 每個命令行參數。 那麼,我們將看到這意味著什麼。 空中接力。 得到了一些bug。 錯誤隱式聲明 庫函數strlen的。 所以要回到我們的節目,我 忘了哈希包括string.h中。 所以string.h中會是在 該聲明的頭文件 該函數strlen的。 好了,它編譯。 現在,讓我們來運行它。 所以這一點。 這將打印出我們的 程序名,你好世界。 這將打印每一件事情,每一個 人物,在自己的行。 確定。 因此,讓我們確實有此 進了一步。 而不是使用string.h中和,讓我們 想了解我們如何想實現自己的 strlen函數。 於是我馬上給 一個函數簽名。 因此,讓我們在my_strlen調用,它的 要採取一個字符串作為參數, 和我們預期的回報 長度字符串。 因此,如果是那個人​​嗎? 是。 確定。 因此,從早期的幻燈片記得 也是從上週開始,即一個 字符數組,那麼,一個字符串, 所以讓我們說這是我們的字符串s。 所以,如果s是字符串,你好,那麼, H-E-L-L-O,內存,那將 定,然後將這個反斜杠 0字符。 那麼,如何才能得到s的長度? 好了,關鍵是找這個 背隙0字符,此空 終結者。 所以該算法是怎麼回事 要像數 足夠的字符 - 讓我們來這一手代表的一些 計數器,讓我們稱這個整數長度。 所以,從在這裡開始,我們 要遍歷我們的字符串。 所以第一個字符,它的H, 而且它不是反斜杠0,所以 的長度為1。 迭代到下一個字符, E,並且它不是反斜杠0。 長度為2。 L,3。 L,4。 O,5。 最後,我們到達反斜線 0,這樣就意味著,好吧, 這個字符串就結束了。 因此,讓我們回到5。 因此,實際上執行的是,第一, 我的N長度等於0,我的右手。 而且我們要遍歷 - 揚聲器1:[聽不清] ROB BODEN:哦,拍攝。 良好的通話。 熱潮。 因此n長度等於0。 所以現在,而S長度不 平等,那麼,反斜線0。 所以請記住,這個反斜線0,它是一個 實際的字符,它表示 字符串的結尾。 就好像,另外,反斜杠 n是一個實際的字符。 反斜線0是要表明 我們的字符串的末尾。 我不希望把他們那裡。 並同時通過索引的長度s是不 等於空終止,然後 我們只是要增加長度。 那麼,在我們節目的最後, 長度最終將 是5在這種情況下。 我們將只返回長度。 確定。 所以,現在在這兒,我不 做my_strlen。 讓我們來編譯它,以確保 一切順利。 我是在2幹什麼? 或者是1? 這應該做的。 好的。 所以這是ARGV 2。 作品如預期,但 是一個我在做的嗎? 是。 確定。 這個版本的東西沒有 printf的新行之後,但它 沒有任何區別。 確定。 因此,如預期般運作。 現在,我們甚至可以結合這一步 進一步,在這裡通知,好了, 首先,我們要抓住的argv的strlen的 我,然後我們遍歷 每個字符在該字符串。 而不是這樣做,那麼,如果我們 只是結合在等待這個邏輯 直到我們打反斜線0右 這個for循環? 所以,當遍歷ARGV I,J呢 不等於反斜線0。 因此,讓我們運行它第一次。 好的。 所以在這裡,這種情況是說 - 讓我們澄清這一點。 所以,現在,讓這次成為我們的argv。 所以,當我剛剛才跑了程序, argv是一個字符串數組。 所以,如果我用點斜線的argv運行 2,你好世界,那麼在argv 本身是一個長度為3,為ARGV 零,你好,和世界。 而這些指標裡面是, 本身是一個數組,其中該會 點,這將是斜線,我不知道 如果這是正確的方向,我 不認為它是。 A-R-V的儀表板,需要更多的空間。 讓我們切入這個數組。 A-R-V的儀表板0,然後反斜線0。 然後趁亂會打招呼。 比方說,H-E反斜杠0。 最後,W-O反斜杠0。 所以,我們剛剛編寫的算法, 嵌套的for循環,他們在做什麼 做的是,我們首先有 計數器i和則j。 這與代碼上更容易 屏幕上,讓我們回到這一點。 確定。 所以請注意,我是迭代器的 遍歷每個命令 行參數。 和j為迭代器迭代 過在每一個字符 命令行參數。 那麼,這個最裡面的printf是做 是,我們的printf的argv 0 0,printf的 argv的0 1,printf的ARGV 0 2 0 3 0 4 0 5,0 6,但現在,argv的0 7即將 等於反斜線0。 於是我們退出了for循環, 現在我遍歷1。 現在我們將要打印 argv的1 0,argv的1 1 - 好了,現在,因為我砍你好短, argv的1 2再次將是 反斜杠0。 因此,增加我和繼續, 依此類推,直到我們打印出所有的 世界的,那些是三個命令行 的論點,我們會退出了 最外面的圈,並 完成我們的計劃。 確定。 因此,讓我們再回到這裡。 所以,你會獲得一些熟悉 在這個命令行參數 特別是設置的問題。 現在,調試。 所以,你可能已經不得不做 與以前的一些調試 問題集。 和調試的一個非常簡單的方法, 首先,讓我們來看看一個錯誤的程序。 好了,走過這個程序, 我們要問一個用戶 整數,搶了整數,然後, 隨意,我們有一個while循環, 只是要遞減 我直到它等於10。 讓我們只是假設我進入 的整數大於10。 所以我遞減,直到它等於10。 然後我們還有一個while循環 ,雖然我不等於0,我們是 要通過3遞減我。 所以,如果你看到錯誤的意圖 在這裡,它是這將減小到我 是10,然後這個while循環的意志 遞減我從10到07到4,1, 至負2,負5,依此類推, 負無窮大,因為我將 從來沒有實際等於0。 然後在這個節目的最後, 我們有foo函數是 怎麼回事打印出來,我。 因此,這是一個短期和瑣碎的程序, 而錯誤是顯而易見的, 特別是在我剛 說什麼錯誤了。 但這裡的意圖是,很好,這可能 實際上看起來像你的一些 從最後貪心解 問題集,也許你確實有 一些無限循環在你的程序, 而你不知道 什麼導致它。 所以有一個非常有用的調試技術 是剛剛加入的printfs 在你的代碼。 所以在這裡我想外面一個printf 第一個while循環。 在這裡,我想一個printf, 我將只打印我。 我什至可以做第一個while循環,我。 外,第二個while循環。 再次,裡面打印 這裡,i的值。 讓我們來運行這個。 所以點斜線調試。 輸入的整數。 讓我們做13。 和熱潮。 我們看到,我們是無限循環 裡面的第二個while循環。 所以,現在我們知道到底是什麼錯誤。 但printf的調試是完全很棒, 但是一旦你的程序得到 更長,更複雜,有 更複雜的解決方案, 把事情的工作。 因此,讓我們刪除所有這些的printfs。 並讓我們確保我沒有 破壞任何東西。 確定。 所以我們要去的程序 引進被稱為 GDB,為GNU調試器。 嗯,事實上,我們刪除的調試 第二,並再次調試。 嗯,其實第一次,一個很好的教訓 在命令行參數。 請注意,這鏘命令是 編譯一切都被傳遞 在命令行中,這些 命令行參數。 那麼究竟如何你將要使用 命令行參數,因為我們 做之前,並且你會在PSET 2,這就是鐺是如何使用它們。 所以請注意,這第一個標誌,破折號 ggdb3,是什麼在說的是,鐺, 你應該與編譯這個文件 意圖,我們最終將 需要調試它。 所以只要你有該標誌, 那麼我們就可以GDB調試。 它會打開GNU調試器。 所以有很多的命令 你需要去適應。 第一個,你可能會 立即需要的是執行。 那麼,什麼是運行怎麼辦? 這將開始我們的節目。 所以運行,啟動程序,該程序 要求我們為一個整數,13。 然後它是無限循環的 預計,除了我刪除了 的printfs,所以我們甚至看不到這一點。 正常退出。 呵呵。 這是可能的,它包裹著所有 倒過來,回 - 忽略了。 假設它沒有正常退出。 有一個複雜的答案。 所以,現在,這不是非常有用。 因此,只要運行我們的程序裡面 這個調試器不會幫助我們在任何 這樣,既然我們剛才做 點斜線調試的GDB之外。 這樣一個命令 你可能 - 我將退出這個。 控制-d或退出,兩者的工作。 因此,讓我們再次打開它。 另一個命令,你可能會 馬上要 習慣就是休息。 因此,我們將打破對主要就目前來看, 然後我會解釋。 好了,在這裡我們看到,我們設置一個斷點 在此行中debug.c。 那麼,什麼破手段是,當我 鍵入run,該程序將 繼續運行,直到 我打一個斷點。 所以,當我打的運行,程序啟動時, 然後,只要它打破 進入主函數。 突破主要將是什麼 你很常見的事情。 現在,給你介紹 一些更多的命令。 注意這裡,它在說,我們 打破了在第11行,這是 printf的,輸入一個整數。 因此命令下一步將是如何 我們去的下一行代碼。 這將允許我們加強 通過我們的節目一行行。 等下次。 現在,第12行,我們要 得到的整數。 下一步。 如果你只是打再次輸入,它會 重做你做的最後一件事。 所以我不需要鍵入 接下來的每一次。 這樣輸入的整數,13。 所以,現在,第14行,而我是更大 大於10,並且我會做下一個。 我們看到我們將要遞減我。 所以,我們要再次遞減我。 所以,現在,另一種有用的 命令打印。 因此,打印將會打印出 該變量的值。 讓我們帶出的價值 的變量i。 讓我們來打印我。 它會說,我是11。 現在,我們接著再而 i大於10。 所以我仍然大於 10,因為它是11。 我減減。 讓我們再次打印我。 正如預期的那樣,它是10。 所以,現在,未來。 這是要回的情況下,我是 大於10,但我現在是10,所以 它不是大於10,因此我們預計 它掉下來的while循環。 而現在我們下面的那行代碼。 而另一個命令,列表,只是將 顯示上一頁和下一頁 幾行代碼,在 如果你失去了你自己。 所以我們只是退出這個while循環, 現在我們已經進入了這個 while循環中,第18行。 因此,雖然我不等於0。 而且,接下來,我等於我減3,我們將 請注意,這將只是繼續前進。 我們可以打印我。 排序的每個命令都有快捷鍵。 因此P是短期的打印。 因此,我們可以p我。 只要繼續保持N, 或者繼續做下一步。 再次打印我。 現在你看到它的負面167。 因此,這將永遠繼續下去,但不 真的永遠,因為你剛才看到,它 實際上在某個點結束。 所以這是開始GDB。 但讓​​我們做一件事的GDB。 呃,調試。 所以,在這種特定情況下,本 無限循環恰好是內 的主要功能。 而現在,只接受了我 要移動的無限循環 foo函數。 只要記住,在本月底 計劃,嗯,這本來是 調用foo,這只是 要打印我。 但現在我們調用foo,這是 要我遞減,直到它的0, 然後打印該變量。 確定。 保存。 做調試。 而現在,GDB調試。 確定。 所以,如果我只是運行那麼我不會去 可以通過實際步驟我 程序行由行。 因此,讓我們在主破裂, 然後鍵入運行。 所以經過這個,printf的輸入 的整數,得到的整數,13。 因此,我們要保持遞減 直到i大於10。 那麼我們要落空了 while循環,並獲得了線 - 讓我們打開它,在一個單獨的窗口。 因此,我們遞減,直到我不再 大於10,然後就 稱為函數foo。 所以,只要我打發生了什麼 函數foo,好,我叫foo,並且 然後,我不再有超過GDB的控制。 所以,只要我打接下來的這條線, 事情一直持續到發生這種情況, 當程序退出的時候 - 假設它最終沒有存在。 你看到它停頓了一會兒,但。 那麼,我為什麼失去了控制 該方案在這一點? 好吧,當我輸入下一個,那去 代碼的文字下一行 將執行。 所以在第21行的下一行代碼 將執行的是22行, 這就是,從主要退出。 所以,我不想只是去 對下一行代碼。 我想進入該函數foo, 然後還通過加強 那行代碼。 因此,對於這一點,我們有一個替代。 讓我們再次退出了。 突破為主。 呃,1,下一步,下一步,13,接下來, 下一步,下一步,仔細, 之前我們打線富。 確定。 所以,現在,我們正處於第21行, 在這裡我們調用foo。 我們不希望接下來的輸入,因為這 只是調用函數foo,以及 去的下一行代碼。 我們要使用的是什麼步驟。 因此,有步驟之間的差異 而接下來,在步驟步入 功能,並進入下一步 以上的功能。 它只是執行的全部 功能,並保持下去。 所以第一步是要帶給我們 入函數foo。 我們在這裡看到,現在,我們回到了 這個while循環的,從理論上講, 要繼續下去。 如果你打步驟,當它甚至不是 要調用的函數,那麼它的 相同的下一步。 因此,只有當你在一條線 正在調用步驟的函數 打算從明年有所不同。 所以步驟會帶給我們這裡。 一步,一步,一步,一步,一步,一步, 我們只是無限循環下去。 所以,你可能習慣了,作為您的 識別無限循環的方式,是 只是抱著這個回車鍵 看到這裡你會被卡住。 有更好的方法來做到這一點,但 就目前而言,這是完全足夠了。 和曲風,以符合樣式 50,我應該這樣做。 確定。 所以最後一個命令介紹。 那麼,讓我們用gdb調試英寸 因此,而不是在破主,如果我 知道foo函數也是 的問題,那麼我可以只 說,在打破富,而不是。 比方說,我在突破 這兩個主要和foo。 所以,你可以設置盡可能多的斷點 只要你想。 當我鍵入run,這是怎麼回事 停在 - 哦,讓我們重新編譯,因為 我改變的東西。 你會看到這條線,警告,源 文件比可執行的更近一些。 因此,這意味著,我只是在走到這裡 而這些改變,以符合樣式 50,但我沒有重新編譯 該方案。 所以GDB讓我意識到這一點。 我會退出,再次進行調試, 打GDB調試。 確定。 所以,現在,回到我在做什麼。 主要的突破,打破富。 現在,如果我運行這個程序,所以它的 要繼續,直到撞到 斷點。 斷點發生在 是第一個在主。 現在,而不是做下一步,下一步,下一步, 下一步,下一步,直到我打富,我 可以輸入持續,這將繼續 直到你打一個斷點。 我必須先輸入整數。 繼續將繼續下去,直到我打的 下一個斷點,這是 函數foo。 所以運行將運行,直到你打一個 斷點,但你只有在鍵入run 你開始的程序,然後, 從那時起,它的繼續。 如果我只是做了突破和主 然後跑,它會打破在 主,然後繼續。 因為我沒有一個破發點時富, 輸入的整數,那麼現在我 不會打破在foo中。 它只是將無限 循環,直到這一點。 確定。 所以這是介紹到GDB。 你應該開始使用它 在你的習題集。 它可以是非常有幫助 識別錯誤。 如果你真的只是,線,由線,走 通過您的代碼,並比較什麼是 實際發生的事情與你的期望 發生的,那麼它是相當 很難想念你的錯誤。 確定。 所以上週大衛提出這個 密鑰加密的東西了 第一次,在這裡我們不希望 密碼只是被儲存在我們的 計算機在某些純文本文件,其中 有人能過來,只是 打開來閱讀它們。 理想的情況下,他們會被加密 以某種方式。 而在問題2,你會被處理 用的加密方法之一, 或者,好了,兩個方法,但 他們並沒有那麼大。 如果你這樣做的黑客版,你 也將被處理 解密一些事情。 所以,現在的問題是,好吧,就算 我們有強大的加密 算法中的世界,如果你選擇了一個 密碼特別差,那麼它 不會幫你了,因為人們 仍然能夠弄明白。 即使看到加密的字符串和 它看起來像垃圾的一塌糊塗 這意味著什麼給他們,如果他們 還是只需要嘗試一些密碼 弄明白,那麼你 都不是很安全的。 所以,看一個視頻, 使得該點。 [視頻回放] - 頭盔,你魔鬼,是吧。 這是怎麼回事? 你在做什麼,以我的女兒? - 請允許我介紹的輝煌 年輕的整形外科醫生,菲利普博士 Schlotkin,最大的鼻子 工作的人在整個 宇宙,和比佛利山莊。 - 殿下。 - 隆鼻? 我聽不懂。 她已經有了一個隆鼻。 這是一個甜蜜的16出現。 - 沒有。 這不是你的想法。 這是非常非常糟糕。 如果你不給我組合 空氣盾,Schlotkin博士將 給你的女兒回她的老鼻子。 - 沒有。 你從哪兒弄來的? - 所有權利。 我會告訴。 我會告訴。 不,爸爸。 不,你不能。 - 你是對的,我親愛的。 我會想念你的新鼻子。 但我不會告訴他的組合, 不管是什麼。 - 很好。 Schlotkin博士,做你最糟糕的。 - 我的榮幸。 [工具中使用被削尖] - 沒有。 等待。 等待。 我會告訴。 我會告訴。 我知道它是可行的。 好的。 把它給我。 - 組合是1。 一體。 一體。 - 兩個。 - 兩個。 - 兩個。 三。 三。 三。 - 四。 - 四。 - 四。 五。 五。 五。 - 因此,組合是1, 兩個,三個,四個,五個。 這是最愚蠢的組合 我聽說過我的生活。 這是什麼樣的事情白痴 會對他的行李。 - 謝謝你,殿下。 - 你做了什麼? 我關掉了牆上。 - 不,你沒有。 你關閉了整部影片。 - 我一定是按錯了按鈕。 - 好吧,把它放回。 把電影重新打開。 - 是的,先生。 是的,先生。 - 讓我們去,阿諾德。 來吧,格雷琴。 當然,你知道,我還是會 必須向您收取此。 [完視頻回放] ROB BODEN:好吧。 所以,現在我們已經談論 安全在某些方面,不錯的 小電影的海報,所以在最近的 天,這些問題與國家安全局 監視一切。 它可以是很難感受到如你 有在某種隱私 網絡世界,雖然我不能告訴 你最棱鏡的細節。 所以超越棱鏡,我們不會 要談的是,現在 想想你的筆記本電腦。 所以在這裡,我想切換 我的實際帳戶, 我的小企鵝。 所以,我有密碼設置,以及 密碼是什麼,我希望它是。 但要記住一點:我記錄 同,所以這個登錄 及時,一些程序。 它的一些程序,它是 寫的一些人。 因此,這個人,如果它們是 尤其是惡意的,他們可以 已經說過,所有的權利,所以如果密碼 我輸入等於我 實際的密碼,或者它等於 一些特殊的密碼 - 大衛是真棒什麼 - 然後讓他們進來。 因此,一個惡意的程序員可以有 訪問您所有的Mac電腦,或 Windows中,或任何東西。 所以這不是太大的關注,因為, 我的意思是,這是login程序 這是隨OS X中,數百名 或數千人 審查這個代碼。 因此,如果你在代碼中的某處,你 說,如果該字符串等於等於 大衛是真棒,登錄,然後誰家 將是一樣,等待。 這是不對的。 這不應該在這裡。 所以這是我們得到的東西的一種方式 是種安全。 不過想想,即使程序 你寫。 比方說,你寫的登錄程序。 所以,你寫了這個登錄程序, 所以很明顯,你是一個好 程序員。 你不會把任何惡意 如果x等於等於大衛是真棒 到你的代碼。 但這個程序,你將怎麼做 用它來編譯這個程序? 類似鏘。 那麼,如果誰發生的人 寫鐺專用套管中鏘 是這樣,如果我編譯 登錄程序,然後輸入這個代碼 進入login程序,上面寫著,如果 x等於等於大衛是真棒? 所以不太,但我們有同樣的 問題在這裡,在這裡鏘,好了, 成千上萬,如果不是數以萬計 人,都看著鐺,有 看著它的代碼行並表示, 沒事,有什麼不好在這裡。 顯然,沒有一個是做 這什麼惡意。 但是,什麼是鐺本身一樣, 如果我編譯鐺? 如果我有一些編譯器 編譯鏘說插入到鏘 這個特殊的黑客,說,沒事的, 當我編譯鏘,則 可執行我應該得到特別期待 login程序和插件的內部 此密碼,等於等於 戴夫是真棒? 所以請記住,你的編譯器本身 需要在某些時候編譯。 所以,如果你選擇什麼樣的編譯鏘 用,本身就是惡意的,那麼你 可以擰全 後話。 所以在這裡,我們有肯·湯普森 和丹尼斯·里奇。 因此,這是一個標誌性的照片。 丹尼斯·里奇是在右邊。 他是一個重要的 - 幾乎寫道C.所以,你可以 感謝他為這一類。 肯·湯姆森是在左邊。 他們兩個基本上寫的UNIX。 那麼,他們是主要的貢獻者 在UNIX中。 還有一些人。 所以肯·湯普森,在某些時候, 他贏得了圖靈獎。 和圖靈獎,我一直聽說 它引用這樣一來,它的 計算機科學的諾貝爾獎。 因此,在圖靈獎,他要 給他的獲獎感言。 他給出了這樣的非常著名的演講 現在,呼籲信任思考 信任,這是我們鏈接 到課程網站上。 而在這次講話中,他說,沒事, 所以我寫了UNIX,現在所有的 你們這些人使用的是UNIX。 現在,請記住今天,Linux是 直系後裔的UNIX。 OS X中直接使用UNIX。 Windows確實沒有那麼多,但很多 想法是從UNIX。 於是他去了舞台,並說, 沒事,我寫的UNIX。 而只是讓你們知道,我是 能夠登錄到每個 你的電腦單之一。 自從我把這些特殊的一個如果x 等於等於肯·湯姆森是真棒, 然後我允許登錄。 所以人們都喜歡,好了, 你怎麼做呢? 我們看著login程序 僅此而已的存在。 他的樣子,好了,我修改了編譯器 登錄login程序 讓login程序現在將有 即x等於等於肯·湯普森 是真棒。 他們說,好,這是不正確的。 我們正在尋找的編譯器和 編譯器沒有任何行 這樣的代碼。 他想,好,但你是什麼 編譯的編譯器? 他們認為,和他的一樣,很好, 我是誰給你的編譯器之一 你使用編譯的編譯器,所以 你要編譯一個編譯器,即 本身就是惡意的,並會 打破登錄程序。 因此,基本上,在這一點上,有 沒有辦法,你可以看看源 login程序代碼 看看什麼是錯的。 你甚至不能看在 編譯的源代碼 看看什麼是錯的。 你需要看機 代碼的實際的二進制 編譯的編譯器看,等待,這些 行代碼不應該在這裡。 但肯·湯普森把它一步 進一步說,好,有 這些特殊的程序,實際上 幫助你閱讀程序的二進制文件, 所以,如果有人使用該程序來 讀取二進制文件,他們將看到這些 行代碼。 他修改這些程序的說,所有的 好吧,如果你正在尋找的 編譯器,不顯示這個特定的 組二進制的。 這樣,那麼你需要採取的步驟 進一步,基本上,這可以有 採取多層次的間接尋址, 在某些時候,沒有人實際上 將被檢查。 所以這個故事的寓意是,你 不會被寫 鐺在這個類中。 你將要使用攀登 在這個類中鏗鏘很多。 對於所有你知道的,鐺是一種惡意 程序,它是每一個破壞 單個程序你曾經編譯。 並留下你對此很不祥 注意,看你在星期三。 [掌聲] 揚聲器2:在接下來的CS50。 揚聲器3:你怎麼敢這麼說。 你可以做到這一點。 你這樣做之前,你可以這樣做 今天,你可以做到這一點的明天。 你已經做了好幾年了。 只是去那裡做這個。 你可以做到這一點。 [音樂播放]