1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
DAVID馬蘭:你好, 歡迎回到CS50。 因此,這是本週四結束。 剛一公佈第一。 因此,所謂的第五個星期一是 上來今年下星期一。 這是改變的機會 SAT / UNSAT一個字母等級,還是從 字母等級SAT / UNSAT。 煩人,這個過程確實需要一個 簽名,因為你必須填寫 出那些粉紅色的分/插形式之一。 

因為從技術上說,SAT / UNSAT 版本和信級版本 有不同的目錄編號。 但沒什麼大不了的。 只是過來跟我搶 或在任何點的勞倫。 或給我們發電子郵件,如果你沒有那種 你需要的文書工作的今天,我們 一定會幫助您 週一前的護理。 

所有權利,所以今天 -  其實,有一點回音。 我們能否音我倒有幾分? 確定。 因此,我們今天介紹一個主題 被稱為指針。 我承認,這是一個 更複雜的主題,我們傾向於 在這個類中覆蓋,或任何真正的 入門課程使用C. 

但我的話,特別是 如果你的頭腦感覺有點彎曲 今天,在今後幾個星期。 這不是你得到的代表 任何在這個糟糕的,那只是意味著 這是一個特別複雜的話題 我答應,幾個星期 因此,會顯得太驚人 回想起來簡單。 

我還記得這一天。 我坐在食堂埃利奧特, 坐在旁邊我的TF尼沙特梅塔, 誰是居民埃利奧特房子。 出於某種原因,這 只要點擊主題。 這是說,我也掙扎 與一定量的時間,但我 會盡我所能來幫助避免任何此類 一個話題,最終的鬥爭 是相當強大的。 

事實上,我們將討論的話題之一 在未來幾週內, 的安全性,以及如何才能真正 利用機器的方式 並不打算。 而那些剝削通常 錯誤,錯誤的結果,我們 人們不理解一些使 底層的實現 通過哪些程序。 

現在這個問題似乎更多的用戶 友好的,我想我會打10 一個小的黏土動畫的第二個預覽 數字命名賓基被帶到 在斯坦福大學生活,我們的一個朋友, 教授尼克Parlante。 所以,請允許我把這個給你 這裡傳情賓基。 

[視頻回放] 

嘿,賓基。 醒來。 它的時間的指針樂趣。 

 - 那是什麼? 了解指針? 哦,滿載而歸。 

[END視頻播放] 

國寶馬蘭:這是斯坦福 計算機科學。 所以來。 

[掌聲] 

國寶MALAN:對不起,尼克。 

因此,記得我們最後一次止 這真是令人興奮的吊人胃口 據此,此功能 只是沒有工作。 至少憑直覺,感覺 像它應該工作。 簡單地交換值 為兩個整數。 但記得,當我們打印出 在主,一個原始值 二,他們仍然是一個和 兩個,而不是2個和1個。 

因此,讓我真正切換 超過家電。 我寫了一個骨架代碼位 推進在這裡,我要求使得x 1,y將是2。 然後,我打印出他們的兩個 值打印為f。 

然後,我要求在這裡, 我們要交換他們。 我們這裡給我留下了空白點 填寫今天在短短的時刻。 然後,我會要求 已交換兩個變量。 然後,我要打印 他們出來了。 所以我希望,我應該看到1,2。 2,1。 這是超級簡單 現在目標。 

那麼,我們如何去交換 兩個變量? 恩,如果我在這裡提出,這些杯子 可能代表一台計算機的存儲器中。 這是了幾口,這 是另幾叮咬。 我們有一個志願者和 混合一些飲料,如果熟悉嗎? 上來吧。 你叫什麼名字? 

JESS:傑西。 

國寶MALAN:傑斯? 上來吧,傑西。 如果你不介意的話,我們必須把 谷歌的玻璃上,所以我們可以 不朽。 OK,玻璃。 錄製視頻。 OK,我們是很好的 這裡去與傑斯。 好的。 認識你很高興。 

所以,我想什麼你在這裡做 -  如果你能,相當迅速 -  只是我們倒一杯橙汁一半 果汁和一杯牛奶的一半, 較有效的數字1 1杯和2個其他杯中。 

這將是很好的素材。 

JESS:對不起。 

國寶馬蘭:沒有,沒有。 這是確定的。 尼斯。 所有的權利,所以我們有四個字節 值得橙汁。 我們將它稱為值1。 現在另外四個字節價值的牛奶。 將調用它的價值2。 因此,x和y分別。 

所有權利,所以現在如果手頭的任務 -  你,傑西,眼前的一切 你的同學 -  是交換的值的x和y這樣的 我們希望在橙汁 其他杯和這杯牛奶,如何 你可能會 - 之前,你居然做  - 去這樣做呢? 

OK,明智的決定。 所以,你需要多一點的內存。 因此,讓我們分配一個臨時的 杯,如果你願意。 現在進行交換x和y。 

優秀的。 所以做得非常​​好。 謝謝你這麼多,傑西。 給你。 一個小紀念品。 

OK,所以很明顯,超簡單的想法。 完全直觀,我們需要一點點 更多的存儲空間 - 在這種形式中, 一杯 - 如果我們真的要 交換這兩個變量。 因此,讓我們做。 在這裡,我要求我之間上升 我會做一些交換, 走並宣布溫度。 我會設置它等於說,X。 

然後,我要改變的價值 x剛剛像傑斯這裡 牛奶和橙汁 等於y。 我要改變將y等於 而不是x,因為現在我們將 停留在一個圓圈,而是溫度。 我暫時 - 傑斯 暫時把橙汁 前重挫, 一杯牛奶。 

所以,讓我繼續前進,使這個。 它稱為noswap.c。 現在讓我們我運行沒有交換。 事實上,我看到的,如果我擴大 窗口一點點, x為1時,y是2。 然後,x是2,y是1。 

