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 - [各種短信 通知的聲音]