1 00:00:00,000 --> 00:00:03,000 [Powered by Google Translate] [評論] [測驗] 2 00:00:03,000 --> 00:00:05,000 >> [亞力克西斯·羅斯,湯米MacWilliam,盧卡斯·弗雷塔斯,王陽樂] [哈佛大學] 3 00:00:05,000 --> 00:00:08,000 >> 這是CS50。[CS50.TV] 4 00:00:08,000 --> 00:00:10,000 >> 嘿,大家好。 5 00:00:10,000 --> 00:00:15,000 歡迎測驗0,這是本週三舉行的審查會議。 6 00:00:15,000 --> 00:00:19,000 我們要做的今晚,我和其他3個轉錄因子, 7 00:00:19,000 --> 00:00:24,000 和我們一起去了什麼,我們做的過程中,到目前為止,通過審查。 8 00:00:24,000 --> 00:00:27,000 它不會是100%全面,但它應該給你一個更好的主意 9 00:00:27,000 --> 00:00:31,000 你已經有什麼,你仍然需要研究(星期三)前。 10 00:00:31,000 --> 00:00:34,000 而且感覺我們一起去提高你的手的問題, 11 00:00:34,000 --> 00:00:38,000 但請記住,我們還會有一點點的時間結束時, 12 00:00:38,000 --> 00:00:41,000 如果我們通過幾分鐘業餘做一般的問題, 13 00:00:41,000 --> 00:00:47,000 所以記住這一點,所以我們要開始在0週開始。 14 00:00:47,000 --> 00:00:50,000 >> [問答共0] [第0] [亞力克西斯·羅斯]但是,在我們這樣做,它可以讓談 15 00:00:50,000 --> 00:00:53,000 物流的測驗。 16 00:00:53,000 --> 00:00:55,000 >> [物流] [測驗發生在10月10日(星期三)代替演講] 17 00:00:55,000 --> 00:00:57,000 >> (見的詳細信息http://cdn.cs50.net/2012/fall/quizzes/0/about0.pdf)]這是10月10日(星期三)。 18 00:00:57,000 --> 00:01:00,000 >> 這是本週三,如果你去到這個URL, 19 00:01:00,000 --> 00:01:03,000 這也是從CS50.net的訪問的鏈接 20 00:01:03,000 --> 00:01:06,000 去哪裡的基礎上,你可以看到信息 21 00:01:06,000 --> 00:01:10,000 您的姓氏或所屬學校以及 22 00:01:10,000 --> 00:01:14,000 它講述了什麼測驗將涵蓋和類型的問題,你會得到。 23 00:01:14,000 --> 00:01:19,000 請記住,你也有機會審查測驗部分, 24 00:01:19,000 --> 00:01:21,000 所以你的的TFS應超過一些實際問題, 25 00:01:21,000 --> 00:01:29,000 這是另一個很好的機會看到你仍然需要學習測驗。 26 00:01:29,000 --> 00:01:32,000 讓我們從一開始位'N'字節。 27 00:01:32,000 --> 00:01:35,000 請記住一個位是0或1, 28 00:01:35,000 --> 00:01:38,000 和一個字節是8的那些位的集合。 29 00:01:38,000 --> 00:01:42,000 讓我們來看看位在此集合在這裡。 30 00:01:42,000 --> 00:01:44,000 我們應該能夠找出有多少位。 31 00:01:44,000 --> 00:01:48,000 如果我們指望有8人,8個0或1個單位。 32 00:01:48,000 --> 00:01:51,000 而且,由於有8位,這是1個字節, 33 00:01:51,000 --> 00:01:53,000 讓我們把它轉換為十六進制。 34 00:01:53,000 --> 00:01:58,000 十六進制的基數為16,這是很容易轉換 35 00:01:58,000 --> 00:02:01,000 一個二進制數,這是這是一個十六進制數。 36 00:02:01,000 --> 00:02:04,000 我們要做的就是我們期待在4組, 37 00:02:04,000 --> 00:02:07,000 我們將其轉換為相應的十六進制數字。 38 00:02:07,000 --> 00:02:11,000 我們從最右邊的4組,所以0011。 39 00:02:11,000 --> 00:02:16,000 這將是一個1和一個2,這樣在一起,使得3。 40 00:02:16,000 --> 00:02:19,000 然後讓我們來看看其他4塊。 41 00:02:19,000 --> 00:02:24,000 1101年。這將是一個1,一個4,一個8。 42 00:02:24,000 --> 00:02:28,000 在一起,將是13,這使得D。 43 00:02:28,000 --> 00:02:32,000 我們會記住,在十六進制中,我們不只是從0到9。 44 00:02:32,000 --> 00:02:36,000 我們去到F 0,所以在9,10對應到A, 45 00:02:36,000 --> 00:02:40,000 11到B,等,其中F是15。 46 00:02:40,000 --> 00:02:44,000 其中,圖13是一個D, 47 00:02:44,000 --> 00:02:49,000 所以將其轉換為十進制,我們所做的一切是我們實際上 48 00:02:49,000 --> 00:02:52,000 對待每一個位置為2的冪。 49 00:02:52,000 --> 00:02:58,000 這是一個1,一個2,零4秒,零8秒,一個16,等等, 50 00:02:58,000 --> 00:03:03,000 這是一個有點難以計算在你的腦袋,但如果我們去到下一張幻燈片 51 00:03:03,000 --> 00:03:05,000 我們可以看到這個問題的答案。 52 00:03:05,000 --> 00:03:09,000 >> 從本質上講,我們要跨越右到左, 53 00:03:09,000 --> 00:03:14,000 ,我們將每個數字所對應的功率為2。 54 00:03:14,000 --> 00:03:19,000 請記住,十六進制表示,這些數字以0x開始 55 00:03:19,000 --> 00:03:23,000 因此,我們不要混淆一個十進制數。 56 00:03:23,000 --> 00:03:29,000 繼續,這是一個ASCII表, 57 00:03:29,000 --> 00:03:35,000 我們使用ASCII是從字符映射到的數值。 58 00:03:35,000 --> 00:03:39,000 請記住,在密碼學的pset,我們廣泛使用的ASCII表 59 00:03:39,000 --> 00:03:43,000 為了使用密碼學的各種方法, 60 00:03:43,000 --> 00:03:47,000 凱撒和維瓊內爾的密碼,不同的字母轉換 61 00:03:47,000 --> 00:03:52,000 在一個字符串中,根據由用戶給定的關鍵。 62 00:03:52,000 --> 00:03:56,000 讓我們來看看在一點點的ASCII數學。 63 00:03:56,000 --> 00:04:02,000 尋找在“P”以字符的形式,將是Q,+ 1, 64 00:04:02,000 --> 00:04:07,000 記得,'5'≠5。 65 00:04:07,000 --> 00:04:10,000 我們究竟如何轉換之間的2種形式? 66 00:04:10,000 --> 00:04:13,000 它實際上不是太硬。 67 00:04:13,000 --> 00:04:16,000 為了讓我們減去'0' 68 00:04:16,000 --> 00:04:20,000 因為有5個地方之間的'0'和'5'。 69 00:04:20,000 --> 00:04:23,000 為了走另外一條路,我們只是添加了0, 70 00:04:23,000 --> 00:04:25,000 所以這有點像普通的算術。 71 00:04:25,000 --> 00:04:29,000 請記住,有些事情時,周圍的引號字符 72 00:04:29,000 --> 00:04:37,000 ,從而對應於ASCII碼表中的一個值。 73 00:04:37,000 --> 00:04:40,000 移動到更一般的計算機科學課題。 74 00:04:40,000 --> 00:04:43,000 我們了解到的算法是什麼,以及我們如何使用編程 75 00:04:43,000 --> 00:04:45,000 實現算法。 76 00:04:45,000 --> 00:04:48,000 算法的一些例子是很簡單的東西如 77 00:04:48,000 --> 00:04:51,000 檢查是否一個數是偶數還是奇數。 78 00:04:51,000 --> 00:04:54,000 為此,還記得我們國防部的數字2,檢查如果結果是0。 79 00:04:54,000 --> 00:04:57,000 如果是這樣,它甚至。如果沒有,這是奇怪的。 80 00:04:57,000 --> 00:04:59,000 這是一個非常基本的算法的一個例子。 81 00:04:59,000 --> 00:05:02,000 >> 一點點的一個更棘手的是二進制搜索, 82 00:05:02,000 --> 00:05:05,000 後來我們就去了審查會議。 83 00:05:05,000 --> 00:05:09,000 編程是長遠來說,我們使用的算法 84 00:05:09,000 --> 00:05:15,000 和將其轉換為代碼的計算機可讀取。 85 00:05:15,000 --> 00:05:20,000 2實例編程是零起步, 86 00:05:20,000 --> 00:05:22,000 這是我們在0週。 87 00:05:22,000 --> 00:05:25,000 即使我們沒有實際鍵入的代碼,它是一種實施 88 00:05:25,000 --> 00:05:29,000 算法,這是印刷數字1到10, 89 00:05:29,000 --> 00:05:32,000 在這裡,我們做同樣的在C編程語言。 90 00:05:32,000 --> 00:05:41,000 這些功能相同,只是在不同的語言或語法編寫的。 91 00:05:41,000 --> 00:05:44,000 然後,我們了解的布爾表達式, 92 00:05:44,000 --> 00:05:48,000 和一個布爾值,或真或假的, 93 00:05:48,000 --> 00:05:51,000 這裡常常布爾表達式 94 00:05:51,000 --> 00:05:55,000 裡面去的條件下,所以如果(x≤5), 95 00:05:55,000 --> 00:06:00,000 好了,我們已經設置X = 5,所以這個條件會評估為true。 96 00:06:00,000 --> 00:06:03,000 如果這是真的,無論代碼是下面的條件 97 00:06:03,000 --> 00:06:08,000 要由計算機進行評價,使字符串要打印 98 00:06:08,000 --> 00:06:12,000 到標準輸出,和工作條件 99 00:06:12,000 --> 00:06:16,000 是指無論是在括號內的if語句。 100 00:06:16,000 --> 00:06:20,000 記住所有的運營商。 101 00:06:20,000 --> 00:06:26,000 記住它的&&和| |,當我們試圖結合2個或更多的條件, 102 00:06:26,000 --> 00:06:30,000 ==不檢查,是否事情都是平等的。 103 00:06:30,000 --> 00:06:36,000 請記住,=是賦值,而==是一個布爾運算符。 104 00:06:36,000 --> 00:06:41,000 ≤,≥,然後在最後2是不言自明的。 105 00:06:41,000 --> 00:06:45,000 這裡的布爾邏輯的一般審查。 106 00:06:45,000 --> 00:06:48,000 和布爾表達式在循環中也是很重要的, 107 00:06:48,000 --> 00:06:50,000 現在我們就去了。 108 00:06:50,000 --> 00:06:56,000 我們學會了3種類型的循環迄今為止,CS50,同時,做,而。 109 00:06:56,000 --> 00:06:59,000 重要的是要知道,對於大多數用途 110 00:06:59,000 --> 00:07:02,000 我們實際上可以使用任何類型的循環 111 00:07:02,000 --> 00:07:06,000 有一定的目的或共同的模式 112 00:07:06,000 --> 00:07:09,000 在編程中特別呼籲這些循環 113 00:07:09,000 --> 00:07:13,000 ,使它成為最有效的還是在這樣優雅的代碼。 114 00:07:13,000 --> 00:07:18,000 讓我們在這些循環往往是最常見的。 115 00:07:18,000 --> 00:07:21,000 >> 在循環中,我們已經知道我們要重複多少次。 116 00:07:21,000 --> 00:07:24,000 這就是我們提出的條件中。 117 00:07:24,000 --> 00:07:28,000 對於,= 0,<10,例如。 118 00:07:28,000 --> 00:07:31,000 我們已經知道,我們想要做的東西10倍。 119 00:07:31,000 --> 00:07:34,000 現在,一個while循環中,我們一般不必然 120 00:07:34,000 --> 00:07:36,000 我們要知道有多少次的循環運行。 121 00:07:36,000 --> 00:07:39,000 但我們知道某種條件下,我們希望它是 122 00:07:39,000 --> 00:07:41,000 始終是真實的,永遠是虛假的。 123 00:07:41,000 --> 00:07:44,000 例如,雖然被設定。 124 00:07:44,000 --> 00:07:46,000 比方說,這是一個布爾變量。 125 00:07:46,000 --> 00:07:48,000 雖然這是真的,我們要評估的代碼, 126 00:07:48,000 --> 00:07:52,000 有那麼一點點更多的可擴展性,多一點點普遍比一個for循環, 127 00:07:52,000 --> 00:07:55,000 但任何的for循環也可以轉換為一個while循環。 128 00:07:55,000 --> 00:08:00,000 最後,執行while循環,這可能是最棘手的理解, 129 00:08:00,000 --> 00:08:04,000 經常使用,當我們要評估的代碼 130 00:08:04,000 --> 00:08:06,000 之前我們第一次檢查的條件。 131 00:08:06,000 --> 00:08:09,000 一個常見的用例的do while循環 132 00:08:09,000 --> 00:08:12,000 當你想獲取用戶輸入的,你知道你要問的用戶 133 00:08:12,000 --> 00:08:15,000 輸入至少一次,但如果他們不給你良好的輸入 134 00:08:15,000 --> 00:08:18,000 你要不斷地問他們,直到他們給你良好的輸入。 135 00:08:18,000 --> 00:08:21,000 這是最常見的使用whil​​e循環, 136 00:08:21,000 --> 00:08:23,000 讓我們來看看在這些循環的實際結構。 137 00:08:23,000 --> 00:08:27,000 他們通常總是按照這些模式。 138 00:08:27,000 --> 00:08:30,000 >> 在fo​​r循環內,你有3個組成部分: 139 00:08:30,000 --> 00:08:35,000 初始化,通常的東西,如int i = 0,其中i是計數器, 140 00:08:35,000 --> 00:08:40,000 條件,在這裡我們想說的運行循環,只要這種情況下仍持有, 141 00:08:40,000 --> 00:08:44,000 像我<10,然後在最後,更新,這是我們增加 142 00:08:44,000 --> 00:08:47,000 在循環中的每個點的計數器變量。 143 00:08:47,000 --> 00:08:50,000 看到有一個共同的東西就是我+ +, 144 00:08:50,000 --> 00:08:52,000 這意味著每次遞增i。 145 00:08:52,000 --> 00:08:55,000 你也可以做類似的東西我+ = 2, 146 00:08:55,000 --> 00:08:58,000 這意味著加2我每次去通過循環。 147 00:08:58,000 --> 00:09:03,000 然後這樣做只是指實際運行循環的一部分的任何代碼。 148 00:09:03,000 --> 00:09:09,000 一個while循環,這個時候,我們其實有外循環的初始化, 149 00:09:09,000 --> 00:09:12,000 例如,讓我們說,我們正在試圖做的,因為我剛才所描述的相同類型的循環。 150 00:09:12,000 --> 00:09:16,000 我們會說INT I = 0,在循環開始前。 151 00:09:16,000 --> 00:09:20,000 然後,我們可以這樣說,而我做到這一點, 152 00:09:20,000 --> 00:09:22,000 所以相同的代碼塊之前, 153 00:09:22,000 --> 00:09:26,000 而這一次的更新部分的代碼,例如,我+ +, 154 00:09:26,000 --> 00:09:29,000 其實裡面的循環。 155 00:09:29,000 --> 00:09:33,000 最後,對於一個這樣做的同時,它類似於while循環, 156 00:09:33,000 --> 00:09:36,000 但我們必須記住,代碼將評估一次 157 00:09:36,000 --> 00:09:40,000 前檢查條件,所以它使很多更有意義 158 00:09:40,000 --> 00:09:44,000 如果你看它在從上到下的順序。 159 00:09:44,000 --> 00:09:49,000 在while循環中的代碼進行評估之前,你甚至看while條件, 160 00:09:49,000 --> 00:09:55,000 而一個while循環,它會首先檢查。 161 00:09:55,000 --> 00:09:59,000 報表和變量。 162 00:09:59,000 --> 00:10:04,000 當我們要創建一個新的變量,我們首先要對其進行初始化。 163 00:10:04,000 --> 00:10:07,000 >> 例如,int酒吧初始化變量的酒吧, 164 00:10:07,000 --> 00:10:10,000 但它並沒有給它一個值,所以現在欄的值是什麼? 165 00:10:10,000 --> 00:10:12,000 我們不知道。 166 00:10:12,000 --> 00:10:14,000 這可能是以前存儲在內存中有一些垃圾的價值, 167 00:10:14,000 --> 00:10:16,000 我們不想使用該變量 168 00:10:16,000 --> 00:10:19,000 直到我們真正給它一個值, 169 00:10:19,000 --> 00:10:21,000 因此,我們在這裡聲明。 170 00:10:21,000 --> 00:10:24,000 然後,我們把它初始化為42。 171 00:10:24,000 --> 00:10:28,000 現在,當然,我們知道這是可以做到一條線,酒吧= 42。 172 00:10:28,000 --> 00:10:30,000 但僅僅是明確的多個步驟,是怎麼回事, 173 00:10:30,000 --> 00:10:34,000 聲明和初始化分別在這裡發生。 174 00:10:34,000 --> 00:10:38,000 它發生在一個步驟,下一個,巴茲=酒吧+ 1, 175 00:10:38,000 --> 00:10:44,000 這以下聲明,遞增的的巴茲,所以在這個代碼塊的結束 176 00:10:44,000 --> 00:10:48,000 如果我們要打印的價值巴茲這將是44 177 00:10:48,000 --> 00:10:52,000 因為我們聲明並把它初始化為1>酒吧, 178 00:10:52,000 --> 00:10:58,000 然後我們增加一次+ +。 179 00:10:58,000 --> 00:11:02,000 我們去了這個漂亮的簡要,但它有一個大致的 180 00:11:02,000 --> 00:11:04,000 了解線程和事件是什麼。 181 00:11:04,000 --> 00:11:06,000 我們主要是在刮, 182 00:11:06,000 --> 00:11:09,000 所以你可以把多個線程的代碼序列 183 00:11:09,000 --> 00:11:11,000 在同一時間運行。 184 00:11:11,000 --> 00:11:14,000 實際上,它可能是運行在相同的時間, 185 00:11:14,000 --> 00:11:17,000 但有點抽象,我們可以認為它以這種方式。 186 00:11:17,000 --> 00:11:20,000 >> 從無到有,例如,我們有多個精靈。 187 00:11:20,000 --> 00:11:22,000 它可以在同一時間執行不同的代碼。 188 00:11:22,000 --> 00:11:26,000 人們可以一邊走一邊說的東西 189 00:11:26,000 --> 00:11:29,000 在一個不同的,在屏幕的一部分。 190 00:11:29,000 --> 00:11:34,000 事件是另一種方式分離出來的邏輯 191 00:11:34,000 --> 00:11:37,000 不同元素之間,你的代碼, 192 00:11:37,000 --> 00:11:40,000 在Scratch中,我們能夠模擬活動,利用廣播, 193 00:11:40,000 --> 00:11:43,000 這實際上是當我收到,而不是當我聽到, 194 00:11:43,000 --> 00:11:47,000 但實質上,它是一個傳遞信息的方法 195 00:11:47,000 --> 00:11:49,000 從一個精靈到另一個地方。 196 00:11:49,000 --> 00:11:52,000 例如,您可能要傳輸遊戲, 197 00:11:52,000 --> 00:11:56,000 另一個精靈,當比賽結束, 198 00:11:56,000 --> 00:11:58,000 它以某種方式回應。 199 00:11:58,000 --> 00:12:03,000 這是一個重要的編程模型,以了解。 200 00:12:03,000 --> 00:12:07,000 只是去超過基本的週0,我們已經討論了這麼遠, 201 00:12:07,000 --> 00:12:10,000 讓我們來看看這個簡單的C程序。 202 00:12:10,000 --> 00:12:14,000 文字可能是從這裡有點小,但我會去非常快的。 203 00:12:14,000 --> 00:12:20,000 我們包括2頭文件的頂部,cs50.h的和stdio.h中。 204 00:12:20,000 --> 00:12:23,000 然後,我們定義一個常數,稱為限制為100。 205 00:12:23,000 --> 00:12:26,000 然後,我們執行我們的主要功能。 206 00:12:26,000 --> 00:12:29,000 由於我們沒有使用命令行參數,在這裡,我們需要把作廢 207 00:12:29,000 --> 00:12:32,000 作為主要的參數。 208 00:12:32,000 --> 00:12:38,000 我們看到上述主要的詮釋。這是返回類型,因此返回0,在底部。 209 00:12:38,000 --> 00:12:41,000 我們使用的是CS50庫函數得到詮釋 210 00:12:41,000 --> 00:12:45,000 要求用戶輸入,我們將其存儲在這個變量x, 211 00:12:45,000 --> 00:12:51,000 因此,我們宣布上述X,和我們對它進行初始化,其中x =調用getInt。 212 00:12:51,000 --> 00:12:53,000 >> 然後我們檢查,看是否用戶給了我們很好的輸入。 213 00:12:53,000 --> 00:12:59,000 如果我們要≥LIMIT返回一個錯誤代碼1和打印錯誤消息。 214 00:12:59,000 --> 00:13:02,000 最後,如果用戶已經給了我們很好的輸入 215 00:13:02,000 --> 00:13:08,000 我們要去的平方數,並打印出這個結果。 216 00:13:08,000 --> 00:13:11,000 只是為了確保這些全部命中回家 217 00:13:11,000 --> 00:13:17,000 你可以看到這裡的代碼的不同部分的標籤。 218 00:13:17,000 --> 00:13:19,000 我提到不變,頭文件。 219 00:13:19,000 --> 00:13:21,000 哦,詮釋x。請一定要記住,這是一個局部變量。 220 00:13:21,000 --> 00:13:24,000 對比從一個全局變量,我們將討論 221 00:13:24,000 --> 00:13:27,000 一點點後,在審查會議, 222 00:13:27,000 --> 00:13:30,000 和我們調用庫函數printf, 223 00:13:30,000 --> 00:13:34,000 因此,如果我們不包括stdio.h頭文件 224 00:13:34,000 --> 00:13:37,000 我們將無法調用printf。 225 00:13:37,000 --> 00:13:42,000 我相信,進行了切斷箭頭指向的%d, 226 00:13:42,000 --> 00:13:45,000 這是在printf的格式化字符串。 227 00:13:45,000 --> 00:13:52,000 它說一個數字,第%d打印出這個變量。 228 00:13:52,000 --> 00:13:58,000 這是它第0週。 229 00:13:58,000 --> 00:14:06,000 現在,盧卡斯繼續下去。 230 00:14:06,000 --> 00:14:08,000 嘿,伙計們。我的名字是盧卡斯。 231 00:14:08,000 --> 00:14:10,000 我是一個大二學生在校園裡,奧美最好的房子, 232 00:14:10,000 --> 00:14:14,000 我要談一點,約1週和2.1週。 233 00:14:14,000 --> 00:14:16,000 [1週和2.1週] [盧卡斯·弗雷塔斯] 234 00:14:16,000 --> 00:14:19,000 Lexi的說,當我們開始從頭開始你的代碼翻譯到C 235 00:14:19,000 --> 00:14:23,000 ,我們注意到的事情之一是,你不能只是 236 00:14:23,000 --> 00:14:26,000 寫你的代碼,並運行它使用了一個綠色的標誌。 237 00:14:26,000 --> 00:14:30,000 其實,你必須使用一些步驟,以使你的C程序 238 00:14:30,000 --> 00:14:33,000 成為一個可執行文件。 239 00:14:33,000 --> 00:14:36,000 基本上你做了什麼時,你所編寫的程序是, 240 00:14:36,000 --> 00:14:40,000 你翻譯成一種語言,編譯器能夠理解你的想法, 241 00:14:40,000 --> 00:14:44,000 所以,當你正在編寫一個程序,在C 242 00:14:44,000 --> 00:14:47,000 你在做什麼,實際上是寫東西,你的編譯器是怎麼回事了解, 243 00:14:47,000 --> 00:14:50,000 那麼編譯器會翻譯的代碼 244 00:14:50,000 --> 00:14:53,000 到的東西,你的電腦就會明白。 245 00:14:53,000 --> 00:14:55,000 >> 的事情,您的計算機實際上是非常愚蠢的。 246 00:14:55,000 --> 00:14:57,000 你的電腦只能理解“0”和“1, 247 00:14:57,000 --> 00:15:01,000 所以實際上在第一台計算機的人通常編程 248 00:15:01,000 --> 00:15:04,000 用“0”和“1秒,但現在不是了,感謝上帝。 249 00:15:04,000 --> 00:15:07,000 我們沒有記憶0和1的序列 250 00:15:07,000 --> 00:15:10,000 for循環或一個while循環等。 251 00:15:10,000 --> 00:15:13,000 這就是為什麼我們有一個編譯器。 252 00:15:13,000 --> 00:15:17,000 編譯器只是它基本上是翻譯的C代碼, 253 00:15:17,000 --> 00:15:21,000 在我們的例子中,您的計算機就會明白的語言, 254 00:15:21,000 --> 00:15:25,000 這是目標代碼,我們正在使用的編譯器, 255 00:15:25,000 --> 00:15:30,000 被稱為鐺,所以這實際上是鐺的符號。 256 00:15:30,000 --> 00:15:33,000 當你有你的程序,你必須做兩件事情。 257 00:15:33,000 --> 00:15:37,000 首先,你必須編譯程序,然後你運行你的程序。 258 00:15:37,000 --> 00:15:41,000 編譯你的程序,你有很多的選擇這樣做。 259 00:15:41,000 --> 00:15:44,000 第一個是做鐺program.c 260 00:15:44,000 --> 00:15:47,000 在該程序是你的程序的名稱。 261 00:15:47,000 --> 00:15:51,000 在這種情況下,你可以看到,他們只是說“嘿,編譯我的程序。” 262 00:15:51,000 --> 00:15:56,000 你不是說:“我想我的程序”或其他任何名稱。 263 00:15:56,000 --> 00:15:58,000 >> 第二個選項是給你的程序的名稱。 264 00:15:58,000 --> 00:16:02,000 你可以說鐺-O和你想要的名稱 265 00:16:02,000 --> 00:16:06,000 可執行文件被命名為,然後program.c。 266 00:16:06,000 --> 00:16:11,000 而且你還可以做程序,以及如何在第2例 267 00:16:11,000 --> 00:16:15,000 我把C,我只有在第三個節目嗎? 268 00:16:15,000 --> 00:16:18,000 是啊,你不應該付諸表決。C時使用。 269 00:16:18,000 --> 00:16:22,000 否則,編譯器實際上是要罵你的。 270 00:16:22,000 --> 00:16:24,000 而且,我不知道,如果你們還記得, 271 00:16:24,000 --> 00:16:29,000 但很多時候,我們也使用lcs50或-LM。 272 00:16:29,000 --> 00:16:31,000 這就是所謂的鏈接。 273 00:16:31,000 --> 00:16:35,000 它只是告訴編譯器,你將使用這些庫就在那裡, 274 00:16:35,000 --> 00:16:39,000 所以如果你想使用cs50.h,你必須輸入 275 00:16:39,000 --> 00:16:43,000 鐺program.c,lcs50。 276 00:16:43,000 --> 00:16:45,000 如果你不這樣做,編譯器不會知道 277 00:16:45,000 --> 00:16:50,000 你使用了這些功能cs50.h. 278 00:16:50,000 --> 00:16:52,000 當你要運行你的程序,你有2個選擇。 279 00:16:52,000 --> 00:16:57,000 如果你沒有鐺program.c你沒有給你的程序的名稱。 280 00:16:57,000 --> 00:17:01,000 您必須運行使用。/ a.out的。 281 00:17:01,000 --> 00:17:06,000 a.out是一個標準的名稱,鐺使您的程序,如果你不給它一個名字。 282 00:17:06,000 --> 00:17:11,000 否則,你要做的/計劃,如果你在你的程序出了名的, 283 00:17:11,000 --> 00:17:15,000 ,如果你還做程序的名稱,程序會得到 284 00:17:15,000 --> 00:17:23,000 已經進行編程的C文件相同的名稱。 285 00:17:23,000 --> 00:17:26,000 然後,我們談到數據類型和數據。 286 00:17:26,000 --> 00:17:31,000 >> 數據類型基本上是同樣的事情,他們使用的小盒子 287 00:17:31,000 --> 00:17:35,000 存儲值,所以數據類型實際上是一樣的小寵物。 288 00:17:35,000 --> 00:17:39,000 他們有各種規模和類型。 289 00:17:39,000 --> 00:17:43,000 我不知道這個比喻是有道理的。 290 00:17:43,000 --> 00:17:46,000 數據的大小實際上是依賴於機器的體系架構。 291 00:17:46,000 --> 00:17:49,000 ,我在這裡要告訴所有的數據大小 292 00:17:49,000 --> 00:17:53,000 實際上是一個32位的機器,這是我們的設備的情況下, 293 00:17:53,000 --> 00:17:56,000 但如果你是真正的編碼您的Mac或Windows 294 00:17:56,000 --> 00:17:59,000 可能你有一個64位的機器, 295 00:17:59,000 --> 00:18:03,000 所以請記住,數據的大小,我要在這裡展示 296 00:18:03,000 --> 00:18:06,000 是為32位的機器上。 297 00:18:06,000 --> 00:18:08,000 第一個,我們看到的是一個int, 298 00:18:08,000 --> 00:18:10,000 這是非常簡單的。 299 00:18:10,000 --> 00:18:13,000 您可以使用int來存儲一個整數。 300 00:18:13,000 --> 00:18:16,000 我們也看到了字符,字符。 301 00:18:16,000 --> 00:18:20,000 如果你想使用一個字母或一個小符號,你可能會使用一個char。 302 00:18:20,000 --> 00:18:26,000 一個char 1個字節,這意味著8位,如樂喜說。 303 00:18:26,000 --> 00:18:31,000 基本上我們有一個ASCII表有256個 304 00:18:31,000 --> 00:18:34,000 可能的0和1的組合, 305 00:18:34,000 --> 00:18:37,000 然後當你輸入一個字符,它的翻譯 306 00:18:37,000 --> 00:18:44,000 的字符輸入你一個數字,你有ASCII表中,如樂喜說。 307 00:18:44,000 --> 00:18:48,000 我們也有浮動,我們用它來存儲的十進制數。 308 00:18:48,000 --> 00:18:53,000 例如,如果你想選擇3.14,你要使用浮動 309 00:18:53,000 --> 00:18:55,000 或雙具有更高的精度。 310 00:18:55,000 --> 00:18:57,000 一個浮動有4個字節。 311 00:18:57,000 --> 00:19:01,000 雙有8個字節,所以,唯一的區別是精度。 312 00:19:01,000 --> 00:19:04,000 我們也有很長的,用於整數, 313 00:19:04,000 --> 00:19:09,000 你可以看到一個int和一個長為一個32位的機器具有相同的大小, 314 00:19:09,000 --> 00:19:13,000 所以它不會真正有意義的使用在一個32位的機器。 315 00:19:13,000 --> 00:19:17,000 >> 但是,如果你使用的是Mac和64位的機器,實際上是一個長有大小8, 316 00:19:17,000 --> 00:19:19,000 所以它確實依賴於體系結構。 317 00:19:19,000 --> 00:19:22,000 對於32位的機器,它沒有意義的真正使用長。 318 00:19:22,000 --> 00:19:25,000 再長長,另一方面,有8個字節, 319 00:19:25,000 --> 00:19:30,000 所以這是非常好的,如果你想有一個較長的整數。 320 00:19:30,000 --> 00:19:34,000 最後,我們有字符串,它實際上是一個char *, 321 00:19:34,000 --> 00:19:37,000 這是一個指向字符。 322 00:19:37,000 --> 00:19:40,000 這是很容易想到的字符串的長度將是 323 00:19:40,000 --> 00:19:42,000 的字符數,你必須有, 324 00:19:42,000 --> 00:19:45,000 但實際上本身的char * 325 00:19:45,000 --> 00:19:49,000 有一個指針到一個字符,這是4個字節的大小。 326 00:19:49,000 --> 00:19:52,000 一個char *的大小為4個字節。 327 00:19:52,000 --> 00:19:56,000 這不要緊,如果你有一個小單詞或一個字母或任何東西。 328 00:19:56,000 --> 00:19:58,000 這將是4個字節。 329 00:19:58,000 --> 00:20:01,000 我們也學到了一點關於鑄造, 330 00:20:01,000 --> 00:20:04,000 所以,你可以看到,如果你有,例如,一個程序,說: 331 00:20:04,000 --> 00:20:08,000 INT X = 3,然後輸出(“%d”,X / 2) 332 00:20:08,000 --> 00:20:12,000 你們知道它會在屏幕上打印嗎? 333 00:20:12,000 --> 00:20:14,000 >> 有人嗎?>> [學生] 2。 334 00:20:14,000 --> 00:20:16,000 1 >> 1,是的。 335 00:20:16,000 --> 00:20:20,000 當你做3/2 1.5, 336 00:20:20,000 --> 00:20:24,000 但由於我們使用的是一個整數,它會忽略的小數部分, 337 00:20:24,000 --> 00:20:26,000 你將有1。 338 00:20:26,000 --> 00:20:29,000 如果你不希望發生這種情況你可以做什麼,例如, 339 00:20:29,000 --> 00:20:33,000 聲明持股量Y = X。 340 00:20:33,000 --> 00:20:40,000 則X為3現在要在y是3.000。 341 00:20:40,000 --> 00:20:44,000 然後你就可以打印的Y / 2。 342 00:20:44,000 --> 00:20:50,000 其實,我應該​​有一個2。那邊。 343 00:20:50,000 --> 00:20:55,000 它會做3.00/2.00, 344 00:20:55,000 --> 00:20:58,000 你會得到1.5。 345 00:20:58,000 --> 00:21:06,000 我們有這個.2 f只要求2的小數部分的十進制單位。 346 00:21:06,000 --> 00:21:12,000 如果你有0.3 f實際上1.500。 347 00:21:12,000 --> 00:21:16,000 如果它是2的為1.50。 348 00:21:16,000 --> 00:21:18,000 我們也有這樣的情況在這裡。 349 00:21:18,000 --> 00:21:22,000 如果你這樣做持股量X = 3.14,那麼你的printf x 350 00:21:22,000 --> 00:21:24,000 你將得到3.14。 351 00:21:24,000 --> 00:21:29,000 如果你做x = x的整數, 352 00:21:29,000 --> 00:21:34,000 這意味著把X作為一個int,則在打印x現在 353 00:21:34,000 --> 00:21:36,000 你將不得不3.00。 354 00:21:36,000 --> 00:21:38,000 這是否有意義嗎? 355 00:21:38,000 --> 00:21:41,000 因為你第一次治療x為整數,所以你忽略的小數部分, 356 00:21:41,000 --> 00:21:45,000 然後你印刷。 357 00:21:45,000 --> 00:21:47,000 最後,你也可以做到這一點, 358 00:21:47,000 --> 00:21:52,000 X = 65,那麼你聲明一個char C = X, 359 00:21:52,000 --> 00:21:56,000 然後,如果你打印的C,你實際上是在將要得到的 360 00:21:56,000 --> 00:21:59,000 A,所以基本上你在這裡做什麼 361 00:21:59,000 --> 00:22:02,000 的整數轉換成字符, 362 00:22:02,000 --> 00:22:05,000 就像ASCII表。 363 00:22:05,000 --> 00:22:08,000 我們還談到數學運算符。 364 00:22:08,000 --> 00:22:14,000 他們中的大多數都非常簡單,+, - ,*,/, 365 00:22:14,000 --> 00:22:20,000 我們也談到關於MOD,這是剩下的一個部門,2個數字。 366 00:22:20,000 --> 00:22:23,000 如果你有10%3,例如, 367 00:22:23,000 --> 00:22:27,000 這意味著10除以3,其餘的是什麼? 368 00:22:27,000 --> 00:22:30,000 這將是1,所以它實際上是非常有用的節目了很多。 369 00:22:30,000 --> 00:22:38,000 對於維瓊內爾和凱撒,我敢肯定,如果大家都使用MOD。 370 00:22:38,000 --> 00:22:43,000 關於數學運算符時,必須非常小心,將*和/。 371 00:22:43,000 --> 00:22:48,000 >> 例如,如果你這樣做(3/2)* 2,你會得到嗎? 372 00:22:48,000 --> 00:22:50,000 [學生] 2。 373 00:22:50,000 --> 00:22:54,000 呀,2,因為二分之三是要為1.5, 374 00:22:54,000 --> 00:22:57,000 但因為你是做2個整數之間的操作 375 00:22:57,000 --> 00:22:59,000 其實你只是要考慮, 376 00:22:59,000 --> 00:23:03,000 1 * 2,然後將是2,所以要非常非常小心 377 00:23:03,000 --> 00:23:07,000 做數學運算時,整數,因為 378 00:23:07,000 --> 00:23:12,000 你可能會得到2 = 3,在這種情況下。 379 00:23:12,000 --> 00:23:14,000 也非常小心的優先級。 380 00:23:14,000 --> 00:23:21,000 通常,你應該使用括號,要確保你知道你在做什麼。 381 00:23:21,000 --> 00:23:27,000 一些有用的快捷鍵,當然,一個是我+ +或i + = 1 382 00:23:27,000 --> 00:23:30,000 或使用+ =。 383 00:23:30,000 --> 00:23:34,000 這是同樣的事情,做I = I + 1。 384 00:23:34,000 --> 00:23:39,000 你也可以做我 - 我 - = 1, 385 00:23:39,000 --> 00:23:42,000 這是同樣的事情I = -1, 386 00:23:42,000 --> 00:23:46,000 東西你們使用了很多在for循環中,至少。 387 00:23:46,000 --> 00:23:52,000 此外,*,* =,如果你這樣做了,例如,如果你使用, 388 00:23:52,000 --> 00:23:57,000 *的話說,I = I * 2 = 2是同樣的事情, 389 00:23:57,000 --> 00:23:59,000 同樣的事情為師。 390 00:23:59,000 --> 00:24:08,000 如果你做的I / = 2,I = I / 2,這是同樣的事情。 391 00:24:08,000 --> 00:24:10,000 >> 現在功能。 392 00:24:10,000 --> 00:24:13,000 你們的經驗教訓,其功能是一個很好的策略,以節省代碼 393 00:24:13,000 --> 00:24:16,000 而你編程,所以如果你要執行相同的任務 394 00:24:16,000 --> 00:24:20,000 在代碼中一遍又一遍,可能您要使用的功能 395 00:24:20,000 --> 00:24:25,000 只是讓你不必一遍又一遍的複製和粘貼代碼。 396 00:24:25,000 --> 00:24:28,000 其實,主要是一個函數,當我告訴你一個函數的格式 397 00:24:28,000 --> 00:24:32,000 你會看到,這是很明顯的。 398 00:24:32,000 --> 00:24:35,000 我們還可以使用一些庫的功能, 399 00:24:35,000 --> 00:24:39,000 例如,printf,進球,這是從CS50庫, 400 00:24:39,000 --> 00:24:43,000 和其他功能,如TOUPPER。 401 00:24:43,000 --> 00:24:46,000 所有這些功能實際上是實現其他圖書館, 402 00:24:46,000 --> 00:24:49,000 當你把這些繫繩文件的開始你的程序 403 00:24:49,000 --> 00:24:53,000 你說可以請你給我的代碼為這些功能 404 00:24:53,000 --> 00:24:57,000 所以我沒有實現他們自己嗎? 405 00:24:57,000 --> 00:25:00,000 你也可以編寫自己的函數,因此,當你開始編程 406 00:25:00,000 --> 00:25:04,000 你會意識到,圖書館不具有的所有功能,你需要的。 407 00:25:04,000 --> 00:25:10,000 例如,我們在過去的pset,寫,畫,加密和查找, 408 00:25:10,000 --> 00:25:13,000 這是非常,非常重要的是要能寫功能 409 00:25:13,000 --> 00:25:17,000 因為他們是有用的,我們使用他們所有的時間編程, 410 00:25:17,000 --> 00:25:19,000 這樣可以節省大量的代碼。 411 00:25:19,000 --> 00:25:21,000 函數的格式是這一個。 412 00:25:21,000 --> 00:25:24,000 我們開始返回類型。返回類型是什麼? 413 00:25:24,000 --> 00:25:27,000 這只是當你的函數會返回。 414 00:25:27,000 --> 00:25:29,000 如果你有一個函數,例如,階乘, 415 00:25:29,000 --> 00:25:31,000 是要計算的階乘的整數, 416 00:25:31,000 --> 00:25:34,000 可能它會返回一個整數。 417 00:25:34,000 --> 00:25:37,000 然後返回類型為int。 418 00:25:37,000 --> 00:25:41,000 的printf實際上有一個返回類型為void 419 00:25:41,000 --> 00:25:43,000 因為你不返回任何東西。 420 00:25:43,000 --> 00:25:45,000 你只是在屏幕上打印的東西 421 00:25:45,000 --> 00:25:48,000 和退出的功能之後。 422 00:25:48,000 --> 00:25:51,000 然後,你的功能,你可以選擇的名稱。 423 00:25:51,000 --> 00:25:55,000 您應該有點合理,如不選擇一個名稱,如某某 424 00:25:55,000 --> 00:25:58,000 或像X2F。 425 00:25:58,000 --> 00:26:02,000 嘗試彌補的名稱是有道理的。 426 00:26:02,000 --> 00:26:04,000 >> 例如,如果是因子,說階乘的。 427 00:26:04,000 --> 00:26:08,000 如果要畫的東西,它是一個函數,將它命名畫。 428 00:26:08,000 --> 00:26:11,000 然後我們有參數,也被稱為參數, 429 00:26:11,000 --> 00:26:14,000 這是像你的函數所需要的資源, 430 00:26:14,000 --> 00:26:17,000 從你的代碼來執行其任務。 431 00:26:17,000 --> 00:26:20,000 如果你要計算一個數的階乘 432 00:26:20,000 --> 00:26:23,000 可能你需要有一個數字來計算階乘。 433 00:26:23,000 --> 00:26:27,000 的論點,你將有一個是這個數字本身。 434 00:26:27,000 --> 00:26:31,000 那麼它會做一些事情,結束時,返回的值 435 00:26:31,000 --> 00:26:35,000 除非它是一個void函數。 436 00:26:35,000 --> 00:26:37,000 讓我們看一個例子。 437 00:26:37,000 --> 00:26:40,000 如果我想編寫一個函數,總結一個整數數組中的所有數字, 438 00:26:40,000 --> 00:26:43,000 首先,返回類型為int 439 00:26:43,000 --> 00:26:46,000 因為我有一個整數數組。 440 00:26:46,000 --> 00:26:51,000 然後我要的功能名稱,如sumArray, 441 00:26:51,000 --> 00:26:54,000 然後是怎麼回事本身採取的陣列,為int NUMS, 442 00:26:54,000 --> 00:26:58,000 然後長度的數組,所以我知道我有多少個數字來概括。 443 00:26:58,000 --> 00:27:02,000 然後,我要初始化的變量稱為總和,例如,為0, 444 00:27:02,000 --> 00:27:08,000 每次我看到一個數組中的元素,我把它添加到總和,所以我做了一個for循環。 445 00:27:08,000 --> 00:27:15,000 就像樂喜說,你INT I = 0,I <長度和i + +。 446 00:27:15,000 --> 00:27:20,000 數組中的每一個元素,我所做的次數總和+ = [I], 447 00:27:20,000 --> 00:27:24,000 然後我又回到了一筆,所以這是很簡單的,這樣可以節省大量的代碼 448 00:27:24,000 --> 00:27:28,000 如果您使用此功能了很多次。 449 00:27:28,000 --> 00:27:32,000 然後,我們看看條件。 450 00:27:32,000 --> 00:27:38,000 我們有,否則,如果和else if。 451 00:27:38,000 --> 00:27:42,000 讓我們來看看者的區別是什麼。 452 00:27:42,000 --> 00:27:45,000 看一看在這些代碼。它們之間的區別是什麼? 453 00:27:45,000 --> 00:27:49,000 第一個基本的代碼要你告訴 454 00:27:49,000 --> 00:27:51,000 一個數是否為+, - ,或0。 455 00:27:51,000 --> 00:27:55,000 第一個說,如果> 0,則它的正面。 456 00:27:55,000 --> 00:28:00,000 如果它是= 0,那麼它是0,並且,如果是<0,那麼它的負。 457 00:28:00,000 --> 00:28:04,000 >> 和其他人正在做的,如果,否則,如果,否則。 458 00:28:04,000 --> 00:28:07,000 兩者之間的區別是,這一個實際上是要 459 00:28:07,000 --> 00:28:13,000 如果> 0,<0或= 0三次, 460 00:28:13,000 --> 00:28:17,000 所以,如果你有2號,例如,它會到這裡來,並說 461 00:28:17,000 --> 00:28:21,000 如果(X> 0),它會說“是”,所以我打印陽性。 462 00:28:21,000 --> 00:28:25,000 但是,即使我知道,這是> 0,它不會是0或<0 463 00:28:25,000 --> 00:28:29,000 我仍然會做的是0,<0, 464 00:28:29,000 --> 00:28:33,000 所以實際上,我要進去,如果我沒有到 465 00:28:33,000 --> 00:28:38,000 因為我已經知道,它不是要滿足這些條件。 466 00:28:38,000 --> 00:28:41,000 我可以使用,否則的話,else語句。 467 00:28:41,000 --> 00:28:45,000 它基本上是說,如果X = 0我打印的積極。 468 00:28:45,000 --> 00:28:48,000 如果不是的話,我也對此進行測試。 469 00:28:48,000 --> 00:28:51,000 如果這是我要做到這一點。 470 00:28:51,000 --> 00:28:54,000 基本上,如果我有X = 2,你會說 471 00:28:54,000 --> 00:28:57,000 如果(X> 0),是的,打印本。 472 00:28:57,000 --> 00:29:00,000 現在,我知道,這是> 0,它滿足了第一,如果 473 00:29:00,000 --> 00:29:02,000 我什至要運行此代碼。 474 00:29:02,000 --> 00:29:09,000 的代碼運行速度更快,實際上,3倍的速度,如果你用這個。 475 00:29:09,000 --> 00:29:11,000 我們還了解到,和(或)。 476 00:29:11,000 --> 00:29:15,000 我不會去,因為亞力克西斯已經談到他們。 477 00:29:15,000 --> 00:29:17,000 這只是&&和| |運算符。 478 00:29:17,000 --> 00:29:21,000 >> 我唯一​​會說的時候要小心,有3個條件。 479 00:29:21,000 --> 00:29:24,000 使用小括號,因為當你有一個條件,這是非常令人困惑的 480 00:29:24,000 --> 00:29:27,000 和其他的一個或另一個。 481 00:29:27,000 --> 00:29:30,000 使用括號只是為了確保你的條件是有意義的 482 00:29:30,000 --> 00:29:34,000 因為在這種情況下,例如,你可以想像, 483 00:29:34,000 --> 00:29:38,000 它可以是第一個條件和一個或另一個 484 00:29:38,000 --> 00:29:41,000 或2中所組合的條件和 485 00:29:41,000 --> 00:29:45,000 或第三人,所以,只是小心些而已。 486 00:29:45,000 --> 00:29:48,000 最後,我們談到了開關。 487 00:29:48,000 --> 00:29:53,000 交換機是非常有用的,當你有一個變量。 488 00:29:53,000 --> 00:29:55,000 比方說,你有一個變量如:n 489 00:29:55,000 --> 00:29:59,000 這些情況下,可以是0,1,或2,並且對於每個 490 00:29:59,000 --> 00:30:01,000 你要去執行一項任務。 491 00:30:01,000 --> 00:30:04,000 你可以說開關變量,它表明, 492 00:30:04,000 --> 00:30:08,000 像值1的值,然後是我要做到這一點, 493 00:30:08,000 --> 00:30:12,000 然後我打破,這意味著在任何其他情況下,我不會看 494 00:30:12,000 --> 00:30:15,000 因為我們已經滿足這種情況下, 495 00:30:15,000 --> 00:30:20,000 然後value2和等等,我也可以有一個默認的開關。 496 00:30:20,000 --> 00:30:24,000 這意味著,如果它不能滿足的情況下,我 497 00:30:24,000 --> 00:30:29,000 我做別的事情,但是這是可選的。 498 00:30:29,000 --> 00:30:36,000 這一切對我來說。現在,讓我們湯米。 499 00:30:36,000 --> 00:30:41,000 好吧,這將是第3週上下。 500 00:30:41,000 --> 00:30:45,000 這些都是一些我們的主題將涵蓋,密碼,範圍,數組,等等。 501 00:30:45,000 --> 00:30:49,000 一個快字上的密碼。我們不會敲定這個家。 502 00:30:49,000 --> 00:30:52,000 >> 我們這樣做的pset 2,但測驗,請確保您知道其中的差別 503 00:30:52,000 --> 00:30:54,000 之間的凱撒密碼和維瓊內爾的密碼, 504 00:30:54,000 --> 00:30:57,000 如何這些密碼的工作是什麼樣子的加密 505 00:30:57,000 --> 00:30:59,000 和解密使用這些密碼的文本。 506 00:30:59,000 --> 00:31:03,000 請記住,簡單的愷撒密碼的每個字符的旋轉相同的量, 507 00:31:03,000 --> 00:31:06,000 確保你在字母表中的字母數模。 508 00:31:06,000 --> 00:31:09,000 和維瓊內爾密碼,在另一方面,每個字符旋轉 509 00:31:09,000 --> 00:31:12,000 不同的金額,而不是說 510 00:31:12,000 --> 00:31:15,000 每一個字符3維瓊內爾旋轉,旋轉每個字符 511 00:31:15,000 --> 00:31:17,000 由不同的金額,根據一些關鍵字 512 00:31:17,000 --> 00:31:20,000 中的關鍵字,其中每個字母代表了一些不同的量 513 00:31:20,000 --> 00:31:26,000 旋轉清晰的文本。 514 00:31:26,000 --> 00:31:28,000 讓我們先說說變量的作用域。 515 00:31:28,000 --> 00:31:30,000 有2種不同類型的變量。 516 00:31:30,000 --> 00:31:33,000 我們有局部變量,而這些將要定義的 517 00:31:33,000 --> 00:31:36,000 外的主要或以外的任何函數或塊, 518 00:31:36,000 --> 00:31:39,000 和這些將在你的程序中的任何地方訪問。 519 00:31:39,000 --> 00:31:41,000 如果你有一個函數,在該函數中是一個while循環 520 00:31:41,000 --> 00:31:44,000 大的全局變量的訪問無處不在。 521 00:31:44,000 --> 00:31:48,000 ,另一方面,是一個局部變量的作用域的地方,它被定義。 522 00:31:48,000 --> 00:31:53,000 >> 如果你有一個函數,例如,我們有這個函數g, 523 00:31:53,000 --> 00:31:56,000 和內部的g是一個變量,在這裡稱為y, 524 00:31:56,000 --> 00:31:58,000 這意味著,這是一個局部變量。 525 00:31:58,000 --> 00:32:00,000 即使這個變量被稱為y 526 00:32:00,000 --> 00:32:03,000 這個變量是所謂的Y這兩個函數 527 00:32:03,000 --> 00:32:06,000 不知道對方的局部變量。 528 00:32:06,000 --> 00:32:10,000 另一方面,在這裡,我們說X = 5, 529 00:32:10,000 --> 00:32:12,000 這範圍以外的任何函數。 530 00:32:12,000 --> 00:32:16,000 它的主要範圍以外的,所以這是一個全局變量。 531 00:32:16,000 --> 00:32:20,000 這意味著,這些功能裡面,當我說X - 或x + + 532 00:32:20,000 --> 00:32:26,000 我訪問相同的x,,這y和這家Y是不同的變量。 533 00:32:26,000 --> 00:32:30,000 這是一個全局變量和局部變量之間的差異。 534 00:32:30,000 --> 00:32:33,000 就設計而言,有時,它可能是一個更好的主意 535 00:32:33,000 --> 00:32:37,000 保持局部變量時,你可能可以 536 00:32:37,000 --> 00:32:39,000 因為有一堆全局變量可以得到真正的混亂。 537 00:32:39,000 --> 00:32:42,000 如果你有一堆的功能,所有的修改同樣的事情, 538 00:32:42,000 --> 00:32:45,000 你可能會忘記此功能,如果不慎修改, 539 00:32:45,000 --> 00:32:47,000 這功能不知道這一點, 540 00:32:47,000 --> 00:32:50,000 它變得相當混亂,因為你得到更多的代碼。 541 00:32:50,000 --> 00:32:53,000 保持局部變量時,你可能可以 542 00:32:53,000 --> 00:32:56,000 是剛剛好的設計。 543 00:32:56,000 --> 00:33:00,000 陣列,請記住,僅僅是同一類型的元素的列表。 544 00:33:00,000 --> 00:33:04,000 裡面的CI不能有一個列表,如1,2.0,你好。 545 00:33:04,000 --> 00:33:06,000 我們不能做到這一點。 546 00:33:06,000 --> 00:33:11,000 >> 當在C我們聲明一個數組的所有元素必須是相同的類型。 547 00:33:11,000 --> 00:33:14,000 在這裡,我有3個整數的數組。 548 00:33:14,000 --> 00:33:18,000 在這裡,我有數組的長度,但如果我只是在此語法聲明 549 00:33:18,000 --> 00:33:21,000 我指定所有的元素都是我並沒有從技術上需要這個3。 550 00:33:21,000 --> 00:33:25,000 編譯器足夠聰明,找出數組應為多大。 551 00:33:25,000 --> 00:33:28,000 現在,當我想獲取或設置一個數組的值 552 00:33:28,000 --> 00:33:30,000 這是的語法來做到這一點。 553 00:33:30,000 --> 00:33:33,000 這實際上修改的第二個元素的數組,因為記得, 554 00:33:33,000 --> 00:33:36,000 編號從0開始,而不是1。 555 00:33:36,000 --> 00:33:42,000 如果我想讀取該值,我可以這樣說X =數組[1]。 556 00:33:42,000 --> 00:33:44,000 或者,如果我想設置該值,如我在這裡做什麼, 557 00:33:44,000 --> 00:33:47,000 我可以說,數組[1] = 4。 558 00:33:47,000 --> 00:33:50,000 這通過其索引訪問元素 559 00:33:50,000 --> 00:33:52,000 或他們的位置,他們是在數組中, 560 00:33:52,000 --> 00:33:57,000 從0開始,上市。 561 00:33:57,000 --> 00:34:00,000 我們也可以有數組的數組 562 00:34:00,000 --> 00:34:03,000 這就是所謂的多維數組。 563 00:34:03,000 --> 00:34:05,000 當我們有一個多維數組 564 00:34:05,000 --> 00:34:07,000 這意味著我們可以有類似的行和列, 565 00:34:07,000 --> 00:34:11,000 而這僅僅是一個可視化的思考方式。 566 00:34:11,000 --> 00:34:14,000 當我有一個多維數組,這意味著我要開始需要 567 00:34:14,000 --> 00:34:17,000 超過1指數,因為如果我有一個網格 568 00:34:17,000 --> 00:34:19,000 只是說你在哪個行並沒有給我們一個數字。 569 00:34:19,000 --> 00:34:22,000 這真的只是給我們一個數字列表。 570 00:34:22,000 --> 00:34:25,000 比方說,我有這樣的陣列。 571 00:34:25,000 --> 00:34:30,000 我有一個數組稱為網格,和我說這是2行3列, 572 00:34:30,000 --> 00:34:32,000 所以這是一個可視化的方式。 573 00:34:32,000 --> 00:34:37,000 當我說我想要得到的元素[1] [2] 574 00:34:37,000 --> 00:34:41,000 這意味著,因為這些行的第一和然後列 575 00:34:41,000 --> 00:34:44,000 我要跳轉到第1行,因為我說了一句。 576 00:34:44,000 --> 00:34:49,000 >> 然後我到這裡來,到第2列,我要得到的值是6。 577 00:34:49,000 --> 00:34:51,000 有意義嗎? 578 00:34:51,000 --> 00:34:55,000 多維數組,請記住,在技術上是一個數組的數組。 579 00:34:55,000 --> 00:34:57,000 我們可以有數組的數組的數組。 580 00:34:57,000 --> 00:35:00,000 我們可以繼續下去,但一個真正的方式來思考 581 00:35:00,000 --> 00:35:03,000 這是怎麼被解僱,這是怎麼回事,是形象化 582 00:35:03,000 --> 00:35:09,000 在這樣的一個網格。 583 00:35:09,000 --> 00:35:12,000 當我們通過陣列的功能,他們會表現 584 00:35:12,000 --> 00:35:16,000 當我們通過定期的變量功能有點不同 585 00:35:16,000 --> 00:35:18,000 像傳遞一個int或float。 586 00:35:18,000 --> 00:35:21,000 當我們傳遞了一個int或char或任何其他數據類型 587 00:35:21,000 --> 00:35:24,000 我們剛接過來一看,如果修改 588 00:35:24,000 --> 00:35:28,000 該變量的值的變化不會傳播 589 00:35:28,000 --> 00:35:32,000 到調用函數。 590 00:35:32,000 --> 00:35:35,000 有了一個數組,在另一方面,這將發生。 591 00:35:35,000 --> 00:35:39,000 如果我通過在陣列中的一些功能,該功能改變的一些內容, 592 00:35:39,000 --> 00:35:43,000 我回來的時候調用它的函數 593 00:35:43,000 --> 00:35:47,000 我的數組是不同的,為的詞彙 594 00:35:47,000 --> 00:35:50,000 是數組是通過引用傳遞,我們將在後​​面看到。 595 00:35:50,000 --> 00:35:53,000 這是關係到如何指針的工作,而這些基本數據類型, 596 00:35:53,000 --> 00:35:55,000 另一方面,通過值傳遞。 597 00:35:55,000 --> 00:35:59,000 >> 我們可以認為那是一些變量的副本,然後通過在副本中。 598 00:35:59,000 --> 00:36:01,000 不要緊,我們做什麼與該變量。 599 00:36:01,000 --> 00:36:06,000 調用函數將不知道它被改變了。 600 00:36:06,000 --> 00:36:10,000 數組是在這方面,不同的只是一點點。 601 00:36:10,000 --> 00:36:13,000 例如,正如我們剛才看到的,主要是簡單的功能 602 00:36:13,000 --> 00:36:15,000 可以在兩個參數。 603 00:36:15,000 --> 00:36:20,000 第一個參數的主要功能是ARGC,或參數的個數, 604 00:36:20,000 --> 00:36:23,000 第二個參數被稱為ARGV, 605 00:36:23,000 --> 00:36:27,000 這些參數的實際值。 606 00:36:27,000 --> 00:36:30,000 比方說,我有一個程序叫this.c, 607 00:36:30,000 --> 00:36:34,000 和我說這一點,我要在命令行中運行此。 608 00:36:34,000 --> 00:36:38,000 現在在某些參數傳遞到我的計劃,稱這 609 00:36:38,000 --> 00:36:42,000 我可以這樣說,/這是CS 50。 610 00:36:42,000 --> 00:36:45,000 這是我們想像的大衛每天都在做終端。 611 00:36:45,000 --> 00:36:48,000 但是,現在該程序的主函數內的 612 00:36:48,000 --> 00:36:52,000 這些值,因此argc是4。 613 00:36:52,000 --> 00:36:56,000 這可能是有點混亂,因為我們真的只有通過在CS 50。 614 00:36:56,000 --> 00:36:58,000 這是只有3個。 615 00:36:58,000 --> 00:37:02,000 但請記住,第一個元素的argv的第一個參數 616 00:37:02,000 --> 00:37:05,000 是函數本身的名稱。 617 00:37:05,000 --> 00:37:07,190 因此,這意味著我們有4個東西在這裡, 618 00:37:07,190 --> 00:37:10,530 及第一要素將是/這。 619 00:37:10,530 --> 00:37:12,970 這將被表示為一個字符串。 620 00:37:12,970 --> 00:37:18,590 那麼剩下的元素是我們的程序名後鍵入。 621 00:37:18,590 --> 00:37:22,720 因此,正如順便說一句,因為我們在pset中2中所看到的, 622 00:37:22,720 --> 00:37:28,780 記住該字符串50≠50的整數。 623 00:37:28,780 --> 00:37:32,520 因此,我們不能說些什麼,“X = ARGV 3。 624 00:37:32,520 --> 00:37:36,470 >> 這只是不會是有道理的,因為這是一個字符串,這是一個整數。 625 00:37:36,470 --> 00:37:38,510 所以,如果你要轉換之間的2,請記住,我們要 626 00:37:38,510 --> 00:37:40,810 有這種神奇的功能,稱為ATOI。 627 00:37:40,810 --> 00:37:46,270 這需要一個字符串並返回該字符串表示的整數內。 628 00:37:46,270 --> 00:37:48,360 所以這是一個容易犯的錯誤的測驗, 629 00:37:48,360 --> 00:37:51,590 只是在想,這會自動將正確的類型。 630 00:37:51,590 --> 00:37:53,860 但我們知道,這將永遠是字符串 631 00:37:53,860 --> 00:38:00,920 即使只包含字符串的整數或一個字符或一個浮子。 632 00:38:00,920 --> 00:38:03,380 所以,現在讓我們來談談運行時間。 633 00:38:03,380 --> 00:38:06,700 當我們做這些瘋狂的事情,所有這些算法, 634 00:38:06,700 --> 00:38:11,580 它變得非常有用的,要問的問題,“他們需要多長時間?” 635 00:38:11,580 --> 00:38:15,500 我們表示,所謂的漸近符號。 636 00:38:15,500 --> 00:38:18,430 因此,這意味著 - 好,讓我們說,我們給我們的算法 637 00:38:18,430 --> 00:38:20,840 一些真的,真的,真的很大的投入。 638 00:38:20,840 --> 00:38:23,840 我們要問的問題,“如何是將要採取的嗎? 639 00:38:23,840 --> 00:38:26,370 多少個步驟將需要運行我們的算法 640 00:38:26,370 --> 00:38:29,980 作為輸入的函數的大小?“ 641 00:38:29,980 --> 00:38:33,080 因此,第一種方式我們可以形容運行時間是大澳 642 00:38:33,080 --> 00:38:35,380 這是我們的最壞情況下的運行時間。 643 00:38:35,380 --> 00:38:38,590 因此,如果我們要對數組進行排序,我們給我們的算法的一個數組 644 00:38:38,590 --> 00:38:41,000 時,應在升序降序排列, 645 00:38:41,000 --> 00:38:43,130 那將是最壞的情況。 646 00:38:43,130 --> 00:38:49,800 這是我們的最大長度的時間,我們的算法將採取的上限。 647 00:38:49,800 --> 00:38:54,740 在另一方面,本Ω是要描述的最佳情況下的運行時間。 648 00:38:54,740 --> 00:38:58,210 因此,如果我們給一個已排序的數組排序算法, 649 00:38:58,210 --> 00:39:00,940 排序需要多長時間? 650 00:39:00,940 --> 00:39:06,610 而這一點,然後,描述了一個運行時間的上下限。 651 00:39:06,610 --> 00:39:10,980 因此,這裡有一些話,介紹一些常見的運行時間。 652 00:39:10,980 --> 00:39:13,120 這些是按升序排列。 653 00:39:13,120 --> 00:39:16,060 我們有最快的運行時間不變。 654 00:39:16,060 --> 00:39:19,800 >> 這意味著,無論有多少個元素,我們給我們的算法, 655 00:39:19,800 --> 00:39:22,280 不管有多大,我們的陣列,整理 656 00:39:22,280 --> 00:39:26,510 或做我們正在做的陣列將始終以相同的時間。 657 00:39:26,510 --> 00:39:30,270 因此,我們可以表示,只需用1,這是一個常數。 658 00:39:30,270 --> 00:39:32,410 我們也期待在數運行時間。 659 00:39:32,410 --> 00:39:34,800 因此,類似二進制搜索是對數, 660 00:39:34,800 --> 00:39:37,140 我們削減了問題的一半,每次 661 00:39:37,140 --> 00:39:40,970 然後事情就從那裡獲得更高的。 662 00:39:40,970 --> 00:39:43,580 如果你正在編寫一個O任何階乘的算法, 663 00:39:43,580 --> 00:39:47,850 你可能不應該認為這是你的日常工作​​。 664 00:39:47,850 --> 00:39:53,910 當我們比較的運行時間,重要的是要記住這些東西。 665 00:39:53,910 --> 00:39:57,760 所以,如果我有一個算法是O(N),而其他人 666 00:39:57,760 --> 00:40:03,590 有一個度為O(2n)的算法,這其實是漸近等價。 667 00:40:03,590 --> 00:40:06,590 因此,如果我們想像Ň像一百十億元是一個很大的數字: 668 00:40:06,590 --> 00:40:13,090 所以,當我們比較一百十億元的東西像一百十億元+ 3, 669 00:40:13,090 --> 00:40:17,640 突然,3並沒有真正使一個很大的區別了。 670 00:40:17,640 --> 00:40:20,980 這就是為什麼我們要開始考慮這些事情是相等的。 671 00:40:20,980 --> 00:40:24,220 因此,這些常量在這裡的事情,比如,有這2個,或加入3, 672 00:40:24,220 --> 00:40:27,180 這些僅僅是常數,而這些會下降。 673 00:40:27,180 --> 00:40:32,480 所以這就是為什麼這些運行時間是相同的,說他們是O(n)的所有3。 674 00:40:32,480 --> 00:40:37,490 同樣,如果我們有2個運行時間,比方說為O(n 3 + 2N²),我們可以添加 675 00:40:37,490 --> 00:40:42,070 + N,+ 7,然後我們有另一種運行時,只是Ø(N³)。 676 00:40:42,070 --> 00:40:46,290 再次,這些是相同的東西,因為這些 - 這些是不一樣的。 677 00:40:46,290 --> 00:40:49,840 這是同樣的事情,對不起。因此,這些都是一樣的,因為 678 00:40:49,840 --> 00:40:53,090 這n³將主宰這個2N²。 679 00:40:53,090 --> 00:40:59,130 >> 什麼是不一樣的事情是,如果我們的運行時間,如O(N³)和O(N 2) 680 00:40:59,130 --> 00:41:02,820 因為這n³是遠遠大於這n 2。 681 00:41:02,820 --> 00:41:05,470 因此,如果我們的指數,突然開始啦, 682 00:41:05,470 --> 00:41:08,280 但是,當我們只是處理因素,因為我們是在這裡, 683 00:41:08,280 --> 00:41:12,810 那麼它不會的問題,因為他們只是要輟學。 684 00:41:12,810 --> 00:41:16,760 讓我們來看看到目前為止,我們已經看到的一些算法 685 00:41:16,760 --> 00:41:19,260 並談談它們的運行時間。 686 00:41:19,260 --> 00:41:23,850 第一種方法尋找一些在列表中,我們所看到的,是線性搜索。 687 00:41:23,850 --> 00:41:26,950 而實施的是超級簡單的線性搜索。 688 00:41:26,950 --> 00:41:30,490 我們只是有一個列表,我們要看看在列表中的每一個元素 689 00:41:30,490 --> 00:41:34,260 直到我們找到的數量,我們要尋找的。 690 00:41:34,260 --> 00:41:38,370 因此,這意味著,在最壞的情況下,這為O(n)。 691 00:41:38,370 --> 00:41:40,860 和這裡,最壞的情況下可能是,如果該元素是 692 00:41:40,860 --> 00:41:45,710 最後一個元素,然後使用線性搜索,我們來看看在每一個元素 693 00:41:45,710 --> 00:41:50,180 直到我們得到的最後一個知道,它實際上是在列表中。 694 00:41:50,180 --> 00:41:52,910 我們不能就這樣放棄半說,“這是可能不存在。” 695 00:41:52,910 --> 00:41:55,980 我們來看看整個事情的線性搜索。 696 00:41:55,980 --> 00:41:59,090 最好情況下的運行時間,在另一方面,是恆定的 697 00:41:59,090 --> 00:42:04,200 因為在最好的情況下,我們要尋找的元素是列表中的第一個。 698 00:42:04,200 --> 00:42:08,930 所以,我們要花費1步,不管有多大的列表 699 00:42:08,930 --> 00:42:12,140 如果我們要找的第一個元素,每一次。 700 00:42:12,140 --> 00:42:15,390 >> 因此,當您搜索時,請記住,它不要求我們的列表進行排序。 701 00:42:15,390 --> 00:42:19,430 因為我們只是去看看,每一個元素,它其實並不重要 702 00:42:19,430 --> 00:42:23,560 什麼樣的順序,這些元素所在 703 00:42:23,560 --> 00:42:28,110 一個更聰明的搜索算法是類似二進制搜索。 704 00:42:28,110 --> 00:42:31,500 記住,是當你要執行的二進制搜索 705 00:42:31,500 --> 00:42:34,320 在中間的列表中繼續尋找。 706 00:42:34,320 --> 00:42:38,000 因為我們正在尋找的中間,我們需要對列表進行排序 707 00:42:38,000 --> 00:42:40,580 否則,我們不知道在哪裡,中間是,我們來看看以上 708 00:42:40,580 --> 00:42:44,480 整個列表中找到它,然後在這一點上,我們只是在浪費時間。 709 00:42:44,480 --> 00:42:48,480 因此,如果我們有一個排序的列表中,我們發現中間,我們要比較的中間 710 00:42:48,480 --> 00:42:51,590 的元素,我們要尋找的。 711 00:42:51,590 --> 00:42:54,640 如果是太高,那麼我們就可以忘記的右半邊 712 00:42:54,640 --> 00:42:57,810 因為我們知道,如果我們的元素已經過高 713 00:42:57,810 --> 00:43:01,080 和一切該元素的權利甚至更高, 714 00:43:01,080 --> 00:43:02,760 那麼我們就需要看看那裡了。 715 00:43:02,760 --> 00:43:05,430 凡在另一方面,如果我們的元素是太低, 716 00:43:05,430 --> 00:43:08,700 我們知道一切該元素的左側還太低, 717 00:43:08,700 --> 00:43:11,390 所以它不是真正意義,看看有,。 718 00:43:11,390 --> 00:43:15,760 通過這種方式,每一步,每一次我們看的列表中點, 719 00:43:15,760 --> 00:43:19,060 我們要削減一半,因為我們的問題,我們突然知道 720 00:43:19,060 --> 00:43:23,040 一大堆的數字,不能是一個我們要找的。 721 00:43:23,040 --> 00:43:26,950 >> 在偽代碼,這將是這個樣子, 722 00:43:26,950 --> 00:43:30,990 而且,因為我們切割的列表中每一次的一半, 723 00:43:30,990 --> 00:43:34,920 我們的最壞情況下的運行時間從線性到對數的跳躍。 724 00:43:34,920 --> 00:43:39,260 因此,我們突然有記錄的步驟,以便找到列表中的元素。 725 00:43:39,260 --> 00:43:42,460 最好的情況下的運行時間,不過,仍然是不變的 726 00:43:42,460 --> 00:43:45,180 因為現在,讓我們只想說,我們正在尋找的元素是 727 00:43:45,180 --> 00:43:48,380 原始列表總是精確中間。 728 00:43:48,380 --> 00:43:52,080 因此,我們可以成長為大,因為我們希望我們的名單,但如果我們要尋找的是在中間元素, 729 00:43:52,080 --> 00:43:54,910 那麼我們要花費1步。 730 00:43:54,910 --> 00:44:00,920 所以這就是為什麼我們是O(log n)的Ω(1)或恆定。 731 00:44:00,920 --> 00:44:04,510 讓我們實際運行在此列表中的二進制搜索。 732 00:44:04,510 --> 00:44:08,020 因此,讓我們說,我們正在尋找的元素164。 733 00:44:08,020 --> 00:44:11,650 我們要做的第一件事是找到這個列表的中點。 734 00:44:11,650 --> 00:44:15,060 它只是發生的中點是要倒在這兩個數字之間, 735 00:44:15,060 --> 00:44:18,960 所以我們就武斷地說,每次2號的中點之間, 736 00:44:18,960 --> 00:44:21,150 讓我們圓了。 737 00:44:21,150 --> 00:44:24,330 我們只需要確保我們這樣做的每一個步驟的方式。 738 00:44:24,330 --> 00:44:29,040 因此,我們要圓了,和我們說,161是我們的名單中。 739 00:44:29,040 --> 00:44:34,640 因此,161 <164,和161的每一個元素的左側 740 00:44:34,640 --> 00:44:39,120 <164,所以我們不知道它會幫助我們在所有 741 00:44:39,120 --> 00:44:42,690 開始尋找的元素,因為在這裡我們不能有。 742 00:44:42,690 --> 00:44:47,060 所以,我們可以做的是,我們只是忘了,整個左半邊的列表, 743 00:44:47,060 --> 00:44:51,700 現在只考慮從右邊的161起。 744 00:44:51,700 --> 00:44:54,050 >> 所以,再一次,這是中點;讓我們圓了。 745 00:44:54,050 --> 00:44:56,260 現在175是太大了。 746 00:44:56,260 --> 00:44:59,180 因此,我們知道它不會幫助我們期待在這裡或在這裡, 747 00:44:59,180 --> 00:45:06,610 因此,我們就可以扔一邊去,和我們最終會達到了164個。 748 00:45:06,610 --> 00:45:10,560 二進制搜索的任何問題? 749 00:45:10,560 --> 00:45:14,180 讓我們從搜索通過一個已經排序的列表 750 00:45:14,180 --> 00:45:17,660 實際以任何順序的號碼列表 751 00:45:17,660 --> 00:45:20,960 該列表以升序排列。 752 00:45:20,960 --> 00:45:24,060 我們看到在第一種算法被稱為冒泡排序。 753 00:45:24,060 --> 00:45:27,300 這將是比較簡單的,我們看到的算法。 754 00:45:27,300 --> 00:45:32,970 冒泡排序法說,當任意2個元素列表內的地方, 755 00:45:32,970 --> 00:45:36,500 這意味著有一個更高的編號,以左側的一個較小的數字, 756 00:45:36,500 --> 00:45:40,190 然後,我們將交換他們,因為這意味著,該清單將是 757 00:45:40,190 --> 00:45:42,860 “更多排序”比以前。 758 00:45:42,860 --> 00:45:45,180 我們只是打算再繼續這個過程中,一次又一次地 759 00:45:45,180 --> 00:45:52,100 直到最後元素的的種泡到正確的位置,我們有一個排序的列表。 760 00:45:52,100 --> 00:45:57,230 >> 這是怎麼回事運行時間為O(N²)。為什麼呢? 761 00:45:57,230 --> 00:46:00,370 好了,因為在最壞的情況下,我們採取的每一個元素,並 762 00:46:00,370 --> 00:46:04,570 我們要結束了列表中的所有其他元素進行比較。 763 00:46:04,570 --> 00:46:08,030 但是,在最好的情況下,我們有一個已排序的列表中,冒泡排序 764 00:46:08,030 --> 00:46:12,230 只通過一次去,說:“不,我沒有做任何掉期,所以我所做的一切。” 765 00:46:12,230 --> 00:46:17,410 因此,我們有最好的情況Ω(n)的運行時間。 766 00:46:17,410 --> 00:46:20,680 讓我們來運行冒泡排序的列表。 767 00:46:20,680 --> 00:46:23,560 首先,讓我們看一些偽真的很快。 768 00:46:23,560 --> 00:46:28,160 我們想說,我們要跟踪的,在每一次迭代的循環, 769 00:46:28,160 --> 00:46:32,190 我們是否改變任何元素的跟踪。 770 00:46:32,190 --> 00:46:37,610 如此的原因是,我們要停下來的時候,我們沒有交換任何元素。 771 00:46:37,610 --> 00:46:41,980 因此,在我們的循環的開始,我們還沒有交換任何東西,所以我們會說這是假的。 772 00:46:41,980 --> 00:46:47,170 現在,我們要去列表,並比較i個元素的元素i + 1 773 00:46:47,170 --> 00:46:50,310 如果是的情況下,有一個更大的編號,以左側的一個較小的數字, 774 00:46:50,310 --> 00:46:52,310 然後,我們只是來交換他們。 775 00:46:52,310 --> 00:46:54,490 >> 然後,我們要記住,我們交換元素。 776 00:46:54,490 --> 00:46:58,900 這意味著,我們需要在列表中至少1個或更多的時間去 777 00:46:58,900 --> 00:47:02,160 因為我們停止的條件,其中已排序的整個列表時, 778 00:47:02,160 --> 00:47:04,890 這意味著我們還沒有作出任何掉期。 779 00:47:04,890 --> 00:47:09,960 所以這就是為什麼我們的條件,在這裡是“,而一些元素已被調換。 780 00:47:09,960 --> 00:47:13,720 所以,現在就讓我們看一看在此名單上的運行。 781 00:47:13,720 --> 00:47:16,640 我的名單5,0,1,6,4。 782 00:47:16,640 --> 00:47:19,850 要開始冒泡排序的方式在左側,和它的比較 783 00:47:19,850 --> 00:47:24,700 的第i個元素,所以0到i + 1,它是元件1。 784 00:47:24,700 --> 00:47:29,020 它說,5> 0,但現在是向左, 785 00:47:29,020 --> 00:47:32,500 所以我需要換5和0。 786 00:47:32,500 --> 00:47:35,470 當我換,我突然得到這個不同的列表。 787 00:47:35,470 --> 00:47:38,260 5> 1,所以我們要來交換他們。 788 00:47:38,260 --> 00:47:42,160 5是6,所以我們不需要在這裡做任何事情。 789 00:47:42,160 --> 00:47:46,690 但6> 4,所以我們需要交換。 790 00:47:46,690 --> 00:47:49,740 同樣,我們需要貫穿整個名單,最終發現 791 00:47:49,740 --> 00:47:52,330 這些是為了,我們交換, 792 00:47:52,330 --> 00:47:57,120 在這一點上,我們需要更多的時間運行在列表中 793 00:47:57,120 --> 00:48:05,390 以確保一切都在它的順序,並在這一點上冒泡排序已經完成。 794 00:48:05,390 --> 00:48:10,720 採取一些元素,不同的算法和排序,選擇排序。 795 00:48:10,720 --> 00:48:15,740 選擇排序背後的想法是,我們要建立一個排序的列表部分 796 00:48:15,740 --> 00:48:18,150 在一個時間的1個元素。 797 00:48:18,150 --> 00:48:23,170 >> 而要做到這一點的方式,我們是通過建立列表中的左部。 798 00:48:23,170 --> 00:48:27,510 基本上,每 - 每一步,我們將要採取的最小元素,我們已經離開 799 00:48:27,510 --> 00:48:32,310 尚未排序,我們將它移動到該排序段。 800 00:48:32,310 --> 00:48:35,850 這意味著我們需要不斷發現的最小的未分類的元素 801 00:48:35,850 --> 00:48:40,720 然後,最小的元素交換的任何一種 802 00:48:40,720 --> 00:48:45,090 最左邊的元素進行排序。 803 00:48:45,090 --> 00:48:50,890 運行時間為O(N 2),因為在最壞的情況下 804 00:48:50,890 --> 00:48:55,070 我們需要比較每一個元素的所有其他元素。 805 00:48:55,070 --> 00:48:59,250 因為我們說,如果我們在左半邊的列表,我們需要 806 00:48:59,250 --> 00:49:02,970 整個右段去尋找最小的元素。 807 00:49:02,970 --> 00:49:05,430 然後,再次,我們需要去整個右段和 808 00:49:05,430 --> 00:49:08,210 繼續一遍又一遍,再次。 809 00:49:08,210 --> 00:49:11,350 這為n²。我們將需要一個for循環內的另一個循環 810 00:49:11,350 --> 00:49:13,350 這表明N²。 811 00:49:13,350 --> 00:49:16,530 在最好的情況下思想,讓我們說,我們給它一個已排序的列表; 812 00:49:16,530 --> 00:49:19,270 我們其實並不比n²做的更好。 813 00:49:19,270 --> 00:49:21,730 由於選擇排序有沒有辦法知道 814 00:49:21,730 --> 00:49:25,540 最小的元素只是我正好要尋找的。 815 00:49:25,540 --> 00:49:28,970 它仍然需要確保,這實際上是最低的。 816 00:49:28,970 --> 00:49:31,670 >> 只有這樣,才能確保它的最低限度,使用這種算法, 817 00:49:31,670 --> 00:49:34,640 再看看每一個元素。 818 00:49:34,640 --> 00:49:38,420 所以,真的,如果你給它 - 如果你給一個已排序的列表中選擇排序, 819 00:49:38,420 --> 00:49:42,720 它不會做任何比給它一個列表,該列表還沒有排序。 820 00:49:42,720 --> 00:49:46,320 順便說一下,如果真的發生的情況下,有什麼是O(的東西) 821 00:49:46,320 --> 00:49:50,640 及的歐米茄的東西,我們只是說,它是θ的東西更簡潔。 822 00:49:50,640 --> 00:49:52,760 所以,如果你看到在任何地方,這是什麼,僅僅表示。 823 00:49:52,760 --> 00:49:57,580 >> 如果事情是THETA的n²,它既是大O(N 2)和Ω(N ​​2)。 824 00:49:57,580 --> 00:49:59,790 因此,最好的情況和最壞的情況下,它不會有所作為, 825 00:49:59,790 --> 00:50:04,400 該算法是每次都做同樣的事情。 826 00:50:04,400 --> 00:50:06,610 因此,這是選擇排序的偽代碼可能看起來像。 827 00:50:06,610 --> 00:50:10,630 基本上,我們會說,我想遍歷列表 828 00:50:10,630 --> 00:50:15,180 由左到右,並在每個迭代循環,我要移動 829 00:50:15,180 --> 00:50:19,780 到這部分的列表中最小的元素。 830 00:50:19,780 --> 00:50:23,260 有一次我移動的東西,我從來沒有需要再看看該元素。 831 00:50:23,260 --> 00:50:28,600 因為只要我換的左部的列表中的一個元素,它的排序 832 00:50:28,600 --> 00:50:32,600 因為我們正在做的一切都在按升序排列使用最小值。 833 00:50:32,600 --> 00:50:38,740 所以我們說,好了,我們在i位置上,我們需要的所有元素 834 00:50:38,740 --> 00:50:42,260 i的右邊的,以便找到最低。 835 00:50:42,260 --> 00:50:46,150 因此,這意味著,我們想看看從i + 1到列​​表末尾。 836 00:50:46,150 --> 00:50:51,610 而現在,如果我們目前正在觀察的元素是低於我們的最低到目前為止, 837 00:50:51,610 --> 00:50:54,190 請記得,我們​​開始只是最小關斷 838 00:50:54,190 --> 00:50:57,020 任何元素,我們目前在我假設這是最低的。 839 00:50:57,020 --> 00:51:00,270 如果我找到比這更小的元素,然後我會說,好吧, 840 00:51:00,270 --> 00:51:02,700 好了,我已經找到了新的最低。 841 00:51:02,700 --> 00:51:06,080 我要記住,最低為。 842 00:51:06,080 --> 00:51:09,560 >> 所以,現在,我已經經歷了一次該權利未分類的分類, 843 00:51:09,560 --> 00:51:16,690 我可以說,我要交換的最小元素的位置i的元素是。 844 00:51:16,690 --> 00:51:21,100 這是要建立我的清單,我的排序部分,由左到右的名單, 845 00:51:21,100 --> 00:51:25,190 我們永遠不需要看一個元素,再一次在該部分。 846 00:51:25,190 --> 00:51:27,930 一旦我們交換了。 847 00:51:27,930 --> 00:51:30,260 因此,讓我們在此列表中選擇排序的運行。 848 00:51:30,260 --> 00:51:38,220 這裡的藍色元件將是在i,和紅色的元件將是最小元素。 849 00:51:38,220 --> 00:51:41,570 所以,我開始一路在左側的列表,所以在5。 850 00:51:41,570 --> 00:51:44,610 現在,我們需要找到最小的未分類的元素。 851 00:51:44,610 --> 00:51:49,480 所以我們說0,所以0是我的新的最低。 852 00:51:49,480 --> 00:51:53,820 >> 但我不能停止,因為即使我們能夠識別出0是最小的, 853 00:51:53,820 --> 00:51:59,390 我們需要運行通過列表以確保所有其它元素。 854 00:51:59,390 --> 00:52:01,760 因此,1是更大的,6是更大的,是更大的。 855 00:52:01,760 --> 00:52:05,850 這意味著,在所有這些元素後,我已經決定0是最小的。 856 00:52:05,850 --> 00:52:09,800 所以,我要交換5和0。 857 00:52:09,800 --> 00:52:15,480 一旦我換,我會得到一個新的列表,我知道,我從來沒有需要再次看,0 858 00:52:15,480 --> 00:52:19,380 因為一旦我交換吧,我已經整理它,我們就大功告成了。 859 00:52:19,380 --> 00:52:22,730 現在,碰巧的是​​,藍色的元素又是5, 860 00:52:22,730 --> 00:52:26,030 我們需要在1%,6和4,確定1 861 00:52:26,030 --> 00:52:31,520 是最小最小的元素,所以我們交換1和5。 862 00:52:31,520 --> 00:52:36,890 同樣,我們需要看看 - 比較5〜6和4, 863 00:52:36,890 --> 00:52:39,830 我們交換4和5,最後,比較 864 00:52:39,830 --> 00:52:45,740 這2個數字,並交換它們,直到我們得到我們的排序列表。 865 00:52:45,740 --> 00:52:49,730 選擇排序的任何問題嗎? 866 00:52:49,730 --> 00:52:56,420 好吧。讓我們繼續上次的話題,那就是遞歸。 867 00:52:56,420 --> 00:52:59,810 >> 遞歸,請記住,這是真的薈萃東西的功能 868 00:52:59,810 --> 00:53:02,740 反复調用自身。 869 00:53:02,740 --> 00:53:05,620 因此,在某些時候,而我們的機能的反复調用本身, 870 00:53:05,620 --> 00:53:10,100 需要有一些點,我們不再稱自己。 871 00:53:10,100 --> 00:53:13,670 因為如果我們不這樣做,那麼我們只是要繼續這樣下去,永遠, 872 00:53:13,670 --> 00:53:16,660 我們的計劃是不會終止。 873 00:53:16,660 --> 00:53:19,200 我們將這種情況的基本情況。 874 00:53:19,200 --> 00:53:22,570 說,而不是再次調用一個函數的基本情況, 875 00:53:22,570 --> 00:53:25,330 我只是返回一些值。 876 00:53:25,330 --> 00:53:28,080 因此,一旦我們返回一個值,我們稱自己已經停止了, 877 00:53:28,080 --> 00:53:32,550 至今,我們已經取得了其餘的電話也可以返回。 878 00:53:32,550 --> 00:53:36,050 的鹼情況下,與此相反的是遞歸的情況下。 879 00:53:36,050 --> 00:53:39,050 這是當我們想要撥打另一個電話的功能,我們目前所處的 880 00:53:39,050 --> 00:53:44,690 雖然並非始終如此,我們可能要使用不同的參數。 881 00:53:44,690 --> 00:53:48,940 >> 所以,如果我們有一個稱為F的函數,且f稱為1個參數, 882 00:53:48,940 --> 00:53:52,010 ,我們只是調用f(1),F(1),F(1),和它碰巧的是, 883 00:53:52,010 --> 00:53:56,510 參數1分為遞歸的情況下,我們仍然永遠不會停止。 884 00:53:56,510 --> 00:54:01,620 即使我們有一個基礎的情況下,我們需要確保,最終我們要達到這一基本情況。 885 00:54:01,620 --> 00:54:04,250 我們不只是保持在這個遞歸的情況下。 886 00:54:04,250 --> 00:54:09,870 通常情況下,當我們調用自己的時候,我們可能有不同的觀點。 887 00:54:09,870 --> 00:54:12,700 這是一個非常簡單的遞歸函數。 888 00:54:12,700 --> 00:54:15,090 因此,這將計算出一個數的階乘。 889 00:54:15,090 --> 00:54:17,790 在這裡往上頂,我們有我們的基本情況。 890 00:54:17,790 --> 00:54:22,330 的情況下,N≤1,我們不會再次打電話因子。 891 00:54:22,330 --> 00:54:26,490 我們要停止,我們只是將返回一定的價值。 892 00:54:26,490 --> 00:54:30,170 如果這是不正確的,那麼我們要達到我們的遞歸的情況。 893 00:54:30,170 --> 00:54:33,550 請注意,在這裡,我們不只是調用的階乘(N),因為那將是非常有用的。 894 00:54:33,550 --> 00:54:36,810 我們會打電話給別的東西的階乘。 895 00:54:36,810 --> 00:54:40,850 >> 所以你可以看到,最終,如果我們通過一個階乘(5)的東西, 896 00:54:40,850 --> 00:54:45,900 我們要調用階乘(4)等,最終我們要達到這一基本情況。 897 00:54:45,900 --> 00:54:51,730 因此,這看起來不錯。讓我們看看會發生什麼,當我們真正運行這個。 898 00:54:51,730 --> 00:54:57,840 這是堆棧,讓我們說,主要是要調用這個函數的參數(4)。 899 00:54:57,840 --> 00:55:02,200 因此,一旦的階乘看到和= 4,階乘將調用本身。 900 00:55:02,200 --> 00:55:05,010 現在,突然之間,我們的階乘(3)。 901 00:55:05,010 --> 00:55:10,780 因此,這些功能都將繼續保持增長,直到最終,我們打我們的基本情況。 902 00:55:10,780 --> 00:55:17,830 在這一點上,這是,則返回值返回(nx的的返回值), 903 00:55:17,830 --> 00:55:21,290 的返回值,這是NX的返回值。 904 00:55:21,290 --> 00:55:23,290 最後,我們需要打一些數字。 905 00:55:23,290 --> 00:55:26,560 我們在上方在這裡,說返回1。 906 00:55:26,560 --> 00:55:30,650 這意味著,一旦我們回到這個數字,我們可以彈出堆棧。 907 00:55:30,650 --> 00:55:36,570 因此,這階乘(1)就完成了。 908 00:55:36,570 --> 00:55:41,190 1時返回時,這個階乘(1)返回,返回1。 909 00:55:41,190 --> 00:55:46,910 返回值,請記住,這是NX的返回值。 910 00:55:46,910 --> 00:55:50,720 突然,這傢伙知道,我想回到2。 911 00:55:50,720 --> 00:55:55,910 >> 所以請記住,返回值,這是NX的返回值。 912 00:55:55,910 --> 00:56:01,160 所以,現在我們可以說,3×2,最後,在這裡,我們可以說, 913 00:56:01,160 --> 00:56:04,010 這將是4×3×2。 914 00:56:04,010 --> 00:56:09,570 而一旦這種回報,我們得到一個整數內的主要。 915 00:56:09,570 --> 00:56:15,460 遞歸有任何疑問? 916 00:56:15,460 --> 00:56:17,090 好的。因此,有更多的時間回答大家的提問結束時, 917 00:56:17,090 --> 00:56:23,360 但現在約瑟夫將支付餘下的主題。 918 00:56:23,360 --> 00:56:25,590 >> 王陽樂]。所以,現在,我們已經談到遞歸, 919 00:56:25,590 --> 00:56:27,840 讓我們來談談合併排序是一點點。 920 00:56:27,840 --> 00:56:31,740 合併排序是基本的數字排序的列表的另一種方式。 921 00:56:31,740 --> 00:56:36,430 它的工作原理是,歸併排序,你有一個列表,我們要做的是 922 00:56:36,430 --> 00:56:39,120 我們說,讓我們將其劃分為兩半。 923 00:56:39,120 --> 00:56:42,750 我們將首先運行再次合併排序的左半邊, 924 00:56:42,750 --> 00:56:45,040 然後我們會遇到合併排序的右半​​, 925 00:56:45,040 --> 00:56:50,240 這給了我們兩半進行排序,和現在我們要結合這些半在一起。 926 00:56:50,240 --> 00:56:55,010 這是一個有點難以看到沒有一個例子,所以我們走走過場,看看會發生什麼。 927 00:56:55,010 --> 00:56:59,590 所以,你開始這個列表中,我們把它分為兩半。 928 00:56:59,590 --> 00:57:02,300 我們經營的第一個合併排序的左半邊。 929 00:57:02,300 --> 00:57:06,660 所以這是左前衛,和現在我們再通過這個列表 930 00:57:06,660 --> 00:57:09,800 被傳遞到合併排序,然後我們看, 931 00:57:09,800 --> 00:57:13,270 在此列表的左側,我們運行它的合併排序。 932 00:57:13,270 --> 00:57:15,880 現在,我們得到了2號的列表, 933 00:57:15,880 --> 00:57:19,010 現在的左半邊長僅1元,我們不能 934 00:57:19,010 --> 00:57:23,380 分裂一個列表,其中只有1成半的元素,所以我們只是說,一旦我們有50個, 935 00:57:23,380 --> 00:57:26,400 這僅僅是1元,它已經排序。 936 00:57:26,400 --> 00:57:29,860 >> 一旦我們完成了,我們可以看到,我們可以 937 00:57:29,860 --> 00:57:32,230 移動至右半此列表, 938 00:57:32,230 --> 00:57:36,480 3排序,所以現在這個列表進行排序的兩半 939 00:57:36,480 --> 00:57:39,080 我們可以將這些數字重新走到一起。 940 00:57:39,080 --> 00:57:45,320 因此,我們期待在50和3,三是小於50,所以它在第一,然後50用武之地。 941 00:57:45,320 --> 00:57:49,340 現在,這樣做了,我們回去這是正確的一半,列表和排序。 942 00:57:49,340 --> 00:57:52,440 42是它自己的號碼,所以它已經排序。 943 00:57:52,440 --> 00:57:57,850 所以,現在我們比較這些2和圖3是小於42,因此,被放在第一, 944 00:57:57,850 --> 00:58:02,340 現年42​​歲的被提出,和50被放進去。 945 00:58:02,340 --> 00:58:07,220 現在,排序,我們去所有的方式回到頂端,1337年和15。 946 00:58:07,220 --> 00:58:14,560 好吧,我們現在看這個名單的左半邊; 1337本身,所以它的排序,並同15。 947 00:58:14,560 --> 00:58:19,020 所以,現在我們結合這2個數字進行排序,原單,15 <1337, 948 00:58:19,020 --> 00:58:23,060 所以在第一位,然後是1337去英寸 949 00:58:23,060 --> 00:58:26,640 現在我們整理的兩半原始列表的頂部。 950 00:58:26,640 --> 00:58:30,440 所有我們需要做的是結合這些。 951 00:58:30,440 --> 00:58:36,890 我們期待在該列表中的第2號,3 <15,所以先進行排序的數組。 952 00:58:36,890 --> 00:58:44,460 15 <42,所以它去了。現在,42 <1337,去英寸 953 00:58:44,460 --> 00:58:51,010 50 <1337,所以去英寸注意到了我們僅僅花了2個號碼,這個列表。 954 00:58:51,010 --> 00:58:53,640 所以,我們不能簡單地交替之間的列表。 955 00:58:53,640 --> 00:58:56,050 我們只是在尋找一開始,我們正在採取元素 956 00:58:56,050 --> 00:59:00,270 這是更小的,然後把它到我們的數組。 957 00:59:00,270 --> 00:59:04,080 現在,我們已經合併了所有的一半就完成了。 958 00:59:04,080 --> 00:59:07,780 >> 有任何疑問,歸併排序?是嗎? 959 00:59:07,780 --> 00:59:14,190 [學生]:如果它分裂成不同的群體,為什麼他們不只是分裂一次 960 00:59:14,190 --> 00:59:19,970 你有3個和2組中的嗎? [其他問題不知所云] 961 00:59:19,970 --> 00:59:24,940 原因 - 所以,問題是,為什麼我們不能只是把它們合併的第一步後,我們有嗎? 962 00:59:24,940 --> 00:59:29,530 我們之所以能做到這一點,雙方在最左邊的元素, 963 00:59:29,530 --> 00:59:33,040 然後採取較小的一個,並把它放在,是因為我們知道,這些 964 00:59:33,040 --> 00:59:35,290 個人的名單中排序的訂單。 965 00:59:35,290 --> 00:59:37,290 所以,如果我在最左邊的元素的兩個部分, 966 00:59:37,290 --> 00:59:40,490 我知道他們將這些列表中的最小元素。 967 00:59:40,490 --> 00:59:43,930 所以,我可以把它們放到這個大名單的最小元素點。 968 00:59:43,930 --> 00:59:47,810 另一方面,如果在第二個層次那邊,我看這2列出了 969 00:59:47,810 --> 00:59:51,640 50,3,42,1337和15,這些都是沒有排序。 970 00:59:51,640 --> 00:59:55,770 所以,如果我在50和1337,我要放50到我的清單。 971 00:59:55,770 --> 01:00:00,130 但是,這並不真正有意義,因為是最小的元素的所有這些。 972 01:00:00,130 --> 01:00:04,390 所以我們可以做到這一點結合步驟的唯一原因是因為我們的名單已經排序。 973 01:00:04,390 --> 01:00:07,010 這就是為什麼我們得到了所有的方式向底部 974 01:00:07,010 --> 01:00:09,800 因為當我們只是一個單一的號碼,你知道,一個單一的數字 975 01:00:09,800 --> 01:00:14,120 在其本身已經是一個排序的列表。 976 01:00:14,120 --> 01:00:19,360 >> 有什麼問題嗎?不是嗎? 977 01:00:19,360 --> 01:00:24,260 複雜性?好了,你可以看到,在每一步的最終數字, 978 01:00:24,260 --> 01:00:27,590 我們可以將一個列表中的一半log N次, 979 01:00:27,590 --> 01:00:31,700 這是我們得到這個N X日誌n的複雜性。 980 01:00:31,700 --> 01:00:34,940 你會看到最好的情況下,歸併排序是n日誌n,它只是恰巧 981 01:00:34,940 --> 01:00:39,340 最壞的情況下,或Ω那邊的,也是n日誌n。 982 01:00:39,340 --> 01:00:42,480 要記住的東西。 983 01:00:42,480 --> 01:00:45,750 移動,讓我們去到一些超級基本的文件I / O。 984 01:00:45,750 --> 01:00:48,830 如果你看,你會發現我們在爭奪某種系統 985 01:00:48,830 --> 01:00:51,270 在那裡你可以寫入到日誌文件中,如果你讀通過的代碼。 986 01:00:51,270 --> 01:00:53,730 讓我們來看看你怎麼可能做到這一點。 987 01:00:53,730 --> 01:00:57,450 好了,我們有fprintf,你能想到的只是輸出, 988 01:00:57,450 --> 01:01:01,720 只是打印到一個文件中,而不是,因此在開始時的f。 989 01:01:01,720 --> 01:01:07,570 這種代碼在這裡,它是什麼,你可能已經看到在爭奪, 990 01:01:07,570 --> 01:01:12,310 它通過你的二維數組打印出來行由行的數字是什麼。 991 01:01:12,310 --> 01:01:17,850 在這種情況下,輸出打印到您的終端或我們所說的標準輸出部分。 992 01:01:17,850 --> 01:01:22,170 >> 而現在,在這種情況下,我們要做的是與fprintf的printf取代, 993 01:01:22,170 --> 01:01:26,770 告訴您要打印的文件,在這種情況下,它只是它打印輸出到該文件 994 01:01:26,770 --> 01:01:32,230 而不是把它打印出來到你的終端。 995 01:01:32,230 --> 01:01:36,500 好了,那麼這引出了一個問題:我們從哪裡得到這類型的文件,對不對? 996 01:01:36,500 --> 01:01:39,840 我們通過在這fprintf機能的,但我們不知道它是從哪裡來的。 997 01:01:39,840 --> 01:01:43,980 好了,早在代碼中,我們有什麼是在這裡,這個代碼塊 998 01:01:43,980 --> 01:01:48,340 基本上說,打開該文件要求log.txt中。 999 01:01:48,340 --> 01:01:53,220 我們做什麼後,我們必須確保該文件實際上是打開成功。 1000 01:01:53,220 --> 01:01:57,070 因此,它可能會失敗的原因有多種,你沒有足夠的空間在您的計算機上,例如。 1001 01:01:57,070 --> 01:01:59,790 因此,它始終是重要的,之前你做任何操作的文件 1002 01:01:59,790 --> 01:02:03,300 我們檢查該文件是否被成功打開。 1003 01:02:03,300 --> 01:02:09,330 那麼,什麼是一個,這是一個爭論的FOPEN,好了,我們可以打開一個文件,在許多方面。 1004 01:02:09,330 --> 01:02:13,510 我們可以做的是,我們可以通過它瓦特,這意味著覆蓋的文件,如果它退出了, 1005 01:02:13,510 --> 01:02:18,070 我們可以通過一個一個,這是他們附加的文件,而不是覆蓋它, 1006 01:02:18,070 --> 01:02:22,730 或者我們可以指定R,這意味著,讓我們打開的文件為只讀。 1007 01:02:22,730 --> 01:02:24,890 因此,如果程序試圖進行任何更改的文件, 1008 01:02:24,890 --> 01:02:30,140 罵他們,不要讓他們這樣做。 1009 01:02:30,140 --> 01:02:33,320 最後,一旦我們完成的文件,完成執行操作就可以了, 1010 01:02:33,320 --> 01:02:35,860 我們需要確保我們關閉文件。 1011 01:02:35,860 --> 01:02:38,830 因此,在你的程序,你要通過他們再次 1012 01:02:38,830 --> 01:02:42,120 您打開這個文件,只是將其關閉。 1013 01:02:42,120 --> 01:02:44,650 因此,這是重要的事情,你必須確保你做。 1014 01:02:44,650 --> 01:02:47,180 所以請記住,你可以打開一個文件,然後就可以寫入到文件中, 1015 01:02:47,180 --> 01:02:51,270 操作中的文件,但你必須在年底關閉該文件。 1016 01:02:51,270 --> 01:02:53,270 >> 任何問題,基本的文件I / O?是嗎? 1017 01:02:53,270 --> 01:02:58,050 [學生提問,不知所云] 1018 01:02:58,050 --> 01:03:02,480 就在這裡。現在的問題是,這log.txt文件出現在哪裡? 1019 01:03:02,480 --> 01:03:07,890 好吧,如果你只要給它log.txt中,它會創建在同一目錄下的可執行文件。 1020 01:03:07,890 --> 01:03:10,500 所以,如果讓隱私無處藏 - >> [學生提問,不知所云] 1021 01:03:10,500 --> 01:03:18,830 是。在同一個文件夾中,或在同一個目錄下,如你所說的話。 1022 01:03:18,830 --> 01:03:21,400 現在,內存,堆棧和堆。 1023 01:03:21,400 --> 01:03:23,400 因此,如何在計算機的內存嗎? 1024 01:03:23,400 --> 01:03:26,270 那麼,你可以想像內存塊的排序。 1025 01:03:26,270 --> 01:03:30,260 而在內存中,我們有什麼所謂的堆卡在那裡,棧,在那裡。 1026 01:03:30,260 --> 01:03:34,480 和堆向下增長的堆棧是向上增長的。 1027 01:03:34,480 --> 01:03:38,620 因此,作為托米提到的 - 哦,好了,我們這些其他4段,我會在第二 - 1028 01:03:38,620 --> 01:03:42,890 湯米剛才說,你知道他的功能是如何稱呼自己和稱呼對方? 1029 01:03:42,890 --> 01:03:44,930 他們建立這種堆棧幀。 1030 01:03:44,930 --> 01:03:47,360 那麼,如果主調用foo,foo的被放在堆棧中。 1031 01:03:47,360 --> 01:03:52,430 foo調用了酒吧,酒吧將在堆棧上,並因此獲得在堆棧中。 1032 01:03:52,430 --> 01:03:57,040 當他們返回,他們各拿採取的堆棧。 1033 01:03:57,040 --> 01:04:00,140 什麼這些地方,保持記憶的? 1034 01:04:00,140 --> 01:04:03,110 那麼,頂部,這是文本段包含程序本身。 1035 01:04:03,110 --> 01:04:06,390 的存在,所以本機代碼,一旦你編譯的程序。 1036 01:04:06,390 --> 01:04:08,520 其次,任何初始化的全局變量。 1037 01:04:08,520 --> 01:04:12,660 >> 所以,你必須在你的程序中的全局變量,和你說的一樣,A = 5, 1038 01:04:12,660 --> 01:04:15,260 得到段,下, 1039 01:04:15,260 --> 01:04:18,990 您有任何未初始化的全局數據,它只是詮釋一個, 1040 01:04:18,990 --> 01:04:20,990 但你不說,它等於任何東西。 1041 01:04:20,990 --> 01:04:23,870 實現這些都是全局變量,所以他們在外面的主。 1042 01:04:23,870 --> 01:04:28,560 因此,這意味著任何的已宣告但不會被初始化的全局變量。 1043 01:04:28,560 --> 01:04:32,310 那麼,是什麼在堆嗎?分配的內存使用malloc,我們將在一點點。 1044 01:04:32,310 --> 01:04:35,990 最後,與堆棧您有任何局部變量 1045 01:04:35,990 --> 01:04:39,950 任何功能,你可以調用他們的任何參數。 1046 01:04:39,950 --> 01:04:43,720 的最後一件事,你不真正了解的環境變量做什麼, 1047 01:04:43,720 --> 01:04:46,700 但只要你運行的程序,有一些相關的,如 1048 01:04:46,700 --> 01:04:49,550 這是用戶名的人誰跑的程​​序。 1049 01:04:49,550 --> 01:04:51,550 這就是將要排序的底部。 1050 01:04:51,550 --> 01:04:54,540 的內存地址,這是十六進制值, 1051 01:04:54,540 --> 01:04:58,170 值的頂部從0開始,和他們走一路下滑到了谷底。 1052 01:04:58,170 --> 01:05:00,440 在這種情況下,如果你在32位系統上, 1053 01:05:00,440 --> 01:05:05,390 在底部的地址將是0x開頭,然後自動對焦,因為這是32位, 1054 01:05:05,390 --> 01:05:10,890 它是8個字節,並且在這種情況下,8個字節對應於8個十六進制數字。 1055 01:05:10,890 --> 01:05:20,110 所以,在這裡你將有一樣,0xFFFFFF具有,和在那裡,你將有0。 1056 01:05:20,110 --> 01:05:23,660 那麼,什麼是指針?你們有些人可能不涉及這部分之前。 1057 01:05:23,660 --> 01:05:26,660 但我們沒有去,所以在課堂上的指針只是一個數據類型 1058 01:05:26,660 --> 01:05:34,030 店,而不是某種類型的值,如50,它存儲在內存中的某個位置的地址。 1059 01:05:34,030 --> 01:05:36,020 這樣的記憶[不知所云]。 1060 01:05:36,020 --> 01:05:41,120 因此,在這種情況下,我們所擁有的,我們有一個指針,指向一個整數或一個int *, 1061 01:05:41,120 --> 01:05:46,210 它包含這個十六進制的0xDEADBEEF地址。 1062 01:05:46,210 --> 01:05:50,880 >> 那麼,我們有什麼,現在,該指針指向在內存中的某個位置, 1063 01:05:50,880 --> 01:05:56,020 這只是一個,值50是在此內存位置。 1064 01:05:56,020 --> 01:06:01,810 在32位系統中,所有32位系統上,指針佔用32位或4個字節。 1065 01:06:01,810 --> 01:06:06,020 但是,例如,在64位系統中,指針是​​64位。 1066 01:06:06,020 --> 01:06:08,040 所以,你要記住的東西。 1067 01:06:08,040 --> 01:06:12,310 因此,在結束位系統,指針是結束位長。 1068 01:06:12,310 --> 01:06:17,320 指針是一種難以消化的,沒有多餘的東西, 1069 01:06:17,320 --> 01:06:20,300 所以,讓我們通過一個例子來動態內存分配。 1070 01:06:20,300 --> 01:06:25,130 動態內存分配為你做,或者我們調用malloc, 1071 01:06:25,130 --> 01:06:29,280 它可以讓你分配某種形式的設置之外的數據。 1072 01:06:29,280 --> 01:06:31,830 因此,此數據是一種程序的持續時間更永久的。 1073 01:06:31,830 --> 01:06:36,430 因為你知道,如果你裡面的一個函數,該函數返回x聲明, 1074 01:06:36,430 --> 01:06:40,910 你不再需要訪問的數據存儲在x。 1075 01:06:40,910 --> 01:06:44,420 讓我們做什麼指針,是他們讓我們存儲記憶體或存儲值 1076 01:06:44,420 --> 01:06:46,840 在不同的內存段,即堆。 1077 01:06:46,840 --> 01:06:49,340 現在,一旦我們返回的功能,只要我們有一個指針 1078 01:06:49,340 --> 01:06:54,960 內存中該位置,那麼我們能做些什麼,我們就可以看的值。 1079 01:06:54,960 --> 01:06:58,020 讓我們看一個例子:這是我們的內存佈局。 1080 01:06:58,020 --> 01:07:00,050 我們有這個功能,主要。 1081 01:07:00,050 --> 01:07:06,870 它所做的是 - 好了,就這麼簡單,對不對? - 詮釋第X = 5,這只是一個變量在堆棧中的主。 1082 01:07:06,870 --> 01:07:12,450 >> 另一方面,現在我們宣派指針調用函數giveMeThreeInts。 1083 01:07:12,450 --> 01:07:16,800 所以現在我們進入這個功能,我們創建了一個新的堆棧幀。 1084 01:07:16,800 --> 01:07:20,440 然而,在這個堆棧幀中,我們聲明int *溫度, 1085 01:07:20,440 --> 01:07:23,210 這對我們的mallocs 3個整數。 1086 01:07:23,210 --> 01:07:25,880 因此,大小的int會給我們帶來多少字節,int是, 1087 01:07:25,880 --> 01:07:29,620 和malloc為我們提供了多少字節的空間在堆中。 1088 01:07:29,620 --> 01:07:32,890 因此,在這種情況下,我們已經建立了足夠的空間,3個整數, 1089 01:07:32,890 --> 01:07:36,830 和堆在那裡,這就是為什麼我畫更高。 1090 01:07:36,830 --> 01:07:42,900 一旦我們完成了,我們回來在這裡,你只需要3個int返回, 1091 01:07:42,900 --> 01:07:47,000 ,它返回的地址,在這種情況下,內存是的。 1092 01:07:47,000 --> 01:07:51,250 我們設置指針開關,在那裡,我們只是一個指針。 1093 01:07:51,250 --> 01:07:54,550 但該函數返回被堆積在這裡消失。 1094 01:07:54,550 --> 01:07:59,250 因此,臨時消失,但我們仍然保持的地址在哪裡 1095 01:07:59,250 --> 01:08:01,850 這3個整數內的電源。 1096 01:08:01,850 --> 01:08:06,180 因此,在這組中,指針的範圍,為本地的堆疊框架, 1097 01:08:06,180 --> 01:08:09,860 但他們指的是在堆中的內存。 1098 01:08:09,860 --> 01:08:12,190 >> 這是否有意義嗎? 1099 01:08:12,190 --> 01:08:14,960 [學生]:你能重複一次嗎? >> [約瑟夫]是的。 1100 01:08:14,960 --> 01:08:20,270 所以,如果我回去只是一點點,你會看到該臨時分配 1101 01:08:20,270 --> 01:08:23,500 一些內存的堆在那裡。 1102 01:08:23,500 --> 01:08:28,680 所以,此功能時,giveMeThreeInts收益,該協議棧在這裡會消失。 1103 01:08:28,680 --> 01:08:35,819 而與它的任何變量,在這種情況下,該指針被分配在層疊幀。 1104 01:08:35,819 --> 01:08:39,649 這是怎麼回事消失,但由於我們返回臨時 1105 01:08:39,649 --> 01:08:46,330 我們設定指針= temp中,指針現在指向相同的內存位置溫度。 1106 01:08:46,330 --> 01:08:50,370 所以,現在,即使我們失去了溫度,即本地指針, 1107 01:08:50,370 --> 01:08:59,109 我們仍保留什麼該變量的指針指向內部的內存地址。 1108 01:08:59,109 --> 01:09:03,740 有問題嗎?這可以是種一個令人困惑的話題,如果你還沒有看過它在部分。 1109 01:09:03,740 --> 01:09:09,240 ,你的TF我們可以肯定會去,當然,我們可以回答問題 1110 01:09:09,240 --> 01:09:11,500 在年底的審查會議。 1111 01:09:11,500 --> 01:09:14,220 但,這是一個複雜的話題,我有更多的例子,是要顯示 1112 01:09:14,220 --> 01:09:18,790 這將有助於澄清指針實際上是什麼。 1113 01:09:18,790 --> 01:09:22,500 >> 在這種情況下,指針是相當於陣列, 1114 01:09:22,500 --> 01:09:25,229 同樣的事情作為一個int數組,這樣我就可以使用這個指針。 1115 01:09:25,229 --> 01:09:29,840 所以我索引為0,和不斷變化的第一個整數為1, 1116 01:09:29,840 --> 01:09:39,689 改變所述第二至2的整數,和第三至3的整數。 1117 01:09:39,689 --> 01:09:44,210 因此,更多的指針。好了,記得Binky。 1118 01:09:44,210 --> 01:09:48,319 在這種情況下,我們分配了一個指針,或我們宣布一個指針, 1119 01:09:48,319 --> 01:09:52,760 但最初,當我剛剛宣布的指針,它不指向在內存中的任何地方。 1120 01:09:52,760 --> 01:09:54,930 這只是它裡面的垃圾值。 1121 01:09:54,930 --> 01:09:56,470 所以,我不知道該指針所指向的。 1122 01:09:56,470 --> 01:10:01,630 它有一個地址,只是充滿了0和1的地方,它最初宣布。 1123 01:10:01,630 --> 01:10:04,810 我不能做任何事情,直到我調用malloc 1124 01:10:04,810 --> 01:10:08,390 然後它給了我一個很小的空間就堆在那裡我可以把內部的值。 1125 01:10:08,390 --> 01:10:11,980 再說,我不知道,此內存裡面有什麼。 1126 01:10:11,980 --> 01:10:16,780 所以我必須做的第一件事是檢查系統是否有足夠的內存 1127 01:10:16,780 --> 01:10:20,850 給我1個整數擺在首位,這就是為什麼我在做此檢查。 1128 01:10:20,850 --> 01:10:25,020 如果指針是空的,這意味著,它沒有足夠的空間,或某些其他錯誤發生, 1129 01:10:25,020 --> 01:10:26,320 所以我要退出,我的計劃。 1130 01:10:26,320 --> 01:10:29,400  但是,如果它沒有成功,現在我可以使用這個指針 1131 01:10:29,400 --> 01:10:35,020 *指針的地址在哪裡 1132 01:10:35,020 --> 01:10:38,480 該值的地方是,它設置它等於1。 1133 01:10:38,480 --> 01:10:41,850 因此,在這裡,我們檢查,如果該內存存在。 1134 01:10:41,850 --> 01:10:45,380 >> 一旦你知道它的存在,你可以把它 1135 01:10:45,380 --> 01:10:50,460 你要投入什麼樣的價值,在這種情況下,1。 1136 01:10:50,460 --> 01:10:53,060 一旦我們完成它,你需要釋放該指針 1137 01:10:53,060 --> 01:10:57,160 因為我們需要的系統內存,你提出的要求擺在首位。 1138 01:10:57,160 --> 01:10:59,690 因為電腦不知道什麼時候,我們已經完成了它。 1139 01:10:59,690 --> 01:11:02,510 在這種情況下,我們明確地告訴它,好吧,我們就大功告成了與記憶。 1140 01:11:02,510 --> 01:11:10,780 如果其他應用程序需要它,其他一些程序需要它,感覺自由地前進,並把它。 1141 01:11:10,780 --> 01:11:15,110 我們還可以做的是,我們就可以得到局部變量上設置的地址。 1142 01:11:15,110 --> 01:11:19,080 所以int x是裡面堆放的主要框架。 1143 01:11:19,080 --> 01:11:23,060 而當我們使用這個符號,這和運營商,它是什麼 1144 01:11:23,060 --> 01:11:27,310 它需要的x,和x是只是一些數據在存儲器中,但它有一個地址。 1145 01:11:27,310 --> 01:11:33,790 它位於什麼地方。因此,通過調用&X,這是什麼做的是它給了我們x的地址。 1146 01:11:33,790 --> 01:11:38,430 通過這樣做,我們正在做的指針指向其中x是在內存中。 1147 01:11:38,430 --> 01:11:41,710 現在,我們只是做一些事情,如* X,我們會得到5回。 1148 01:11:41,710 --> 01:11:43,820 這顆恆星被稱為提領。 1149 01:11:43,820 --> 01:11:46,640 按照地址,你會得到它的價值,存放在那裡。 1150 01:11:51,000 --> 01:11:53,310 >> 有什麼問題嗎?是嗎? 1151 01:11:53,310 --> 01:11:56,500 [學生]:如果你不這樣做的三尖的東西,它仍可以編譯嗎? 1152 01:11:56,500 --> 01:11:59,490 是。如果你不這樣做的3指針的東西,它仍然要進行編譯, 1153 01:11:59,490 --> 01:12:02,720 但我會告訴你發生了什麼在第二,並沒有這樣做, 1154 01:12:02,720 --> 01:12:04,860 這就是我們所說的內存洩漏。你不給系統 1155 01:12:04,860 --> 01:12:07,850 支持它的記憶,所以一段時間後程序會積累 1156 01:12:07,850 --> 01:12:10,940 內存,它的使用,並沒有其他人可以使用它。 1157 01:12:10,940 --> 01:12:15,750 如果你見過有150萬字節在您的計算機上的Firefox, 1158 01:12:15,750 --> 01:12:17,840 在任務管理器,這是怎麼回事。 1159 01:12:17,840 --> 01:12:20,760 你有內存洩漏的程序,他們沒有處理。 1160 01:12:23,080 --> 01:12:26,240 那麼,如何指針的算術運算的工作嗎? 1161 01:12:26,240 --> 01:12:29,480 好了,指針的算術運算是有點像到一個數組中的索引。 1162 01:12:29,480 --> 01:12:36,370 在這種情況下,我有一個指針,我做的是我的第一個元素的指針指向 1163 01:12:36,370 --> 01:12:42,100 此數組中的3個整數,我已經分配好了。 1164 01:12:42,100 --> 01:12:46,670 所以現在我做什麼,明星的指針只是改變列表中的第一個元素。 1165 01:12:46,670 --> 01:12:49,140 星級指針+1點在這裡。 1166 01:12:49,140 --> 01:12:53,140 因此,指針是在這裡,指針+1是在這裡,指針+2是在這裡。 1167 01:12:53,140 --> 01:12:56,610 >> 因此,只要加1是沿著這個數組同樣的事情。 1168 01:12:56,610 --> 01:12:59,880 我們做的是,當我們這樣做的指針+1,你的地址在這裡, 1169 01:12:59,880 --> 01:13:04,180 中獲得的價值在這裡,你把一個明星從整個表達式 1170 01:13:04,180 --> 01:13:05,990 取消對它的引用。 1171 01:13:05,990 --> 01:13:09,940 所以,在這種情況下,我這個數組中的第一位置設置為1,則 1172 01:13:09,940 --> 01:13:13,970 第二位置為2〜3中的第三位置。 1173 01:13:13,970 --> 01:13:18,180 我在做什麼在這裡是我打印的指針+1, 1174 01:13:18,180 --> 01:13:19,970 這只是給了我2。 1175 01:13:19,970 --> 01:13:23,650 現在,我遞增指針,所以指針等於指針+1, 1176 01:13:23,650 --> 01:13:26,780 向前移動。 1177 01:13:26,780 --> 01:13:30,810 所以現在如果我打印出來的指針+1 +1指針現在是3, 1178 01:13:30,810 --> 01:13:33,990 在這種情況下,打印出3。 1179 01:13:33,990 --> 01:13:36,560 而以免費的東西,我給它的指針 1180 01:13:36,560 --> 01:13:40,540 必須指出的數組,我回來了從malloc的開始。 1181 01:13:40,540 --> 01:13:43,430 因此,在這種情況下,如果我在這裡呼籲3,這不會是正確的, 1182 01:13:43,430 --> 01:13:45,070 因為它是在中間的數組。 1183 01:13:45,070 --> 01:13:48,820 我必須減去到原來的位置 1184 01:13:48,820 --> 01:13:50,420 最初的第一點,我才可以釋放它。 1185 01:13:56,300 --> 01:13:58,450 因此,這裡是一個更複雜的例子。 1186 01:13:58,450 --> 01:14:03,360 在這種情況下,我們7個字符,一個字符數組分配。 1187 01:14:03,360 --> 01:14:06,480 >> 在這種情況下,我們正在做的是,我們在第6循環, 1188 01:14:06,480 --> 01:14:09,900 我們將它們設置為Z。 1189 01:14:09,900 --> 01:14:13,350 因此,對於int i = 0,I> 6,我+ +, 1190 01:14:13,350 --> 01:14:16,220 所以,指針+我只是給我們,在這種情況下, 1191 01:14:16,220 --> 01:14:20,860 指針,指針1,指針2,指針3,依此類推等等迴路中。 1192 01:14:20,860 --> 01:14:24,040 它要做的是獲取該地址,解引用獲得的價值, 1193 01:14:24,040 --> 01:14:27,440 和變化值到Z。 1194 01:14:27,440 --> 01:14:30,350 那麼,在年底記住這是一個字符串,對不對? 1195 01:14:30,350 --> 01:14:33,560 所有的字符串結束的空終止字符。 1196 01:14:33,560 --> 01:14:38,620 所以,我要做的就是在指針6,我把空終止符中。 1197 01:14:38,620 --> 01:14:43,980 現在我基本上是做什麼在這裡實現輸出一個字符串,對不對? 1198 01:14:43,980 --> 01:14:46,190 >> 所以,當輸出現在,當它達到一個字符串的結束嗎? 1199 01:14:46,190 --> 01:14:48,230 當它擊中的空終止字符。 1200 01:14:48,230 --> 01:14:52,030 因此,在這種情況下,我原來的指針指向該數組的開始。 1201 01:14:52,030 --> 01:14:56,410 我的第一個字符打印出來。我將它移到1。 1202 01:14:56,410 --> 01:14:58,420 我打印的字符。我移動過來。 1203 01:14:58,420 --> 01:15:02,180 我一直這樣做,直到我到達終點。 1204 01:15:02,180 --> 01:15:07,750 而現在的結束*指針解引用,並得到空終止字符。 1205 01:15:07,750 --> 01:15:11,780 所以我的while循環運行,只有當該值不是空終止字符。 1206 01:15:11,780 --> 01:15:13,770 所以,現在我退出這個循環。 1207 01:15:18,780 --> 01:15:21,180 所以,如果我從這個指針減去6, 1208 01:15:21,180 --> 01:15:22,860 我回去的方式開始。 1209 01:15:22,860 --> 01:15:27,880 請記住,我這樣做是因為我去的開始,以釋放它。 1210 01:15:27,880 --> 01:15:30,270 >> 所以,我知道這是一個很多。有什麼問題嗎? 1211 01:15:30,270 --> 01:15:31,870 請,是嗎? 1212 01:15:31,870 --> 01:15:36,610 [學生提問不知所云] 1213 01:15:36,610 --> 01:15:38,190 你能說大聲嗎?抱歉。 1214 01:15:38,190 --> 01:15:44,140 [學生]:最後一張幻燈片之前釋放的指針, 1215 01:15:44,140 --> 01:15:47,300 你改變指針的值嗎? 1216 01:15:47,300 --> 01:15:50,370 [約瑟夫]所以,就在這裡。 >> [學生]:哦,好吧。 1217 01:15:50,370 --> 01:15:51,890 [約瑟夫]所以,我有一個指針減減,右, 1218 01:15:51,890 --> 01:15:54,140 移動的東西回來,然後我釋放它, 1219 01:15:54,140 --> 01:15:57,000 因為這個指針指向的數組的開始。 1220 01:15:57,000 --> 01:16:00,420 [學生]:但是,這不會需要你停止了之後的所有行。 1221 01:16:00,420 --> 01:16:03,130 [約瑟夫]所以,如果我停止後,這將被視為內存洩漏, 1222 01:16:03,130 --> 01:16:04,810 因為我沒有運行免費的。 1223 01:16:04,810 --> 01:16:11,290 [學生]:我後的第一個三線指針+1 [不知所云] [不知所云]。 1224 01:16:11,290 --> 01:16:13,140 [約瑟夫]嗯。那麼,什麼是那裡的問題? 1225 01:16:13,140 --> 01:16:14,780 抱歉。不,不。走,走,請。 1226 01:16:14,780 --> 01:16:16,870 [學生]:所以,你就不會改變指針的值。 1227 01:16:16,870 --> 01:16:19,130 你會不會有,做指針減減。 1228 01:16:19,130 --> 01:16:19,730 [約瑟夫]是的,沒錯。 1229 01:16:19,730 --> 01:16:21,890 所以,當我做指針+1和+2指針, 1230 01:16:21,890 --> 01:16:24,410 我不這樣做指針等於指針+1。 1231 01:16:24,410 --> 01:16:27,260 所以,只是停留指針指向的數組的開始。 1232 01:16:27,260 --> 01:16:31,460 這是只有當我做加再加,它的值設置裡面的指針, 1233 01:16:31,460 --> 01:16:33,550 它實際上移動一起。 1234 01:16:36,860 --> 01:16:37,780 好的。 1235 01:16:40,550 --> 01:16:42,030 還有問題嗎? 1236 01:16:44,680 --> 01:16:47,790 >> 同樣的,如果這是鋪天蓋地的,這將覆蓋在會議上。 1237 01:16:47,790 --> 01:16:50,710 問問你的教學研究員,它結束時,我們可以回答的問題。 1238 01:16:53,510 --> 01:16:56,600 通常我們不喜歡做這減去的事情。 1239 01:16:56,600 --> 01:16:59,760 這要求我跟踪我多少數組中的偏移。 1240 01:16:59,760 --> 01:17:04,520 所以,總的來說,這是只是為了解釋如何指針運算。 1241 01:17:04,520 --> 01:17:07,970 但是,我們通常喜歡做的是什麼,我們要創建的副本的指針, 1242 01:17:07,970 --> 01:17:11,640 然後,我們將使用該副本,當我們走動的字符串。 1243 01:17:11,640 --> 01:17:14,660 因此,在這些情況下,您使用的整個字符串複製到打印, 1244 01:17:14,660 --> 01:17:19,040 但我們沒有這樣做指針減6跟踪我們搬到了多少, 1245 01:17:19,040 --> 01:17:22,700 因為我們知道,我們仍然指向原來的點開始的列表 1246 01:17:22,700 --> 01:17:25,340 我們改變的是這個副本。 1247 01:17:25,340 --> 01:17:28,250 因此,在一般情況下,改變你原來的指針的副本。 1248 01:17:28,250 --> 01:17:32,350 不要試圖有點像 - 不要改變原來的副本。 1249 01:17:32,350 --> 01:17:35,290 試圖改變你原來的只讀副本。 1250 01:17:41,540 --> 01:17:44,870 所以,你會注意到當我們通過串入的printf 1251 01:17:44,870 --> 01:17:48,990 你不必在它前面放一個明星,像我們一樣與所有其他指針引用,對不對? 1252 01:17:48,990 --> 01:17:54,180 所以,如果你打印出整個字符串的%s需要一個地址, 1253 01:17:54,180 --> 01:17:57,610 在這種情況下一個指針,或在這種情況下,像一個字符數組。 1254 01:17:57,610 --> 01:18:00,330 >> 字符,字符*和數組同樣的事情。 1255 01:18:00,330 --> 01:18:03,690 指針是字符,字符數組同樣的事情。 1256 01:18:03,690 --> 01:18:05,720 所以,我們要做的是通過指針。 1257 01:18:05,720 --> 01:18:08,150 我們沒有通過,如*指針或類似的東西。 1258 01:18:13,110 --> 01:18:14,930 因此,數組和指針是同樣的事情。 1259 01:18:14,930 --> 01:18:19,160 當你正在做的事情,比如x [Y]在這裡的數組, 1260 01:18:19,160 --> 01:18:21,960 它在做什麼引擎蓋下的是它說,沒關係,這是一個字符數組, 1261 01:18:21,960 --> 01:18:23,690 所以這是一個指針。 1262 01:18:23,690 --> 01:18:26,510 因此,x是同樣的事情, 1263 01:18:26,510 --> 01:18:28,650 所以它做什麼是Y到X, 1264 01:18:28,650 --> 01:18:31,820 這是同樣的事情向前發展在內存中。 1265 01:18:31,820 --> 01:18:34,930 而現在X + Y為我們提供了某種形式的地址, 1266 01:18:34,930 --> 01:18:37,570 我們解引用地址或箭頭 1267 01:18:37,570 --> 01:18:41,640 內存中該位置在哪裡,我們得到的價值,在內存中的位置。 1268 01:18:41,640 --> 01:18:43,720 所以,所以這兩個是完全一樣的東西。 1269 01:18:43,720 --> 01:18:45,840 這只是一個語法糖。 1270 01:18:45,840 --> 01:18:48,090 他們做同樣的事情。他們只是對彼此的不同句法。 1271 01:18:51,500 --> 01:18:57,590 >> 那麼,什麼可能出錯的指針嗎?一樣,有很多。好吧。所以,不好的事情。 1272 01:18:57,590 --> 01:19:02,410 你可以做一些不好的事情不檢查,如果您的malloc調用返回null,正確的嗎? 1273 01:19:02,410 --> 01:19:06,560 在這種情況下,我要求給我的系統 - 這個數字是什麼? 1274 01:19:06,560 --> 01:19:11,200 2億次4一樣,因為一個整數的大小為4個字節。 1275 01:19:11,200 --> 01:19:13,810 我要求它像8十億字節。 1276 01:19:13,810 --> 01:19:17,270 當然,我的電腦是不是能夠給我這麼大的內存回。 1277 01:19:17,270 --> 01:19:20,960 而我們沒有檢查,如果這是空的,所以,當我們試圖取消對它的引用在那裡 - 1278 01:19:20,960 --> 01:19:24,270 按照箭頭的地方的去 - 我們沒有這方面的記憶。 1279 01:19:24,270 --> 01:19:27,150 這就是我們所說的釋放空指針。 1280 01:19:27,150 --> 01:19:29,710 這基本上使你出現段錯誤。 1281 01:19:29,710 --> 01:19:31,790 這是你可以segfault錯誤的方式之一。 1282 01:19:34,090 --> 01:19:38,090 其他不好的事情可以做 - 哦,好的。 1283 01:19:38,090 --> 01:19:40,650 這是一個空指針解引用。好吧。 1284 01:19:40,650 --> 01:19:45,160 其他不好的事情 - 嗯,要解決,你只要把在那裡的檢查 1285 01:19:45,160 --> 01:19:46,980 檢查指針是否為空 1286 01:19:46,980 --> 01:19:51,000 和退出的程序,如果它發生了,malloc返回一個空指針。 1287 01:19:55,110 --> 01:19:59,850 這是XKCD漫畫。人們理解了。排序的。 1288 01:20:06,120 --> 01:20:09,350 >> 因此,記憶體。我去了這一點。 1289 01:20:09,350 --> 01:20:12,000 我們在一個循環中調用malloc,但我們每次調用malloc 1290 01:20:12,000 --> 01:20:14,370 我們正在失去這個指針指向的軌道, 1291 01:20:14,370 --> 01:20:15,750 因為我們弄錯了。 1292 01:20:15,750 --> 01:20:18,410 因此,初始調用malloc給我的記憶在這裡。 1293 01:20:18,410 --> 01:20:19,990 我的指針的指針。 1294 01:20:19,990 --> 01:20:23,020 現在,我不釋放它,所以現在我調用malloc。 1295 01:20:23,020 --> 01:20:26,070 現在,在這裡。現在,我的記憶中指出在這裡。 1296 01:20:26,070 --> 01:20:27,640 指著在這裡。指著在這裡。 1297 01:20:27,640 --> 01:20:31,820 但我已經失去所有的記憶,在這裡,我分配的地址。 1298 01:20:31,820 --> 01:20:35,100 所以現在我沒有任何參考了。 1299 01:20:35,100 --> 01:20:37,230 所以,我不能讓他們自由這個循環之外。 1300 01:20:37,230 --> 01:20:39,390 因此,為了解決這樣的事情, 1301 01:20:39,390 --> 01:20:42,250 如果你忘了空閒內存,你會得到此內存洩漏, 1302 01:20:42,250 --> 01:20:45,810 你必須釋放內部的存儲器中,這個循環一旦你用它做。 1303 01:20:45,810 --> 01:20:51,400 那麼,這是什麼情況。我知道很多你不喜歡這一點。 1304 01:20:51,400 --> 01:20:55,270 但現在 - 耶!你得到這樣的44,000千字節。 1305 01:20:55,270 --> 01:20:57,110 所以,你釋放它的循環結束時, 1306 01:20:57,110 --> 01:20:59,770 而這只是每次釋放內存。 1307 01:20:59,770 --> 01:21:03,620 從本質上講,你的程序沒有內存洩漏了。 1308 01:21:03,620 --> 01:21:08,150 >> 現在,別的東西你可以做的是釋放一些內存,你問過兩次。 1309 01:21:08,150 --> 01:21:11,060 在這種情況下,你的malloc東西,你改變它的值。 1310 01:21:11,060 --> 01:21:13,140 您可以免費一次,因為你說你用它做。 1311 01:21:13,140 --> 01:21:14,940 但後​​來我們再釋放它。 1312 01:21:14,940 --> 01:21:16,730 這是非常糟糕的東西。 1313 01:21:16,730 --> 01:21:18,820 它不會到最初出現段錯誤, 1314 01:21:18,820 --> 01:21:23,350 但經過一段時間這樣做是雙重釋放這會破壞你的堆結構, 1315 01:21:23,350 --> 01:21:27,200 你將學習多一點點,如果你選擇一個類CS61。 1316 01:21:27,200 --> 01:21:30,000 但本質上一段時間後你的電腦會感到困惑 1317 01:21:30,000 --> 01:21:33,010 什麼樣的內存位置和它的存儲 - 1318 01:21:33,010 --> 01:21:34,800 在數據被存儲在內存中。 1319 01:21:34,800 --> 01:21:38,080 因此,兩次釋放一個指針是一個壞的事情,你不想做。 1320 01:21:38,080 --> 01:21:41,600 >> 其他的東西,可以去錯了不使用sizeof。 1321 01:21:41,600 --> 01:21:44,460 因此,在這種情況下,你的malloc 8個字節, 1322 01:21:44,460 --> 01:21:46,700 這是為兩個整數同樣的事情,對不對? 1323 01:21:46,700 --> 01:21:49,580 所以,這是絕對安全的,但它呢? 1324 01:21:49,580 --> 01:21:52,160 那麼,作為盧卡斯談到不同的體系, 1325 01:21:52,160 --> 01:21:54,220 整數是不同長度。 1326 01:21:54,220 --> 01:21:57,970 因此,在您正在使用的電器,整數是4個字節, 1327 01:21:57,970 --> 01:22:02,370 但其他一些系統上,他們可能是8個字節,也可能是16個字節。 1328 01:22:02,370 --> 01:22:05,680 所以,如果我只是在這裡使用這個號碼, 1329 01:22:05,680 --> 01:22:07,310 這個程序可能會在設備上工作, 1330 01:22:07,310 --> 01:22:10,360 但它不會在其他一些系統分配足夠的內存。 1331 01:22:10,360 --> 01:22:14,020 在這種情況下,這是si​​zeof運算符用於。 1332 01:22:14,020 --> 01:22:16,880 當我們調用的sizeof(int),這樣做是什麼 1333 01:22:16,880 --> 01:22:21,910  它為我們提供了一個程序正在運行的系統上的整數的大小。 1334 01:22:21,910 --> 01:22:25,490 所以,在這種情況下,表示sizeof(int)將返回4類似器具上, 1335 01:22:25,490 --> 01:22:29,980 現在這個意願,4 * 2,8, 1336 01:22:29,980 --> 01:22:32,330 這僅僅是為兩個整數的必要的空間的量。 1337 01:22:32,330 --> 01:22:36,710 在不同的系統中,如果一個int是16個字節或8字節一樣, 1338 01:22:36,710 --> 01:22:39,380 它只是將返回足夠的字節來存儲量。 1339 01:22:41,830 --> 01:22:45,310 >> 最後,結構。 1340 01:22:45,310 --> 01:22:48,340 所以,如果你想存儲在內存中的數獨板,怎麼可能我們做到這一點呢? 1341 01:22:48,340 --> 01:22:51,570 你可能會想到的第一件事像一個變量, 1342 01:22:51,570 --> 01:22:53,820 一個變量的第二件事情,第三件事情是一個變量, 1343 01:22:53,820 --> 01:22:56,420 第四件事 - 壞,右一個變量? 1344 01:22:56,420 --> 01:23:00,750 所以,你可以在此之上的一種改進是一個9×9陣列。 1345 01:23:00,750 --> 01:23:04,480 這很好,但是如果你想其他事物關聯的數獨板 1346 01:23:04,480 --> 01:23:06,490 喜歡的難度董事會, 1347 01:23:06,490 --> 01:23:11,740 或者,例如,你的分數是什麼,或你解決這個板多少時間呢? 1348 01:23:11,740 --> 01:23:14,970 好了,你可以做的是,你可以創建一個結構。 1349 01:23:14,970 --> 01:23:18,910 我基本上可以說是在這裡,我定義這個結構, 1350 01:23:18,910 --> 01:23:23,230 我定義的板9×9的數獨板組成。 1351 01:23:23,230 --> 01:23:26,650 >> 它所擁有的,它具有的水平的名稱的指針。 1352 01:23:26,650 --> 01:23:30,730 它還具有X和Y,這是我現在的坐標。 1353 01:23:30,730 --> 01:23:35,980 還花費的時間[不知所云],它有到目前為止,我已經輸入的總數的移動。 1354 01:23:35,980 --> 01:23:40,010 因此,在這種情況下,我可以分組一大堆的數據整合到一個結構 1355 01:23:40,010 --> 01:23:42,790 而不是它像飛舞著像不同的變量 1356 01:23:42,790 --> 01:23:44,540 ,我真的不能跟踪的。 1357 01:23:44,540 --> 01:23:49,720 這讓我們有很好的語法形式的引用不同的結構,這裡面的東西。 1358 01:23:49,720 --> 01:23:53,430 我可以做board.board,我得到的數獨板。 1359 01:23:53,430 --> 01:23:56,320 Board.level,我是多麼艱難。 1360 01:23:56,320 --> 01:24:00,540 ,Board.x和board.y給我,我可能會在董事會的坐標。 1361 01:24:00,540 --> 01:24:04,730 因此,我訪問就是我們所說的結構體中的字段。 1362 01:24:04,730 --> 01:24:08,840 這定義sudokuBoard,這是一個類型,我。 1363 01:24:08,840 --> 01:24:14,800 現在,我們在這裡。我有一個變量稱為“板”的類型sudokuBoard。 1364 01:24:14,800 --> 01:24:18,820 因此,現在就可以訪問這個結構在這裡的所有領域。 1365 01:24:20,830 --> 01:24:22,450 >> 任何關於結構的問題嗎?是嗎? 1366 01:24:22,450 --> 01:24:25,890 [學生]:對於整數X,Y,你宣布一個行嗎? >> [約瑟夫]嗯。 1367 01:24:25,890 --> 01:24:27,400 [學生]:所以,你可以做,所有的人? 1368 01:24:27,400 --> 01:24:31,200 喜歡在x,y的逗號倍,總? 1369 01:24:31,200 --> 01:24:34,460 [約瑟夫]是的,你可以做到這一點,但我之所以把x和y在同一行 - 1370 01:24:34,460 --> 01:24:36,330 ,問題是我們為什麼能做到這一點在同一行嗎? 1371 01:24:36,330 --> 01:24:38,600 我們為什麼不把所有這些在同一行上 1372 01:24:38,600 --> 01:24:42,090 x和y是彼此相關的, 1373 01:24:42,090 --> 01:24:44,780 而這僅僅是風格上更正確的,在一定意義上, 1374 01:24:44,780 --> 01:24:46,600 因為它的分組在同一行上的兩件事情 1375 01:24:46,600 --> 01:24:49,340 ,像那種同樣的事情。 1376 01:24:49,340 --> 01:24:51,440 而我只是分裂分開。它只是一種風格的東西。 1377 01:24:51,440 --> 01:24:53,720 在功能上並沒有任何差別。 1378 01:24:58,150 --> 01:24:59,270 對結構的任何其他問題? 1379 01:25:03,030 --> 01:25:06,620 您可以定義一個圖鑑與結構。 1380 01:25:06,620 --> 01:25:11,720 寵物小精靈有一個數字,它有一個字母,一個老闆,一個類型。 1381 01:25:11,720 --> 01:25:16,990 然後,如果你有一個數組的神奇寶貝,你可以彌補圖鑑,對不對? 1382 01:25:16,990 --> 01:25:20,810 好了,爽。因此,結構的問題。這些都是相關的結構。 1383 01:25:20,810 --> 01:25:25,270 >> 最後,GDB。 GDB讓你做什麼呢?它可以讓你調試你的程序。 1384 01:25:25,270 --> 01:25:27,650 如果你還沒有使用GDB,我建議看短 1385 01:25:27,650 --> 01:25:31,250 只是在GDB是什麼,你如何使用它,你會如何使用它, 1386 01:25:31,250 --> 01:25:32,900 和測試程序。 1387 01:25:32,900 --> 01:25:37,400 因此,讓你做什麼GDB是它讓暫停[不知所云]你的程序 1388 01:25:37,400 --> 01:25:38,920 和一個實際線。 1389 01:25:38,920 --> 01:25:42,600 例如,我想在我的計劃,如3號線暫停執行, 1390 01:25:42,600 --> 01:25:46,010 而我在第3行,我可以打印出所有的值有。 1391 01:25:46,010 --> 01:25:49,710 因此,我們所說的像行暫停 1392 01:25:49,710 --> 01:25:52,350 我們稱這種放一個斷點,在該行 1393 01:25:52,350 --> 01:25:55,920 然後我們就可以打印出當時的變量在程序狀態的。 1394 01:25:55,920 --> 01:25:58,990 >> 然後,我們可以從那裡通過的程序行由行一步。 1395 01:25:58,990 --> 01:26:03,200 然後我們就可以看的堆棧狀態的時間。 1396 01:26:03,200 --> 01:26:08,600 因此,為了使用GDB,我們所做的就是我們稱之為鐺上的C文件, 1397 01:26:08,600 --> 01:26:11,290 但我們有通過-ggdb標誌的。 1398 01:26:11,290 --> 01:26:15,850 一旦我們做,我們只是運行gdb生成的輸出文件。 1399 01:26:15,850 --> 01:26:18,810 所以你得到一些像這樣質量的文本, 1400 01:26:18,810 --> 01:26:21,990 但真的所有您需要做的是輸入命令的開頭。 1401 01:26:21,990 --> 01:26:24,250 在主要突破主要把一個斷點。 1402 01:26:24,250 --> 01:26:28,470 列表400列出了400行左右的代碼行。 1403 01:26:28,470 --> 01:26:31,410 因此,在這種情況下,你可以環顧四周,說,哦, 1404 01:26:31,410 --> 01:26:34,360 我想設置一個斷點,在397行,這條線, 1405 01:26:34,360 --> 01:26:37,170 那麼你的程序運行到這一步,這將打破。 1406 01:26:37,170 --> 01:26:41,120 這將暫停在那裡,您可以打印出來,例如,價值高或低。 1407 01:26:41,120 --> 01:26:46,410 因此,有一堆你需要知道的命令, 1408 01:26:46,410 --> 01:26:48,660 該幻燈片將在網站上, 1409 01:26:48,660 --> 01:26:54,000 所以,如果你只是想引用這些還是喜歡把它們放在你的備忘單,感覺很自由。 1410 01:26:54,000 --> 01:27:00,650 >> 酷。這是測試複習0,如果您有任何問題,我們將堅持圍繞。 1411 01:27:00,650 --> 01:27:03,850 好的。 1412 01:27:03,850 --> 01:27:09,030 >>  [掌聲] 1413 01:27:09,030 --> 01:27:13,000 >> [CS50.TV]