但記得,上週一,我們做的事情 一點點不同,讓我 而不是實現一個輔助函數, 如果你願意,這實際上是無效的。 我把它叫做交換。 我給它兩個參數,我叫 他們,我叫他們b。 

坦白說,我可以給他們打電話x和y。 有什麼能夠阻止 我這樣做。 不過,我會認為它是那麼 有點曖昧。 因為週一召回我們 權利,這些參數是 值的副本傳入 因此,它只是弄亂你 記住,我覺得,如果你使用 完全相同的變量。 

所以,我會打電話給他們,而不是一個 B,僅僅是為了清楚。 但是,我們可以給他們打電話最 我們想要的東西。 我要去複製和粘貼 有有效代碼 下來到這裡。 因為我剛看到它的工作原理。 所以這是相當不錯的形狀。 我會改變我,我的x x到 ,我的Y b和我的Y到b。 

所以換句話說,相同的邏輯。 確切的同樣的事情,傑斯做。 然後我必須做的一件事 這裡,當然,現在調用當前 函數或調用這個函數。 因此,我會調用這個函數有兩個 輸入,X和Y,並點擊保存。 

所有權利,所以從根本上 同樣的事情。 事實上,我可能已經作出計劃 不必要的複雜 寫一個函數,這只是服用 約6行代碼,而我 此前實施 這個只有三歲。 

因此,讓我先走,現在改造 這一點,沒有掉。 好吧,我搞砸了這裡。 這應該是一個錯誤,你可能 看到越來越普遍作為 程序變得更加複雜。 但有一個簡單的辦法。 讓我向後滾動在這裡。 

什麼是我看到的第一個錯誤? 隱式聲明。 通常什麼指示? 哦,我忘了原型。 我忘了教的編譯器,交換 會存在,即使他 在開始時不存在 的方案。 所以,我只是說無效,交換, INT,一個int B,分號。 

所以我不打算重新實現它。 但現在它匹配這裡。 和通知,沒有一個分號 這裡,這是沒有必要的時候 實施。 

因此,讓我重拍,沒有掉。 好得多。 運行沒有交換。 該死的。 現在我們回到我們上週一, 那裡的東西也不會掉。 

有什麼直觀的解釋 為什麼是這種情況呢? 是嗎? 

學生:[聽不清]。 

DAVID馬蘭:沒錯。 因此,a和b是x和y的副本。 而事實上,任何時候,你已經 迄今為止,調用一個函數 通過像整數變量 -  只是作為交換期待 -  你們已經通過副本。 

現在,這意味著它需要一點點 的時間內,第二次分裂, 計算機從一個複製位 變到另一個位。 但是,這不是什麼大不了的。 但是,他們卻一個副本。 

所以現在,在交換的背景下, 事實上,我在成功 改變a和b。 事實上,讓我們做一個快速 完整性檢查。 打印F A%,新生產線。 讓我們插上了。 現在讓我們做同樣的事情,用b。 讓我們在這裡做同樣的事情。 

現在,讓我複製這些相同的行 再次在底部的功能 後,我的三個有趣的線 可以執行, 再次打印a和b。 所以,現在讓我們做,沒有掉。 讓我一個終端窗口 高一點,這樣我們就可以看到 它一次。 

和運行沒有交換。 x為1時,y是2。 a是1,b是2。 然後,a為2,b是1。 因此,它是工作,就像傑西 在這裡做過內部的交換。 不過,當然,它不具有效果 主要變量。 

於是,我們看到了一招,讓我們 可以解決這個問題,對不對? 當你面對這個範圍 的問題,你可能只是平底船,使X 和y變量,而不是什麼樣的呢? 

你可以讓他們在全球範圍。 把他們在最高層的文件 我們這樣做,甚至在比賽中15。 我們使用一個全局變量。 但是在遊戲15的上下文中, 有一個全球性的,這是合理的 變量,代表董事會,因為 15.C全部是所有 關於實施的那場比賽。 這就是該文件存在。 

但是,在這種情況下,在這裡,我 調用函數swap。 我想交換兩個變量。 它應該開始覺得只是馬虎 如果我們所有的解決方案 當我們碰上範圍的問題 問題是使其全球。 因為速度非常快,我們的計劃是 要成為相當混亂。 我們這樣做絕少 作為一個結果15.c. 

但事實證明,有一個 完全有更好的辦法。 實際上,讓我回去,並刪除 打印F的,只是為了簡化代碼。 讓我提出, 這確實是壞的。 但是,如果我不是在一些星號 和星星,我反而可以把這個 成一個功能 實際運作。 

因此,讓我回到這裡,並承認說 星號總是很困難, 所以我會說星星。 我就明說那個。 好的。 而現在,我該怎麼 做什麼呢? 

所以首先,我要指定 ,而不是通過一個int 交換功能,而不是我 去,說INT星級。 現在的明星,什麼指示? 這是一個指針,該概念 賓基,黏土動畫人物, 指一時年前。 

所以,如果我們說詮釋明星的意思 現在,不打算要 通過在其價值。 它不會被複製英寸 的地址的情況相反,是 將要傳遞的。 

因此,記得您的計算機內 一大堆的內存,否則 被稱為RAM。 而且,RAM僅僅是一個 一大堆字節。 所以,如果你的Mac或PC 兩個千兆字節,你有2個 十億字節的內存。 

現在,讓我們假設只是為了 保持美好的東西,有序的,我們 分配一個IP地址 -  一個數字 -  在您的計算機上的每一個字節的RAM。 那些2的第一個字節 億元是由多少個零。 下一個是字節數一數 二,所有的方式起來,點點 點,約2億元。 

所以,你可以的字節數 在您的計算機的內存。 因此,讓我們假設,這是什麼 我們所說的地址。 所以,當我看到INT星級一個,這是怎麼回事 要通過期現掉換是 地址。 不是它的價值,但不論其郵政 地址,可以這麼說 -  它的位置在RAM中。 

同樣為b,我要去 說同樣的事情。 詮釋,星級,B。 順便說一句,技術上的明星 在其他地方可以去。 但是,我們將標準化星級 旁邊的數據類型。 

