[音樂播放] DAVID J.馬蘭:好吧,這是CS50 這是5週開始。 所以今天,坐墊底下, 你不會找到任何東西。 但最重要的,你應該找到這些, 我們欣賞的一點小小的心意 你把所有的工作 進入15遊戲。 只要簡單地除去小圈上 底部開始打 其餘類。 所以記得或知道這個問題集 四,本週末出去, 涉及編寫另一場比賽。 但是,這一次,它涉及到使用 實際的圖形用戶界面,而不是一個 文本界面,如 十五的遊戲。 而本場比賽在於你前面, 如果你還沒有見過這下, 看起來有點像這樣的東西。 我要進入我的終端 在GDB窗口。 而且我要繼續前進並運行 員工的解決方案,您可以訪問 運行update 50後,像往常一樣。 不過,我打算把它放入少許 秘密模式,一點點的復活節彩蛋, 所謂的上帝模式, 讓上帝argv1。 我要按照我自己的方向, 在我自己的運行 問題設置目錄。 所以,現在你看到一個完整的版本 的突圍的比賽。 其實,這是沒有手模式。 因此,它實際上是 - 叫絕儘管你可能會對 - 很容易實現上帝模式 突圍,不像十五的遊戲, 一些你可能已經解決 黑客版。 在突圍中,只要在上帝 模式簡單地做什麼, 直觀地與槳? 只要使它等於不管 水平位置的球。 所以只要你做到這一點步調一致 ,球移動這個遊戲會 永遠,永遠,永遠錯過了球 你會每次都贏。 但在本週的黑客版 有以上只是上帝模式。 有一些其他功能。 其中,激光器。 所以,如果你真的不耐煩 可以擊落磚開始 和其他幾個人。 而對於那些你誰想要 校準標準與黑客 版,我可以看到,本週的 黑客版故意是一個 更可行一點,也就是說,不是神 模式是與遊戲的十五。 所以,如果你正在尋找一個舒展和 你正在尋找一些額外的樂趣 如果感興趣的功能做潛水。 現在更實際,讓我點 一件事。 GDB,有些人可能還沒有 親自感動,這是很好的。 但現在是真正的時間來習慣 這和舒適的使用這個工具 因為它會讓你的生活 更容易,真正做到。 每羅布GDB的一對夫婦的講座 數週前,記得 ,GDB調試器。 這是一個工具,可以讓你運行你的 程序,但運行它一步一步,線 行,讓你可以閒逛, 所以,你看到的事情發生,所以 您可以打印出來 變量的值。 總之,它給了你這麼多 功率比printDef。 誠然,現在的界面 是相當神秘。 黑色和白色的文本界面 在大多數情況下。 命令有些艱難 記得在第一。 但是,即使它可能需要你的一半 一個小時,一個小時,把前期 投資的時間把它,相信我。 當然學期的結束,這將節省 你一個數量級以上 時間比。 所以早在本週長驅直入 在突圍方面,知道你 能做到這一點,只要你有 分配代碼或您自己的代碼 在建您的Pst4目錄。 要知道,你可以運行gdb。/突破。 這將開闢 這樣的窗口。 讓我給自己更多 一個終端窗口。 然後呢,我要繼續前進 做的,它的不只是運行它。 我要首先設置了一個破發點 召回,它允許你暫停 在一個特定的地方執行。 只是為了簡單起見,我要去 只需鍵入打破行一 頭號。 實際上讓我重新打開此窗口 因為它才獲得了 有一點小。 所以現在,我要在這裡做什麼 如果我打開終端窗口。 來吧,我們去那裡。 所以,現在如果我回去到Dropbox,Pst4 運行gdb。/突破進入,請注意 我要打破一個設置 一個破發點,線一條。 現在我要去 運行前方和類型。 而當我這樣做,注意什麼 似乎發生。 有沒有彈出。 有沒有圖形 用戶界面。 但是,這是可以理解的,因為我 字面上線在我的計劃之一。 注意到我快進, 特別是現在到62,因為所有的 在這個文件的頂部的東西是 像註釋和常量和 現在的無趣的東西。 所以我現在的主要內, 看起來,在第62行。 而這僅僅是分配 代碼,召回。 如果我開這件事,同樣, 進入我的下拉框成Pst4目錄, 到breakout.c。 如果我向下滾動下來,下來, 並讓我繼續前進,打開 我的行號。 我會看到什麼,如果我向下滾動到 62號線,是完全行 我們已經暫停。 因此,這條線在這裡,62歲, 我們是。 所以,現在在GDB,如果我先走,然後鍵入 現在下,進入它要 執行這條線。 瞧,我們有 所謂的克窗口。 如果什麼GWindow不熟悉 ,不用擔心。 該規範將為您介紹它,因為 以及大量的演練視頻 嵌入在規範中。 但現在讓我們做一個 更有趣一點。 讓我移動這個窗口 一邊一點點。 讓我一點窗戶 更大,所以我可以看到更多。 現在讓我繼續 和再下一步要做。 而且有我的磚。 如果我再接下來鍵入 現在我看到球。 如果我再接下來鍵入 現在我明白了槳。 幸運的是,這gedit中不 通過展示我真正合作 我想要的一切。 但現在如果我再下一步做, 再接下來,我只是 聲明一些變量。 我可以打印任何一個 這些傢伙。 打印磚,版畫的生活。 現在如果我繼續做 接下來,請注意,我會 裡面的這個循環。 但是代碼執行 正是因為我的期望。 所以,當我打這個功能,等待 按一下,它會做 它的字面。 所以,我似乎已經失去了控制 在節目。 GDB是不給我另一個提示。 但不用擔心。 轉到我的遊戲,點擊的地方。 瞧,現在進行到第86行。 再次,它是無價的,最終, 調試問題。 因為你可以從字面上步驟通過 你的代碼,打印多東西出來, 多少,等等。 但現在,這些工具本身 應該讓你很遠。 因此,我們,當然,考慮看看 現在顯卡,一下子。 現在我們的世界變得有點 更有趣。 你知道,或許,從一些 我們這些在線視頻 短褲,你已經看 習題集的一部分。 他們已經出手,故意 以白色背景。 他們中的一些教學 圖紙上的某些文本研究員 屏幕覆蓋 上側。 不過,當然,這還不是全部, 在現實世界中有趣。 這僅僅是一個與報告廳 白色的大屏幕和背景。 我們驚人的生產隊排序 讓一切看上去很美 通過裁剪後的事實 或覆蓋任何東西 我們做什麼或不想要的。 現在只是為了激勵這個星期, 真的,你可以去,最終, 計算機科學。 問題後,不只是設置了四個。 但之後其他課程或整個 課程是驚人的,你可以 這幾天而言, 尤其是在圖形。 你們當中有些人可能已經看到了這 網上四處流淌。 但我想我會告訴你,只是一個 兩分鐘,一窺究竟 計算機技術和CGI 計算機圖形可以做這些天 熟悉的歌曲 也許電影。 [MUSIC - LANA DEL射線, “年輕和美麗] 揚聲器1:這只是一點點 驚人的,也許,只是如何 無處不在 - [掌聲] 揚聲器1:我剛下載了它。 但它真的很神奇,我想,只要 無所不在的軟件和代碼, 真的是這樣的工具。 所以這是一個品味的方向 在其中,你可以走了。 哦,沒有更多的電器。 嗯,這實際上是悲慘的時機 點我只是試圖讓。 好吧,讓我們推出 再次融合。 稍後提醒我。 沒事了,你應該有一個 順便說一句,如果你確實得到了電子郵件 類似的通知。 好吧,所以記得,上週 我們開始剝離回 後來被稱為串。 字符串回憶起一個數據類型 宣派CS50庫。 它的一部分訓練輪 現在將開始起飛。 這是一個有用的概念,早期。 但現在它要得到更多 有趣和更強大 實際看到的引擎蓋下, 一個字符串就是什麼,我們說的嗎? 是啊,所以這是一個所謂的char *。 *表示有 涉及某種形式的地址。 因此,當你說你的char *僅僅意味著 一個變量,其數據類型是一個 指針現在。 事實上,有星級 只是意味著你聲明 所謂的指針。 該指針是怎麼回事顯然 存儲的地址, 當然,一個字符。 現在為什麼不這樣做有意義嗎? 那麼,什麼是一個字符串 引擎蓋下? 那麼,未來一段時間,我們一直在說 引擎蓋下是一個字符串 只是H-E-L-L-ø,例如。 但我們已經談到這是 即,本質上,一個數組。 陣列,然後看起來有點 類似這樣的,與這些 咬了一口。 然後我們說,有 一些特別的東西,回到這裡, 反斜線0或null終止。 所以這一切的時候,在這裡 一個字符串。 不過說真的,一串串 實際上是一個地址。 和地址,如我們所看到的,往往是 按照慣例用0x前綴。 0X表示什麼? 有誰知道? 因此,它只是表示十六進制。 所以,你可能還記得,實際上,從PST 1,我相信,一個熱身 問題居然問 十六進制表示法中除了 二進制和十進制。 這裡的動機是 與十六進制你有16 數字在您的處置。 0,1,2,3,4,5,6,7,8,9,其次 由A,B,C,D,E,F。 如果算上所有這些向上, 你得到了總共16個。 因此,這是在對比 小數,其中有10個 數字0到9。 它的對比度與二進制 我們只是0和1。 但在年底的一天,你可以 表示相同的數字,但 有所不同。 和十六進制是常見的,因為 事實證明 - 我們將看到這一點 後面的課程 - 即使當我們得到 web編程的背景下, HTML和顏色代碼, 十六進制是好的。 因為每一個數字,事實證明, 代表完美四位。 因此,它只是一種很好的線 因為我們最終會看到。 所以這可能是Ox123或東西 這樣,表示地址123 裡面有我的地方 計算機的內存。 不過,當然,出現了一些問題 因為這一基本 實現。 記得我把刺在 實現這樣的功能 - 比較破折號0 C點上週 即使它看起來就像是 沒錯,它根本不比較 兩個字符串正確。 我扔掉的主,我已經拋出 遠的意見只是集中在上 代碼的興趣。 ,它是紅色的,因為它是越野車。 什麼原因呢? 嗯,上方還有,當我宣布 一個字符串,什麼是真的 引擎蓋下? 那麼,就讓我走了過來的 此處的畫面和借鑒。 所以,我再次宣布, 字符串s的GetString。 所以我要繼續前進,現在 畫為它到底是什麼。 這將是一個正方形。 我要去要求 那是32位。 至少它通常是, 至少在CS50 很多計算機的器具。 我會打電話給它s。 但是,現在還記得我們 稱為GetString的。 所以GetString的回報, 當然,一個字符串。 如果H-E-L-L-Ø用戶類型進入 獲取返回字符串hello。 而該字符串,正如我們剛才所說,結束 某處在您的計算機的內存 在最後一個反斜杠0。 我會得出這樣的像數組 - 連續的字符塊 - 它實際上是。 而現在,則由GetString引發什麼 實際上返回? 有什麼的GetString返回 所有這段時間呢? 好吧,我們說,在幾週之前, 它返回一個字符串。 但更多的技術上的,這是什麼 顯然則由GetString引發返回? 觀眾:一個地址。 揚聲器1:一個地址。 具體來說,它返回的地址 第一口,不​​管它是什麼。 我只是不停地用一,二,三 因為它的方便。 返回地址的第一個 字符串中的字符。 我們上週說, 是足夠的。 因為我們總是可以找出其中 僅僅通過結束的字符串 遍歷它,也許,與為 循環或while循環或類似的東西 ,只是在尋找“反斜線0”, 特殊定點字符。 然後我們知道該字符串 的長度恰好是 - 在這種情況下 - 五。 因此,技術上的GetString做什麼 是在這種情況下,它返回Ox123。 技術上然後發生了什麼 我們存儲,裡面的s,Ox123。 在一天結束時,儘管這 是新的概念,指針,他們 只是變量。 但他們碰巧存儲位 共同表示一個地址。 所以技術上都得到 在s中存儲的是Ox123。 但我們作為人類 - 包括今天起 - 真的不會在意,通常, 實際地址是什麼 一些大塊的內存。 這只是低水平的細節 智力有趣。 所以我打算撤消此。 ,而是更多的高層次,只是說 當我們在談論指針 我要吸引更多 用戶友好的箭頭,傳達 同樣的想法和摘要走 什麼實際的詳情 基礎地址。 現在,如果我們回去的代碼, 上週發生,如果我們有字符串t 等於則由GetString引發? 好吧,如果我再次類型打招呼 這次我會得到 另一塊內存。 H-E-L-L-O反斜線0。 但是,因為我要求則由GetString引發 第二次 - 我知道這看著 GetString的源代碼 - 即使 雖然這是巧合,打招呼 輸入兩次,GetString的是不 要嘗試優化 和聰明。 只是要得到另一塊 從計算機中的存儲器,這是 要在另一個地址。 讓我們任意只是說456。 然後它是什麼會回來? 這將返回456 並將其存儲在t。 那麼,什麼是真的,在 左側是我有另一塊 內存,通常是32位。 在那裡要去Ox456。 不過,我沒有興趣在這些 特殊的數字了。 我只是抽象 繪製箭頭。 所以這是現在一種新的解釋。 但它是完全相同的想法 發生這一切的時候。 等原因,那麼,這首 版本比較的是越野車, 上週是為什麼呢? 當你這樣做,如果s等於等於 什麼是你真正的噸 引擎蓋下比較? 你的地址進行比較。 只是直觀,清晰,Ox123 不會等於Ox456。 這些數字,那些位 只是不同而已。 所以一致,上週說 你鍵入不同的事情,即使 話逐字相同。 因此,我們解決這個問題。 通俗地說,什麼是修復? 觀眾:使用功能。 揚聲器1:使用功能。 明星們肯定參與, 但使用功能做什麼呢? 觀眾:要比較字符串。 揚聲器1:比較字符串。 所以這裡的根本問題是 我只是考慮 質量被定義的字符串 他們的地址相比較。 很顯然,這只是愚蠢的現在一次 你明白這是怎麼回事 引擎蓋下。 要真正比較字符串,看是否 他們是平等的,一個人的方式 會考慮兩個字符串是否相等 我們需要對它們進行比較字符 對於字符。 現在我可以做 這很繁瑣。 但是,我們親熱 使用for循環。 而只比較Ş支架 我對T支架í。 Ş支架I加1對T支架 i加1,依此類推,裡面 某種循環。 如果我發現任何兩個字符 不同,或者如果我意識到,哦,S 小於t或長於t 我可以馬上說是假的, 他們是不一樣的。 但如果我通過s和t說 相同的,相同的,相同的,相同的,同樣,年底 這兩個字符串,我可以說, 真的,他們都是平等的。 那麼,令人欣慰的是,幾年前,有人 為我們寫的代碼。 他們把它稱為StrComp 字符串比較。 即使它是一個小櫃檯 直觀,StrComp返回0,如果這些 兩個字符串中,s和t是相同的。 但是,如果返回負值 應該是之前按字母順序或 它應該是正值,如果 後T字母順序排列。 所以,如果你要排序的東西, StrComp是有用的。 因為它不只是說 yes或no,等於或不。 它給你一個訂貨感 喜歡字典威力。 所以StrComp,S逗號T等於 等於0,則表示 字符串是真正的平等。 因為誰寫了這個功能 幾年前大概使用了一個for循環 或一個while循環或類似的東西 再次,整合過的字符 一遍又一遍。 但這裡出現問題2。 這是copy0.c。 和兩個紅色 因為它是有缺陷的。 我們做了什麼? 嗯,首先我叫則由GetString引發。 我和存儲在s的返回值。 所以這是相當多的相同 這個圖片的上部。 但之後呢? 好吧,讓我繼續前進,擺脫 一大堆。 我們的地方,我們只是時間會倒轉 有,這是現在一致 線那裡。 我檢查。 如果s等於等於0。 現在,快速側面說明,當 可能的GetString返回0? 有沒有足夠的內存。 對嗎? 這是罕見的,這是將要發生, 當然這是一個計算機 有數百兆 甚至音樂會的RAM。 但也有可能,在理論上,返回 0,特別是如果 用戶不配合。 有辦法假裝像你有沒有 輸入任何東西和訣竅 返回到則由GetString引發 0有效。 因此,它要檢查。 因為如果你開始 已經得到的,分割故障 - 這可能是一個源 有些無奈 - 這些結果幾乎總是 內存相關的錯誤。 不知怎的,你搞砸了,對於一個 指針,即使你沒有意識到 有一個指針。 所以,你可能誘發分割 早在第一個星期使用故障 像一個循環或while 循環和陣列走得太遠的 過去的一些陣列的邊界 宣布,在本週二 尤其如此。 你可能已經做了,即使問題 設置四個與突圍。 即使你可能從來沒有見過 任何恆星分佈代碼 突圍,事實證明,那些GRect 和GOval和其他這樣的事情, 其實這些都是指針 引擎蓋下。 但是,斯坦福大學,像我們這樣的,排序的皮革 至少詳細的庫 的目的,就像我們做 字符串和char *。 但GRect GOval所有這些 你們的事情或將使用 這個星期都少不了 內存地址。 你只是不知道這一點。 所以這是不奇怪的話,也許, 你可能會絆倒一些 段故障。 但是,什麼是有趣的, 如果我們檢查後我們做 字符串t得到s。 好吧,讓我申報噸。 我打算把它畫一個正方形, 32位,它噸。 然後我要做的事情,得到s。 那麼,是什麼意思呢? 嗯,這是一個有點很難想像 關於它的想像明智的。 但是讓我們想想 裡面的x是什麼? 這裡面變量字面上什麼? 價值Ox123。 所以當我說字符串t得到s,這只是 字面意思是取數 在s,這是Ox123,並把它Ox123。 或形象,如果我有點抽象 遠離細節,它有 從字面上做效果 這一點。 所以,現在,回想起上週 我們進行資本主義T.我 Ť支架0。 那麼,T支架0,即使它是一個 指針,你可以把它彷彿 它是一個數組,用方形 支架符號。 那麼,是T支架0? 那麼,它的h。 因此,當我們使用這行代碼, 兩個上,是C type.h中的 頭文件,這就是 它的聲明。 你把握H.但 當然,這是完全相同的h上 s的內部,可以這麼說。 所以現在你已經改變或 資本化的原件和 所謂的副本。 因為你沒有做一個副本 的方式,一個人會希望它是。 那麼,什麼是這裡的修復, 在上週copy1.c? 功能,所以實際上,我們可以 複製字符串。 從根本上說,我們需要 做以複製字符串? 那麼,在我這裡這個綠色版 要做到這一點相當低的水平。 實際上有功能 他們可以幫助這一點。 但是最基本的,而最 熟悉的,至少會很快 我們所熟悉的,是下面的 - 所以在第一行 現在代碼在綠色。 我剛剛改寫的char * s作為。 有沒有功能 區別。 我只是扔掉CS50庫 我打電話是什麼,它是一個char *。 現在,點,點,點,因為有 這不是一些錯誤檢查 有趣的念叨。 所以,現在t的聲明。 它也是一個char *。 所以我畫了一個小廣場上 屏幕上像前。 但在右側時,malloc 我們說的是內存分配。 因此,分配一定的內存塊。 和我們實際上做了多少字節 要分配,它似乎? 嗯,字符串的長度為s。 所以,如果要打招呼, 是五。 我們會說:H-E-L-L-O。 因此,5個字節。 但是,再加上1,為什麼? 0字符。 如果我們不留有餘地,這傢伙我們 可能無意中造成這樣的局面 字符串是H-E-L-L-O。 那麼下一次的GetString 叫我輸入,例如, 戴維,D-α-v型的i-ð時,計算機會 認為s是 h-e在升升 - 鄰-D-α-v型的i-D因為有 沒有打破這些單詞之間。 因此,我們需要休息。 所以,我們不希望五。 我們需要6個字節。 和字節我說。 但它是真的時大小字符。 技術上char是幾乎 始終是一個單字節。 但是,只是為了讓我們的代碼便攜, 可以這麼說,所以它的工作原理 不同的計算機上,即使他們可能 下方的有所不同 油煙機,我要籠統 說尺寸的字符,所以 我的代碼總是工作。 我沒有重新編譯它只是 因為我的計算機升級或使用 一些不同的平台。 所以我已經有了6倍的大小 一個字符,這恰好是1。 因此,這意味著的malloc 給我六個月字節。 ,實際上做的是什麼? 好吧,讓我回滾時間在這裡 我們所處的這個故事。 所以,如果我回到這裡,我已經聲明 一個char *名為t。 我現在已經被稱為6字節的malloc。 現在我要吸引那些六 就像字節數組同期。 但其實我不知道什麼是 這個數組裡面。 如果你分配內存事實證明, 你可以不相信有一些 已知值。 它可能已被使用的東西 否則,其他的一些功能,其他一些 你寫的代碼行。 所以,我們一般會調用這些垃圾 價值和借鑒他們,也許, 問號,只是表明我們 不知道什麼是實際存在的。 這沒什麼大不了的,只要我們 有足夠的智慧來覆蓋這些 垃圾值以數字或 我們關心的字符。 因此,在這種情況下,我該怎麼辦? 好吧,我行代碼 接下來,我有四個。 INT I得到0,n變 字符串s的長度。 因此,一個熟悉的for循環。 I小於或等於n, 這通常是上述。 但是,這一次它是經過深思熟慮的。 我+ +,然後我只是做 噸支架我得到s。 因為我的照片看起來像這樣 儲存在這一刻,是 ,隨機的內存塊的地址 它的值是未知的。 但只要我做T支架 0,讓我在這裡。 什麼最終會被繪製在那裡? 我們最終把ħ。 ,因為這是在s支架0。 然後同樣的事情 E,和l,和l和o。 N,為什麼我去通過 一個等於n? 由於“0”字符。 所以只要是明確的,那麼,如果我真的 清除這些垃圾 值,然後繪製 我所期望的,這是支架1,2, 3,4,加尾隨 新的字符。 所以,如果我們現在繼續過去的點, 點,點在這條正確的版本 及資本化支架0我想, 當然,把握這一點 傢伙在這裡,從概念上講, 最終的目標。 所以這是所有的指針。 而你一直在使用他們週 現在在字符串的上下文中。 但引擎蓋下他們 更複雜一點。 但如果你認為他們在這 圖文並茂的形式,我建議他們 可能不是所有的可怕,因為他們 可能先乍一看, 尤其是這種新的語法。 如有任何問題上的指針, 字符串或字符? 是嗎? 觀眾:你能回去 [聽不清]? 揚聲器1:當然。 觀眾:那麼,為什麼你最後的 行了,你沒有一個* T線 行中的A * S? 難道你不具有參考 - 揚聲器1:啊,一個很好的問題。 為什麼不我有一個* t和A * S? 因為簡單地說,上週,像在我們的 交換功能,我沒有說,當 你已經有了一個指針的手段 你去那裡,因為我們沒有 身體在舞台上,實際 使用星算。 事實證明,這個方括號 符號是什麼,我們會打電話給句法 糖,這僅僅是一個性感的方式 說這是速記符號 正是你所描述的。 但它更直觀一點。 決策的風險,這似乎更 複雜,比它需要的是, 這裡到底發生了什麼 - 如果我說*噸,這意味著去 在t存儲的地址。 從字面上看,如果T是存儲 使得h的地址 最初,* T手段去這裡。 現在,噸支架0是什麼意思? 完全相同的事情。 這只是一個對用戶來說更加 友好的寫。 但我還沒有完成。 我不能只是說* T *秒獲得。 因為我會做什麼呢? 我把H,H,H,H,H 在整個事情。 對嗎? 由於* t是在t的地址。 但是,我們是在一個循環內。 什麼樣的價值,我在遞增, 當然,在每次迭代中嗎? (一) 但是,有一個機會 在這裡,對不對? 儘管這種感覺就像它變得 更複雜一點 方括號表示法比 我們已經用了一段時間 - 讓我撤消我的H有變化 - 即使是現在開始有點 神奇的是,基本的想法,如果* T 這裡指的* t是剛剛 去t的地址。 但是,什麼是在t的地址? 我們一直使用的號碼? 像Ox456,讓帶回來 只是就事論事。 好吧,如果我想要得到電子 噸字符串,我只是想歸想, 從本質上講,456。 或者更確切地說,457。 我只需要添加一個。 但我可以做到這一點,對不對? 因為T,即使我把圖紙 現在作為一個箭頭,它只是一個 號,Ox456。 而如果我添加一個,或多個 一般而言,如果我加我,我可以 實際上,正是我想要的。 所以,如果我真的這樣做 - 這就是現在被稱為 指針運算 - 我可以刪除這一行。 這是,坦率地說,我覺得更清晰, 對用戶來說更加友好的閱讀。 但是,這是不正確的。 現在這行代碼使用 指針的算術運算。 說去 地址如下 - 無論噸開始,這 再加上我是,最初 為0,這是偉大的。 因為這意味著噸的開始 加1,加2,加3,依此類推。 和相同的處理為s。 所以語法糖。 但是,了解究竟發生了什麼事情 引擎蓋下,我認為, 本身實際上是有用。 因為這意味著現在有沒有 更魔法 引擎蓋下。 不會多 我們可以剝離備份你的層。 這是c。 這是編程。 真是個好問題。 所有的權利,所以這是那個馬車 我指的是早期的程序。 交換是有缺陷的。 如果沒有似乎工作。 回想一下,就像牛奶和 橙汁 - 我開始 喝今天的示範。 因此,正如橙汁和 牛奶,我們也必須使用 臨時變量,TMP,舉行 暫時這樣,我們便可以 改變它的值,然後更新B。 但是這個功能,我們說,這 程序中,此功能 寫的是錯的,有缺陷的,為什麼呢? 是嗎? 觀眾:[聽不清]。 揚聲器1:沒錯,當 你叫掉期 - 或者更一般地,當你 調用任何功能最 - 如果該函數的參數 原始的,可以這麼說,整數和字符 雙打和花車,萬物而不 星星,你是通過在副本 的說法。 因此,如果x為1,y為2,將 1和b為2。 但他們要去不同的塊 位,不同的塊 內存發生存儲 相同的值。 因此,這段代碼是超級完美 在交換a和b。 這是沒有什麼好交換 - 在上週的例子 - x和y。 這還是因為同樣的原因,他們是 在錯誤的範圍內。 現在,我們怎麼去解決這個? 我們不得不做出的功能 看起來有點醜陋。 但是還要考慮什麼 這也就意味著。 而實際上,讓我的一致性, 改變的一件事,所以這是相同的 我們只是做了什麼。 正如我上週提到的,它不會 無論身在何處。 事實上,通常你會放 星級旁邊的變量名。 但我認為這將是更容易一些 旁邊的考慮* 這意味著它的數據類型是一個指針 在這種情況下,一個int。 所以我在這裡做什麼? 我說不要給我一個int 其次另一個詮釋, 稱他們為a和b。 給我一個int的地址。 給我地址的另一種詮釋。 調用這些地址a和b。 然後使用*符號下降 下面,每個地址 根據需要,以得到 或設置其價值。 但這裡有一個例外。 為什麼我不會有* TMP旁邊? 為什麼我不能做到這一點,例如? 這感覺就像我應該全力以赴 和糾正整個事情。 是嗎? 觀眾:[聽不清]。 揚聲器1:我還沒有宣布 tmp作為一個字符串。 因此,這將聲明,在這種情況下, 一個tmp目錄是一個int的地址。 但是,這不是我想要的那種, 一對夫婦的原因。 觀眾:你不想來交換他們。 揚聲器1:沒錯,我不想要交換 任何與TMP。 tmp是剛 本週一的東西。 所有我想要的是一個變量 存儲一些數字。 我什至不關心地址 在這一刻。 我只需要32位或 因此存儲一個int。 我要把這32位 無論是不是在,可以這麼說,但 處於什麼,只是為了更​​精確。 因為如果是一個地址,一個表示 去那裡,並獲得價值1。 例如,在上週的例子 或在b的情況下,得到的價值2。 所以,到底發生了什麼? 讓我畫一幅畫,在這裡,將 只梳理除了今天的一部分。 但是,這將繼續出現 相當長的一段時間。 ,我要求,這就是您的電腦 當你運行一個內存看起來像 程序,任何程序。 當你運行一個程序在最高層 您的計算機的RAM - 所以想到 這個矩形,真正實現了,因為你的 計算機的RAM或內存,所有101 全2億億字節, 字節,兩個千兆字節的, 無論你有, 讓我們繪製一個矩形。 我要求,當你運行一個程序 如Microsoft Word或Chrome 或類似的東西,的位 微軟,谷歌寫道 - 在這些程序的案件 - 被加載到您的計算機的內存 在那裡他們可以執行 迅速送入CPU, 是計算機大腦。 譚它們存儲非常 你的程序,可以這麼說。 換言之,如果這是一個塊的 內存,當你雙擊 微軟的Word,位來 關閉硬盤驅動器。 他們得到加載到RAM中。 我們要趕路他們在最高層 這個矩形的概念。 好吧,剩下的是你的記憶 用於不同的事情。 在最頂端,你看到初始化 數據和未初始化的數據。 這樣做的,在大多數情況下, 常量或全局變量 有值。 但那些其他時間。 然後你有堆, 我們會回來的。 但在底部則是部分 尤其是現在有密切關係。 這是所謂的堆棧。 所以,就像在任何D廳 大學校園,你有那些托盤 只是堆放在彼此頂部上 你可以把食物和諸如此類的東西。 在計算機系統中的堆棧 是非常相似的。 除而托盤,我們使用 食堂,當然是 隨身攜帶的東西托盤 或框架 - 因為我們會打電話給他們 - 在計算機的 存儲器是用來存放 變量和值。 那麼真正的推移 引擎蓋下? 好吧,讓我翻轉 這裡的畫面。 而讓剛上的重點 片刻的底部的一部分。 如果這是我的底部 電腦的記憶體,它原來的時候我 調用函數主 - 發生的事情,坦率地說, 自動為我 - 我得到一個內存塊 我的內存的底部可以這麼說。 這是主要的 局部變量去。 這是argc和argv也許 走,和我的任何變量 主要內申報。 他們最終在底部 我的電腦的RAM。 現在,假設主要的電話功能 像掉,像它上週? 好吧,我們基本上是把一個新的托盤, 新的框架,到我的內存塊。 我要形容這是 屬於交換功能。 現在裡面有什麼交換? 嗯,根據上週的節目 我們剛才看到的一段摘錄, 交換的框架內,或掉期 托盤,有哪些變量? 那麼,a和b。 因為那是其本地的參數, 加上第三,TMP。 所以,說真的,我可以得出這樣的 一個更乾淨一點。 讓我繼續前進,撤消標籤。 我要求你知道是什麼嗎? 一個很可能會在這裡結束了。 B是在這裡要結束了。 和TMP在這裡要結束了。 現在,順序可能 有點不同。 但是,這是概念上的想法。 只是統稱,這是什麼 我們會打電話給交換的框架,或 餐飲大廳托盤。 同樣處理主要。 但我不會重繪。 但是,這其中argc和argv和任何 等局部變量x和y 可能。 所以,現在考慮到底發生了什麼 當你調用掉。 當你調用swap,執行這樣的代碼 這一點,你正在傳遞中,在 越野車的版本,a和b; 作為x和y的副本。 所以,如果我現在得出這樣的 在屏幕上 - 得到得到更好的產品 - 這樣的故事,我告訴我自己 在這個馬車版本,當我們 調用交換傳遞字面上a和b 整數,到底發生了什麼? 那麼,這到底發生了什麼。 讓我繼續前進,只是撤消 這裡明確了一些空間。 所以這是我的電腦的內存。 所以,如果我有,例如 - 居然讓這樣來做 - 如果這是我要求的x,存儲 就像上週的值為1。 這是Y,存儲的價值 就像上週。 這是主要的,當我打電話交換, 從而給自己訪問和 b和TMP,我要去聲稱 這是一個,這是1。 這是b。 這是2。 這就是所謂的TMP。 最初,它有一些垃圾值 直到我真正存儲在一個 這是1。 然後,我去動手改變 一個是什麼? B的值。 所以現在我這裡有兩個。 然後我們說,B得到TMP。 同樣,就像進行仔細的檢查,第三 這裡的代碼很簡單,就是 一,B得到TMP。 所以最後,我該怎麼辦? 我繼續前進,變動b是什麼 tmp的值,也就是1。 我不碰TMP。 但是,現在的問題是盡快交換 的回報,因為它的不移交 備份有一定的價值,不歸路 聲明中明確。 實際上發生了什麼? 嗯,基本上這一切的記憶 - OK,顯然橡皮擦喜歡 只用一根手指在一個時間 - 就這樣消失。 現在,在現實中,它不是 去任何地方。 但是,你可以把它想像 現在為問號。 因為它不再 實際使用。 並沒有什麼做這些值。 因此,在的情況下,綠色版的 這段代碼,而不是什麼是 傳遞到交換? 所以解決。 因此,x的地址和 y的地址。 因此,如果我們重新講述這個故事的最後一 時間,其實我畫再次交換, 但與指針,這是一個,這 B,這是TMP,是什麼 實際上存儲在這個綠色 我通過我的代碼版本 在地址? 這將是一個指向x的指針。 所以,我可以畫一個箭頭。 但是,讓我們使用相同的任意 如前。 比方說,這是 像Ox123。 這是怎麼回事Ox127,因為 這四個字節,因為它是一個 INT,所以Ox127。 再次,我採取了一些自由 數字。 他們會比他們小得多 實際上是在不同的順序。 但是,這是怎樣的畫面 現在不同了。 但是當我使用這個綠色的代碼 我INT TMP * A。 *一種手段,做到以下幾點,採取 解決在去 這是1。 這就是我然後把tmp中。 同時,在下一行代碼 在這裡,一個得到b,是什麼意思呢? 那麼,*,所以要在這裡得到* B, 這意味著去那裡。 這意味著把那裡的價值。 最後,最後一行代碼 簡單地說* B得到TMP。 所以B說去那裡,覆蓋它 tmp的,在這種情況下,將 再次,1。 這就是為什麼綠色版 我們的代碼工作,而紅色 版本從來沒有。 這一切都只是歸結到如何 內存管理,並在它的 實際上放置在您的 計算機的RAM。 現在來看,這是一個的事 堆棧被用於。 佈局上的問題? 指針? 或掉期? 所有的權利,這樣的malloc,召回, 做這樣的事情。 這是一個超級簡單的例子。 這是一個賓基 向我們介紹,雖然相當 很快,在末級。 該死,我們又來了。 所以記得,這是例子 賓基向我們介紹,儘管 有些快速末級。 在這裡,我們真正使用的malloc 第二次。 因為我們第一次用它來 創造足夠的RAM,分配足夠的RAM 存儲字符串。 這一次賓基保持簡單。 因此,它是只存儲 一個int,顯然。 這是完全正常的。 這是一個有點怪異,坦率地說, 使用malloc來分配一個int。 但有一點是尼克的黏土動畫 真的只是講什麼樣的故事 發生或不會發生在 你虐待內存。 因此,在這種情況下,本程序 做了幾件事。 這裡在第一種情況下,它聲明 一個指向名為x為int類型。 然後聲明一個指針 稱為y為一個int。 然後,它存儲在x,什麼? 現在別人。 什麼被存儲在x 第三行這個程序嗎? 觀眾:[聽不清]。 揚聲器1:嗯,不太 字節,每說。 現在更精確。 被存儲在x什麼? 一個地址,我想我聽到了。 那麼,是什麼的malloc返回? 行為上的malloc分配 一塊內存。 但它是如何給你訪問它? 它返回什麼? 第一個字節的地址 在內存塊。 現在,這是超級簡單。 這只是一個字節,這意味著 解決我們要的是 整個事情的地址。 因此,存儲在x,那麼,地址是 該內存塊。 同時,接下來會發生什麼? 因此,實際上,讓我們繼續前進, 繪製出真正的快。 因此,如果我們去到屏幕 我們玩了這一點* X和int * Y 打算做什麼我? 我要求它只是打算做 這樣的事情,並稱之為x, 這Ÿ。 同時,第三行代碼 要分配一個int的大小, 這恰好是 - 對不起,如果我說 前一個,我的意思是一個int - 一個典型的計算機上的四個字節。 至少與CS50器具。 所以,這是怎麼回事分配 它,誰知道? 某處在這裡。 而這在某些存儲 地址牛,誰知道? 但是,這是怎麼回事返回 是該地址。 但是,我們會得出這樣的形象 只是這樣的箭頭。 現在,在下一行* x變42。 * X是什麼意思通俗地說? 只是去那裡。 進入到該地址。 或者換句話說,按照 箭頭,並有42把。 但是壞事發生 賓基,對不對? 回想一下,行五在這裡,* Y獲取 13日,確實是一個不吉利的數字, 做了什麼,對我們? 那麼,* y表示去那裡。 嗯,這還沒有得到 值,對不對? 代碼沒有y為 初始化任何東西。 我們照了X被初始化 一個地址。 但Y被宣布往上頂。 但隨後一個分號,沒有價值 實際上是把它。 所以這是公平地調用這個 垃圾值。 誰知道那裡有什麼? 這是殘存使用的位 以前的一些行代碼 我的計劃。 所以,如果我說去那裡,這是什麼樣子, 我不知道這個箭頭 要結束了。 這時候你通常 得到分割故障。 如果你不小心取消引用,所以 說話,還是去這不是一個地址 實際上是一個合法的地址, 不好的事情發生。 這到底發生了什麼 賓基認為。 所以記得尼克的故事 這裡講的是同樣的想法什麼 我畫的錯覺 粉筆在黑板上板。 X和Y宣布。 然後我們分配的大小 一個int,並把它保存在x。 然後我們所做的下一行* X。 這是尼克的魔杖 提領。 這把42在存儲器 指出由x。 但是,這是東西 去可怕的錯誤。 對嗎? 試圖取消引用Ÿ。 但Y有一些虛假的價值,對不對? 在左下方即箭頭 角落裡,是不是 其實都指向任何東西。 這是一種做什麼,我 在這裡做的在黑板上。 如此糟糕的事情發生,分割 故障時,或賓基故障,在這種情況下。 但是,如果我們再解決,通過做x 得到Ÿ的故事是如何變化的呢? 嗯,如果我做X得到Y,這是 同樣有效的話說 不管這是牛的東西 這裡是相同的, 牛年的東西。 或者形象,我們將繪製一個箭頭。 所以在這裡賓基板, 的下一行 代碼* y表示去那裡。 哪裡有? 這意味著在這裡。 而當我們更新到13 它只是涉及到要和 寫13現在在這裡。 因此,也許不完全 乍一看簡單。 但總括來說,並使用相同的行話 賓基是用在這裡,所以 前兩個分配的指針, x和y,但不是指針對象。 指針對象是不是一個 通常使用的術語。 但指針絕對是。 但究竟是什麼原因被指向 在賓基命名。 這下一行,當然 分配一個int pointee的。 所以一大塊內存 - 因為我吸引了 右手側 - 集 x等於指向它。 這解引用x到存儲42 內存,它的指向。 然後,當然,這 是一件壞事。 因為Y並不是指向 任何東西。 這修復它。 因此,這仍是錯誤的程序。 只是因為我們正在吹遍 代碼一行行,並說,很不錯哦, 讓它崩潰。 這是一件壞事。 賠率是程序只是要 完全中止在該行。 但是,如果你要刪除墜毀 排隊,取而代之的是與過去兩年 線等也有你分配 - 使用指針賦值 - γ 指向x作為點t。 然後你取 y在一個非常安全的方式。 那麼,這給我們嗎? 嗯,事實證明,引擎蓋下 的CS50庫中,指針是 用於整個。 實際上,我們將開始剝離 沒過多久回那層。 但事實證明,一個表達式, 一些你可能很熟悉, 特別是那些更舒適, 實際上是一個非常受歡迎的 網站,或者堆棧溢出, 這些天。 但是,這實際上有很 技術含義。 我們現在知道堆棧是什麼。 這就像一摞托盤 內的食堂。 或您的計算機內的 內存它的那些幀 所使用的功能。 嗯,事實證明,正因為如此 非常簡單的實現 所謂的存儲器和幀 疊加,實際上你可以控制 一個計算機系統相當容易。 你能砍成一個系統,如果人們 像我們這樣沒有寫我們的代碼 特別好。 如果像我們這樣的人用大塊 內存或使用陣列 - 更常見 - 但有時會忘記檢查 我們的數組的邊界,你可能 有自己的時候,迭代 路太遠結束過去的一個數組。 在最好的情況下,你的程序 可能只是崩潰。 分割故障,善良 尷尬的。 不是很大,但是它不一定 一個非常糟糕的事情。 但是,如果你的程序實際上是對真實 用戶的計算機上,如果它的運行 在網站上,實際隨機人 在互聯網上打,讓 人們引發不好的事情,對你的代碼 一般不是一件好事,因為 這意味著一個機會,採取 計算機的控制權。 這是怎麼回事看 有點神秘。 但我想我會嚇唬你 這裡最後一個例子。 下面是一個例子的代碼。 維基百科有一個很好的 文章,走過 這更多的細節。 我有主的底部電話 富,1 argv中傳遞。 而這僅僅是這樣就可以了 運行程序,並通過 任意輸入。 然後foo被宣布往上頂 接受一個字符串,或者更 準確地說,一個char *。 然後聲明一個字符數組。 緩衝液,更一般地, 大小為12。 所以,可以裝進12個字符 該數組名為c。 然後,它使用這個新功能, 這是新的,但並不難 理解,記憶複製。 將內存複製吧,這是 過去的變量N,無論 用戶輸入到argv 1到c。 多少個字節? 的字符串長度酒吧。 因此,換句話說,如果用戶鍵入的 H-E-L-L-o輸入字符串的長度 你好五。 所以五個那些字節是會得到 複製到陣列名為c, 大小為12。 但是,什麼類型的用戶在更長 這是13個字符或14字 字符或100個或更多字符? 他們要去哪裡去了? 嗯,這架,托盤 在用餐大廳堆棧, 他們去那裡。 它只是將開始覆蓋 其他的東西,這已經 該堆棧上,滿溢 棧,可以這麼說。 因此,形象,認為這種方式。 這僅僅是一個多彩版 圖片中,我們一直在畫畫。 在底部,讓我們說,是主要的。 和頂部,你現在看到的 的幀,顏色編碼,對於一個 名為foo的功能。 但是,什麼是有趣的,在這裡對 foo是,這裡是它的框架。 所以,就像我畫 沒有,但在淡藍色的。 現在這是 Ç支架0去。 這是其中c支架 11要結束了。 換句話說,它發生在 被表示為一個正方形。 但如果你只是保持撲通字節 - 煤焦 - 他們將結束 位置0一路上揚 0到11,因為它是建立索引。 但如果是13個字符 要結束了嗎? 14日在哪裡? 50字符在哪裡 要結束了嗎? 這將繼續下去。 因為即使我們已經得出了 圖片與堆棧長大, 事實證明,地址,從 小的地址,小 指針,大的地址。 因此,它只是不斷向上和向上。 因此,如果用戶鍵入 你好,這是偉大的。 沒有錯誤,沒有問題,每個人的安全。 但是,如果我們的用戶類型 調用對抗性的代碼,代表 統稱為,攻擊,攻擊, 發作,發作時,會發生什麼? 好了,如果所有的輸入,用戶 鍵入不只是一些友好 或令人反感的一串字符。 它實際上是一個字符序列 如果你編譯它, 它實際上是代碼。 也許這是代碼,刪除所有 您的硬盤驅動器上的文件或發送垃圾郵件 或類似的東西。 請注意,這裡的關鍵是, 如果壞傢伙得到了足夠幸運 覆蓋紅色的內存塊 - 我沒有畫上我的照片,但 這個維基百科的圖片在這裡 - 其所謂的返回地址。 當食品的回報,掉期回報時, 電腦知道如何去從 這裡這裡? 或者在高科技板塊上面,如何 它知道去從交換 代碼 - 0和1的 構成掉期 - 回到主? 有一個所謂的返回地址 存儲在相同的堆棧幀,在 同一食堂盤。 因此,如果壞傢伙是足夠聰明, 把攻擊代碼,攻擊代碼,攻擊 代碼,並獲得足夠幸運 - 往往是通過試驗和錯誤 - 覆蓋,紅色返回地址, 的地址和通知 極頂。 注意0835C080。 倒著寫往上頂 原因也許我們會重新審視。 這是這個數字。 因此,如果壞傢伙得到足夠幸運或 足夠聰明,紅色覆蓋 剝離用的地址的存儲器 他或她有某種代碼 注入到你的電腦,你猜的 代碼將被返回到 富盡快執行完? 壞傢伙的代碼。 因此,這種攻擊代碼,AAA,再次,可能 發送垃圾郵件,可能會刪除所有文件 您的硬盤驅動器上。 但是,這是一個真正的堆棧溢出 或緩衝區溢出,或 緩衝區溢出攻擊。 這是令人難以置信的,令人難以置信的普遍 這一天,編寫的程序 C,C + +,甚至還有一些其他的語言。 在那個可怕的音符,我們將 結束一個笑話。 [笑] 星期三見。 於下CS50 - 所以,我所有的磁盤燈,但今天 等待,無脂牛奶,有一半的手機 書,橙汁 今天我喝。 USB連接線,一個扳手。 [音樂播放]