1 00:00:07,260 --> 00:00:09,180 [Powered by Google Translate] 讓我們來談談結構。 2 00:00:09,180 --> 00:00:12,130 結構為我們提供了一組變量的一種方式進行分組 3 00:00:12,130 --> 00:00:14,350 一個漂亮的包裝。 4 00:00:14,350 --> 00:00:17,020 這也可能是最容易看到的一個例子, 5 00:00:17,020 --> 00:00:20,030 所以我們說結構, 6 00:00:20,030 --> 00:00:23,340 然後打開大括號, 7 00:00:23,340 --> 00:00:26,630 此結構中,我們將有一個int的年齡, 8 00:00:28,920 --> 00:00:31,350 一個char *的名字, 9 00:00:31,350 --> 00:00:34,670 就是這樣。 10 00:00:37,350 --> 00:00:40,650 它可能看起來怪異的一個大括號後的分號, 11 00:00:40,650 --> 00:00:43,620 但它其實是必要的結構。 12 00:00:43,620 --> 00:00:46,270 任何有效的數據類型可以在struct定義。 13 00:00:46,270 --> 00:00:49,530 在這裡,我們使用了一個int和一個char *, 14 00:00:49,530 --> 00:00:52,610 但你也可以使用一個數組的說,100個元素 15 00:00:52,610 --> 00:00:54,910 另一個結構。 16 00:00:54,910 --> 00:00:56,960 當你在C的結構, 17 00:00:56,960 --> 00:00:58,430 你創建新的類型 18 00:00:58,430 --> 00:01:00,860 的集合其他類型的。 19 00:01:00,860 --> 00:01:02,620 在這裡,我們正在做一個新的類型 20 00:01:02,620 --> 00:01:05,060 從一個整數和一個char *。 21 00:01:05,060 --> 00:01:07,400 正如我們將在後​​面看到,一個結構類型 22 00:01:07,400 --> 00:01:10,700 是在相當於你使用的任何其他類型的方式有很多。 23 00:01:10,700 --> 00:01:13,310 通常情況下,我會比較結構類型, 24 00:01:13,310 --> 00:01:15,790 是類似於一個整數類型。 25 00:01:15,790 --> 00:01:18,520 雖然我們寫的代碼是有效的C, 26 00:01:18,520 --> 00:01:20,320 這是非常有用的, 27 00:01:20,320 --> 00:01:22,340 和鐺會給我們一個警告。 28 00:01:22,340 --> 00:01:24,970 請記住結構和其相似? 29 00:01:24,970 --> 00:01:26,710 好了,我們基本上只是說: 30 00:01:27,840 --> 00:01:30,060 INT, 31 00:01:30,060 --> 00:01:33,140 這是不是一個非常有幫助的行。 32 00:01:33,140 --> 00:01:35,760 因此,讓我們聲明該類型的變量 33 00:01:35,760 --> 00:01:38,760 給它起名字前的分號。 34 00:01:42,170 --> 00:01:45,000 我們將調用該變量的學生。 35 00:01:48,190 --> 00:01:51,350 現在,我們已經聲明了一個變量所謂的學生 36 00:01:51,350 --> 00:01:53,980 由結構所給出的類型。 37 00:01:53,980 --> 00:01:56,730 我們怎樣才能得到裡面的結構變量? 38 00:01:56,730 --> 00:01:59,040 從技術上講,這些變量的名稱為 39 00:01:59,040 --> 00:02:01,070 的成員。 40 00:02:01,070 --> 00:02:04,000 要訪問任何特定成員的​​學生結構, 41 00:02:04,000 --> 00:02:06,440 你追加一個點的變量名, 42 00:02:06,440 --> 00:02:08,860 其次是你想要的成員的名稱。 43 00:02:08,860 --> 00:02:11,690 所以在這裡,唯一有效的可能性 44 00:02:11,690 --> 00:02:17,760 是student.age 45 00:02:17,760 --> 00:02:24,460 student.name。 46 00:02:24,460 --> 00:02:26,820 我們可以做這樣的事情 47 00:02:26,820 --> 00:02:30,320 student.age = 12 48 00:02:30,320 --> 00:02:39,310 和student.name學生。 49 00:02:39,310 --> 00:02:42,580 現在,如果我們想進行第二次的學生嗎? 50 00:02:42,580 --> 00:02:44,760 你可能會認為複製和粘貼這些行 51 00:02:44,760 --> 00:02:48,110 改變學生到學生2或東西, 52 00:02:48,110 --> 00:02:50,090 將工作, 53 00:02:50,090 --> 00:02:52,670 但在技術上,與學生,學生2 54 00:02:52,670 --> 00:02:54,540 不具有相同的類型。 55 00:02:54,540 --> 00:02:56,940 你看,你將無法將其分配給另一個。 56 00:02:56,940 --> 00:02:58,560 這是因為,到目前為止, 57 00:02:58,560 --> 00:03:00,950 你的結構是匿名的。 58 00:03:00,950 --> 00:03:02,290 我們需要給它一個名字。 59 00:03:02,290 --> 00:03:04,420 要做到這一點,我們插入了名的結構 60 00:03:04,420 --> 00:03:06,950 後字結構。 61 00:03:09,440 --> 00:03:11,170 學生, 62 00:03:11,170 --> 00:03:14,680 其次由定義。 63 00:03:16,500 --> 00:03:18,940 我們仍然可以立即聲明一個變量的類型 64 00:03:18,940 --> 00:03:21,570 結構的學生,就像我們之前。 65 00:03:24,320 --> 00:03:28,360 我們把它叫做S1 66 00:03:28,590 --> 00:03:30,760 通過結構的名稱, 67 00:03:30,760 --> 00:03:33,050 現在,我們可以使用struct學生 68 00:03:33,050 --> 00:03:36,950 在幾乎相同的方式,我們將使用int。 69 00:03:36,950 --> 00:03:39,580 因此,我們可以聲明一個變量的類型結構學生, 70 00:03:39,580 --> 00:03:42,360 喜歡 71 00:03:42,360 --> 00:03:49,500 結構學生S2。 72 00:03:51,020 --> 00:03:55,130 像數組,結構提供了一個快捷的初始化語法, 73 00:03:55,130 --> 00:03:58,670 所以我們可以說,結構學生S2 74 00:03:58,670 --> 00:04:01,420 等於 75 00:04:01,420 --> 00:04:06,040 左花括號3,S2。 76 00:04:09,210 --> 00:04:12,600 在這裡,S2.age將是3, 77 00:04:12,600 --> 00:04:15,910 和S2.name將指向S2。 78 00:04:15,910 --> 00:04:19,149 把所有的事情你可以做一個int類型的 79 00:04:19,149 --> 00:04:22,460 他們的大多數你可以做與結構學生類型。 80 00:04:22,460 --> 00:04:26,060 作為函數參數的類型,我們可以使用一個struct學生。 81 00:04:26,060 --> 00:04:28,790 我們可以使用一個新的結構的內部結構學生。 82 00:04:28,790 --> 00:04:31,010 我們可以有一個指針,指向一個結構的學生。 83 00:04:31,010 --> 00:04:33,540 我們可以做的結構尺寸學生。 84 00:04:33,540 --> 00:04:35,510 結構學生是一種 85 00:04:35,510 --> 00:04:38,030 就像是int類型。 86 00:04:38,030 --> 00:04:40,540 我們也可以指定S1到S2 87 00:04:40,540 --> 00:04:43,760 因為兩者都是相同的類型的,所以我們可以做 88 00:04:44,390 --> 00:04:47,540 S1 = S2。 89 00:04:47,540 --> 00:04:50,430 如果我們這樣做,會發生什麼事 90 00:04:50,430 --> 00:04:55,300 S1.age = 10? 91 00:04:56,340 --> 00:04:58,880 是否S2的變化呢? 92 00:04:58,880 --> 00:05:02,800 同樣,認為就像常規整數的結構。 93 00:05:02,800 --> 00:05:05,590 如果我們給一些int X的一些詮釋y, 94 00:05:05,590 --> 00:05:08,970 如X = Y 95 00:05:08,970 --> 00:05:10,850 然後改變X, 96 00:05:10,850 --> 00:05:14,230 作為在X + +中, 97 00:05:14,230 --> 00:05:17,020 Ÿ改變呢? 98 00:05:17,020 --> 00:05:20,980 Y不改變這裡,也沒有S2以上。 99 00:05:20,980 --> 00:05:24,120 S2.age仍然是3。 100 00:05:24,120 --> 00:05:27,350 但是請注意,分配一個struct時, 101 00:05:27,350 --> 00:05:30,300 所有的指針指向了同樣的事情, 102 00:05:30,300 --> 00:05:32,260 因為他們只是複製。 103 00:05:32,260 --> 00:05:34,300 如果你不想共享的指針, 104 00:05:34,300 --> 00:05:36,100 你需要手動處理, 105 00:05:36,100 --> 00:05:39,780 也許通過一個塊內存malicking其中一個指針以指向 106 00:05:39,780 --> 00:05:42,120 以及將數據複製過來。 107 00:05:42,120 --> 00:05:45,540 這可能是惱人的學生到處寫結構。 108 00:05:45,540 --> 00:05:48,730 使用類型定義,我們可以做的 109 00:05:51,630 --> 00:05:55,850 類型定義 110 00:05:55,850 --> 00:05:58,830 結構 111 00:05:58,830 --> 00:06:01,270 我們會打電話給學生。 112 00:06:05,620 --> 00:06:08,360 現在,我們可以使用學生無處不在 113 00:06:08,360 --> 00:06:11,090 我們使用使用struct的學生。 114 00:06:11,090 --> 00:06:13,410 這種類型高清的匿名結構 115 00:06:13,410 --> 00:06:15,750 並調用它的學生。 116 00:06:15,750 --> 00:06:18,220 但是,如果我們也能保持學生的標識符 117 00:06:18,220 --> 00:06:22,380 旁邊的字結構,typedef結構的學生, 118 00:06:27,670 --> 00:06:31,590 我們可以同時使用的結構學生和學生互換。 119 00:06:31,590 --> 00:06:34,060 他們甚至不必須具有相同的名稱。 120 00:06:34,060 --> 00:06:36,710 我們可以鮑勃類型定義結構學生 121 00:06:36,710 --> 00:06:38,950 然後STRUCT學生和Bob 122 00:06:38,950 --> 00:06:41,270 將互換的類型。 123 00:06:41,270 --> 00:06:44,050 不管類型高清 124 00:06:44,050 --> 00:06:46,750 我們需要的標識下,以結構 125 00:06:46,750 --> 00:06:48,250 如果定義的結構 126 00:06:48,250 --> 00:06:50,450 是遞歸的。 127 00:06:50,450 --> 00:06:52,620 例如, 128 00:06:52,620 --> 00:06:56,140 類型定義結構節點 129 00:06:56,140 --> 00:07:01,200 它被定義為一個int VAL 130 00:07:01,200 --> 00:07:05,420 將有一個指針,指向另一個結構節點。 131 00:07:05,420 --> 00:07:09,490 中節點*下。 132 00:07:09,490 --> 00:07:13,670 然後,我們把它叫做節點。 133 00:07:15,490 --> 00:07:18,020 這個結構是遞歸的, 134 00:07:18,020 --> 00:07:21,450 自定義的結構節點包含在這 135 00:07:21,450 --> 00:07:24,200 指針的struct節點。 136 00:07:24,200 --> 00:07:27,740 請注意,我們不得不說結構節點下 137 00:07:27,740 --> 00:07:30,690 內的struct節點的定義, 138 00:07:30,690 --> 00:07:33,620 因為類型定義尚未完成,使我們能夠簡化這一 139 00:07:33,620 --> 00:07:36,210 只是節點。 140 00:07:36,210 --> 00:07:39,260 您將了解更多關於結構與此類似 141 00:07:39,260 --> 00:07:41,750 在處理鍊錶和樹。 142 00:07:41,750 --> 00:07:44,130 什麼結構的功能呢? 143 00:07:44,130 --> 00:07:46,800 這也是完全有效的。 144 00:07:46,800 --> 00:07:49,430 我們可以有 145 00:07:49,430 --> 00:07:53,630 喪失功能 146 00:07:53,630 --> 00:07:55,930 作為參數, 147 00:07:55,930 --> 00:07:59,590 學生小號 148 00:07:59,590 --> 00:08:02,790 並與學生做一些事情。 149 00:08:05,270 --> 00:08:08,450 然後,我們可以通過它為學生結構像這樣。 150 00:08:08,450 --> 00:08:12,850 功能從之前的S1。 151 00:08:12,850 --> 00:08:15,230 該結構的行為 152 00:08:15,230 --> 00:08:18,460 正是因為整數時傳遞給函數。 153 00:08:18,460 --> 00:08:21,510 功能的S1收到一份 154 00:08:21,510 --> 00:08:23,690 所以不能修改S1; 155 00:08:23,690 --> 00:08:27,110 相反,只有副本中存儲的S. 156 00:08:27,110 --> 00:08:30,010 如果你想要的功能可以修改S1, 157 00:08:30,010 --> 00:08:33,000 功能將需要採取一個學生* S, 158 00:08:33,000 --> 00:08:36,570 你必須通過S1的地址,像這樣。 159 00:08:37,549 --> 00:08:41,100 學生* S,功能和S1。 160 00:08:41,100 --> 00:08:44,760 還有另外一個原因,通過地址在這裡。 161 00:08:44,760 --> 00:08:48,030 如果我們的結構中包含100個字段? 162 00:08:48,030 --> 00:08:51,250 每一次我們給函數傳遞一個學生, 163 00:08:51,250 --> 00:08:55,770 我們的程序需要所有這100場複製到函數的參數s, 164 00:08:55,770 --> 00:08:59,320 即使它從來沒有使用他們的絕大多數。 165 00:08:59,320 --> 00:09:02,700 因此,即使功能並不打算修改學生, 166 00:09:02,700 --> 00:09:05,170 如果仍然是有價值的,通過地址。 167 00:09:05,170 --> 00:09:08,990 好吧,如果我們想創建一個指向結構的指針? 168 00:09:08,990 --> 00:09:11,130 我們可以做這樣的事情 169 00:09:11,130 --> 00:09:17,580 學生* S 170 00:09:17,580 --> 00:09:20,980 平等的malloc 171 00:09:20,980 --> 00:09:26,600 大小的學生。 172 00:09:30,450 --> 00:09:33,590 請注意,在這裡仍然起作用的大小。 173 00:09:33,590 --> 00:09:37,260 所以,我們現在怎麼辦訪問歲成員 174 00:09:37,260 --> 00:09:39,640 的塊的S點到? 175 00:09:39,640 --> 00:09:42,300 首先,你可能會覺得這樣做 176 00:09:42,300 --> 00:09:47,970 * S.age = 4, 177 00:09:47,970 --> 00:09:50,220 但是這將不是那麼回事。 178 00:09:50,220 --> 00:09:52,940 因為這真的會被解釋為 179 00:09:52,940 --> 00:09:57,740 *括號中S.age = 4, 180 00:09:57,740 --> 00:10:00,160 甚至不能編譯, 181 00:10:00,160 --> 00:10:03,600 因為S是不是一個結構,或者是一個指向結構的指針, 182 00:10:03,600 --> 00:10:06,270 點不會在這裡工作。 183 00:10:06,270 --> 00:10:08,860 我們可以做 184 00:10:08,860 --> 00:10:13,760 (* S)= 4歲。 185 00:10:13,760 --> 00:10:16,790 但括號可以得到惱人的和混亂的。 186 00:10:16,790 --> 00:10:19,880 值得慶幸的是,我們有一個特殊的箭頭操作符 187 00:10:19,880 --> 00:10:22,350 看起來像 188 00:10:22,350 --> 00:10:28,860 S-> = 4歲。 189 00:10:28,860 --> 00:10:31,600 這2種方法的引用年齡 190 00:10:31,600 --> 00:10:33,270 是等價的 191 00:10:33,270 --> 00:10:36,870 和我們真的沒有以往任何時候都需要的箭頭操作符, 192 00:10:36,870 --> 00:10:39,300 但它使事情看起來更漂亮。 193 00:10:39,300 --> 00:10:43,050 由於S是一個指向一些內存塊,它包含結構, 194 00:10:43,050 --> 00:10:47,820 你能想到的S>年齡為指針箭頭 195 00:10:47,820 --> 00:10:50,250 並抓住時代成員。 196 00:10:50,250 --> 00:10:53,750 那麼,為什麼我們應該使用結構? 197 00:10:53,750 --> 00:10:57,560 這是絕對有可能只用原始的整數, 198 00:10:57,560 --> 00:10:59,050 字符,指針和等 199 00:10:59,050 --> 00:11:01,550 我們已經習慣了; 200 00:11:01,550 --> 00:11:03,340 代替S1和S2之前, 201 00:11:03,340 --> 00:11:06,290 我們可以有AGE1,平方,NAME1,NAME2 202 00:11:06,290 --> 00:11:09,120 在單獨的變量。 203 00:11:09,120 --> 00:11:11,390 這是罰款,只有2名學生, 204 00:11:11,390 --> 00:11:13,310 但是,如果我們有10個,其中? 205 00:11:13,310 --> 00:11:15,540 什麼,如果不是只有2個字段, 206 00:11:15,540 --> 00:11:17,720 學生結構有100個字段? 207 00:11:17,720 --> 00:11:21,240 GPA,課程,發色,性別,等等。 208 00:11:21,240 --> 00:11:25,790 10結構,而是我們需要1,000個獨立的變量。 209 00:11:25,790 --> 00:11:28,360 另外,還要考慮功能 210 00:11:28,360 --> 00:11:32,270 100個字段,它唯一的參數,該結構 211 00:11:32,270 --> 00:11:34,350 並打印出所有的領域。 212 00:11:34,350 --> 00:11:36,320 如果我們不使用結構, 213 00:11:36,320 --> 00:11:38,540 我們每一次調用該函數, 214 00:11:38,540 --> 00:11:41,460 我們需要通過在所有100個變量, 215 00:11:41,460 --> 00:11:44,430 如果我們有學生1 100個變量, 216 00:11:44,430 --> 00:11:47,020 學生2 100個變量, 217 00:11:47,020 --> 00:11:50,540 我們需要確保我們不小心從學生的一些變量1 218 00:11:50,540 --> 00:11:52,910 學生和一些變量。 219 00:11:52,910 --> 00:11:55,710 這是不可能犯類似的錯誤使用結構, 220 00:11:55,710 --> 00:11:59,010 因為所有的100個變量都​​包含在一個單一封裝。 221 00:11:59,010 --> 00:12:02,050 只是一對夫婦的最後的注意事項: 222 00:12:02,050 --> 00:12:04,870 如果你什麼都明白了這一點,偉大的。 223 00:12:04,870 --> 00:12:07,900 其餘的視頻僅僅是為了完整起見。 224 00:12:07,900 --> 00:12:11,010 由於結構可以持有任何類型的指針, 225 00:12:11,010 --> 00:12:14,220 他們還可以保存函數指針。 226 00:12:14,220 --> 00:12:17,040 如果你熟悉面向對象編程, 227 00:12:17,040 --> 00:12:21,790 這提供了一種方法,使用結構程序在一個面向對象的風格。 228 00:12:21,790 --> 00:12:24,500 在其他時間的函數指針。 229 00:12:24,500 --> 00:12:27,760 此外,有時你可能有2結構 230 00:12:27,760 --> 00:12:30,220 其定義依賴於另一個。 231 00:12:30,220 --> 00:12:32,320 例如, 232 00:12:32,320 --> 00:12:35,470 我們可以有結構A, 233 00:12:35,470 --> 00:12:38,580 它被定義為 234 00:12:38,580 --> 00:12:41,910 指針到一個struct B, 235 00:12:41,910 --> 00:12:47,180 B * X, 236 00:12:47,180 --> 00:12:50,470 現在,我們可以有一個struct乙 237 00:12:53,890 --> 00:12:56,280 它被定義為一個指針 238 00:12:56,280 --> 00:12:59,180 一個結構A, 239 00:12:59,180 --> 00:13:03,640 A * Y. 240 00:13:07,230 --> 00:13:09,060 但是,這不能編譯, 241 00:13:09,060 --> 00:13:14,110 因為結構B不存在在結構A正在編制。 242 00:13:14,110 --> 00:13:17,600 如果我們交換結構A和結構B, 243 00:13:17,600 --> 00:13:20,100 然後我們就只是留下了同樣的問題; 244 00:13:20,100 --> 00:13:22,640 這個時候,結構中有一個不存在的。 245 00:13:22,640 --> 00:13:24,720 為了解決這個問題,我們可以這樣寫 246 00:13:24,720 --> 00:13:29,290 結構B; 247 00:13:29,290 --> 00:13:32,460 之前定義的結構A. 248 00:13:32,460 --> 00:13:35,590 這就是所謂的前瞻性聲明。 249 00:13:35,590 --> 00:13:38,590 這只是讓編譯器知道 250 00:13:38,590 --> 00:13:42,040 結構B是一個有效的類型,將完全定義或其他地方。 251 00:13:42,040 --> 00:13:45,980 我的名字是羅布·波頓,這是CS50。 252 00:13:45,980 --> 00:13:48,980 [CS50.TV]