因此,交換簽名意味著現在,給我 一個int的地址和呼叫 地址一個。 並給我的另一個地址 INT和調用該地址b。 

但現在這裡有我的代碼改變。 因為如果我聲明INT溫度 -  這仍然是int類型的 -  但我存儲在它, 什麼樣的價值? 要清楚,我把一個一個 現在寫的代碼? 

我將在一個位置。 但我不關心 現在的位置,對不對? 溫度存在只是傑斯第三杯 存在,目的是什麼? 要存儲一個值。 牛奶或橙汁。 不實際存儲的地址 那些東西,感覺 在這個現實有點無厘頭 全球上下文反正。 

所以真的,我希望把溫度 的地址的情況,但 內容。 因此,如果a是一個數(如123),這是 123字節的內存,一個公正的 恰好是佔領,該值 在一個恰好是佔領。 

如果我想去到該地址, 我需要說一個明星。 同樣,如果我要改變什麼 地址,我改變 這開始。 如果我要存儲在什麼 什麼位置的位置 B,明星B星。 

因此,在短,即使這是不太 下沉還沒有 - 我不希望 它會如此之快 -  意識到,我做的是前綴 這些星星我的變量, 說不要搶值。 不要改變值。 而是去到這些地址 和得到的價值。 轉到該地址和變化 存在的價值。 

所以,現在讓我回滾動到頂部, 只是為了解決這條線,在這裡, 改變相匹配的原型。 但我現在需要做的另一件事情。 直觀地說,如果我已經改變了類型 論點交換期待, 我需要做什麼 在我的代碼改變? 

當我打電話掉。 因為現在,我是什麼 我仍然通過交換嗎? x的值和y的值,或 牛奶和橙汁。 但我不想這樣做。 我不是要傳遞什麼? 的位置x和 y的位置。 什麼是他們的郵政地址, 可以這麼說。 

因此,要做到這一點,有一個符號。 與符號那種聽起來地址。 因此n&符號,地址 為x,y的地址。 因此,它是故意的,我們使用 &符號調用函數時, 和恆星時,聲明和當 執行的功能。 

符號,只是覺得作為 地址運算符,明星的 去那裡運營商 -  ,或更確切地說, 引用操作 所以這是一個整體的很多話只是 說,現在希望,交換是怎麼回事 是正確的。 

讓我繼續前進,使 -  其實,讓我們重命名文件,以免 這個程序仍然可以稱為無交換。 我要求我們叫它swap.c的現在。 所以,交換。 點,斜線,交換。 

現在確實,x為1時,y是2。 然後,x是2,y是1。 好吧,讓我們來看看,如果我們不能做到這 有點什麼不同 怎麼回事。 首先,讓我放大我們 這裡繪製屏幕。 讓我提出了一會兒 -  每當我在這裡畫將被鏡像 那裡現在 - 讓我提出, 這裡有一大堆的內存,或 RAM,在我的電腦裡面。 

這將是咬號碼, 比方說,1。 這將是字節數2。 ,我會盡一大堆, 然後一堆點點點 表明有是2億美元 這些東西。 4,5,等等。 

因此,有前5個字節 我的計算機的內存。 沒事吧? 很少有人出2億美元。 但現在我要建議 以下。 我要建議,x是要 存儲數字1,和y會 來存儲數字2。 讓我去現在領先,並代表 這些值如下所示。 

讓我們做如下。 給我一秒。 一秒鐘。 確定。 我想這一點 -  讓我們再次做到這一點。 否則我要使用 相同的號碼,無意中, 多次。 

所以只是讓我們有不同的電話號碼, 說說,讓這個字節 123,124,125,126, 點點點。 讓我要求現在我要去 把值1,值2 這裡,否則稱為x和y。 因此,它只是恰巧 這是X,這是Y。 

只是一些隨機的機會, 計算機,操作系統, 碰巧把x的位置 123號。 和Y位置124  -  該死的。 我應該已經解決了這個問題。 哦,男人,我真的想這樣做嗎? 是的,我想解決這個問題和 b今天這個約是恰當的。 很抱歉,在這個新的。 

127,131,我不希望是這樣的 複雜,但為什麼我改變 有數字嗎? 因為我想的整數 實際上是四個字節。 因此,讓的這超肛門。 這樣,如果發生要處理的 123 2將是在地址 127,因為它是距離酒店僅有4輪空。 這就是全部。 我們會忘記所有 在世界的其他地址。 

所以x是在123的位置, y是在位置127。 而現在,其實我做什麼 想幹什麼? 當我打電話期現掉換,有什麼 實際上是怎麼回事呢? 好吧,我調用swap時,我傳遞 的地址x和y的地址。 因此,例如,如果這兩個條 現在的紙張代表兩個 參數A和B交換,我是什麼 打算寫第一, 我要打電話給作為? 

沒錯,123。 因此,我要求的是一個。 這是參數a。 我把x的地址在那裡。 

那是什麼? 

那是什麼? 

沒有,沒有。 這是確定的。 還是不錯的,還是不錯的。 所以這是一個。 現在,在第二張紙, 這將是B,我是什麼 要編寫上 一張紙嗎? 127。 

因此,唯一的改變,因為 這個故事我們以前有說服力的是, 而不是字面上的1和2,我 要通過123和127。 我現在打算把這些內部 這個盒子,所有的權利? 所以,現在黑盒子代表 交換功能。 

同時,讓我們現在有一個人 實現交換功能。 會有人在這裡 喜歡做義工? 上來吧。 你叫什麼名字? 查理。 好吧,查理。 上來吧。 

因此,查理是要發揮 我們黑匣子的作用。 查理,我想請你做什麼 現在以這樣的方式實現交換 的是,由於這兩個地址, 你實際上會 改變值。 我會在你耳邊低語 如何運行這裡的電視。 

所以先走了,你的黑盒子。 到達那裡。 你看到什麼樣的價值觀, 為B你看什麼樣的價值觀? 

