>> DAVID馬蘭：好的，歡迎回來。
這是CS50。
這是七週的開始。
因此，它已經有一段時間，所以我想我們最好 在哪裡，我們需要旋風之旅
離開的，我們現在要。
>> 所以這個東西在這裡可能有 造成了一定的焦慮在第一。
但我希望，你開始 適應新環境，這表示在這裡 -
星級代表一個指針，它是 究竟是什麼，更通俗地說？
因此，它是一個地址。
>> 因此，它的地址是 在內存中的東西。
我們開始剝開層層 幾個星期前，事情喜歡
GetString的和其他類似的功能 這一切的時候已經返回
地址在內存中的東西，像 地址中的第一個字符
一些序列。
>> 因此，我們也介紹了valgrind的， 你會開始使用這個問題
設置，尤其是為下一個 問題設置。
valgrind的為我們做什麼？
檢查內存洩漏， 檢查濫用記憶。
>> 以一定的概率，它可以檢測，如果 你的代碼將觸摸內存
那根本不應該。
所以不一定洩漏，但如果你 一些超越的界限
數組，並在實際運行Valgrind的 並誘發這種行為，而
Valgrind是運行在你的程序是 它內部的運行，你會得到
這樣的消息 - “無效寫 尺寸4，“記得一對夫婦
兩週前意味著我不得不意外 喜歡上一個int太遠
邊界之外的一個數組。
等大小4表示這裡的大小 該特定的詮釋。
>> 因此，需要安慰的事實， Valgrind的輸出，它的格式，
僅僅是殘暴的。
這真的很難識破的一塌糊塗 有趣的信息。
所以我們在這裡所做的只是摘錄 一些對情侶更
有趣的線。
但要意識到80％的valgrind 輸出將是一個有點
分心。
>> 只要看看這些模式，如 - 無效的，正確的，無效的閱讀，40個字節
和一些的塊數是絕對 丟失，這樣的關鍵字。
什麼，你會希望看到的是一些 那種一絲什麼功能
錯誤是實際上英寸的
在這種情況下，在這裡，在哪一行 我的代碼，顯然是錯誤的嗎？
>> 在一個名為memory.c，這是26 例如，我們都在玩
的時間。
所以它可能不是malloc的。
這可能是在我的代碼代替。
因此，我們將再次看到這 前再次長。
>> 因此，scanf函數，這是在一個 夫婦迄今形式。
我們看到sscanf的簡要介紹。
而東西 你在你跳入
準備測驗。
和scanf實際上是什麼CS50 圖書館一直使用下面的
相當長的一段時間，以便罩 得到來自用戶的輸入。
>> 舉例來說，如果我移動到CS50 家電在這裡，讓我開了
比如今天這就是所謂的scanf函數0.C 它的超簡單。
這只是一個幾行代碼。
但它真的演示如何調用getInt 已經工作的這段時間。
>> 在這個程序中在這裡，在第16行 請注意我聲明一個int。
因此，沒有指針，沒有什麼神奇 在那裡，只是一個int。
然後在第17行，我提示 用戶輸入一個數字，請。
然後在18年底，我這裡使用的scanf。
我和規定，一種如printf， 我期待報價
引文結束％。
>> 所以我％，當然， 表示一個int。
但是要注意什麼第二 是scanf函數參數。
你會如何形容第二 逗號後的參數？
那是什麼？
>> 這是x的地址。
因此，這是非常有用的，因為通過提供 scanf函數x的地址，什麼
授權功能怎麼辦？
不只是去那裡，而且還做什麼呢？
>> 它的變化。
因為你可以去那裡，它的排序 就像一張地圖在內存中的位置。
所以只要你提供scanf函數，或 任何這樣的地圖，即功能
功能可以去那裡，不僅 看一看的價值，但它也可以
更改該值，這是有用的，如果 scanf函數在生活中是
掃描來自用戶的輸入，具體 從鍵盤輸入。
和F表示格式化，就像 printf的一個格式化的，f表示
要打印的串。
>> 因此，在短期，簡單地說，此行18， 從用戶的嘗試讀取一個int
鍵盤和它裡面存儲的x， 無論地址x恰巧住在。
然後最後，19號線剛說， 感謝為int的，在這種情況下。
>> 所以，讓我繼續前進，使這個。
所以使：scanf的0。
讓我繼續放大。
我會去，並運行此 點斜線：scanf的0。
號碼好嗎？
50。
感謝為50。
因此，它是相當簡單的。
>> 現在是什麼是不是在做什麼？
這不是做了一大堆 錯誤檢查。
舉例來說，如果我不配合， 我不鍵入一個數字，但
而不是我寫的東西，如“你好”， 這只是一種奇怪的。
因此CS50的事情之一 庫已經為我們做了一些
時間是再次提示 並再次提示。
>> 重試短語召回在cs50.c， 的原因，調用getInt
CS50庫實際上是一個整體 一堆線長，因為我們
檢查這樣的愚蠢的東西。
用戶不要給 我們，其實，一個int？
他或她給我們的東西 像一個字母？
如果是這樣，我們要檢測 ，並大聲喝斥。
>> 但是，事情變得更加有趣 在下一個例子。
如果我去scanf函數1.C，什麼是一個 事情是從根本上改變
在下一個例子嗎？
我使用char *，當然， 而不是int。
>> 因此，這是有趣的，因為char *， 回想一下，其實只是
同樣的事情串。
所以感覺一樣，也許這是一個超級 GetString的簡單實現。
但我已經去皮層 CS50庫，所以我
現在調用這個char *的。
讓我們看看，如果在任何地方， 我們去錯了。
>> 第17行 -
我再次說，請你給我的東西， 在這種情況下，一個字符串。
然後在下一行，我調用scanf函數， 再次，給它一個格式碼，
但這次％秒。
那麼這個時候，我 給它的緩衝區。
>> 現在請注意，我沒有使用 符號。
但是，這是為什麼這裡大概OK？
原因是什麼緩衝了嗎？
這已經是一個指針。
它已經一個地址。
>> ，讓我們這個“混淆視聽”，讓我 只是把它，例如，
簡約。
不過，我已經把它稱為緩衝，因為在 一般情況下，在編程中，如果你有一個
大塊的內存，這一個字符串真的 只是，你可以稱之為一個緩衝區。
這是一個地方來存儲信息。
>> 類似的事情，如YouTube，當 他們正在緩衝，可以這麼說，
只是意味著它的下載位 將它們保存在互聯網和
本地陣列，一個地方的內存塊，所以 ，你可以看它，以後不
跳躍或掛在 你一邊玩。
>> 所以這是一個問題，但在這裡， 因為我告訴scanf函數，期望
來自用戶的字符串。
這裡的地址是 一塊內存。
把該字符串。
這是為什麼綁定給 給我們帶來麻煩，但？
>> 那是什麼？
我允許訪問 內存的那部分？
你知道，我不知道。
由於緩衝區被初始化 什麼嗎？
真的沒有。
因此，這是我們一直呼籲 垃圾值，這
是不是一個正式的詞。
它只是意味著，我們不知道什麼位 內的四個字節，
我已經分配緩衝區。
>> 我還沒有叫的malloc。
我肯定不叫GetString的。
那麼，誰知道什麼是真正的 緩衝液內？
還告訴scanf的盲目，去那裡 並把任何用戶輸入。
>> 那麼，什麼是可能造成 在我們的代碼中，如果我們運行呢？
大概一個segfault。
也許不是，但可能是一個段錯誤。
和我說，也許不是因為有時 你這樣做，有時
你沒有得到一個段錯誤。
有時候你就是幸運的，但 但是這將是
在我們的程序中的一個bug。
>> 所以，讓我繼續前進，編譯這個。
我要做到這一點老派的方式。
所以鐺破折號scanf函數-1，0， scanf函數1.C，回車。
哎呀，太舊的學校。
讓我們來看看。
我應該在哪裡？
哦，字符*緩衝區。
哦，謝謝你 -
保存，OK -
很老的學校。
好吧，它已經有一段時間。
>> 所以，我剛剛保存後的文件 使該臨時
前改變了一會兒。
現在我已經編譯 手動鏘。
現在我要繼續前進 並運行scanf函數-1，回車。
字符串。
我會鍵入“你好。”
>> 而現在，這裡的地方，坦率地說，PRINTF 可以是有點惱人。
它實際上並不是要 在這種情況下，段錯誤。
printf是有點特殊的，因為 它是如此的超級常用
基本上printf是做 我們贊成和實現，
這不是一個有效的指針。
讓我把它後，我自己只是打印 在括號空，甚至
雖然它不一定是 我們自己的預期。
>> 因此，我們不能真的很容易誘發 段錯誤這一點，但顯然這
是不是我想要的行為。
那麼，有什麼簡單的解決方案？
那麼，在scanf-2，讓我提出， 而不是實際只是分配
的char *，讓我有點小聰明有關 這一點，讓我分配緩衝區
為16個字符的序列。
>> 所以，我可以做到這一點的方式在一對夫婦。
我完全可以使用malloc。
但我可以回去兩個星期時 我只是需要一大堆
字符。
這只是一個數組。
因此，讓我，而不是重新定義緩衝區 是一個數組為16個字符。
>> 而現在，當我通過緩衝區 -
這是我們沒有的東西 談談在本週二 -
但你可以把一個數組作為 雖然它是一個地址。
技術上，正如我們已經看到的那樣，他們是 有一點點不同。
但scanf函數不會介意，如果你傳遞給它 數組名，原因是什麼
鐺會為我們做本質上是 作為治療該數組的名稱
16個字節的數據塊的地址。
>> 因此，這是更好的。
這意味著，現在我希望能 做到以下幾點。
讓我縮小了一會兒， 做scanf的-2，編譯OK。
現在讓我做了斜線scanf函數2。
字符串。 “你好。”並且它 似乎工作時間。
>> 但有人提出了一個方案 它仍然可能不工作？
是嗎？
東西超過16個字符。
而實際上，我們可以 更確切的一點。
東西不再那麼15個字符， 因為我們真的需要牢記
我們需要反斜杠零 上面的字符串末尾的隱式
這是一個拋開scanf函數通常會 照顧我們。
>> 因此，讓我做這樣的事情 -
有時我們就可以 離開它這樣。
好了，我們現在已經引起 我們的分割故障。
為什麼呢？
因為我打字不超過15個 字符，所以我們實際上已經
其實我感動內存 不應該有。
>> 那麼，什麼是真正的解決方案在這裡？
那麼，如果我們需要一個更長的字符串？
好吧，我們也許做32個字節。
那麼，如果不夠長嗎？
大約64個字節？
如果不夠長？
約128或200字節？
什麼是真正的解決方案，在這裡 一般情況下，如果我們不知道在
推進用戶要輸入什麼？
>> 這是一個很大的痛苦的屁股只是一種， 說實話，這是為什麼
CS50庫有幾十行 共同實施的代碼
字符串的方式，我們不這樣做，則由GetString引發 提前知道什麼
用戶將要輸入。
特別是，如果你回頭看看 cs50.c從兩個星期前，你會看到
確實，GetString的 以這種方式不使用的scanf。
相反，它讀取一個字符 的時間。
>> 因為一個美好的事情 我們可以讀取一個字符
保證自己總是 至少有一個字符。
我可以聲明一個char，然後採取 只是這些真正的嬰兒的步驟
在讀取一個字符 從鍵盤輸入的時間。
然後，你會看到的GetString 確實是每次用完，
說，16字節的內存，它使用 malloc的，或一個表弟物，
分配更多的內存，複製舊 內存成新的，然後爬
一直以來，得到一個字符的時間， 當它用完
的內存塊，它扔了出去，待價而沽 更大的內存塊複製舊
進入新的和重複。
，它是一個真正的痛苦其實 實現的東西一樣簡單
得到來自用戶的輸入。
>> 所以，你可以使用scanf函數。
您可以使用其他類似功能。
而很多課本和在線 例子，但他們都
脆弱到這樣的問題。
最終，得到一個segfault 是有點惱人。
這不是為用戶好。
>> 但是，在最壞情況下，這是什麼 它從根本上把你的
代碼的風險嗎？
某種攻擊，有可能。
我們談到了一個這樣的攻擊 - 堆棧溢出。
但在一般情況下，如果你允許 緩衝區溢出，像我們做了一個
幾個星期前，只是寫 以上的“你好”，你在堆棧上
的確可以考慮，潛在的， 計算機上，或者至少在數據
不屬於你。
>> 因此，在短期，這就是為什麼我們有 這些培訓輪子。
但是現在，我們開始把他們趕走， 因為我們的課程不再需要，
必須的，來自用戶的輸入。
但在問題的情況下，設置6個， 您的輸入將來自一個巨大的
一些字典文件150 奇千言萬語。
>> 所以，你將不必擔心 用戶任意輸入。
我們會給你一些假設 關於該文件。
指針上有任何疑問或scanf 或用戶輸入一般？
>> 所有的權利，所以在一個快速瀏覽一下，然後 尾隨從兩個星期前的話題。
這是一個struct這個概念。
不 - 這個概念， 結構，這是什麼？
什麼結構為我們做什麼？
>> 定義 -
對不起？
定義一個變量的類型。
因此，排序。
其實我們兩個主題結合。
因此，用typedef，回想一下，我們可以 聲明一個類型，像我們自己的
的代名詞，就像字符串的char *。
但是，我們可以使用typedef和結構 真正創造我們自己的數據結構。
>> 舉例來說，如果我回去到gedit中 這裡只是一個瞬間，我先走
做這樣的事情，讓我節省 本作，讓我們說，structs.c
暫時我只是 繼續前進，包括
standardio.h，INT主要無效。
然後在這裡，假設，我想 寫一個程序，存儲
多個學生從多個 房屋，例如。
因此，它是像一個registrarial的 某種數據庫。
>> 所以，如果我需要一個學生的名字，我 可能會做一些像char *的名稱，
我會做這樣的事情 -
其實，讓我們使用CS50庫 只是一瞬間，使這個
簡單一點的，所以我們可以借用 那些幾十行代碼。
只是，讓我們保持它的簡單。
我們會保持它的字符串， 現在則由GetString引發。
>> 因此，我要求現在，我已經存儲的名稱 一些學生，房子
一些學生，只需使用變量 像我們一樣，在第一個星期。
但是，假設我現在要支持 多個學生。
好吧，讓我的直覺是做 字符串名稱2，得到的GetString，串
house2得到的GetString。
然後我們的第三個學生， 讓我們做NAME3 GetString的。
>> 所有的權利，所以這是希望引人注目 作為一種愚蠢的，
因為這個過程是真的從來沒有 將要結束，它只是要
使我的代碼看起來更糟糕 和每況愈下。
但我們解決了這個在本週二也。
我們比較乾淨的解決方案是什麼 當我們有多個變量，
相同的數據類型都有關，但 我們不希望這種殘暴的混亂
同樣命名的變量？
我們做了什麼呢？
>> 所以我想我聽到了幾個地方。
我們有一個數組。
如果你想的多個實例 的東西，為什麼不要我們清理這一切
，只是說，給我 數組的名字呢？
>> 現在，讓我們的硬編碼3。
然後給我另一個數組 稱為房子，讓我
現在硬編碼3。
而且我已經大規模清理 亂，我只是創建。
現在，我還是硬編碼3，但即使 3可以動態來自
用戶，或者argv的或類似。
所以這已經是清潔。
>> 但惱人的是， 現在，即使名字是某種
根本聯繫 學生的家 -
這是一個學生，我真的 要代表 -
我現在有兩個平行的陣列 在這個意義上，他們是
相同的大小，名稱托架0 想必映射到房子支架0，
和名稱支架1地圖 房屋支架1。
換句話說，該學生生活在 那房子，房子和其他學生
生活在其他的房子。
但可以肯定，這可能是 做得更乾淨。
>> 好吧，它可以，其實。
並讓我繼續前進，打開 了structs.h，你會
在這裡看到這個想法。
請注意，我用的typedef，因為你 剛才提到申報我們
自己的數據類型。
但是，我也使用此關鍵字 稱為struct這給了我一個新的
的數據結構。
>> 而這一數據結構，我要求是怎麼回事 有兩件事情裡面
- 一個字符串名為name， 一個字符串，稱為房子。
和名字我要去給 將這樣的數據結構
被稱為學生。
我可以打電話給我想要的任何東西， 但這種語義
我感覺到，在我的腦海裡。
>> 所以，現在，如果我打開了一個更好的版本 的節目，我開始寫
那裡，讓我滾動到頂部。
還有一些更多的代碼行 在這裡，但讓我專注
一個時刻。
我宣布一個恆定的所謂學生 硬編碼的現在。
但現在，注意到何潔 我的代碼開始就搞定了。
>> 在22行，我宣布 陣列的學生。
並注意學生顯然是 現在的數據類型。
因為在頂部的文件，通知 我已經包含了該頭文件
我拉起剛才。
該頭文件很簡單 這個定義一個學生。
>> 所以，現在，我創建了自己的自定義數據 類型，作者的C年
前事先沒有想到的。
但沒有問題。
我可以做自己。
所以這是一個陣列稱為學生， 其每名成員
是學生結構。
我想三個 在數組中。
>> 而現在，沒有休息 這個程序怎麼辦？
我需要的東西有點武斷。
因此，從24日起在網上， 我遍歷從0到3。
然後我再問用戶 學生的名字。
然後我用則由GetString引發如前。
然後，我問學生的房子， 我用則由GetString引發像以前那樣。
>> 但通知 - 稍微新 一塊語法 -
我仍然可以索引到的第i個學生， 但我怎麼得到的具體數據
領域裡面的結構嗎？
那麼，什麼是顯然 新語法？
這僅僅是點操作符。
>> 這之前，我們還沒有真正見過。
你已經看到了它的pset五，如果你 已經跌位圖文件。
但點只是意味著在這裡面， 結構或多個領域，給點
名稱，或者給我點的房子。
這意味著內部結構 得到這些特定的領域。
>> 這個程序的其餘部分做什麼？
這還不是全部，性感。
請注意，我再次循環從0到3， 我只是創造英語
短語，比如某某等 這樣的房子，通過在點名稱
的第i個學生和他們的 房子，以及。
>> 最後，現在我們將開始得到 肛門，現在我們
熟悉什麼malloc和 其他功能已經
做這一切的時候。
為什麼我一定要釋放這兩個名字 和房子，即使我
沒有調用malloc？
>> GetString的了。
那是骯髒的小秘密 幾個星期，但GetString的
遍布洩漏內存 把所有學期迄今為止。
valgrand終於將 揭示給我們。
>> 但是，它不是一個大不了的，因為我知道， 我可以簡單地釋放名稱
和房子，雖然在技術上， 超強，安全，應該是我
做一些錯誤檢查。
什麼是你的直覺告訴你嗎？
我應該怎麼檢查 之前，我釋放什麼是
字符串，又名一個char *？
>> 我真的應該進行檢查，如果學生 支架I點名稱不
等於空。
然後，它會確定先走，並免費 該指針，相同或其他
別人。
如果學生支架I點的房子是不是 等於為null，這將保護
對角落的情況 的形式返回類似空。
而且我們剛才也看到了，printf的 保護我們在這裡只是說
null，這是怎麼回事，看起來很怪異。
但至少它不會出現段錯誤， 正如我們所看到。
>> 好吧，讓我在這裡做另一件事。 結構-0是​​一個愚蠢的計劃
因為我輸入所有數據，然後 它失去了，一旦程序結束。
但是，讓我繼續前進，做到這一點。
讓我做終端 窗口有點大了。
讓我結構-1， 這是一個新版本。
>> 我會在一點點放大。
現在讓我跑點 削減結構1。
學生的名字 -
大衛·馬瑟，讓我們做羅布·柯克蘭， 讓勞倫利維瑞特。
現在是什麼有趣的通知 -
我只知道這是因為 我寫的程序 -
現在我目前有一個文件 目錄students.csv。
你們當中有些人可能已經看到 這些在現實世界中。
>> 什麼是CSV文件？
逗號分隔值。
它有點像一個窮人的 版本的Excel文件。
這是一個表中的行和列， 你可以打開一個程序如Excel，
或在Mac上的數字。
>> 如果我在這裡打開此文件gedit中， 通知 - 數字是不存在的。
這只是gedit的告訴 我行號。
的第一行通知 文件是大衛和馬瑟。
下一行是羅布逗號柯克蘭。
第三行是勞倫 逗號利維瑞特。
>> 所以，我創建了什麼？
我現在寫的C程序 可以有效地生成電子表格
可以打開在 如Excel程序。
並非所有引人注目的一個數據集，但 如果你有更大的大塊
數據，你其實是要 操縱，使圖表和
喜歡，這也許是一個 的方式來創建數據。
此外，特裝車點實際上超共同 只是簡單的數據存儲 -
雅虎財經，舉例來說，如果你得到 通過他們所謂的股票行情
API的免費服務，讓您 獲取當前到最新的庫存
公司的報價，他們 在給數據
超簡單的CSV格式。
>> 所以，我們是怎麼做到的呢？
注意到，這一計劃的最 幾乎是相同的。
但是請注意，在這裡，而不是打印 學生，上線35
開始，我要求我保存 學生到磁盤，保存文件。
>> 因此，注意到我聲明一個FILE * -
現在，這是一種異常C. 無論出於何種原因，文件是全部大寫，
這是不是像大多數其他數據類型 但是這是一個內置的
數據類型，文件*。
我聲明一個指針到一個文件， 你怎麼能想到的。
>> FOPEN意味著打開的文件。
你想打開什麼文件？
我想打開一個文件，我將 任意調用students.csv。
我可以打電話，我想要的任何東西。
>> 再取一個猜測。
第二個參數做什麼 FOPEN大概是這個意思嗎？
右，w代表寫， 是讀r為。
還有一個附加的，如果你 要添加行，而不是
覆蓋整個事情。
>> 但我只是想創建這個文件 一次，所以我會使用報價引文結束瓦特。
而且我知道，只有在讀取 文檔或手冊頁。
如果文件不為空 - 換句話說， 如果沒事就去那裡錯了 -
讓我遍歷 從0到3的學生。
>> 現在注意到有什麼東西 曾經如此略有不同
行約41。
這不是printf的。
fprintf printf的文件。
因此，它會寫入文件。
哪個文件？
您指定的指針 作為第一個參數。
>> 然後，我們指定格式字符串。
然後，我們指定我們想要什麼字符串 插頭的第一％S和
然後另一個變量或 第二個％秒。
然後關閉文件FCLOSE。
比我釋放內存之前，雖然 我應該回去，並添加
一些檢查為空。
>> 就是這樣。
FOPEN，fprintf等FCLOSE給我 創建文本文件的能力。
現在，你會看到問題集五， 涉及圖像，您將使用
二進制文件來代替。
但是從根本上說，這個想法是一樣的， 即使功能，你會
看到的是有一點點不同。
>> 所以旋風之旅，但你會得到 太熟悉文件I/O--
輸入和輸出 - pset中五。
而任何疑問 初始的基礎在這裡？
是嗎？
>> 如果你試圖釋放一個空值？
我相信，除非已經得到了自由 對用戶來說更加友好，你可以
潛在的段錯誤。
它傳遞空是不好的，因為我不 相信自由困擾為你檢查，
因為它可能會是浪費 為它做自己的時間
在世界上的每個人。
好問題，雖然。
>> 好，那麼這種得到 我們一個有趣的話題。
習題集的主題 五是取證。
至少這是一個部分 問題集。
取證一般是指在 恢復的信息，可能或
可能沒有被刪除 故意的。
所以我想，我想給你一個快速 什麼味道真的
下面這段時間 引擎蓋您的計算機。
>> 舉例來說，如果你裡面有你 筆記本電腦或桌面電腦一
硬盤驅動器，它可以通過機械 設備實際旋轉 -
有圓形的東西稱為盤片 看起來很喜歡我
剛剛在這裡，雖然在屏幕上 這是越來越多的老同學。
這是三個和一個半英寸 硬盤驅動器。
三個半英寸指 的東西，當你安裝它
在一台計算機。
>> 你們中許多人的傢伙現在在您的筆記本電腦 有固態硬盤或SSD，
沒有移動部件。
他們更像RAM不像 這些機械設備。
但這些想法仍然是相同的， 當然，因為它們涉及
問題五。
>> 如果你想想現在的硬盤驅動器 代表了一圈，這
在這裡，我會得出這樣的。
當您在您的計算機上創建一個文件， 無論它是一個SSD，或在
這種情況下，硬盤驅動器是較舊的學校， 該文件包括多個位。
比方說，它的0和1， 一大堆的0和1。
所以這是我的整個硬盤驅動器。
這顯然是一個相當大的文件。
並且被使用在該0s和1s 部分的物理盤片。
>> 那麼，什麼是物理部分？
嗯，事實證明，在硬盤上， 至少在此類型中，有
這些微小的磁性粒子。
他們基本上有北部和 南極，因此，如果您
打開其中一個，這些磁性顆粒 通過這種方式，你可能會說，這是
較1。
如果它是倒掛南下 北，你可能會說，這是
代表一個0。
>> 因此，在真實的物理世界，這是 你如何能代表的東西
二進位的0狀態和1。
所以這是一個文件。
有一大堆磁 是他們這樣或顆粒
通過這種方式，創建模式 0和1。
>> 但事實證明，當你保存文件， 一些信息分開保存。
所以這是一個小桌子， 一個目錄，可以這麼說。
我會打電話給這列名， 我會打電話給這個列位置。
>> 我要去說，假設 這是我的簡歷。
我的resume.doc被存儲在 位置，比方說123。
我總是去該號碼。
但我只想說，就像 在RAM中，你可以把一個硬盤驅動器
這是一個千兆字節或200千兆字節 TB級，你可以
所有的字節數。
你可以列出所有的8位塊。
>> 因此，我們會說，這 是123的位置。
因此，這個目錄裡面，我的作業 系統會記住我
簡歷是在位置123。
但它變得有趣，當 你刪除一個文件。
>> 因此，例如 -
令人欣慰的是，世界上大多數國家都有 捕捉到這 - 時會發生什麼
拖動文件到您的Mac OS垃圾桶 或Windows回收站？
這樣做的目的是什麼？
這顯然是要擺脫的文件， 但到底是什麼行為拖動
下降到廢紙簍或 回收站在電腦上做的嗎？
>> 絕對沒有，真的。
這就像一個文件夾。
這是一個特殊的文件夾，可以肯定的。
但它實際上刪除的文件？
>> 哦，不，因為一些你可能 一直喜歡，哦，該死的，你沒有
意味著這樣做。
所以，你雙擊 垃圾桶或回收站。
你周圍戳，你已經恢復 只需拖動文件
離開那裡。
所以很明顯，它不一定 刪除。
>> OK，你聰明得多。
你知道，只是拖動它到 垃圾桶或回收站並不意味著
你清空垃圾桶。
所以，你上去的菜單，和你說 清空廢紙簍或清空回收站。
然後會發生什麼？
>> 是啊，所以它被刪除，更是這樣。
但所發生的一切是這樣的。
電腦忘記 是resume.doc。
>> 但什麼也沒有明顯變化 在畫面？
位，0和1，我要求的是 在現場的一些物理方面的
硬件。
他們還在那裡。
這只是電腦有 遺忘它們是什麼。
>> 因此，它本質上釋放文件的 位的，所以它們可以被重複使用。
但直到你創建更多的文件， 多個文件，多個文件
概率，這些0和1， 這些磁性粒子，得到重用，
上攻或右側， 其他文件，0和1。
>> 所以，你有這樣的時間窗口。
它不是可預測 長度，真的。
這取決於你的硬盤的大小 驅動器和你有多少個文件
你如何迅速做出新的。
但是這期間的時間窗口 該文件仍然是完美的
收回。
>> 所以，如果你使用的程序如McAfee 或Norton嘗試恢復
數據，他們正在做的是試圖 恢復這個所謂的目錄
弄清楚你的文件在哪裡。
有時諾頓和會說， 文件是可收回93％。
那麼，是什麼意思呢？
這只是意味著，其他一些文件 巧合的結束使用，也就是說，
那些位出你的原始文件。
>> 那麼，什麼是真正參與 在恢復數據？
好吧，如果你不會有這樣的事情 諾頓預先安裝在電腦上，
有時你可以做的是最好的看 在整個硬盤尋找
的位模式。
和問題集的主題之一 五是，你會搜索
相當於一個硬盤驅動器，一個法醫 形象從一個緊湊的閃存卡
數碼相機，搜索為0 和1，通常，具有較高的
概率，代表 開始的JPEG圖像。
>> 你們可以收回這些圖像 假設，如果我看到這個圖案
位法醫形象， 的概率很高，這標誌著
開始的JPEG。
如果我再次看到同樣的模式， 可能標誌著開始
另一個JPEG格式，和其他 JPEG格式，和其他的JPEG。
這通常是如何 數據恢復工作。
關於JPEG文件有什麼高興的是，即使 的文件格式本身是有點
複雜，每一個這樣的開頭 文件其實是相當可識別
和簡單，因為你會看到， 如果你還沒有準備好。
>> 因此，讓我們來仔細看看下面 正是一直罩
回事，這些0和1 ，給你多一點的
上下文這個特殊的挑戰。
>> [視頻回放]
>> ，如果您的電腦存儲最 其永久性的數據。
要做到這一點，數據從RAM 隨著軟件信號，告訴
硬盤驅動器如何將這些數據存儲。
硬盤驅動器電路翻譯 這些信號轉換成電壓
波動的影響。
這些，反過來，控制硬盤驅動器的 移動部件，一些數
留在移動部件 現代計算機。
>> 部分的信號控制電機 其中旋轉金屬塗層盤片。
您的數據實際上是存儲 這些盤片上。
其他信號將讀/寫 頭讀取或
寫在盤片上的數據。
這個機器，一個人如此精確 頭髮甚至不能之間傳遞
磁頭和旋轉盤片。
然而，這一切都以驚人的速度。
>> [END視頻播放]
>> 國寶馬蘭：在一個小放大 更深現在什麼
實際上這些盤片上。
>> [視頻回放]
>> - 讓我們來看看，在我們剛才 看到慢動作。
當一個簡短的電脈衝 發送到讀/寫頭，如果翻轉
一個微小的電磁 的一小部分的第二個。
磁鐵創建一個字段，該字段 一個微小的，微小的改變極性
部的金屬顆粒 大衣每個盤片表面。
>> 這些微小的一個模式系列， 充電區，在磁盤上的
表示的一個位 二進制數中的數據
由電腦系統使用。
現在，如果當前發送的一種方法 通過讀/寫頭，該地區
是在一個方向上極化。
如果當前的發送，在 相反方向上，
極化反轉。
>> 您是怎樣從硬盤的數據？
只要相反的過程。
因此，它是在磁盤上的顆粒 獲取中的電流
讀/寫頭移動。
這些放在一起百萬 磁化段，
你已經得到了一個文件。
>> 現在，一個單一的文件件 遍布驅動器的
盤片的一塌糊塗，有點像 你的辦公桌上的文件。
因此，一個特殊的額外的文件跟踪 這裡的一切是。
難道你不希望你有 類似的東西？
>> [END視頻播放]
>> 國寶MALAN：OK，大概不會。
所以，你們的許多球員 從小一起長大的這些嗎？
OK，所以越來越少 表決時，每一年。
不過，我很高興你至少熟悉 與他們，因為這和我們自己的
可悲的是，書的演示，死一個非常 熟悉拖死。
>> 但是，這是我，至少，早在 高中，用於備份。
它是令人驚異的，因為你 可以存儲140兆字節
這個特定的磁盤。
這是高密度版本， 所指示的HD，其中有
這意味著之前今天的高清視頻。
>> 標準密度為800千字節。
而在這之前，有 400千字節的磁盤。
而在這之前，共有5和1/4 英寸磁盤，這是真正的軟盤，
和一點點更寬，更高 比這裡這些事。
但實際上你可以看到所謂的 這些磁盤的軟盤方面。
>> 和功能，它們實際上是 非常相似，在硬盤驅動器
至少這種類型。
同樣，固態硬盤在新電腦 工作方式略有不同。
但是，如果你移動，小金屬卡， 實際上，你可以看到一個小的cookie，
或拼盤。
>> 它不是像這樣的金屬。
其實這其中的一些便宜 塑料材料製成。
你可以擺動它的那種。
你trully只是抹去一些 位或磁性顆粒的數量
從該磁盤。
>> 令人欣慰的是，它沒有什麼。
如果這件事情的方式 - 並覆蓋 你的眼睛和你的鄰居 -
你可以只是一種拉 整個鞘關閉這樣的。
但是，有一個小彈簧，所以 知道你的眼睛。
所以，現在你有一個真正的軟盤。
>> 什麼顯著 在盡可能多的是，因為這是一個
一個更大的小規模的代表性 硬盤驅動器，這些東西都是超，
超級簡單的。
如果你捏它的底部，現在 該金屬的東西，和剝離
他們打開，有兩件 感到，並且所謂的軟盤
一塊金屬在裡面。
>> 並有去一半 我的磁盤的內容。
去他們的另一半。
但是這一切，裡面紡紗 您的計算機在昔日。
>> 再次，把這種成角度， 有多大你的大部分
硬盤驅動器，這些天？
500千兆字節，TB級，也許在 一台台式電腦，3，2 TB的
TB級，4 TB的，對不對？
這是一個兆字節，或採取 甚至不能符合一個典型的MP3
這些天了，還是有些 類似的音樂文件。
>> 有那麼一點點的紀念品今天為你， 也能幫助處境是什麼
我們將採取理所當然的 現在的問題設置5個。
所以，那些是你的保持。
因此，讓我這裡將成為過渡 花下的pset。
所以我們現在已經設置這個頁面 - 哦， 一對夫婦很快公佈。
>> 本星期五，如果您想加入CS50 吃午飯，去平常的地方，
cs50.net/rsvp。
最終項目 -
所以每教學大綱，我們已經發布了 項目最終規範已經。
要認識到，這並不意味著 這是由於特別快。
它的貼吧，真的，只是為了得到 你們想著它。
果然，有一個超級顯著 將解決你的百分比
最終項目的材料，我們 甚至還沒有得到在課堂上，
但下週初。
>> 但請注意，該規範要求 幾個不同的組件的
最終的項目。
第一，在幾個星期內，是一種 建議前期，很隨意的電子郵件
你的TF告訴他，或者你在做什麼 想為您的項目，
沒有承諾。
建議將您的特定 的承諾，他說，在這裡，這是什麼
我想為我的項目做。
你覺得呢？
太大？
太小？
是管理？
你可以看到更多的細節。規範
>> 幾個星期後，狀態 報告，這是一個類似的
休閒電子郵件到TF說多麼 不甘落後，你在你的最終
項目的實施，其次是 CS50 Hackathon大家
被邀請，這將是一個事件 下午8:00至7:00一個晚上
AM第二天早晨。
比薩，因為我可能會提到週 為零，將擔任下午9:00，
中國食品在凌晨1:00。
而如果你還醒著上午5:00， 我們帶你去IHOP早餐。
>> 因此，黑客馬拉松是其中一個比較 類中的難忘的經歷。
然後執行由於 然後高潮CS50展。
在所有這些的更多細節 在今後幾個星期。
>> 但是，讓我們回去的東西 舊學校 -
再次，一個數組。
所以數組是不錯的，因為它解決 的問題，像我們看到的只是一個
剛才學生結構 開始有點失控，如果我們
希望有學生，學生， 學生點點點三，學生，
一些任意數量的學生。
>> 所以陣列，幾個星期前，猛撲 並解決我們的問題不
事先知道有多少東西 某種類型的，我們想要的。
我們已經看到，結構可以幫助我們 進一步組織我們的代碼，並保持
概念類似的變量，就像一個 名稱和房子一起，使我們
可以把它們當作一個實體，裡面 其中有小塊。
>> 但是，陣列具有一些缺點。
的一些缺點是什麼 我們遇到
陣列，從而有多遠？
那是什麼？
固定大小 - 所以即使你可能 能夠分配內存的
陣列，一旦你知道有多少學生 你有，你有多少個字符
從用戶，一旦你分配 數組，你樣的畫
自己陷入了困境。
>> 因為你不能插入新元素 到一個數組中。
您不能插入更多的元素 在結束一個數組。
真的，你不得不求助於創造一個 全新的數組，如我們已經討論了，
複製舊到新。
再次，這是頭痛 則由GetString引發為您處理。
>> 不過，你不能甚至插入 成的中間的數組的東西
如果利率沒有被完全填充。
例如，如果該數組的大小 六只有五件事情，
好了，你可能只是粘 到年底的東西。
但是，如果你要插入的東西 到中間的
陣列，即使它可能有 五六個的東西在裡面？
>> 哦，那我們做的時候，我們都 我們人類志願者在舞台上
週過去？
如果我們希望把這裡有人，無論是 這些人該如何移動
的方式，還是這些人該如何移動 方式，並且變得昂貴了。
裡面的人轉移 陣列加起來和成本
我們的時間，因此我們很多ñ平方 運行時間，如插入排序，
例如，在最壞的情況下。
所以數組是偉大的，但你必須 提前知道你希望他們有多大。
>> 這樣就OK了，這裡是一個解決方案。
如果我事先不知道多少 我可能有學生，而且我知道，一旦
不過，我決定，我堅持與 許多學生，為什麼不我只是一直
分配兩倍的空間 因為我可能認為我需要什麼？
那是不是一個合理的解決方案嗎？
>> 實際上，我不認為我們 將需要超過50個插槽
陣列中的一個中等大小的類， 因此讓剛剛圍捕。
我會讓我的數組，只需100插槽 這樣我們就可以肯定得到
我期望的學生數 在一些中等大小的類。
那麼為什麼不圍捕和分配 更多的記憶體，典型地，一個數組
比你想像的，你甚至可能需要？
這是什麼簡單的推託 這個想法？
>> 你只是浪費內存。
從字面上看你寫的每一個程序，然後 也許使用兩倍的內存
你的實際需要。
而這只是不覺得自己像一個 特別是優雅的解決方案。
此外，它只是降低了 出問題的概率。
如果你碰巧有一個流行的課程 一個學期，你有101
學生，你的程序仍然是 從根本上面臨著同樣的問題。
>> 令人欣慰的是，有一個解決方案， 這個廣告的形式我們所有的問題
的數據結構的 之外的更複雜的
到目前為止，我們已經看到了。
，我要求，這是一個鍊錶。
這是一個數字列表 -
9，17，22，26，34 -
已連在一起的方式 什麼，我畫箭頭。
>> 換句話說，如果我想代表 我可以做一個數組，
這樣的事情。
我就把這個開銷 在短短的時刻。
我可以做的 -
你好，所有的權利。
待機。
在這裡，新的計算機明確 -
所有權利。
>> 所以，如果我有這些數字陣列 -
9，17，22，26，24 -
未必按比例繪製。
所有的權利，所以這裡是我的數組 -
噢，我的上帝。
所有的權利，所以這裡是我的數組。
哦，我的上帝。
>> [笑]
>> 國寶馬蘭：假裝。
這是太多精力回去 解決這個問題，所以有 -
26。
因此，我們有這陣 9，17，22，26，和34。
對於那些你可以看到 令人尷尬的錯誤，我只是做了
它是。
>> 因此，我要求這是一個 非常有效的解決方案。
我分配盡可能多的int類型， 我需要 - 一，二，三，
四，五，六 -
然後我存儲的數字 這個數組裡面。
但是，假設，然後，我要插入 8號這樣的值？
那麼，它在哪裡去了？
假設我想插入 20這樣的數字。
那麼，它在哪裡去了？
某處有在中間， 或數字35去
某處在年底。
但我所有的空間。
>> 所以這是一個根本性的挑戰 的陣列，它的解決方案。
剛才我聲稱是，GetString 解決了這個問題。
如果你想插入第六號 進入此陣列，什麼是至少一種
解決方案，您可以依傍的肯定， 就像我們做的GetString？
那是什麼？
>> 嗯，使其更大 說起來容易做起來難。
我們不一定可以使數組 大，但我們能做些什麼呢？
創建一個新的更大的數組，大小 6，或者大小為10，如果我們想要
出人頭地的東西，然後複製 舊到新的數組，然後
釋放舊的陣列。
>> 但是，什麼是運行時間 現在這一進程？
大O n的，因為複製 要花費你一些單位
時間，所以不是那麼理想，如果我們有 分配一個新的數組，這是怎麼回事
消耗的兩倍多 暫時記憶。
複製舊到新的 -
我的意思是，它只是頭痛， 再次，我們為什麼寫
則由GetString引發你。
>> 所以我們可能會做什麼呢？
那麼，如果我們的數據結構 實際上有差距？
假設我的目標是讓我放鬆 連續的內存塊，其中9
至17日，這是旁邊 旁邊22，依此類推。
>> 假設9可以在這裡 RAM，17能在RAM中，在這裡
22可以在這裡，在RAM中。
換句話說，我並不需要他們 甚至背靠背了。
我只是必須以某種方式穿針 通過每個這些數字，或每個
這些節點，我們稱之為 我畫的矩形，
記得怎麼到最後 從第一個這樣的節點。
>> 那麼，什麼是編程構造 我們最近見過不少與我
可以實現，線程，或者 吸引到這裡，我可以
實現這些箭頭？
所以指針，對不對？
如果我不只是一個分配 int，但是一個節點 - 和
節點，我的意思只是容器。
和視覺，我的意思是一個矩形。
所以一個節點顯然需要 包含兩個值 -
的int本身，然後，如所暗示的 矩形的下半部分，
類型為int的足夠的空間。
>> 所以只是想提前在這裡， 有多大，這是節點，這
容器中的問題？
多少字節的整數？
大概4，如果是 一樣平常。
那麼有多少字節 指針？
4。
所以這個容器中，或此節點 將是一個8字節的結構。
哦，這是一個令人高興的巧合， 我們剛剛推出這個概念
一個結構或C結構。
>> 所以我要求，我要採取的一個步驟 朝著這個更複雜
實施數字的列表， 鍊錶的數字，我需要做一個
多思考一點前面 聲明不只是一個int，但結構
我會打電話的，傳統 在這裡，節點。
我們可以把它稱為我們想要的東西，但 節點將是在一個特定的主題
的事情，我們現在開始尋找。
>> 該節點的內部是一個INT N。
那麼這個語法，一點點 怪異的第一眼 -
結構節點*。
形象好了，那是什麼？
這是下半部分的 我們看到的矩形
剛才。
>> 但是為什麼我說結構節點* 而不是只是節點*？
因為如果指針指向 在另一個節點時，它只是
一個節點的地址。
這是符合我們什麼 關於指針討論迄今。
但是，為什麼，如果我要求這個結構 稱為節點，我不得不說結構
內部節點這裡？
>> 沒錯。
這是一個愚蠢的現實C. typedef的，可以這麼說，有沒有
尚未發生。
C的超級字面。
它讀取你的代碼頂級 底部，從左到右。
直到它擊中，分號 底線，你猜怎麼著不
作為數據類型存在？
節點，報價引文結束節點的。
>> 但由於更詳細 聲明，我做的第一行 -
的typedef struct節點的 -
因為來之前，首先 大括號，有點像
前教育鏘，你 知道嗎，給我一個struct
所謂結構節點。
坦率地說，我不喜歡調用的東西 結構節點，結構節點
在我的代碼。
但我會只使用一次，只是裡面， 讓我能有效地
創建一個循環引用，而不是 一個指針，指向自己本身，而是一種
另一個指針 屬於同一類型。
>> 所以，事實證明，一個數據結構 這樣，有幾
操作，可能會對 我們感興趣的。
我們可能要插入 進入這樣的名單。
我們可能想要刪除 從這樣的名單。
我們可能要搜索一個列表 值，或者更普遍的是，遍歷。
和橫向只是一個奇特的方式 說你應該開始在左側和移動全部
的方式的權利。
>> 通知，即使有這樣的稍多 複雜的數據結構，讓
我建議，我們可以借用一些 在過去兩個星期的思想和
執行一個函數調用 搜索這個樣子。
這將返回true或 false，表示yes或
不中，n為在列表中。
它的第二個參數是一個指針 列表本身，所以
到一個節點的指針。
>> 我要那麼做是申報 一個臨時變量。
我們叫它PTR按照慣例， 指針。
我給它等於 開始的名單。
>> 現在注意到while循環。
只要指針不等於 空，我要來檢查。
指針箭頭n等於 中傳遞的n？
並等待一分鐘 - 新 一塊語法。
什麼是箭頭一下子？
是嗎？
>> 沒錯。
因此，而在幾分鐘前，我們使用 點符號訪問一些東西
內部的一個結構中，如果變量 你是不是該結構
本身，而是指向結構的指針， 令人欣慰的是，一塊語法
終於使得直觀的感覺。
箭頭指按照指針， 像我們的箭通常意味著
形象，並去 數據字段內。
所以箭頭是點，但同樣的事情 你使用它的時候，你有一個指針。
>> 因此，只要回顧一下，然後，如果n場 裡面的結構稱為指針
等於等於N，則返回true。
否則，這條線的位置 - 指針 等於指針。
所以，這是什麼做的，通知，如果我 我目前指向的結構
含有9，和9的不數 我要找的 - 假設我要找
n等於50 -
我要更新我的臨時指針 在這個節點不指向
了，但指針旁邊的箭頭， 正打算把我在這裡。
>> 現在，我意識到是旋風 的介紹。
上週三，我們將真正做到這一點 用一些人類和一些較
代碼以較慢的速度。
但要意識到，我們現在正在做我們的數據 更複雜的結構，使我們的
算法可以得到更高效， 將是必要條件
pset中六，當我們加載，再次，那些 15萬字，但需要這樣做
高效，理想的情況下，創建一個 我們的用戶不是在運行的程序
線性的，而不是在n的平方，但在 恆定的時間，在理想。
>> 上週三，我們會看到你。
>> 演講嘉賓：在未來CS50大衛 忘記了他的基本情況。
>> 國寶馬蘭：這就是你如何發送 短信與C -
>> [各種短信 通知的聲音]