>> [音樂播放]
>> 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：你怎麼敢這麼說。
你可以做到這一點。
你這樣做之前，你可以這樣做 今天，你可以做到這一點的明天。
你已經做了好幾年了。
只是去那裡做這個。
你可以做到這一點。
>> [音樂播放]