查理:一個是123,b是127。 

國寶馬蘭:OK,正好。 現在停在那裡只是一瞬間。 第一件事,你現在打算怎麼辦, 根據代碼 -  現在我會拉在屏幕上 -  將是分配一點 位的內存稱為溫度。 所以,我要繼續前進, 給你的記憶。 

因此,這將是第三個變量 你有訪問 你名為溫度。 你有什麼打算寫 上臨時紙上? 

查理:指針,對不對? 

國寶MALAN:“確定”,遠的不 一定指針。 所以我的代碼行 上突出顯示在右手邊, 我們從這裡開始。 一個明星說。 所以目前保存 數字123。 只是直覺,什麼 星級123是什麼意思? 

但是,具體地,如果a是 123,一個明星意味著什麼? a的值。 或者更隨意,去那裡。 因此,我建議,持有中 你的手,繼續和治療 就好像它是一個地圖。 走自己電腦的 內存,並找到我們的是什麼 在123的位置。 沒錯。 

所以我們看到在位置123 是什麼,很明顯嗎? OK,所以什麼樣的價值現在是你 去付諸溫度? 沒錯。 因此,繼續前進,並做到這一點。 寫數字1片 紙的溫度題為。 

而現在的下一個步驟即 你要實現 會是什麼。 以及,在右手側的 下一行代碼是星級住宿。 ,, 當然,存儲一個地址。 地址127。 星b表示什麼,隨便說嗎? 

進入到該位置。 因此,繼續前進,並找到我們什麼 在127的位置。 確定。 當然,在位置127, 仍然是值2。 那麼你現在店 無論是在上面的位置? 所以明星的手段去的位置。 是什麼位置? 

沒錯。 所以,現在,如果你想改變 什麼是在那個位置 -  我會繼續運行 橡皮擦都在這裡。 現在把它刷上。 你打算寫什麼號碼 在該空白框現在呢? 

沒錯。 所以這行代碼,要明確 - 讓 我暫停了查理的做 這裡指出,他剛剛做了什麼 寫入那個盒子位置123 以前在b的值。 所以我們現在確實實施 這第二行代碼。 

不幸的是,現在有 還有一個剩餘行。 現在是什麼溫度,從字面上看? 這顯然是頭號。 這不是一個地址。 這只是一個號碼,排序 從本週一的變量。 

而現在,當你說星級B,這意味著 去的地址b,這對 當然在這裡。 所以,一旦你到達那裡 -  我會繼續前進,抹去了實際上  - 你是什麼 去現在寫地點127? 

查理:溫度,這是一種。 

DAVID馬蘭:溫度,是其中一個。 和溫度到底發生了什麼? 好了,我們真的不知道。 我們不在乎。 任何時候,我們已經實現了一個功能 到目前為止,你有任何局部變量 確實是本地的。 他們只是消失。 他們回收經營 最終系統。 

因此,溫度的事實,仍然有 數值1是一種從根本上 無趣我們。 好吧,讓掌聲雷動 如果我們能為查理。 非常出色。 

好,那麼還有什麼不 這意味著我們可以做的嗎? 所以,事實證明,我們已經 告訴一些善意的謊言 相當長的一段時間。 事實上,它變成了一個字符串, 這段時間,是不是真的 本身的字符序列。 樣的,直觀的。 

但是從技術上來說,字符串是一個 數據類型,我們內部聲明 CS50庫簡化了世界 類的頭幾個星期。 字符串真的是地址是 一個字符在RAM中的某個地方。 一個字符串,是一個真正的號碼,如123 或127,出現這種情況劃定 字符串開始 您的計算機的內存。 

不過,這並不代表 字符串,每se,本身。 我們可以看到如下。 讓我去進取,不斷開拓 一些代碼之間 今天的源代碼示例。 而且我要繼續前進,並打開 ,讓我們說,比較0.C。 這是一個錯誤的程序會 以如下方式實現。 

第一。 我要說什麼。 然後,我要繼續前進, 從用戶得到一個字符串 在該下一行。 然後,我要再說一遍。 然後我會得到另一個 來自用戶的字符串。 

通知,我展示之一 字符串中的變量稱為S, 另一個這些字符串 在一個變量名為t。 現在,我要索賠,非常 合理,如果s等於等於T, 字符串是相同的。 你鍵入同樣的事情。 否則,琴弦 不一樣的東西。 

畢竟,如果我們輸入兩個整數,兩 字符,兩個浮筒,兩個雙打,任何 我們談過的數據類型 迄今為止對它們進行比較 -  記得我們前一陣子很清楚 你不這樣做,因為一個 當然是一個等號 賦值運算符。 因此,這將是一個錯誤。 

我們用平等等號, 這確實比較 事情真正的平等。 不過,我要求這是越野車。 如果我繼續前進,使比較零, 然後做點斜線比較為零。 我輸入,讓我們說,你好。 然後讓我們再次問好。 從字面上看同樣的事情,電腦 索賠我打不同的事情。 

現在,也許我只是打錯了。 這個時候,我會輸入我的名字。 我的意思是,你好。 你好。 這是不同的,每一次。 

那麼,這是為什麼? 到底發生了什麼 引擎蓋下? 那麼,什麼是真正回事下方 引擎蓋然後是字符串 我輸入的,例如首次 這個詞打招呼,當然。 但是,如果我們代表這底下 引擎蓋,回想一下, 字符串是在一個數組中。 我們已經說了這麼多了過去。 

所以,如果我畫這樣的數組,我 要代表的東西相當 類似剛才我們所做的事情。 並有實際的東西 特別在這裡,太。 我們什麼確定 每一個字符串的結尾? 是啊,這反斜杠零,這是 只是表示方式, 從字面上看,00000000。 八0位成一排。 

