揚聲器1:大家好。 我們將開始。 我認為,人們仍然要 是在過濾。 但因為時間的關係,所以我們可以 讓你們離開這裡的時候, 我們將要開始。 所以,歡迎到CS50測驗0條評論。 對於那些你還沒有意識到誰 然而,你必須在週三的問題。 宇豪。 如果你還沒有開始研究,或尚未 還沒有意識到這還不存在, 過去的測驗和有關的所有信息 您的測驗上cs50.net/quizzes。 這裡也有一些不錯的東西放在那裡, 從過去10過去的測驗 年以及信息 有關本測驗和主題 將被覆蓋。 所以,讓我們開始吧。 所以你們可能還記得,第一次 一流的大衛每天對這些燈。 所以基本上,一切都變 就在一台計算機的引擎蓋 二進制進行。 二是指它的聲音是什麼 等,0和1的。 它有兩個值,即 可以被表示。 所以就像在節的第一天 當大衛打開一盞燈 球來表示,或者1,我們的電腦 懂二進制的0和 1的,打開或關閉。 二進制的基礎。 每個地方的代表 在基地2。 所以,你加2到0至 1至2一路上揚。 要計算你的二進制文件是什麼 十進制,你只要按照這個公式 類型的事情。 如果你有一個1在其中任何一個地方, 您可以通過乘以什麼 基地是在加了起來, 你得到的小數點。 因此,這是怎麼算 5二進制。 就像我們在做什麼的 最後一張幻燈片,這是你會如何 代表1到5。 同樣,就像你可以添加和 減去十進制或基10,或 任何真正的基地,就可以添加 並減去二進制。 你會什麼期望時,你 添加兩個起來,如果它等於更大 比1,你隨身攜帶1,使之成為0, 做加法的方式,只是 就像你所期望的定期 小數或任何其它位置。 酷。 所以像我,以前的一切說, 我們的計算機的引擎蓋下繼續 在0和1的,或二進制完成。 那麼,我們如何表達,例如, 字母或數字或字符? 而這個問題的答案是ASCII碼。 ASCII是字符之間的映射 我們會在常看到 英語類的A,B的, C'S,下劃線,破折號和 類似的事情。 它映射了一個ASCII值。 ASCII值僅僅是一個數字, 可以通過你的計算機可以理解。 就這樣,你可以做加法和 減法與數字,你可以做 他們的ASCII值。 所以在本例中,什麼 這將打印出來? 是啊,所以只是一個空間B空間c空間 D.在哪裡我的鼠標去了? 請注意,你可以在65定義為int。 而當你使用打印出來 %的C,它會解釋,作為一個 性格和打印出A。 同樣,你可以聲明 它作為一個字符。 而當你使用百分比打印出來 C,它會解釋,由於 百分之四。就像你可以添加一個 號,可以添加字符 ASCII值,在這種情況下。 那麼一點點的指針為大家。 5,作為一個字符串,不 實際上等於5。 那麼我們如何轉換 串5的整數5? 任何想法? 是啊。 因此,如果我們有5個為一個字符串, 我們可以減去0。 而這將給我們5。 同樣,如果我們有5作為 整數,字符串添加0。 這給予我們的字符串5。 酷。 如今,回想起演講之一, 我們談到的算法。 那麼,如何才能真正想要一台電腦 做有趣的事情? 你知道,只是加減 數字和印刷出來的東西是不是 令人興奮。 通常情況下,我們希望我們的計算機 執行某種算法。 一些更複雜 不僅僅是簡單的算術題。 一個算法就是一步步套 對於如何執行的指令 一定task-- 就像一個配方。 你可能還記得第一天 培訓班裡大衛指望我們的房間 人又有多少人 在房間裡。 您可以用來計數 一個接一個。 1,2,3,4。 在這種情況下,一個線性時間算法。 但大衛介紹的算法 你算人在房間裡 每個人都站起來,你說你的 號給他人,添加 號了,一個人坐了下來。 而你再說一遍。 這是一種算法。 我們可以分析一下如何有效的 算法是基於它的運行時間。 但我們會談論一​​點點 稍後詳細說明。 因此,所有的算法也 寫成偽代碼。 偽就像是一個英語 語法用來表示 一種編程語言。 例如,如果我們想問問用戶 猜我最喜歡的數字,我們 可能具有偽代碼本身。 獲取用戶的猜測。 如果猜測是正確的,告訴他們 他們是正確的,別人告訴他們 他們是不正確的。 和偽代碼是很容易的方式 代表一個想法或一種算法。 所以,現在我們可能要實際寫 這在語言的計算機 可能認識。 因此,我們可以寫我們的偽代碼和 理解到這一點的源代碼。 到目前為止,源代碼必須堅持 到了一定的語法 一種編程語言。 到目前為止,在CS50,我們已經 使用大多數是C被。 所以這可能是C語言源代碼。 後來在使用過程中,你晚上來 與其它編程接觸 語言如PHP。 或者,如果你甚至採取其他的類,你 可以做使用Java,Python,甚至OCML。 但是,在我們的C程序語言,這是 我們如何編寫的源代碼 偽代碼算法 我剛才前面所述。 因此,如何真正做你的電腦 明白嗎? 就像我之前,只說真的 理解零和一。 那麼它是怎樣從源頭上得到 代碼的東西,可以 明白? 那麼,我們有什麼 所謂的編譯器。 如果你還記得早在大部分的 pset時,你有一些程序 寫在一個點C文件。 然後,您可以鍵入化妝。 那麼,是什麼讓做什麼? 您可以鍵入make來編譯 計劃,因為someone-- 誰寫的p將; 大概David-- 創建make文件。 並且告訴make知道你跑 編譯器,叫做鐺,這將 然後編譯源代碼,以反對 代碼,這是零和一 您的計算機理解。 但過了一會兒,我們會去 更深入的了解編譯器。 所以記得PSET 0,where--是, 你有問題嗎? 聽眾:[聽不清]? 揚聲器1:是的。 我覺得他們其實 應該是在網上。 是啊。 聽眾:是不是像[聽不清]? 揚聲器1:不是。 在上cs50.net/quizzes。 聽眾:斜線測驗,削減到2013年, 斜線0,只是通過點擊 競猜2013年和測驗0, 審查部分幻燈片。 揚聲器1:是啊,所以如果你們想 拉了起來,看著它在你的 自己的電腦,那也沒關係。 再說一遍。 聽眾:[聽不清]。 揚聲器1:是啊,[聽不清] 為虛擬變量。 哦,是嗎? 聽眾:[聽不清]? 揚聲器1:沒有,罷工 不在考試。 對不起,她的問題是,為 罷工的考試。 而事實並非如此。 所以PSET 0,你們應該都 使用臨時實施的東西。 我們學到了一些基本的編程 採用從頭構建塊。 因此,讓我們來看看一些 這些積木 組成一個程序。 首先是布爾表達式。 布爾表達式是那些與 0或任何有 兩個可能的值。 在這種情況下,真的還是假的, 開啟或關閉,是或否。 一個簡單的,很簡單的一個例子, 使用布爾程序 表現在這裡。 因此,為了使布爾表達式 是有用的,我們有布爾運算符。 這些操作符可以使用 比較特定值。 因此,我們有和或不等於,小於 大於或等於,大於或 等於和小於 或大於。 但這些運營商並不十分有用 除非我們可以將它們組合成 條件。 所以你們可能還記得從頭 並從p設置我們 有情況。 它們本質上是一樣的叉 你的程序的邏輯 執行取決於是否 一個條件得到滿足。 所以,我們有一個條件 在這個過程中多次使用的是 如果,否則,如果和其他條件。 這裡有一個如何的例子 你可能會使用。 有誰知道之間的區別 if語句都只是用 下節如果,其他的方式, 如果和別人結合起來呢? 是嗎? 聽眾:[聽不清]。 揚聲器1:沒錯。 所以,如果我有,如果沿著這條一路 這樣,即使該狀態下返回 如此,它仍然會繼續 測試下兩個。 然而,與其他人,如果一個else 語句中,如果返回true, 其他人都沒有測試。 關於什麼問題嗎? 酷。 所以,你使用的if-else的其他內容 語句,如果你知道,它只能 是這些案件之一。 因此,我們知道,如果x小於0,它的 絕對不會是 大於0。 接下來,另一個積木 我們學到的循環。 我們有三種類型的循環。 for循環,while循環, 做while循環。 一般,當你坐下來 寫的東西​​,你必須決定 要使用三種。 那麼,我們如何決定哪一個? 我們一般使用for循環,如果我們知道 多少次我們要遍歷 通過什麼或多少次 我們要執行的任務。 我們使用whil​​e循環,如果我們需要一些 條件是真實的,以保持正常運行。 我們用做的,而非常相似, 一段時間,但我們希望我們的代碼在運行 至少一個時間。 所以,做一段時間,無論是在DO線 總是至少運行一次。 然而,隨著時間,它 可能無法運行在所有如 條件不成立。 有任何問題嗎? 因此,一個結構循環。 你們都看到了這一點。 您初始化它。 你有某種條件。 因此,舉例來說,我們可能會初始化 作為i等於0。 i小於10。 我+ +。 很簡單的事,我們所做的一切。 對於一個while循環,同樣的,你有 有某種初始化的, 某種情況下,與 一些更新。 因此,我們可以實現我們的for循環也 作為一個while循環利用這一點。 同樣用do while循環, 我們可能有一些初始化, 執行的東西,更新,和 然後檢查狀態。 所以,現在的功能。 我們把一切融合在一起。 我們可能需要寫一些 種功能。 常見的功能,你可能 看到已經是主要的。 主要是一個函數。 它有一個返回類型,int類型。 它有一個函數名,主。 它有參數,argc和argv。 因此,主要就是一個函數。 你可能已經使用的其他功能, printf--的printf是一個函數 - 調用getInt,TOUPPER。 但這些發生在已 實施為我們 一些庫。 如果你們還記得,包括 這CS50.h庫或 標準I / O庫。 是的,問題? 聽眾:主要是用C只是固有的? 難道只是一種[聽不清]嗎? 揚聲器1:現在的問題是 如果主要是內在℃。 是的,所有的功能 有一個主要功能。 這是一種必要的計算機 要知道從哪裡開始 運行代碼。 聽眾:那你會不會[聽不清]? 揚聲器1:第 還有沒有其他問題? 酷。 所以,就像你可以使用一個函數 這是為你寫的,你也可以 編寫自己的功能。 這是一個功能,有人可能 寫來計算容積 一個Q,例如。 有一個返回類型在這裡,在這種情況下, INT,我們的函數名稱Q和我們 參數列表。 並請注意,您必須寫入數據 要的參數類型 使用,否則該函數不 知道什麼樣的 參數我應該接受。 所以,在這種情況下,我們希望 整數作為我們的輸入。 那麼,為什麼我們要使用的功能呢? 首先,偉大的組織。 他們幫助打破你的代碼 更多的組織塊,使 它更易於閱讀。 簡化。 這是很好的設計。 當你讀一段代碼 而主要功能是真的, 真的很長,它可能是更難 原因是什麼回事。 所以,如果你把它分解成函數, 這可能是更容易閱讀。 和复用能力。 如果你有一個代碼塊,它的被 所謂或運行多次, 而不是重寫代碼的10倍 在主函數中,你可能會 想重新使用它。 然後每次需要使用 一段代碼,調用該函數。 因此,如果我們記得劃傷, 我們也談到了幾個概念, 其中的一個線程。 線程是多的概念 代碼序列 執行在相同的時間。 所以回想起大衛有一天1 你們算過的數 人在房間裡。 從本質上講,是怎麼回事 上都是你們的人 運行單獨的線程。 而這些線程都撞在了一起 得到某種答案。 同樣,在刮,當你有 多精靈,你可能 有一隻貓和一隻狗。 他們會同時 運行自己的腳本。 即穿線的一個例子。 和其他的概念,這是 在從頭開始介紹了事件。 而事件的多個部位時, 與對方你的代碼進行通信。 在划痕,這時候你用的是 廣播控制和我 接收模塊。 而且,在習題集4,我們看到 事件一點點為好。 你們可能已經使用 在GEVENT庫。 並有一個功能waitForClick 在你等待 為用戶點擊。 和你的點擊,在這種情況下,將 該事件並等待點擊是你的 事件處理程序。 而且,在整個運行你的pset 與工作有關的pset時,你 可能接觸到 其中一些命令。 這就是你輸入到您的 終端窗口或其他窗口 這顯示了對你的G編輯, 本質上,瀏覽你的計算機。 因此,例如,ls列出了 一個目錄的內容。 使目錄中創建一個新的文件夾。 CD,改變目錄。 RM,刪除,刪除文件 或者某些目錄。 然後刪除目錄 刪除一個目錄。 聽眾:[聽不清]? 揚聲器1:是的,當然。 不好意思,問題是,如果你 建議把這個 在備忘單。 它可以幫助。 如果你有足夠的空間,你可以把它放在。 它也只是一般夠用了 要記住,因為當你使用它 你可能只想 有它記住。 這會讓你的生活變得更加簡單。 我有沒有回答你的問題? 所以,現在,我們談一點點 簡單說一下庫。 但是,這兩個主要的,我們已經 使用至今在使用過程中有 標準I / O和CS50。 都包括什麼樣的東西 在標準I / O庫? 是的,到目前為止,我們已經使用了printf的。 在CS50,我們使用調用getInt 和GetString。 和數據類型的字符串也恰好 在這CS50庫中聲明。 我們將討論多一點深入了解 圖書館如何工作的,以及他們如何 用你的代碼的其他部分交互。 但就是這兩種主要的是我們 已經走在接觸至今 過程。 類型。 這些都是很好的記住多少 每個類型由或代表如何 許多個字節的每個類型的requires-- INT,4個字節;字符,1個字節。 浮存金是4個字節。 什麼是雙? 聽眾:[聽不清]。 揚聲器1:是啊,所以浮動 但增加一倍的大小。 那麼長? 聽眾:[聽不清]。 揚聲器1:確定。 什麼是多長時間? 聽眾:[聽不清]。 揚聲器1:是的,加倍的詮釋。 是的。 聽眾:[聽不清]。 揚聲器1:長[聽不清]。 然後很長很長的兩倍。 聽眾:沒有,沒有。 長僅僅是一個int。 它依賴於結構 前[聽不清] 及詮釋具有相同的尺寸。 [聽不清]。 揚聲器1:那麼漫長而 int類型是相同的。 再長的長 是雙INT。 酷。 然後,什麼是最後的類型? 聽眾:指針。 揚聲器1:是的,所以我們學會了 約三分一點點。 也不管指針是什麼 指著to--它可能是一個char明星 或int star-- 它總是4個字節的指針。 有關該問題? 是嗎? 聽眾:[聽不清]? 揚聲器1:那麼長的和一個int是 同樣在這CS50設備。 聽眾:該設備是完全 互換。 揚聲器1:是啊。 所以後來很長很長的兩倍一個int。 聽眾:這是32位? 揚聲器1:32位,是的。 聽眾:所以[聽不清]? 揚聲器1:是的,如果它不 明確地說,你 應承擔32位。 聽眾:它會說什麼 像假設的 建築類的設備。 對於64位的唯一的事情, 變化是long和指針。 他們都[聽不清]。 揚聲器1:是嗎? 聽眾:問。 因此,在實踐測驗之一, 它詢問一個unsigned int。 因此,如何將是決定 從一個int [聽不清]? 揚聲器1:一個無符號 在同樣4個字節。 但是,什麼是有關簽署不同 int和無符號整型? 聽眾:[聽不清]。 揚聲器1:對。 一個可以代表負值。 但它是如何做到這一點? 聽眾:[聽不清]。 揚聲器1:是啊,這樣可以節省1 位來表示的符號。 簽名的有一位是 代表符號。 和無符號僅僅是全部陽性。 聽眾:確定。 所以,你說,一個是雙 一個浮動的兩倍? 揚聲器1:雙兩倍 一個浮動的大小,是的。 聽眾:如何做一個指針 到長隆[聽不清]? 揚聲器1:所以,問題是怎麼做 指針長long-- 怎麼只有4個字節時, 很長很長的8個字節。 所以,記得是一個指針, 本質上,在非常基礎的值。 聽眾:[聽不清]。 揚聲器1:是啊,所以指針 僅僅是一個內存位置。 所以不要緊多少空間 該指針指向。 它僅需要4個字節來跟踪 的內存位置。 還有沒有其他問題? 酷。 所以,過去的事情我有 是標準輸出。 你應該使用它們經常 以至於你能記住。 但是,這是當我們使用 printf的,例如。 而我們這些佔位符 被稱為格式代碼。 所以百分之c char字符,%的I為整數, 而且我們還可以用百分比Ð。 這是同樣的事情。 但是,一般地,在CS50我們 嘗試使用%的I。 百分比的f浮動。 LD百分比長和長 %的S代表字符串。 同樣,我們一直在使用數 這些轉義序列。 例如,反斜杠N代表新的生產線。 這僅僅是當你的格式 你的代碼進行打印F。 是嗎? 聽眾:什麼是百分之D代表? 揚聲器1:所以問題 是什麼%的D代表? 百分比d為為整數。 百分比D和百分之i是相同的。 聽眾:有什麼的區別 反斜杠n和反斜線R' 揚聲器1:所以,問題是有什麼 反彈n和區別 反彈R' 我覺得反斜線Řis-- 聽眾:所以反斜線Ř只是意味著 返回到行的開始 沒有實際去一個新的生產線。 所以,如果你打印一個反斜杠r和你 回到該行的開頭 那麼您打印更多的東西,您覆蓋 的東西,這已經在 [聽不清]。 然而,正實際上進入到一個新的 線並進入[聽不清]。 揚聲器1:嗯,沒有其它問題? 好吧。 我將它交給 丹誰將會繼續。 [掌聲] DAN:所有用右手。 因此,我將談論另一個廣 來自屬於類思想範圍 大約有代表性兩週和 本週三開始出發 擁有鑄造,這是只是一種方式 治療某些類型的值作為 不同類型的值。 因此,我們可以用字符來做到這一點 整數,浮點數到整數,並 長期多頭增加一倍。 所有這些東西可以作為方法 一種治療某些數值的 減炭一些其他 數值。 因此,有一些問題這一點, 當然,當你投來的 之類的東西浮到整數。 所以這是一個有點怪異。 我們有一個浮動是1.31。 我們10,000相乘。 然後我們將其打印為int。 這是什麼輸出? 10000次1.31。 所以13000,是猜測? 觀眾:我認為這是一萬元。 丹:所以我10,000乘以它 之前我投它。 聽眾:哦。 那豈不是有1個9 有的0號? 丹:你可能有一些奇怪的數字。 所以,正確的,它的1.3倍10,000元。 這就是13000。 而這額外的weird-- 聽眾:13,100。 DAN:13,100。 謝謝,羅布。 而這額外的weirdness-- 這9,9-- 很簡單,因為這件 結束了向下舍入其中 它不應該有。 是啊。 聽眾:鑄件發生 以後別的什麼嗎? 丹:是因為我有這樣的,印刷的,它 做這個乘法之前 這是否鑄造。 聽眾:[聽不清]。 丹:我想會先投, 是的,這將是10,000元。 還要別的嗎? 酷。 因此,這是13099。 為什麼會這樣? 不精確。 花車是不完美的。 他們只能代表數字一 若干顯著數字。 因此,如果我們在打印出8 SIG的無花果 這個浮球,我們得到了一種 難看的數字。 那是因為1.31不能準確 可以通過簡單的表示 兩個機器的權力。 所以,它最終以最接近 猜,這結束了 是有點低。 有意義嗎? 行。 現在,切換為不同的方式 這樣做的條件語句,所有 我們關心的是一個單一的變量。 所以在這個特定的例子中,我們 獲取來自用戶的整數。 然後,我們正在尋找 什麼是整數。 據推測,它的數量 與第一和第四。 這就是我們要求的。 所以,你要做的開關 變量名稱。 然後你建立可能的案件 值可能有關係。 所以,案例一,說這是低的。 然後你打破脫身 的開關狀態,以便 你不繼續下去。 在接下來的case-- 所以案例二和案例three-- 如果是情況2,它只是下降到 代碼的第一行就認為與 案例三,直到看到一個突破。 因此原因,你得到的情況下一個 僅打印低是因為我 這裡有這樣的突破。 如果我說,忽略了這個break-- 如果我把這個breakaway-- 它將打印低,然後它會 打印中,然後它會斷裂。 所以休息時間是一個重要的組成部分 開關條件和 他們應該在那裡。 未明確規定的個案 由默認處理 案例中的開關,應投。 聽眾:那1,2,3, 4為N? DAN:價值是n即可。 是的。 是嗎? 聽眾:所以當你有 在[聽不清]? 丹:你將打印低,然後 它將打印中間,並 那麼它會打破。 聽眾:為什麼會打印 中間如果[聽不清]? 丹:所以根據案件的一切 前下破下降。 因此,案件一個打印是下面情況 一個作為這列打印。 是嗎? 聽眾:[聽不清]? 丹:所以這個數字僅僅是一個特定的 值,該變量 可以了吧? 這是否有道理? 是啊。 聽眾:[聽不清]? 丹:是的,案例2將打印 中間再突破。 聽眾:[聽不清]? 丹:我覺得任何? 還有什麼其他的數據類型 你能切換? 聽眾:您可以切換 以上的任何數據類型。 但它只是意味著任何超過個字符 和整數之類的東西,因為 如果你切換指針 這並沒有真正意義, 切換負載,如果它甚至讓我們 你這樣做,因為浮點說, 在精確度,你不會真的 要做到這一點呢。 這麼漂亮多了,只是整數和 字符之類的東西。 丹:是的,這是當你有明確的 值,你知道,我認為,可以 一個開關實際上是有用的。 好不好? 行。 範圍是聲明的範圍 可變的延伸。 因此,在這個代碼塊小我, 這將是完全錯誤的。 而原因就是我聲明此詮釋 這個範圍的循環中島 然後我試圖引用 I的,對循環範圍之內。 所以基本上,你可以考慮一下範圍 如任何聲明 用大括號內只 存在這些大括號內。 如果你嘗試使用該變量 這些大括號外面,你會 獲得來自編譯器的錯誤。 是嗎? 聽眾:所以這個也不行? 丹:這是不行的,肯定的。 字符串。 串一個char *。 他們是完全一樣的。 他們只是指向字符。 那您有任何字符串應該結束 用反斜杠零,這就是 一個C約定。 這就是所謂的NULL結束。 和NULL-- 資本氮,大寫的U,資本 L,資本L-- 是不一樣的 NULL結束。 這是一個指針。 這是一個字符。 他們是非常不同的。 記住它。 這將是對測驗,大概。 我還沒有看到測驗。 是嗎? 聽眾:那空是,比如說,指針? 丹:是的。 聽眾:是什麼[聽不清]? 丹:如果說,malloc的調用,當你 沒有足夠的內存來獲得 無論你要求的尺寸, malloc的返回NULL。 這是,基本上,每當一個函數 應該返回一個指針,你 需要核對NULL,因為 null是一個漂亮的good-- 這是,排序,垃圾的價值。 這是一個零盡可能指針走。 當你調用一個函數, 返回一個指針。 你會想要檢查是 確保該指針不為NULL 因為空是很常見的。 這有點垃圾的回報。 所以,如果事情沒有去正確的, 剛剛返回NULL來代替。 聽眾:[聽不清]? 丹:是的,這就是這個。 聽眾:[聽不清]? DAN:拼寫它,因為這。 這是NULL結束。 這是小寫的n-U-L-L,如果 你拼了。 聽眾:我剛去 背部和測試它。 如果你試圖把一個浮點 值轉換開關,它會罵你 他說,聲明需要表達 的整數類型。 丹:你去那裡。 但是,是的,究竟是什麼問題又來了? 聽眾:[聽不清]? 丹:所以資本氮,大寫的U,資本 L,資本,L是一個實際的C件事。 這是空指針和意志 只有這樣看待。 你永遠不會嘗試拼 NULL字符和看到任何 除此之外的方法。 是嗎? 聽眾:所以回國為char或最大 東西在音符,將它 體現了相同的功能 為[聽不清]? 聽眾:所以你指的是 從getchar函數返回的字符最大,或 不管它是什麼? 聽眾:是的。 聽眾:是啊,所以一般 長期為所有這些事情 是定點值。 因此,像從調用getInt返回int最大 從getchar函數字符最大,它的 應該是這樣,那好吧,如果 這些東西都返回給我們, 出事了。 為指針,我們只是碰巧有 該標記值,每個人都 同意後。 這就是你回來的東西 當事情出錯。 因此,焦炭max是我們正在使用的是什麼 代表什麼 如NULL或的getchar。 聽眾:所以,如果你正在測試的getchar, 可能你只是把空? 會有所作為? 丹:你不能只檢查空。 你必須檢查字符最大,因為 從函數返回值是 一個字符不是一個指針。 是嗎? 聽眾:這個問題問 字符串長度。 這是否包括NULL字符? 丹:沒有。 而這實際上是字符串的長度如何 知道要停止,因為它通過 您的字符數組,直到 它看到一個空字符。 然後,它像所有 沒錯,我完成了。 聽眾:[聽不清] 5? 丹:你好是5。 是的。 所以數組是連續 的存儲器塊。 他們可以即時訪問說的 數組的名字,然後,在大 牙套,不管指數你想要去 到,他們是從零到索引 減去1的陣列的長度。 他們正在用的類型聲明 那你存儲的東西 陣列,該陣列的名稱,然後 無論大小是數組。 因此,這是長度的字符數組 6有這些值。 是嗎? 聽眾:[聽不清]? 丹:是的。 聽眾:[聽不清]? 丹:如果你有什麼事 入陣已經作出。 所以,你可以指定,而不是以此為, 比如說,焦炭,無論名稱的 數組是空的方括號等於花 振奮ħ逗號ê逗號Ł逗號Ł逗號 Ø逗號NULL字符 和大括號。 這也將作為一個聲明。 聽眾:[聽不清]? DAN:然後,你需要有 規模已經作出。 聽眾:[聽不清]? 丹:是的。 所有用右手。 命令行參數的方法 從用戶為獲得輸入 參數為主。 主要有兩個參數。 爭論正被數 沿著命令行和傳遞 串載體或一個字符串數組 所有的參數。 所以,如果我說,所謂的功能,如 點了1個空格,2的空間,3, ARGC是4。 而在argv 0將是一個點了。 Argv1將是1。 argv2將2 argv3會 3,在特定的情況下。 是嗎? 聽眾:[聽不清]? DAN:數組中的最後一個元素 因為數組長度的argc加 1 ARGB的,最後一個元件 是NULL指針。 它的argc加1。 所以,我剛才說了,它的情況下, 會做argv 0點了。 ARGV 1是1 argv2是2的argv 3 3。 的argv 4,它是一個容量較大的 比的argc將是NULL。 這就是NULL指針。 是的。 那是因為字符串 一個char星是一個指針。 所以它必須是相同的類型。 是嗎? 聽眾:兩個問題。 所以一,什麼是之間的區別 這和GetString超過一種類型的其他 在用戶發動機? 其二,它是存儲在 您最近的記憶? 所以像,GetString的會 是[聽不清]? DAN:它在哪裡存放? 我不知道它的存儲。 聽眾:所以,其實,你知道如何任何 函數調用它的參數 被存儲在棧? 所以argc和argv是參數主要 他們是在棧上,還是真的 只是上面的你在想什麼的 堆棧的開始。 什麼是另一部 的問題嗎? 聽眾:那麼什麼是[聽不清]? 丹:是的,它只是用不同的方式 的獲取來自用戶的輸入。 這一次的稍微更高效, 這是順手的腳本,因為你 只需將參數傳遞到您的主 功能,而不必等待 對於用戶,如果你沒有任何用戶。 聽。是啊,弄弦 將[聽不清]。 它會存儲你所需要的東西。 丹:是嗎? 聽眾:[聽不清]? 丹:是的,argv的0總是包括 點斜線函數調用。 是嗎? 聽眾:[聽不清]? 丹:是的,每個參數都 在NULL字符結束,因為他們 都是字符串。 聽眾:[聽不清]? 丹:是的,argv中的argc是一個NULL指針。 聽眾:[聽不清]? 丹:哦,是的。 是啊,對不起。 聽眾:所以[聽不清]? 丹:所以現在的問題是,如果你有 命令行點斜線點了1,2, 會命令行的數量 論據有兩個或會是3? 觀眾:我覺得它不 真正的問題。 我傾向於說,哦,你沒有通過 當任何命令行參數, 很明顯,你調用的函數。 所以,我傾向於用聲音排除 在命令行功能 即使它的參數 包括argv中。 DAN:但如果是在test-- yeah--而且如果你說的東西 喜歡的argc等於3, 你在安全的地位。 是嗎? 聽眾:[聽不清]? 丹:我認為,如果不調用此 在argc和argv的字符串括號 但保留了相同的類型,只是叫 不同的像他們的東西 和b,是否仍然有效? 它仍然正常工作, 你只是 - 代替使用argc-- 你會用A和B。 是嗎? 聽眾:[聽不清]? 丹:所以,問題是GetString的是 將存儲存儲器中的堆 因為GetString的為char *。 它在人堆裡,因為它存儲內存 現在要求在實際的malloc 實施的GetString的。 好了,繼續前進。 安全。 因此,要實現真正的安全,你靠不 1,你不許任何人進入任何 您的信息,這是為什麼 每個人都建立自己的機器, 自己的操作系統,其所有 從頭開始計劃,顯然 不要連接到任何其他機器 通過互聯網。 所以,電腦是不安全的。 他們真的是。 我們必須相信其他人。 和安全的想法是,你 試圖限制的量 你需要信任。 而你做到這一點的方法之一 就是通過加密。 密碼學是,本質上, 我們有秘密。 有時候,我們必須通過我們的秘密 沿著通過,比方說,因特網或 其他事情。 我們不希望人們 要知道這些秘密。 所以我們我們的秘密加密成一個方法 我們希望沒有人能搞清楚。 因此,我們used-- 通過這個類別 - 的過程中 事情像愷撒密碼和 [聽不清],這兩者都是非常 加密的東西不安全的方式。 他們很容易找出他們 是和你的秘密是。 現實世界中使用的多 複雜的加密方案。 我們不會進入 不止於此。 調試。 GDB是最好的。 我要再次強調這一點。 用GDB所有的時間每 時間你有問題。 命令,在廣發行是有用的 打破,你通過其中一條線 數,函數名,基本上是 凡在你的代碼要停止, 並能夠採取控制。 打印需要一個變量,並打印出 不管這個變量是在那 點在你的執行。 接下來將您執行 沿著一個步驟。 並加強在函數內部的步驟 在你執行。 其他的東西跑,這是怎麼 你實際運行的代碼。 繼續採取所有必要的步驟 到達下一個斷點。 還有很多很多的人。 找一找。 他們是偉大的。 是嗎? 聽眾:[聽不清]? 丹:是的,這是一個調試器。 因此,一個調試器是一個程序, 讓你調試你的程序。 這不是一個程序,發現錯誤的 你,雖然這將是巨大的。 而在去年對我來說是搜索。 所以,我們談到搜索的類型 大約在這個類是線性搜索, 這只是你通過每 搜索空間的元素,1 元素的時間,直到你找到什麼 你正在尋找或直到您到達 您的搜索空間的末端,在這 點你說你找不到 你要找的元素。 而這需要在最佳恆定時間 這是0的1,最差線性 時間,這是0的n。 二進制搜索,它需要 骯髒的元素。 你去你的元素中間, 看你要尋找的元素 是比元件更大或更小 你是在中間。 這是更大的,你說的底部 您的搜索空間是你的 當前的位置,中間, 你重新啟動該進程。 如果是更小的,你看說 這the--是啊,這是怎麼回事? 聽眾:[聽不清]? 丹:是的。 樣的一個已經教任何形式 這個類是公平的遊戲進行測試。 [笑] DAN:而事實上,你有沒有 這樣做的問題集,這是公平 遊戲進行測試。 聽眾:我們能過目一下如何to-- 丹:這將是走了過來。 揚聲器2:在實際的代碼 [聽不清]是study.cs50.net。 所以,如果你看一下實際問題 在合併排序頁面 study.cs50.net,存在的代碼 實現合併排序。 所以,你不必實施 它自己今晚。 但要確保你了解它,而 單純的記憶。 聽眾:[聽不清]? 揚聲器2:合併排序頁面 study.cs50.net,有一種做法是 即,如果您通過點擊問題 的問題,在最後有一個 溶液,這是合併 排序的實現。 但要確保你了解它 而不是單純的記憶 或複製下來。 聽。一個完全有效的 考試問題會 像這裡有一個列表。 這是什麼表像後 的選擇排序一步或 插入排序或什麼的。 列表中的一個完整的循環。 所以,即使你沒有最終需要 它的代碼,你需要了解它 足以知道怎麼回事 要修改這個數組。 丹:這是對我來說。 [掌聲] 盧卡斯:嘿大家。 我的名字是盧卡斯。 我要談的遞歸,所有 我們所學的種類,以及 所有指針點點。 行? 所以首先,遞歸。 這是什麼意思是說, 函數是遞歸? 聽眾:自稱。 盧卡斯:好,調用自身,是的。 所以喜歡這幅畫,例如。 這就像裡面的圖片 的圖像的等等。 因此,舉例來說,你可以have--丹 這說的是二進制搜索。 一種方法,其中二進制搜索是 遞歸是你的事實 試圖找到一個號碼。 所以,你去中間。 然後檢查是否有數字 在左和右。 然後,如果你發現了數量為 要在左邊,這是相同的 為再次做搜索的事情,但 只是在列表的左邊。 所以這是它的聲音 喜歡它的遞歸。 所以這就是為什麼你們有遞歸 解決方案歸併排序。 好了,這裡有一個例子。 所以我們可以說,我想選擇 所有的數字從1到n。 我也意識到,n的總和 數為n加N減1至1。 但是,如果我看以n減1加 Ñ​​減2加1,這是相同的 作為求和號的事 直到n減去1。 所以我可以說的平等和之和的 等於n,減去1的n個加的總和。 這是否有道理? 而且我也有別的東西 稱為基的情況下,它是 數的總和最多 零是零。 所以,當我到達數 零,我停止計數。 這是否有道理? 因此,這裡有一個如何的例子 我可以實現這一點。 所以我有一些這樣的功能。 這需要一個整數n。 所以在這裡我首先檢查是否n是 小於或等於零。 所以,如果是小於或等於零,我 返回零,這是我們的基本情況。 否則,我只能返回否加 的數字從和 1到n減1。 有意義嗎? 行。 因此,這裡是什麼樣子。 你有2等於總和 2加1的總和。 而一些1是1加 總和為0,即0。 有意義嗎? 因此,如果我們看一下堆棧的 程序,這是什麼樣子。 首先,我們的主要功能。 然後在主功能 所謂的總和2。 然後和2會說,哦,總和 2等於2加一的總和。 所以我加1和堆棧。 與1之和為要撥打的總和 0時,其也將被加入 到堆棧中。 然後每個這些那些是 在另一個上面有回 之前,其他的人可以繼續下去。 因此,例如,這裡,0相加, 首先,將要返回0。 然後選擇1和。 然後的1之和為要 返回1總結2。 最後,2之和為將 返回3主。 這是否有道理? 這是非常重要的,了解如何 堆棧的工作,並嘗試 看它是否有道理。 OK,這樣排序。 那麼,為什麼是排序重要的是, 首先? 我們為什麼要關心? 任何人嗎? 舉個例子? 是嗎? 聽眾:[聽不清]。 盧卡斯:是的,確定。 這樣你就可以更有效地進行搜索。 這是一個很好的方式。 因此,舉例來說,我們有很多的 的東西,其實,在我們的生活中 進行排序。 例如,詞典。 這是非常重要的,以把所有的 在某種順序的話,我們 可以輕鬆地訪問。 這就是他在說什麼。 可以更有效地搜索。 想起來有多難將有 字典中的詞語是在 隨機順序。 你必須看,好看多了, 每一個字,直到找到 一句話,你要尋找的。 如果你使用Facebook還時 你看你的朋友,你是 要看到,Facebook的把你的 仔細的朋友的上的那些頂級 你不要跟那麼多。 如果你走一路的底部 你的好友列表,你會看到 的人,你可能甚至不 請記住,你的朋友。 那是因為Facebook的種種 你的朋友的基礎上如何 關閉您是給他們。 因此,組織數據。 也口袋妖怪。 所以你看,所有的小寵物 有數字。 這就是像一個簡單的 存取數據的方式。 聽眾:訪問口袋妖怪。 盧卡斯:是的。 聽眾:[聽不清]。 盧卡斯:是的。 好了,選擇排序。 選擇排序是要選擇 列表中最小的未分類的每個值 時間在每一次迭代。 這有點像你做的那種 在你的頭腦,當你試圖 排序手頭上的列表。 基本上,所有你要做的就是你 為最小的數。 你把它在排序列表。 然後你去找 下一個最小的數。 然後你繼續做 該等等。 因此,選擇排序,基本上是你 選擇每次最小 未分類的價值。 把在排序結束 該列表的一部分。 並繼續這樣做。 因此,讓我們趕緊看看 這看起來像。 因此,這裡的排序 和未排序的列表。 這樣的排序列表, 它最初是空的。 然後我會選擇 最小數目在這裡,這是2。 所以我得到了2號,我把 在列表的前面。 然後我找下一個最小 元件,它是3。 所以我把它在最後 的排序列表。 然後我一直在這樣做。 我發現4,並把它在末端。 查找5,並把它在末端。 以及怎麼看待那些時代的 我是說把它放在結尾是, 基本上,交換兩個值。 行? 然後最後一個,你只 多了一個元素。 因此,它已經排序。 好了,插入排序。 插入排序,你要去也有 中有一個排序的事情, 一個未排序的列表。 唯一的一點是,每一次 您要添加的元素排序 列表中,你只要挑元素 在未排序列表的前面。 然後你會發現什麼 位置應該是在所劃分的 該列表的一部分。 讓我們來看看這是什麼,所以 這更有意義。 所以一開始,例如,我想 插入的數目3 列表排序的一部分。 因此,列表不會有什麼。 所以,我可以把數字3。 現在,我想5號添加到 列表的排序的一部分。 所以,我看5號。 我注意到,這是大於3。 所以,我知道,那一定是3後。 所以我把3和5。 然後,我想插入數字2。 我注意到,2號居然是 最後則兩個3和5。 所以,我居然還要把它所有的 方式在列表的開頭。 所以,我必須這樣做,種,將所有 在分類列表中,這樣我可以元素 令空間的數量2。 然後,我看到的數字6。 我認為,它應該是在5。 所以我把它放在那裡。 最後,我看4號。 而且我注意到它應該 介於3和5。 然後我把它放在那裡,移 所有其他元素。 有意義嗎? 冒泡排序。 因此,冒泡排序,基本上是你在做什麼 要do--我們稱之為泡沫 那種因為你通過列表中 - 它實際上是更好,如果我只是展示 你喜歡this-- 你要去比較 相鄰的號碼。 而且你要交換他們 如果他們沒有立場 以正確的順序。 所以基本上,看到的是什麼 發生在這裡,例如, 你有8個和6個。 你知道的排序順序會 實際上是6和5,對不對? 所以,你要交換的訂單。 然後,我看到8和4在這裡。 我做同樣的事情。 我換了。 最後,圖2和8。 我也掉他們。 這就是所謂的冒泡排序,因為後 每個迭代,其實, 最多列表中得到所有 的方式向列表的末尾。 這是否有道理? 因為它保持它的交換 並且將它移動到右側。 好了,這是第二個迭代。 這將是同樣的東西。 我會做一個交換和 然後最後一個。 í不存在互換 和列表進行排序。 所以在冒泡排序,我們基本上保持 經歷名單和交換 事情直到我注意到,我沒有做 任何掉期這樣做迭代,這 意味著列表已經排序。 有意義嗎? 讓我們來談談一點點 有關運行時間。 所以,不要你們還記得大 O,歐米茄,和Theta? 是嗎? 好了,什麼是大O,首先? 聽眾:[聽不清]。 盧卡斯:是的,這就是所謂的最壞情況 運行時,它只是意味著它的 你所期望的程序多少 取來運行。 如,在上of-- 在這個case--ñ。 中的元素的數量 列表中的最壞情況。 如,在最壞的情況下。 因此,對於冒泡排序,例如, 我們有N多的大O。 為什麼我們呢? 為什麼冒泡排序大OÑ多? 聽眾:[聽不清]。 盧卡斯:是的,所以最壞的情況下會 我必須做n次迭代。 所以每次迭代將要 帶來的最大的元素,以結束 的列表。 因此,最壞的情況是,我有 要做到這一點的事情n次。 並為每個時代,我要 做了N互換,因為我有比較 每兩個元素。 所以這就是為什麼它的Ñ平方 因為它的n次ñ。 然後,選擇排序是也可為N平方 因為,每一次迭代,我要 看每一個元素 在列表中。 然後找到最小的, 這意味著我必須 期待通過n個元素。 而我所要做的是n次,因為 我要選擇所有的n個元素。 插入排序是也可為N平方 因為在最壞的情況下會 是,一,我要插 n個數,對不對? 所以,我已經知道我要去 有n次迭代。 但對於每一個這些數字,如果我有 把所有的數字中 排序列表,並把它所有的方式 在前面,該將為n平方 因為這將為n n次重試。 有意義嗎? 怎麼樣歐米茄? 聽眾:[聽不清]。 盧卡斯:這是最好的情況。 所以,這就像在很多次的 排序,最好的情況下是 當列表已經排序。 所以,你真的沒有 做任何事情。 冒泡排序有最好的 情況的n。 難道你們知道為什麼嗎? 聽眾:[聽不清]。 盧卡斯:是的,如果你防不勝防 數據配給是否有任何掉期或 不,如果你碰到這樣的設置 如果有一個迭代中,如果真 名單已經排序,基本上, 什麼事情要發生是我要去 試換每兩個 相鄰的元素。 我要看到 有沒有掉。 我只是回來的時候了。 因此,這意味著我不得不 通過列表一次。 因此,它是N,因為我期待 在n個元素。 為什麼選擇排序Ñ方? 是啊,即使列表進行排序,對於 選擇排序的每次迭代,我 有選擇最小的元素。 因此,這意味著我必須出去找 在未排序的所有元素 列出並找出最小 對於每一次迭代。 這是否有道理? 和插入劍的,因為Ñ 情況下我試圖插入 號碼和所有的數字,當我 嘗試插入他們,我看到他們 在正確的位置上。 我沒有去檢查所有的其他 在未排序的列表編號。 所以,這就是為什麼它會為n。 有意義嗎? 什麼是時間值損耗? 聽眾:[聽不清]。 盧卡斯:什麼,對不起? 再說一遍。 聽眾:[聽不清]。 盧卡斯:沒錯。 所以,你可以看到只有選擇 存儲在歸併排序有θ驅動。 那是因為你只有西塔 如果這兩個大O和歐米茄是相同的。 行。 最後,合併排序是在為log N。 然後,作為丹說,合併排序 是一種像同樣的方式, 你做的二進制搜索。 所以,你得到的清單。 而且你會在半切。 然後把它們剪掉 在較小的一半。 然後將它們合併。 你們記住這一點,對不對? 好了,因為他說的話。 好了,指針。 那麼,什麼是指針? 聽眾:[聽不清]。 LUCAS:一個地址。 行。 我知道大衛展示了一堆 賓基和視頻的東西指著 彼此。 但我喜歡把指針 為僅僅是一個地址。 因此,這是即將變 以存儲一個地址。 所以它只是這個特殊的變量 這是4個字節長。 請記住,該指針是什麼 總是4字節長為32位 機,以便與外殼 家電。 它只是有位置 它裡面的變量。 好了,有這個記憶,基本上是這樣。 因此,每個內存塊實際上有一個 標籤,這是在地址 slotty內存。 因此,這意味著我可以有 指針指向 所有這些地址。 那麼,為什麼我們要使用指針的原因是 如果我要記住位置 一個特定的變量是內存。 和你們記得其中的一個 案例是,如果我有一個函數 如果我真的想你 掉期為實數,其實我 必須發送一個指針。 不變量。 難道你們還記得嗎? 所不同的between-- 名稱是什麼? 按價值計算,調用調用 參考了吧? 好吧,是的。 所以,通過值調用。 當你剛發一個變量 發揮你只是發送一個值。 所以你實際發送 該變量的副本。 和你的程序一點也不在乎 關於是否真正相同的變量 進行複印。 並呼籲參照指 實際上,我送的副本 指針指向的變量。 因此,這意味著我要送的 該變量的位置。 所以感覺我的位置 可變的,當我打電話的功能 使用指針,我能夠真正 改變是在主數據。 有意義嗎? 雖然,指針是複印件, 指針仍具有的實際地址 我想改變的變量。 有意義嗎? 所以創建的指針。 請記住,指針總是有 它的指向的類型 到,然後一個明星。 然後你把這個名字。 所以請記住,只要你有 什麼明星,它就像一個指針 ,無論變 輸入您了。 因此,這裡在星,例如,它的 指針和一個整數。 然後炭星是一個指針 炭星等等。 是嗎? 聽眾:如果我們有一個 指針到n明星的X. 我知道,創建一個指向x的指針。 它也x聲明為整數? 盧卡斯:好了,當你說北辰X, 你沒有創建一個指向 變量x。 您正在創建一個名為x的指針。 聽眾:[聽不清]。 盧卡斯:所以當我說北辰X,我 他說,嘿,在內存中,我將 讓這三個框之一。 而我會說,那 將是x,它 將是一個指針。 和一些有趣的指針 就是我們說他們有 4個字節的32位機。 和用於其原因是因為 4個字節的32位。 和機器都是64位的實際 有地址的指針 這是64位長。 因此,它只是意味著的大小 在機器的地址是不同的。 因此,引用和間接引用。 有兩個運算符 你們應該還記得。 第一是符號。 二是明星。 不要誤會由明星和這 STAR因為記得,在 這種情況下,你有n個明星。 這就像一個整體的東西在一起。 有否N空間的明星。 因此,這意味著,它的類型。 請記住,當你擁有 變星,你是 談論的類型。 當你只有明星,然後 變量的名稱,它意味著 你提領的指針,它 也就是說你正在看 指針,找到地址是 指向,將這個地址, 看著那無論何時 你在那裡。 所以我告訴我的學生,當你有 明星,你應該認為這是 的內容的縮寫。 所以,如果你有一個指針,你 做明星的指針,它的 該指針的內容。 所以,你去到任何它的指向 並期待在恆定內容。 而符號是一樣的 東西的地址。 所以,如果我有A--像一個變量,讓我們 說我做的int a等於3-- 如果我想找到該地址 變量的存儲,我可以做 &符號à。 因此,它的地址。 有意義嗎? 因此,這裡有一個例子。 這是缺少INT B和詮釋三。 所以的int a = 3意味著 我打算去記憶。 我要去尋找一個插槽 和把數3此處。 然後INT b等於c 4。 我會做同樣的事情。 轉到內存放了一些 4在一個箱子。 和INT等於5。 發現了另一個盒子,並把數字5。 那麼,什麼是這行做了呢? 北辰PA等於符號à。 所以,首先,正星PA。 它是什麼做的? 聽眾:[聽不清]。 盧卡斯:是的,所以北辰PA,第一, 聲明了一個名為PA指針。 然後它的分配的值 該指針是一個地址。 所以連字號à。 然後,如果我做星PB, 什麼是星PB? 哦,對不起。 這也不翼而飛。北辰PB。 我的意思是明星的PC。 我很抱歉。 這是同樣的事情。 但現在我很好AR創建一個指針 到B,然後指向到c。 是嗎? 聽眾:[聽不清]? 盧卡斯:是的。 所以,如果你去記憶和你去 盒子是代號為PA, 你究竟要 看到了一個地址。 行? 是嗎? 聽眾:[聽不清]? 盧卡斯:是的,指針是一個地址。 永遠不要忘記這一點。 這就像最重要 部分有關指針。 還有存儲和地址 一些變量。 還要別的嗎? 還有沒有其他問題? 行。 所以,指針和數組。 請記住,當我做int數組3, 基本上,我在做什麼是我,那種 的,在聲明一個指針。 所以數組是一種像一個指向 在內存中特定的地方中,我 分配三個插槽的整數。 這是否有道理? 所以,當我做int數組3,就是我 這樣做,基本上是創建三個 插槽中的內存。 所以,我只是覺得在內存中三個插槽。 所以,如果我這樣做,那麼,星陣,它 基本上意味著陣列的內容, 這意味著我刪除的指針,我走了 到那個地方,它的指向, 我把頭號。 然後,如果我做星陣加1, 這是同樣的事情,因為這樣做陣列 支架一個,這只是意味著我去 它的指向的地方。 然後加1品牌 我移動一個位置。 於是我去到這個位置,實際上, 並把兩個數。 然後,終於,當我做 陣加2,我去哪裡 陣列的指點一下。 然後我移動到內存塊。 然後我把三號這裡。 是嗎? 聽眾:所以星陣簡直是 說的第一點。 你還可以加1,只是因為 我們只有真正 在引用的第一個地址。 盧卡斯:是的。 我們為什麼,例如,假設數組 0,陣列1和陣列2? 我是說,你為什麼這樣做0, 1,2,3,而不是1,2,3? 其中一個原因是,一個,計算機 程序員喜歡開始 從0開始計數。 二是因為當你做陣列0, 這是同樣的事情,因為這樣做陣列 加0,這意味著我去 那個位置,我不 跳過任何存儲器塊。 所以,我不動任何內存塊。 是嗎? 聽眾:[聽不清]? 盧卡斯:所以她叫什麼 這樣的區別 這或做的malloc。 一的區別是 int數組3是創建一個 數組在棧上。 當我這樣做的malloc,它 在堆上創建。 這是否有道理? 那麼,如何malloc的實際工作? 那麼,為什麼我們甚至需要使用malloc? 你的編譯器種人物所有 你聲明的變量。 而他所有的創造空間 他們在堆棧中。 因此,所有的變量都將 在某處的堆棧。 因此,這裡的環境變量。 所以基本上,空間,這些變量 在內存分配在 編譯時間。 因此,這意味著你的電腦有 要知道所有這些變量的 事前。 它並不需要知道什麼樣的價值 你要放他們。 但是,它需要知道如何 你需要多少內存。 但現在讓我們說,例如, 你要創建一個數組或採取 字符串,你正在做 從所述用戶。 你不知道過了多久字符串 將是,例如。 所以,你不知道到底有多少 你分配的內存塊,對不對? 因此,它並沒有真正意義的 你說把100個字符。 然後,如果用戶寫150? 你會擰。 所以基本上,你不能確定如何 您需要分配多大內存 當你編譯的程序。 你只知道,在運行時間。 所以這就是為什麼你必須堆。 所以堆將會有記憶 您在正在分配 時間程序運行。 所以基本上,當你這樣做的malloc什麼 你正在做的,是分配內存 運行時,這意味著你 決定在那一刻的權利,你 應該有存儲器。 所以,當你分配它。 這是否有道理? 所以請記住,棧有變數 這是在編譯時創建的。 然後堆有變數 那你去創建 使用malloc,例如。 聽眾:[聽不清]? 盧卡斯:那麼GetString的是 要調用malloc。 讓我談談malloc和 我會解釋的GetString。 所以malloc的是同樣的事情 內存分配。 因此,它會分配 存儲在堆中。 而且它會返回一個指向 如該內存被分配在。 當你do--所以 這裡example-- 北辰指針。 然後指針相等的malloc 英寸的10倍大小。 我創建一個指針。 然後我分配的指針 的指針,該指針的malloc的值 是給我的。 所以我問的malloc可以分配你 空間為10的整數。 這就是它的說法。 和malloc給我回一個 指針指向的地方。 有意義嗎? 行。 i和GetString的是,基本上,做一個 打電話的malloc,所以你可以分配 在運行時內存。 一定要記住檢查null 因為malloc的是要返回null 如果無法分配內存。 比方說,你問了一個可笑的 內存量。 您的電腦不會是 能夠分配那麼多。 所以malloc的只是去 返回NULL。 所以永遠記得檢查 您從得到的malloc指針 空或不是,因為如果是這樣,你可能 被提領的指針和 導致側故障。 最後,不要忘了 您的可用內存。 malloc的是創建存儲在堆中。 而且你要釋放內存 前程序結束。 好吧,這就是我。 對不起,羅布。 謝謝。 [掌聲] 盧卡斯:最後還有什麼問題 之前搶來? 不是嗎? 是嗎? 觀眾:我沒看到 這個網上。 你已經上載了嗎? 盧卡斯:我認為大衛是 很快上傳。 戴夫:這將被張貼。 盧卡斯:這將是在網上。 聽眾:這是最高。 盧卡斯:這事? 行。 是嗎? 聽眾:[聽不清]? 盧卡斯:是的,你應該釋放所有的 這被放置在堆內存中。 聽眾:[聽不清]? 盧卡斯:是的。 任何時候你有一個文化的malloc, 你應該有自由文化 在您停止使用該變量。 所以malloc和free的 永遠在一起。 他們最好的朋友。 是啊。 羅布? 羅伯:我去快。 而且視頻將被提了起來。 我的麥克風。 好了,每週五天的東西。 第一件事,我們是堆棧。 因此請記住,只有一個堆 每個活動函數調用框架。 我們會看到,在一秒鐘。 還記得究竟去 在每個堆棧幀將要 我們的函數的局部變量, 被傳入的參數我們 功能,再加上一對夫婦 其他的事情你真的不 需要擔心的。 因此,這裡是一個示例程序,其中, 的通知,主要是printfing回報 富4的值。 富只是要返回 的4條6逗號價值。 酒吧是要設置一些當地的 變量n等於4倍6。 然後返回否。 因此,讓我們來看看整個堆棧 這個程序的實際迭代。 所以這是我們的堆棧的底部。 請記住,堆棧長大。 所以在我們的棧底,我們 有主堆棧幀。 當程序啟動時,主 總是要處於 我們的堆棧底部。 什麼是我們的內部 堆棧幀主? 因此,即使沒有本地 變量主,就像我之前說的, 我們argc和RGV佔用空間 裡面主要的棧幀。 所以主要是現在要 調用函數foo。 這意味著foo的是要 讓自己的堆棧幀。 所以,現在我們的內部 函數foo。 什麼需要去 Foo的堆棧幀? 那麼,富有一個參數n。 而n等於4,因為那是什麼 主要是通過為富的說法。 所以,現在富會打電話吧。 什麼是酒吧將有內 它的“堆棧幀? 它具有點¯x等於4 Y等於六。 這還不是全部,我們將不得不 因為在酒吧的堆棧幀 也有局部變量n。 而n我們將設定為24。 所以,現在酒吧是要返回否。 因此,巴將返回24 堆棧幀富。 而由於酒吧現在回來,那 意味著我們出棧幀 在酒吧從堆棧中。 因此,所有的酒吧一直是記憶 用現在堆棧。 現在,富也要去 回到24主。 所以,現在富正在恢復,內存 在富用其' 堆棧幀也不見了。 而現在,主要是要調用printf。 所以printf的只是另一種功能。 當我們調用printf,這將是 對於printf的另一個堆棧幀 函數調用。 什麼是我們傳遞的printf? 這是怎麼回事去 在它的堆棧幀。 最起碼,我們傳遞 即%的I反斜杠n和 參數24。 它可能有更多在它的堆棧幀 如果printf的碰巧使用一些 局部變量。 我們不知道。 但是,所有的雲在printf中的 堆棧幀。 這將執行中的printf。 隨後的printf的實現。 它會回來。 最後,主做。 主會回來。 然後我們的程序就完成了。 是嗎? 聽眾:你看到[聽不清] 參數[聽不清] 參數? 羅伯:所以是有細微的差別 之間的參數和參數。 真的,在共同的說話,人們往往 只是混淆了所有的時間。 但是參數是正規 的東西的名稱。 所以argc和argv是 參數為主。 爭論實際上是你 傳中的那些參數。 所以,當我調用foo 4,4有 是我傳遞的參數。 和參數n,內 富,取值為4 因為4是參數。 聽眾:[聽不清]? 羅伯:n是吧一個局部變量。 n是本地還是要富,但 這是一個參數為foo。 這不是一個局部變量。 是嗎? 聽眾:[聽不清]? 羅伯:富時打電話是酒吧和 返回不管酒吧的回報。 聽眾:[聽不清]? 羅伯:是啊,剛看到多 堆棧幀。 是嗎? 聽眾:為什麼叫做foo 之前的printf? 羅伯:printf的前為何被稱為富? 這樣我就可以有,而是做了一些 如int x等於4富 再印的X. 而是,我結合了功能 調入的printf參數。 但是請注意,我們不能真正 執行調用printf,直到我們 弄清楚了4 foo是。 所以,我們要評估這個。 只有一次這樣做了會 回來和評估的。 是嗎? 聽眾:因為這兩個欄[聽不清] 價值,為什麼我們沒有[聽不清]? 羅伯:他們完全應該是int。 這是沒有抓到過 多遍。 因此,它應該是int酒吧和INT 因為這兩個的富 正在返回的整數。 虛空只有當他們不打算 返回的實際值。 是嗎? 聽眾:如果你有一個以上的行 返回[聽不清]? 羅伯:上面返回的行? 聽眾:是的。 就像如果你做了printf和[聽不清] 將其打印了兩次? 羅伯:所以富裡面? 如果我們有一個printf就在這裡? 聽眾:是的。 羅伯:所以,如果我們有一個正確的printf 這裡,是將打印一次。 由於我們調用foo一次正確的 在這裡,然後我們會打的printf。 然後我們會打電話吧。 再富將返回。 就是這樣。 我們只遇到過 在printf的一次。 是嗎? 聽眾:[聽不清] printf的調用foo,因為我們是第一 調用printf的,然後我們傳遞 的論點。 羅伯:所以在理論上,是不是 printf的調用foo? 因此,沒有。 只是為了使c為要 執行這些東西,我們才可以 調用一個函數,所有的參數 該函數必須 徹底評估。 因此,這是完全評估? 是的,它只是一個字符串。 這只是一個值。 然後,我們必須徹底 評估此。 一旦這樣做了,現在所有的 它的參數進行評估。 現在,我們可以使 調用printf。 是嗎? 聽眾:有一個問題。 如果你有一個void函數,必須 你有回報分號? 羅伯:你不是一回分號 如果你有一個void函數。 行。 所以,現在有些堆東西。 所以堆是我們要如何應對 動態內存管理。 而這直接與對比 堆棧,我們稱之為自動 內存管理。 因此,在堆棧上,你從來沒有真正有 處理如何局部變量 正在入棧和出棧關閉所有 這些堆棧幀和所有的東西。 你不必為此擔心。 這是自動的。 所以堆是手動的。 和[聽不清] 來自這些功能 malloc和free。 因此,這裡的其他程序。 我們所要做的就是mallocing 的整數。 我們將它存儲在明星的X. 當然,我們要檢查 看是否x是零。 然後,我們將只設置什麼 x被指向到50。 打印x的值指向, 打印X,然後自由的X. 所以,這是怎麼實際去看看 如果我們看一下我們的堆棧和堆? 因此,我們將重新開始。 我們的疊層作為前底部。 請記住,你直接堆 反對棧? 因此,我們將有 我們堆的頂部在那裡。 所以我們的棧底,我們有 我們的主堆棧幀。 它具有的argc,argv的空間,而我們 現在有一個局部變量x,它 是一個int明星。 所以,我們要遍歷 通過這一方案。 第一件事,我們是 調用malloc的。 因此,我們正在做一個調用malloc的。 是的malloc函數。 這將得到一個堆棧幀。 什麼是我們通過對malloc? 這是怎麼回事裡面去 堆棧幀。 我們路過N,也就是4的大小。 因此,傳遞函數malloc。 什麼是malloc的呢? 它抓住了我們堆了一些空間。 所以我們會去堆。 而且我們要搶 4個字節從堆中。 所以讓我們只給了 的任意地址。 為0x123假裝這是一個 地址,它是在堆上。 那麼究竟是怎樣的裡面 內存地址為Ox123區域? 垃圾。 所以,我們沒有存儲在它的任何東西。 因此,據我們所知, 可以是任何東西。 你不應該假設它是零。 這是最有可能不為零。 所以,現在的malloc返回。 而我們該怎麼做時malloc的回報? 我們所設置的返回。 我們集合X等於什麼 它返回。 那麼什麼是回歸? 它的返回為0x123自認為是 的存儲器塊的地址,它 只是在堆中分配的。 因此,返回為0x123 x被現在要設定 等於為0x123的,形象地, 我們經常畫為x具有實際 箭頭指向該塊。 但是,x只是存儲的地址。 所以,現在我們要檢查如果x為null。 這不是空。 我們假裝是malloc的成功。 所以現在星x等於50。 因此,星記得這意味著 去那個地址。 所以,0x123的我們要 去那個地址。 所以這給我們帶來了那裡。 什麼是我們在該地址在做什麼? 我們要存儲50。 所以,這條線之後,那是什麼 事情進展到什麼樣子。 所以,現在它不再 垃圾在那裡。 現在我們知道,50是在 具體地址,因為 我們設置了這一點。 行? 所以,現在我們將要打印的F。 因此,首先我們要打印的明星的X. 那麼,什麼是星X你是否 再次,星x表示去 事情是X指向。 所以x被存儲為0x123去那。 我們得到了50。 因此,打印˚F的。 這意味著它要打印50。 然後返回。 然後我們有了第二個printf。 我們現在百分之頁。 如果你還沒有看到它,這就是 只是你如何打印一個指針。 因此,我們有百分之一,百分之 f和所有那些已經是。 因此%的磷,打印一個指針。 因此,x是一個指針。 所以,如果我們要打印的X本身, 我們正在打印什麼是真正的內部 x,它為0x123所以首 打印f被付印50。 第二印刷f的準備 打印0x123的呀? 聽眾:你用百分比 X要打印的指針? 羅伯:所以你用百分比 X要打印的指針? 所以,你可以,但百分之x是公正的, 概括而言,就像如果你有一些 整數,要打印 它作為一個十六進制數。 這只是你如何做到這一點。 然而,百分比D會 打印為十進制。 這是我們得到的百分比 ð。 i是剛剛整數。 %的p是專 為指針。 因此,x是一個指針。 我們要使用百分之頁。 但百分之x可能工作。 是嗎? 聽眾:[聽不清]? 羅伯:是啊。 至少在這個call--所以我 不包括在這裡。 不過,這兩種說法都必然 該堆棧幀中 以及任何局部變量 printf的碰巧使用。 然後下次調用printf的現在 printf的內部堆棧幀 %的p反斜杠n和不管 x值是,這是為0x123。 是嗎? 聽眾:[聽不清]? 羅伯:這將打印的東西 看起來是這樣的。 聽眾:[聽不清]。 羅伯:所以它打印它的地址表。 它看起來像一個地址。 是嗎? 聽眾:[聽不清]? 羅伯:為什麼呢? 聽眾:[聽不清]? 羅伯:這是為什麼指針4個字節? 因此,有一大堆 0的在這方面。 因此,它是真正0x0000000123。 在64位系統上,將有 一大堆的多個零。 是嗎? 聽眾:[聽不清]。 羅伯:所以第一個printf 將要print-- 聽眾:[聽不清]。 羅伯:是的,這是怎麼回事打印 x的值指向。 明星說:這是什麼 事指向。 抓住它。 那麼什麼是指向? 50。 抓住它。 這就是我們將要打印。 然而,下一個,我們 剛剛打印X本身。 什麼是f裡面? 為0x123。 行。 然後,終於,我們有自由。 什麼是我們傳遞給釋放? 我們傳遞的X. 那個時候我居然顯示 它的堆棧幀。 所以我們傳遞的價值 0x123的釋放。 所以,現在免費知道,沒事的, 我必須去到堆 自由內存。 它不再使用的是什麼 在地址為0x123。 所以,自由即將推出 從堆。 現在,我們的堆是空的了。 我們沒有內存洩漏。 現在免費將返回。 注意,x是仍然為0x123。 不過,現在是不是有效的內存。 我們不再提領的X. 是嗎? 聽眾:是返回0冗餘? 羅伯:是returen 0冗餘? 是的。 我們只是把有原因 我們有一個空氣回流之一。 所以,這就像,嗯,讓 包括返回0。 是嗎? 聽眾:[聽不清]? 羅伯:所以免費後X,如果發生了什麼 我們嘗試取消引用指針? 這有可能是萬無一失。 這是可能的,我們還是會得到50。 這是可能的,也即該內存 現在正在使用的東西。 所以這是不確定的行為。 和未定義意味著什麼 可能發生。 是嗎? 聽眾:[聽不清]? 羅伯:無,因此,如果您指定 X要別的東西。 所以,如果在這裡我們說的x等於 malloc的東西else-- malloc的大小event-- 那麼原來的塊 內存不釋放。 我們已經正式失去了它。 這是一個內存洩漏。 我們已經失去了所有的引用 到存儲器塊。 所以沒有辦法,我們可以不斷釋放它。 好了,再回到0來完成。 好吧,那麼堆棧溢出。 這裡有什麼想法? 所以請記住,堆正在下降。 堆棧是怎麼回事了。 因此,這是從演講的例子, 我認為,其中主要的是只是要 調用此函數foo,這是怎麼回事 遞歸調用自身過去, 一遍。 所以堆棧幀要 工作完全相同。 所以,我們要開始主 作為底部堆棧幀。 然後主要是要調用foo,這 會得到一個堆棧幀。 然後,富是要調用foo 再次,這是會得到 另一個堆棧幀。 然後又一次,又一次,又一次, 又一次,直到最後,我們運行 入堆。 因此,這是我們如何得到 堆棧溢出。 在這一點上,你賽格故障。 或者你真的賽格故障前 這一點上,卻是的。 聽眾:是核心轉儲 同賽格錯嗎? 羅伯:所以你會看到分割 故障的核心轉儲。 你會得到一個核心轉儲時, 你賽格故障。 它就像所有的轉儲 您當前內存的內容,以便 你可以嘗試找出 為什麼你賽格故障。 是嗎? 聽眾:[聽不清]? 羅伯:所以分段錯誤方式 有一個堆棧溢出。 所以不一定。 段錯誤意味著你 觸摸記憶的方式 你不應該。 使發生的一種方式是,當 您堆棧溢出,我們開始觸摸 記憶體的方式,我們不應該。 是嗎? 聽眾:[聽不清]? 羅伯:所以的無限循環中。 喜歡,這就像一個無限遞歸 循環,所以我們得到另一個 堆棧每個時間幀。 只是裡面的一個普通 無限的,而埃德蒙頓 好了,讓我們甚至沒有打印F-- 做一些事情。 不管。 我們不會將越來越 另一個堆棧幀。 我們只是要保持循環 在這個單指令。 堆棧沒有增長。 這是事實,每個遞歸 電話是給了我們一個堆棧幀。 這就是為什麼我們得到一個堆棧溢出。 是嗎? 聽眾:如果你說得到 while循環,然後按[聽不清]? 羅伯:所以,如果內部的while循環 有一個printf,你仍然會 不賽格故障。 我只是不希望的事情混淆。 它會循環。 你會得到一個堆棧 框架中的printf。 隨後的printf會回來。 然後你再就不斷循環。 你會得到一個堆棧 框架中的printf。 它會回來。 單棧幀。 所以,你沒有得到這個無限 堆放堆棧幀。 聽眾:[聽不清]? 羅伯:是的。 所以這個堆棧溢出發生 因為沒有這些 調用富都回來了。 因此,如果我們回來,然後我們會 開始失去堆棧幀。 然後我們就不會堆棧溢出。 這就是為什麼你需要一個基本情況 為您的個人功能。 是嗎? 聽眾:是對潛在的尺寸和 棧堆一樣的 所有的程序? 羅伯:大約。 在堆疊的電勢的大小和 堆相同的所有項目? 粗略。 有一些隨機化 其中棧開始和 其中堆開始。 如果你碰巧有一大堆 全局變量和的事情,你可能 從一些空間帶走 你堆。 在64位系統上,你幾乎 有無限懷念。 這裡還有這麼多。 之間的32位和64位,即 是顯著差。 你會得到一大堆更多 在64位堆棧和堆空間 制度,因為只是多 解決了他們可以使用。 但單個系統上,它會 是一疊大約相同數量的 和堆空間。 好吧。 所以最後一件事是編譯。 所以,你應該知道這個過程。 有四個大的步驟。 所以,第一個應該 很容易記住。 預處理。 它具有預先在它的前綴。 所以,說到一切之前。 要記住的是哈希值。 因此,散列定義和散列包括 在所有這些的。 這些都是預處理器 指令。 這些事情了 預處理器需要照顧。 那麼什麼是預處理器嗎? 這是一個非常愚蠢的事情。 所有它的能力是所有這些 複製和剪切和粘貼操作。 因此,散列包括標準I0點小時。 那是什麼做的? 它抓住了標準I0點ħ 文件並將其粘貼到頂部 無論它說散列包括 標準I0點小時。 和任何散列定義,我們已經 可見,那是什麼做的? 其複製的值的哈希 定義的被定義為和粘貼的 無論你使用的值。 所以預處理器少了點真的 基於簡單的文本操作。 它什麼都不聰明。 所以,一切是 更為複雜。 所以,現在預處理器 完成後,我們實際編譯。 那麼,是什麼編制是什麼意思? 我們現在從C代碼中去 為彙編代碼。 是嗎? 聽眾:[聽不清]? 羅伯:是的,我們抓住了這一點。 所以編譯。 我們打算從C到裝配。 因此,這是一個實際的語言變化。 編譯本身就意味著從去 更高層次的語言 低層次的語言。 和c是一個高層次的語言 相比於裝配。 什麼是組件? 它的指令是,相當 多了,做了你的CPU。 但是你的電腦仍然 不明白組裝。 這只能理解和0。 因此,下一步的組裝,這 使我們從這些指令 你的CPU的理解,實際上 它們翻譯,以 1和0。 所以C到組裝成二進制。 但我沒有一個可執行的呢。 所以想CS50庫。 我們已經為您提供了二進制 這CS50庫,裡面有GetString的 和調用getInt和所有。 但CS50 library-- 在itself--和不可執行。 它不具有一個主函數。 這只是一堆二進制 您可以使用。 所以鏈接是我們如何把所有 這些不同的二進制文件 成實際的可執行文件。 一,你可以鍵入 點斜線點出來。 因此,這是類似於文件,你 寫道: - 無論你的程序is-- 塞瑟C點。 但現在它被編譯 下降到二進制。 所以塞瑟點O操作。 這是我們CS50庫二進制。 而且他們正在結合 成一個單一的可執行文件。 是嗎? 聽眾:[聽不清]? 羅伯:所以首先包括,記住, 哈希包括實際上是一個 預處理器步驟。 但是,這是不同的。 如果你不使用任何函數, 是你的單文件之外,那麼, 不,你不需要任何鏈接 因為你擁有了一切。 這就是說,printf的被鏈接英寸 如果你用printf,這東西 需要在要鏈接 因為你沒寫。 並且,實際上,printf的是自動 在聯繫。 你知道如何在命令行或者當 你鍵入make,你看它有 破折號升CS50,它有鏈接 在CS50的圖書館? printf的,和類似的東西,是怎麼回事 將自動鏈接的。 在任何其它的問題嗎? 聽眾:[聽不清]? 羅伯:鏈接? 我們有一大堆 不同的二進制文件。 這就是典型的例子 我們用的是CS50庫。 我們已編制並提供給您的 二本CS50庫。 您要使用的GetString 在你的程序。 所以,你去使用GetString的。 但是,如果沒有我的二進制代碼 GetString的,當你編譯你的代碼 下來,你不能真正運行 計劃,因為GetString的String是 尚未完全確定。 只有當你在我的二進制鏈接 包含的GetString,現在,所有的 沒錯,其實我可以 執行GetString的。 我的文件是完整的。 我可以運行了。 是嗎? 聽眾:是否鏈接轉換 二進制文件到可執行? 所以,即使你沒有其他 圖書館,是不是仍然是 要翻譯 在[聽不清]? 羅伯:所以可執行 仍然是二進制。 它只是結合了全 一串二進制文件。 聽眾:非常感謝你。 羅伯:沒問題。 還有沒有其他問題? 否則,我們的所有設置。 好吧。 謝謝。 [掌聲] 聽眾:謝謝。 羅伯:是啊。