1 00:00:07,360 --> 00:00:09,360 [Powered by Google Translate] 讓我們談論陣列。 2 00:00:09,360 --> 00:00:12,780 那麼,為什麼我們要使用陣列嗎? 3 00:00:12,780 --> 00:00:17,210 那麼讓我們說你有一個程序,需要存儲5個學生證。 4 00:00:17,210 --> 00:00:21,270 這可能似乎是合理的,有5個獨立的變量。 5 00:00:21,270 --> 00:00:24,240 我們會看到在一個位的原因,我們會從0開始計數。 6 00:00:24,240 --> 00:00:30,700 的變量,我們就必須將int ID0,詮釋ID1,等等。 7 00:00:30,700 --> 00:00:34,870 我們想要執行的任何邏輯上學生證需要進行複製和粘貼 8 00:00:34,870 --> 00:00:36,870 這些學生的ID。 9 00:00:36,870 --> 00:00:39,710 如果我們要檢查學生發生在CS50, 10 00:00:39,710 --> 00:00:43,910 我們首先需要檢查,如果ID0代表學生的過程中。 11 00:00:43,910 --> 00:00:48,070 然後做同樣的學生,我們需要的代碼複製並粘貼ID0 12 00:00:48,070 --> 00:00:54,430 替換所有出現ID0 ID1等ID2,3和4。 13 00:00:54,430 --> 00:00:57,560 >> 只要你聽到了,我們需要複製和粘貼, 14 00:00:57,560 --> 00:01:00,440 你應該開始想有一個更好的解決方案。 15 00:01:00,440 --> 00:01:05,360 現在,如果你知道你不需要5個學生證,而是7? 16 00:01:05,360 --> 00:01:09,570 您需要返回到源代碼中添加一個ID5,ID6, 17 00:01:09,570 --> 00:01:14,260 複製並粘貼的邏輯檢查,如果屬於這2個新的ID類的ID。 18 00:01:14,260 --> 00:01:19,600 有沒有所有這些ID連接在一起,所以是沒有辦法的要求 19 00:01:19,600 --> 00:01:22,040 程序做到這一點的ID 0到6。 20 00:01:22,040 --> 00:01:26,120 現在好了,你知道你有100個學生證。 21 00:01:26,120 --> 00:01:30,770 它開始似乎不太理想,需要單獨聲明這些ID, 22 00:01:30,770 --> 00:01:33,760 複製並粘貼這些新的ID任何邏輯。 23 00:01:33,760 --> 00:01:38,380 但是也許我們有決心,我們做的所有100名學生。 24 00:01:38,380 --> 00:01:42,240 但是,如果你不知道有多少學生實際上是什麼? 25 00:01:42,240 --> 00:01:47,320 只是一些有n個學生,你的程序有問什麼,n是用戶。 26 00:01:47,320 --> 00:01:50,250 嗯哦。這是行不通的,非常好。 27 00:01:50,250 --> 00:01:53,820 你的程序只適用於一些固定數量的學生。 28 00:01:53,820 --> 00:01:57,520 >> 解決所有這些問題,是美麗的數組。 29 00:01:57,520 --> 00:01:59,930 那麼,什麼是數組? 30 00:01:59,930 --> 00:02:04,480 在一些編程語言中數組類型可能是能多做一點, 31 00:02:04,480 --> 00:02:09,960 但在這裡,我們將重點放在數組的基本數據結構,就像你會看到它在C. 32 00:02:09,960 --> 00:02:14,030 數組是一個大的內存塊。就是這樣。 33 00:02:14,030 --> 00:02:17,770 當我們說我們有10個整數的數組,這只是意味著我們有一些塊 34 00:02:17,770 --> 00:02:20,740 的內存是大到足以容納10個獨立的整數。 35 00:02:29,930 --> 00:02:33,410 假設一個整數是4個字節,這意味著有10個整數的數組 36 00:02:33,410 --> 00:02:37,180 是一個連續的塊的40個字節在內存中。 37 00:02:42,660 --> 00:02:46,280 即使當您使用多維數組,我們不會在這裡, 38 00:02:46,280 --> 00:02:49,200 它仍然只是一個大的內存塊。 39 00:02:49,200 --> 00:02:51,840 多維符號只是為了方便。 40 00:02:51,840 --> 00:02:55,640 如果你有一個3×3的多維數組的整數, 41 00:02:55,640 --> 00:03:00,650 那麼你的程序會真的只是把這個作為一個大的塊36個字節。 42 00:03:00,650 --> 00:03:05,460 整數的總數是3次3,和每個整數佔用4個字節。 43 00:03:05,460 --> 00:03:07,750 >> 讓我們來看看一個基本的例子。 44 00:03:07,750 --> 00:03:10,660 在這裡我們可以看到兩種不同的方式聲明數組。 45 00:03:15,660 --> 00:03:18,580 我們不得不評論1編譯的程序 46 00:03:18,580 --> 00:03:20,900 因為我們聲明x的兩倍。 47 00:03:20,900 --> 00:03:25,140 我們就來看看一些之間的差異,這2種類型的聲明中位。 48 00:03:25,140 --> 00:03:28,560 這些線路都聲明一個數組的大小為N, 49 00:03:28,560 --> 00:03:30,740 在這裡我們定義N為10。 50 00:03:30,740 --> 00:03:34,460 我們可以要求用戶為一正整數 51 00:03:34,460 --> 00:03:37,250 及使用上,作為我們的數組中的元素數目的整數。 52 00:03:37,250 --> 00:03:41,960 像我們的學生ID的例子之前,這是一種像宣布10完全獨立的 53 00:03:41,960 --> 00:03:49,000 虛變量; X0,X1,x2和等xN的-1。 54 00:03:57,270 --> 00:04:00,840 忽略我們聲明數組的行,注意方括號不變 55 00:04:00,840 --> 00:04:02,090 在fo​​r循環內。 56 00:04:02,090 --> 00:04:09,660 當我們寫的東西,比如x [3],我只是讀為x支架3, 57 00:04:09,660 --> 00:04:13,090 你能想到它是這樣要求的虛X3。 58 00:04:13,090 --> 00:04:17,519 比與大小為N的括號內的數目,這意味著,一個數組的通知 59 00:04:17,519 --> 00:04:22,630 我們稱之為索引,可以是任何東西,從0到N-1, 60 00:04:22,630 --> 00:04:25,660 這是一個總的N個索引。 61 00:04:25,660 --> 00:04:28,260 >> 要想想如何實際工作 62 00:04:28,260 --> 00:04:31,260 請記住,數組是一個大的內存塊。 63 00:04:31,260 --> 00:04:37,460 假設一個整數是4個字節,整個數組x是一個40字節的內存塊。 64 00:04:37,460 --> 00:04:41,360 所以,X0是指非常的塊的第一個4字節。 65 00:04:45,810 --> 00:04:49,230 X [1]是指在接下來的4個字節,等等。 66 00:04:49,230 --> 00:04:53,760 這就是說,開始的x是所有的程序都需要來跟踪。 67 00:04:55,660 --> 00:04:59,840 如果你想使用x [400],然後程序就知道,這相當於 68 00:04:59,840 --> 00:05:03,460 後僅1600字節x的開始。 69 00:05:03,460 --> 00:05:08,780 在哪裡,我們得到1600個字節?這是只有400次4個字節的整數。 70 00:05:08,780 --> 00:05:13,170 >> 在繼續之前,它是非常重要的實現,在C 71 00:05:13,170 --> 00:05:17,080 在陣列中使用的索引,我們沒有強制執行。 72 00:05:17,080 --> 00:05:23,180 我們的大的塊是只有10個整數長,但絕對不會罵我們,如果我們寫X [20] 73 00:05:23,180 --> 00:05:26,060 甚至是X [-5]。 74 00:05:26,060 --> 00:05:28,240 該指數甚至不必須是一個數字。 75 00:05:28,240 --> 00:05:30,630 它可以是任意表達式。 76 00:05:30,630 --> 00:05:34,800 在該方案中,我們使用變量i的循環索引數組。 77 00:05:34,800 --> 00:05:40,340 這是一個非常常見的模式,循環從i = 0到該陣列的長度, 78 00:05:40,340 --> 00:05:43,350 然後使用i作為指數為陣列。 79 00:05:43,350 --> 00:05:46,160 這樣你整個陣列的有效循環, 80 00:05:46,160 --> 00:05:50,600 ,你可以指定數組中的每一個點,或者用它來進行一些計算。 81 00:05:50,600 --> 00:05:53,920 >> 在第一個for循環中,我從0開始, 82 00:05:53,920 --> 00:05:58,680 所以它會分配到0點的數組中的值0次2。 83 00:05:58,680 --> 00:06:04,370 然後,我的增量,和我們指定的第一點在數組中的值1倍,2。 84 00:06:04,370 --> 00:06:10,170 然後,我的增量再等等,直到我們就到了指定的位置N-1陣列中的 85 00:06:10,170 --> 00:06:13,370 值N-1倍,2。 86 00:06:13,370 --> 00:06:17,810 因此,我們創建了一個數組的第一個10個偶數。 87 00:06:17,810 --> 00:06:21,970 也許埃文斯會是一個更好的變量名比x, 88 00:06:21,970 --> 00:06:24,760 但這樣做東西拿走。 89 00:06:24,760 --> 00:06:30,210 第二個for循環,只打印出的價值,我們已經存放在裡面的數組。 90 00:06:30,210 --> 00:06:33,600 >> 讓我們嘗試運行的程序與這兩種類型的數組聲明 91 00:06:33,600 --> 00:06:36,330 看看該程序的輸出。 92 00:06:51,450 --> 00:06:57,020 據我們可以看到,程序的行為同樣的方式為兩種類型的聲明。 93 00:06:57,020 --> 00:07:02,230 讓我們也來看看會發生什麼,如果我們改變了第一循環不停止在N 94 00:07:02,230 --> 00:07:05,040 而是說10,000元。 95 00:07:05,040 --> 00:07:07,430 超出了數組末尾的途徑。 96 00:07:14,700 --> 00:07:17,210 哎呀。也許你已經看到了這一點。 97 00:07:17,210 --> 00:07:20,440 一個分割錯誤意味著你的程序崩潰。 98 00:07:20,440 --> 00:07:24,430 你會開始看到這些,當你觸摸你不應該接觸的內存區域。 99 00:07:24,430 --> 00:07:27,870 在這裡,我們都在觸摸開始的X超過一萬個名額, 100 00:07:27,870 --> 00:07:31,920 這顯然是在內存中,我們不應該接觸的地方。 101 00:07:31,920 --> 00:07:37,690 所以,我們大多數人可能會不小心把10,000,而不是N, 102 00:07:37,690 --> 00:07:42,930 但如果我們做一些更微妙的像說寫小於或等於N 103 00:07:42,930 --> 00:07:46,830 在fo​​r循環中的條件,而不是小於N。 104 00:07:46,830 --> 00:07:50,100 請記住,一個數組只具有從0到N-1的索引, 105 00:07:50,100 --> 00:07:54,510 這意味著,索引N超出陣列的結尾。 106 00:07:54,510 --> 00:07:58,050 在這種情況下,該程序可能不會崩潰,但它仍然是一個錯誤。 107 00:07:58,050 --> 00:08:01,950 其實,這個錯誤是很常見的,它有它的自己的名字, 108 00:08:01,950 --> 00:08:03,970 關閉1個錯誤。 109 00:08:03,970 --> 00:08:05,970 >> 這是它的基本知識。 110 00:08:05,970 --> 00:08:09,960 那麼,什麼是2種類型的數組聲明的主要區別? 111 00:08:09,960 --> 00:08:13,960 一個區別是大的內存塊。 112 00:08:13,960 --> 00:08:17,660 在第一個聲明,我會打電話給支架數組類型, 113 00:08:17,660 --> 00:08:20,300 雖然這絕不是以往的名稱, 114 00:08:20,300 --> 00:08:22,480 它會在棧上。 115 00:08:22,480 --> 00:08:27,450 而在第二,我會打電話給指針數組類型,它會在堆上。 116 00:08:27,450 --> 00:08:32,480 這意味著,當函數返回時,支架陣列會自動被釋放, 117 00:08:32,480 --> 00:08:36,419 而你必須explicitily撥打免費的指針數組 118 00:08:36,419 --> 00:08:38,010 否則,你有內存洩漏。 119 00:08:38,010 --> 00:08:42,750 此外,在托架陣列實際上是不是一個變量。 120 00:08:42,750 --> 00:08:45,490 這是很重要的。這只是一個符號。 121 00:08:45,490 --> 00:08:49,160 你可以認為它是一個常量,編譯器供您選擇。 122 00:08:49,160 --> 00:08:52,970 這意味著,我們不能做什麼,比如x + +的支架類型, 123 00:08:52,970 --> 00:08:56,240 雖然這是完全合法的指針類型。 124 00:08:56,240 --> 00:08:58,270 >> 指針類型是一個變量。 125 00:08:58,270 --> 00:09:01,510 對於指針類型,我們有2個獨立的內存塊。 126 00:09:01,510 --> 00:09:06,060 該變量x自身被存儲在堆棧中,並只是一個單一的指針, 127 00:09:06,060 --> 00:09:08,620 但大的內存塊存儲在堆中。 128 00:09:08,620 --> 00:09:11,010 只是存儲在堆棧中的變量x的地址 129 00:09:11,010 --> 00:09:14,010 大的堆內存塊。 130 00:09:14,010 --> 00:09:17,370 這方面的一個含義是與運營商的規模。 131 00:09:17,370 --> 00:09:22,480 如果你問的支架數組的大小,它會給你的大內存塊的大小, 132 00:09:22,480 --> 00:09:24,620 像40字節, 133 00:09:24,620 --> 00:09:26,920 但如果你問的指針類型的數組的大小, 134 00:09:26,920 --> 00:09:32,740 它會給你變量x本身,而在設備上可能只有4個字節的大小。 135 00:09:32,740 --> 00:09:36,530 使用指針數組類型,它是不​​可能直接要求 136 00:09:36,530 --> 00:09:38,530 大的內存塊的大小。 137 00:09:38,530 --> 00:09:42,530 這是沒多大的限制,因為我們很少想的大小 138 00:09:42,530 --> 00:09:46,980 大的內存塊,如果我們需要的話,我們通常可以計算出它。 139 00:09:46,980 --> 00:09:51,490 >> 最後,支架陣列恰好為我們提供的快捷方式初始化數組。 140 00:09:51,490 --> 00:09:56,130 讓我們看看我們如何可以寫第一個使用快捷鍵在實例10個偶數。 141 00:10:11,220 --> 00:10:14,470 指針數組,有沒有一種方法可以做到這樣的快捷方式。 142 00:10:14,470 --> 00:10:18,120 這僅僅是你可以做什麼與陣列的介紹。 143 00:10:18,120 --> 00:10:20,990 他們出現在幾乎每一個程序,你寫的。 144 00:10:20,990 --> 00:10:24,390 希望你現在可以看到一個更好的方式做學生證的例子 145 00:10:24,390 --> 00:10:26,710 從一開始的視頻。 146 00:10:26,710 --> 00:10:29,960 >> 我的名字是羅布·波頓,這是CS50。