我不知道,坦白說, 什麼是在這之後。 那只是一堆更多的RAM 我的電腦裡面。 但是,這是一個數組。 我們談到陣列。 我們通常談論數組 作為零的位置, 再一個,然後兩個。 但是,這只是為了方便。 而這完全是相對的。 

當你實際上得到內存 電腦,當然,任何 2十億一些奇怪的字節,有可能。 所以,真正的引擎蓋下方, 這一切的時候,是的。 這很可能是支架為零。 但是,如果你挖更深下方 油煙機,這是真的 解決123號。 這是地址124。 這是地址125。 

而且我沒有搞砸這個時候。 這些都是現在一個字節 除了由於什麼原因? 一個char有多大? 一個char是只是一個字節。 一個int通常是四個字節。 所以這就是為什麼我做了它123, 127,131,等等。 現在,我可以保持簡單的數學 只是做加1。 這是現在到底發生了什麼 引擎蓋下。 

所以,當你宣布這樣的事情, 字符串s,這其實是 -  原來 -  字符的明星。 明星,當然,這意味著 地址,又名指針。 因此,它的東西的地址。 這是什麼地址? 

那麼 -  我是唯一一個誰可以看到非常 重要的一點,我在做,還是覺得 我做。 所以字符串 -  可悲的是,我有一個監視器 那裡我 能看到的是。 

所有的權利,所以字符串s是什麼 我先前聲明。 但事實證明,由於一個小 神奇的的CS50庫中,這一切都 從字面上有時間字符串 一直字符星級。 明星再次表示 指針或地址。 事實上,它的側翼 字字符意味著它的 一個字符的地址。 

所以,如果字符串被調用,然後我輸入 在H-E-L-L-Ø,現在建議已得到 字串返回 這個時候,即使我們已經相當 過於簡單化的世界嗎? 沒有得到什麼實際字符串 作為它的返回值返回? 

123在這種情況下,例如。 我們以前說過,得到的字符串 只是返回一個字符串,一個序列 字符。 但是,這是一個有點白色的謊言。 的方式得到真正起作用的字符串 引擎蓋下是它得到 來自用戶的字符串。 它撲通一聲的字符 他或她在內存中。 它把一個反斜杠零結尾 這些字符序列。 

但後​​來沒有得到什麼字符串 從字面上返回? 它的字面返回的地址 的第一個字節在RAM中的 它用於這種力量。 而事實證明,僅僅通過返回 一個單一的地址的 第一個字符串中的字符,那就是 足以查找的全部 的字符串。 

換言之,得到的字符串沒有 返回123,124和125。 它沒有給我一個長 列表中所有的字節 我的字符串使用。 因為,他們都是背靠背。 和兩個,是根據第一個地址,我 可以計算出字符串結束。 怎麼樣? 

特殊的空字符, 結束,反斜線零。 因此,換句話說,如果 你傳遞 -  內部變量 -  一個字符的地址,並承擔 ,任何字符串結束時,任何 作為我們人類的字符序列 想到的字符串,如果你假設 在有任何這樣的字符串的末尾 一個反斜杠零,你的黃金。 因為你總是可以找到 字符串的結尾。 

現在,什麼是真正然後去 在這個程序? 為什麼是這樣的程序, 比較0.C,越野車? 什麼是真正被比較? 是嗎? 

學生:[聽不清]。 

DAVID馬蘭:沒錯。 它的位置比較 的字符串。 因此,如果用戶已鍵入招呼一次, 像我一樣,內存可能會結束 這樣看。 然後,如果用戶類型招呼再次 但再次調用get字符串,c是 不特別聰明,除非你教 它是巧妙地編寫代碼。 

C  -  和計算機更普遍 -  如果你輸入單詞再打招呼, 你知道你要得到什麼。 你只是會得到第二個數組 內存,是的,發生 存儲H-E-L-L-O和等等。 

看起來是一樣的,這是怎麼回事 我們人類,但這個地址 可能不是123。 所以它可能只是發生 操作系統具有一些可用的 空間實例在位置 -  比方說,任意東西, 像這樣的位置200。 這是201的位置。 這是位置202。 我們不知道這 要存在於內存中。 

但是,這是什麼意思是,什麼是 將最終被存儲在s? 123。 這是怎麼回事存儲在T, 在這種武斷的例子嗎? 200號。 那麼這意味著是顯而易見的, 123不等於200。 所以如果條件不 計算結果為true。 由於獲取字符串使用不同 每次的內存塊。 

現在,我們可以再次看到這個 在另一個實例中。 讓我去進取,不斷開拓複製0.C的。 我要求這個例子是要 嘗試 - 失敗 - 複製兩個字符串 如下所示。 

我要說點什麼 給用戶。 然後,我會得到一個 串並調用它s。 而現在,我做這個檢查。 我們提到這一段時間回來。 但是,當可能會返回空字符串, 另一個特殊字符,或特殊 符號讓說。 如果它的內存。 

例如,如果用戶是真的 難以和一個窮凶極惡的類型 上面的的字符數 鍵盤和點擊輸入。 如果這個數字的字符就不能 適合在RAM中,不管是任何瘋狂 原因,以及字符串可能 很好返回null。 

或者,如果你的程序本身是做了很多 其他的事情,而且也只是 沒有足夠的內存來獲取字符串 要取得成功,它可能結束 向上返回null。 但是,讓我們更精確 這是什麼。 s的數據類型,什麼是真的嗎? 字符明星。 

因此,原來現在我們可以剝離 回空層。 原來,null是 - 是的,很明顯 一個特殊的符號。 但什麼是真的? 真的,空,我們只是一個符號 人類使用的代表零。 

因此,作者的C,電腦 更一般地,決定年前 這一點,你知道是什麼。 為什麼我們不確保沒有用戶 數據是永遠,永遠,永遠 存儲再見零? 事實上,即使是在我任意的例子 之前,我並沒有開始編號 在零字節。 我開始在一個。 因為我知道,人在世界上 已決定預定的零 在任何人的RAM作為字節 一些特別的東西。 

原因是,任何時候你想 信號出了毛病 地址中,返回 空 - 否則被稱為零 -  因為你知道,有沒有 合法的數據地址零,顯然 這意味著一個錯誤。 這就是為什麼,按照慣例,我們檢查 空和返回的東西 就像一個在這些情況下。 

因此,如果我們現在向下滾動,這只是 然後一些錯誤檢查,以防萬一 [出事了?保釋?] 完全退出程序 通過提前回國。 現在這條線可以改寫 因為這,這意味著什麼呢? 在左側,再給我一次 指針指向一個字符,並調用它噸。 我是什麼存儲裡面的t,根據 這一行代碼? 

我存儲的位置。 具體來說,位置 這是在s。 因此,如果用戶已鍵入招呼, 你好,第一恰好結束 在這裡,然後數123 要回來得到 串並儲存 -  正如我們前面所說 -  在s。 

當我現在宣布另一個指針 一個char並調用它的T,什麼號碼 從字面上去結束在 噸的故事? 所以123。 

所以現在技術上s和 T是指向的確切 相同的內存塊。 所以通知我要現在做什麼 證明,此計劃是馬車。 

首先,我稍後會要求, 打印F,資本化 拷貝的字符串。 然後我會做一個小小的 錯誤檢查。 我要確保。 讓我們確保該字符串t是 至少大於零的長度, 所以有一些字符 實際利用。 

然後你可能還記得這個 從前面的例子。 2上 - 這是在 ctype.h的文件。 Ť支架零給我零 字符的字符串t。 和2上相同的值, 當然,將其轉換為大寫。 

所以憑直覺,這突出顯示的行 代碼是資本化的第一 在T字母。 但它不直觀,轉增股本, 在s的第一個字母。 但是,如果你超前的思維,我是什麼 看當我運行這個程序 並打印出原來, s,而所謂的副本,T? 

他們實際上是相同的。 他們為什麼會是一樣的嗎? 他們都指向 完全一樣的東西。 因此,讓我們做到這一點。 

使副本為零。 編譯OK。 讓我跑副本為零。 讓我鍵入類似您好 全部小寫,然後按Enter鍵。 它聲稱原來的S 副本的確是相同的。 

所以,這裡到底發生了什麼? 讓我重繪此圖片 在講故事 稍微不同的方式。 到底發生了什麼下方 當我聲明類似罩 字符開始,或字符串s 我得到一個指針 -  這恰好是四個字節 的CS50器具中 和很多計算機。 我要調用這個S。 而這目前有 一些未知的值。 

當你聲明一個變量,除非你 自己把一個價值在那裡,誰 知道那裡有什麼。 這可能是一些隨機序列的 位從以前的執行。 所以,當我在我行的代碼做 字符串,然後存儲返回 價值得到字符串s中不知何故 -  我們最終會剝離怎麼弄 字符串的作品,以某種方式分配 可能看起來的陣列 這有點像。 H-E-L-L-O,反斜杠零。 

讓我們假設這是地址 123只是第一次一致性。 因此,獲得字符串返回,在 有突出顯示的行,它返回 我們說的號碼,123。 那麼什麼真正走進這裡的s? 

嗯,真的什麼 裡面的s是123。 但坦率地說,我開始有點 所有這些地址混淆, 所有這些任意數字。 123,124,127。 因此,讓我們簡化 世界一點點。 

當我們談論指針,坦率地說, 我們人類,他們到底在乎 事情是在內存中? 這完全是任意的。 這將取決於如何 多少內存的用戶。 這將依賴於在白天的時候 你運行的程序,也許和 輸入用戶給你。 我們居住不重要的細節上。 

因此,讓我們抽象掉,並說, 當你運行一個像這樣的代碼行, 字符明星就會越來越回報 獲取字符串值。 為什麼我們不而是畫什麼,我們 保持通話就好像它是一個指針 指著東西? 因此,我要求現在到了 有一個指針指向 -  引擎蓋下,它是一個地址。 但它只是指向 第一個字節 字符串,被退回。 

如果我現在回到這裡的代碼, 在這條線是怎麼回事? 那麼,在現在這個突出的線路, 我聲明顯然是另一個 變量名為t。 但它也是一個指針,所以我要去 畫,從理論上講,確切的 同樣大小的方塊。 我要調用它噸。 

現在,如果我們去回到代碼, 當我存儲裡面的T, 技術上我是什麼 把裡面的t? 那麼從技術上說,這 是數字123。 所以,我真的應該寫 有數字123。 但是,讓我們把它更高的水平。 T,如果它僅僅是一個指針, 直觀的,就是這樣。 這是所有被 存儲在那裡。 

所以,現在在最後一個有趣的線 代碼,當我真正去了解 資本化零字符 T,是怎麼回事? 那麼,T支架零現在指向 什麼樣的性格,想必? 

它指向到h。 因為T支架零 -  記得,這是舊的語法。噸支架 只是意味著,如果t是一個字符串,T零 支架零意味著零 在這種力量的人物。 所以,真正意味著什麼 到這個數組 -  是的,這可能是123, 這可能是124。 但它是相對的,記不清了。 每當談論一個數組,我們有 談論的優勢 相對指標。 

所以現在我們可以假設 那件T支架零小時。 所以,如果我叫2上就可以了,那是什麼 真正做的是資本 大寫小寫h H. 不過,當然,什麼是S? 它指向相同織補字符串。 

因此,這是已經發生 在這段代碼中至今。 那麼什麼寓意? 我們如何解決這兩個問題呢? 我們如何比較實際的字符串? 

直觀地好了,怎麼會 你去比較兩個 真正的平等的字符串? 

是什麼意思,如果兩個 字符串相等? 顯然不是,他們的地址是 等於在內存中,因為這是一個低 一級執行細節。 所有的字符是相同的。 所以我建議,讓我介紹一下 在一個compare.c版本 在這裡,所以比較1.C。 

最後,我提議,我們仍然獲得了 指針,和存儲在它 獲取字符串返回值。 讓我們做同樣的事情與t。 因此,沒有代碼是不同的。 我要加少許 更多錯誤檢查現在。 所以,現在我們有點脫皮 這層CS50什麼字符串 實際上,我們需要更肛門 關於如何確保我們不要濫用 無效的值,如空。 

所以我只是去檢查。 如果s不等於空,T不 等於空,這意味著我們確定。 獲取字符串沒有搞砸得到 無論是這些字符串。 你也許可以猜到現在, STR CMP也許可以做到嗎? 字符串比較。 

所以,如果你已經在Java程序之前, 這是像equals方法 string類。 但是,對於那些你們誰沒有 編程之前, 這僅僅是一個C函數。 它發生在 文件名為string.h中。 這就是它的聲明。 

和字符串比較 -  我居然忘記了它的用法, 但從來沒有介意。 回想一下,我們可以做 人,攪勻比較。 這是怎麼回事,彈出 Linux程序員手冊。 和它的,坦率地說,有點神秘。 但我可以在這裡看到,沒錯。 我必須包括string.h中。 

這裡說下描述,“ 字符串比較功能比較 兩個字符串S1和S2。而S1 和S2是顯然是兩個 參數傳入。 我真的不記得什麼 const是,但現在發現 -  你可能已經看到了這一點時,已經 你使用的手冊頁,如果你 擁有這一切 -  字符星級只是代名詞 字符串。 

因此,比較這兩個字符串S1和 S2,並返回一個整數減 於或等於或大於零的 如果發現S1,分別是 小於或匹配,或者 大於S2。 這只是一個非常複雜的方式說 字符串比較回報 零,如果兩個字符串,可以直觀地 相同的字符 對於字符。 

它返回一個負數,如果 ,按字母順序排列,應該是 來之前噸。 或者返回一個正數,如果 s是應該來後t 按字母順序排列。 因此,這個簡單的函數,可以 例如,排序 一大堆的話嗎? 

因此,在這個新版本中,我要去 繼續前進,做比較。 點斜線比較。 我會全部小寫鍵入打招呼。 我要鍵入你好的 再在全部小寫。 幸好現在實現 我輸入了同樣的事情。 

同時,如果我輸入打招呼較低 情況和Hello大寫 對它們進行比較,我打 不同的事情。 不僅是因為地址 不同的,但我們比較 不同的字符一遍又一遍。 

那麼讓我們去修復一個 現在其他問題。 讓我打開一個版本 複製,現在解決 這個問題如下。 而這個人會看 更複雜一點。 但是,如果你想想什麼問題,我們 需要解決,希望這將是 現在只是一瞬間清除。 

因此,這第一線,燒焦啟動T,在 通俗地說可能有人提出 這條線在這裡是指什麼? 字符明星T,這樣做是什麼? 

好。 創建一個指針,指向某些 現貨在內存中。 讓我提煉它一點點。 聲明一個變量將存儲 一些字符在內存中的地址,只是 要適當多一點。 

好了,現在在右手側,我 從來沒有見過這些功能之一 之前,malloc的。 但是,什麼意思呢? 分配的內存。 內存分配。 

因此,原來,到現在為止,我們 還沒有真正有強大的方式 要求的操作系統, 給我一些內存。 相反,我們現在有一個函數調用 malloc的正是這麼做的。 儘管這是一個有點 現在分心,注意到,在 兩個括號之間是 只是要一個數字。 我輸入問題 商標可以是一個數字。 

而且這個數字意味著, 給我10個字節​​。 給我20個字節。 給我100個字節。 和malloc將盡最大努力 要求操作系統 -  Linux中,在這種情況下 -  哎,他們的100個字節 可用的RAM? 如果是這樣,我返回這些字節 返回的地址中的哪一種 這些字節,也許? 第一個。 

因此,這裡太 - 這是佔主導地位 在C中,任何時候你 處理地址? 你幾乎總是處理 第一個這樣的地址,不管有多大 你被一塊內存 傳回,可以這麼說。 

因此,讓我們在這裡潛水。 我想怎麼分配 多少個字節,到底是什麼? 嘛。 字符串的長度為S  - 讓 做一個具體的例子。 如果你好s是,H-E-L-L-O,什麼是 字符串的長度,顯然? 因此,它是五。 但我在做加1,為什麼呢? 為什麼我要六個字節 而不是五個? 空字符。 

我不想離開這 特殊的空字符。 因為如果我做一個副本您好 只是做H-E-L-L-O,但我不把 特別字符,電腦 可能沒有,一次偶然的機會,一個反斜杠 零對我有。 所以,如果我試圖找出 副本的長度,我可能會認為 這是20個字符長,或者一百萬 如果我只是從來沒有發生字符 打反斜線零。 

因此,我們需要6個字節來存儲 H-E-L-L-O,反斜杠零。 然後,這僅僅是 是超肛門。 假設,我忘了什麼 一個char的大小。 我們一直說這是一個字節。 它通常是。 從理論上講,它可能是一些 不同,在不同的Mac或 不同的PC。 

因此,原來有這個操作符 叫的sizeof,如果你傳遞給它 名稱的數據類型 - 像 char或int或浮 -  它會告訴你,動態的,有多少 字節一個字符佔用 特定的計算機。 

因此,這是有效的只是 好像是說次1或 時間什麼都沒有。 但我這樣做只是為了超級肛門, ,一個char以防萬一不同 在您的計算機與礦山,這樣一來 數學總是要退房。 

最後,這裡我檢查null 這始終是很好的做法 - 再 任何時候,我們正在處理的指針。 如果malloc是不是能夠給 我6輪空 - 這是 可能性不大,但以防萬一 -  馬上返回一個。 而現在,接著複製 的字符串,如下所示。 這是熟悉的語法, 儘管在不同的角色。 

我要繼續前進,讓字符串 s的長度,並將其存儲在n。 然後,我要循環從i等於 零和包括正, 大於或等於。 因此,在每次迭代中,我把 在第i個字符的第i個 字符的t。 

所以,到底發生了什麼,上下方 這裡的引擎蓋? 好吧,如果這樣,例如,S  -  我已經輸入字H-E-L-L-O 並有一個反斜杠零。 再次強調,這是這裡的指點。 這裡現在是t。 

這是現在指向 副本內存,對不對? malloc函數有給我一個完整 的內存塊。 我不知道最初是什麼 在所有這些位置。 所以我打算把它們看作 一大堆問號。 

但只要我一開始從零循環 向上穿過的長度,噸 支架零和t支架1  -  我會立即把這個 上的開銷 -  零噸支架和s支架零的意思 我要複製 迭代ħ在這裡,E-L-L-O。 另外,因為我做的加 ,反斜線零。 

所以現在比較1.C的情況下, 在年底,如果我打印出來的 資本的t,我們應該 看到,s是不變的。 讓我現在繼續做這個。 所以COPY1。 點斜線副本1。 我打招呼,輸入要輸入。 現在注意到,只有副本 已被資本化。 因為我確實有兩個 內存塊。 

不幸的是,你可以做一些漂亮的 這裡壞,相當危險的事情。 讓我拉起一個例子現在在這裡, 為我們提供了一個例子,幾個 不同的線路。 所以只是憑直覺在這裡,第一行 碼,詮釋星級的x,正在申報 一個變量x。 ,什麼是數據類型 該變量? 該變量的數據類型是什麼? 這不是吊人胃口。 

的數據類型為int的明星。 那麼,到底是什麼意思呢? X的 一個int存儲地址。 就這麼簡單。 Y為要存儲 一個int地址。 第三行是什麼 代碼做什麼呢? 它的分配多少 字節,最有可能? 四。 由於一個int的大小是 一般四,四的malloc給 我回了一大塊地址 內存的字節的第一個是 現在存儲在x。 

現在,我們正在一點點迅速。 星x表示什麼? 這意味著進入該地址 並提出有什麼號碼? 將有數字42。 星y表示在y 把有13號。 

但是且慢。 y中的那一刻是什麼? 什麼地址為y存儲? 我們不知道,對不對? 我們從來沒有一次使用賦值 運營商涉及Ÿ。 所以y在第二行的聲明 代碼只是一些垃圾值,大 問號可以這麼說。 它可以指向隨機 在內存中的任何事情,這 普遍不好。 

所以只要我們在那裡打線, 星級y等於13,壞的東西, 太差的東西大約是 發生賓基。 因此,讓我們看看會發生什麼結束 發生在這一分鐘賓基 左右的樣子。 

[視頻回放] 

嘿,賓基。 醒來。 它的時間的指針樂趣。 

 - 那是什麼? 了解指針? 哦,滿載而歸。 

好吧,上手,我想我們 將需要一對夫婦的指針。 

 - 確定。 該代碼分配兩個指針 它可以指向整數。 

OK,好了,我看到兩個指針。 但他們似乎沒有要 指向任何東西。 

這是正確的。 最初,指針不 指向任何東西。 它們指向的東西被稱為 指針對象,設置起來是一個 單獨的步驟。 

哦,對,沒錯。 我知道。 指針對象是分開的。 那麼你是怎麼分配一個pointee的? 

 - 確定。 那麼,這個代碼分配一個新的整數 指針對象,而這部分集合X 指向它。 

嘿,這看起來更好。 所以,讓它做點事。 

 - 確定。 我會取消引用指針x到存儲 42號及其指針。 對於這一招,我需要我的魔法 魔杖提領。 

你的魔杖提領? 呃,這是偉大的。 

這是什麼樣的代碼看起來像。 我剛剛設立的數量,以及 -  

嘿,看。 就這樣吧。 這樣算下來,反引用X服從 箭頭訪問及其指針。 在這種情況下,在那裡存儲42。 嘿,嘗試用它來存儲數字 13通過其他指針,Y。 

 - 確定。 我就在這裡為y,並且 13號成立。 然後拿魔杖 提領,只是 -  哇! 

哦,嘿嘿。 這沒有奏效。 賓基說,我不認為 提領y是一個不錯的主意, 因為設立的pointee, 是一個獨立的步驟。 我不認為我們曾經做到了。 

嗯。 好點。 

是的,我們分配的指針y。 但是,我們從來沒有將其設置為 指向的pointee。 

嗯。 非常細心。 

嘿,你看 好,賓基。 你可以解決它,使y點 到相同的指針對象為x? 

 - 當然。 我會用我的魔杖 指針賦值。 

-IS將是一個 像以前一樣的問題? 

沒有。 這不觸摸指針對象。 它只是改變了一個指針指向 作為另一個同樣的事情。 

哦,我明白了。 y點為x到同一個地方。 所以等待。 現在y的固定。 它有一個指針對象。 所以,你可以嘗試魔杖 再次提領 送13以上。 

 - 確定。 這裡去。 

嘿,看看那。 現在提領工程對y。 而且,由於指針共享 那一個指針對象,他們 看到13。 

呀。 共享。 不管。 所以我們現在去開關的地方嗎? 

哦,看。 我們沒時間了。 

但是 -  

只要記住三個 指針規則。 數一,基本結構 就是你有一個指針。 它指向指針對象。 但是,指針和指針對象 是分開的。 常見的錯誤是 設立一個指針,但到 忘了給定的指針對象。 

兩個指針引用開始 上面的指針和如下 箭頭的訪問及其指針。 正如我們都知道,這只是工作,如果有 指針對象,回來 排除頭號。 

三,需要指針賦值 一個指針,它指向的變化 作為另一個指針的指針對象。 因此,在轉讓之後, 兩個指針 指向相同的pointee。 有時候,這就是所謂的共享。 而這一切就是這麼簡單,真的。 再見了。 

[END視頻播放] 

國寶馬蘭:因此,更多的三分球, 更下週賓基上。 我們會看到你在星期一。