[Powered by Google Translate] 讓我們來談談結構。 結構為我們提供了一組變量的一種方式進行分組 一個漂亮的包裝。 這也可能是最容易看到的一個例子, 所以我們說結構, 然後打開大括號, 此結構中,我們將有一個int的年齡, 一個char *的名字, 就是這樣。 它可能看起來怪異的一個大括號後的分號, 但它其實是必要的結構。 任何有效的數據類型可以在struct定義。 在這裡,我們使用了一個int和一個char *, 但你也可以使用一個數組的說,100個元素 另一個結構。 當你在C的結構, 你創建新的類型 的集合其他類型的。 在這裡,我們正在做一個新的類型 從一個整數和一個char *。 正如我們將在後​​面看到,一個結構類型 是在相當於你使用的任何其他類型的方式有很多。 通常情況下,我會比較結構類型, 是類似於一個整數類型。 雖然我們寫的代碼是有效的C, 這是非常有用的, 和鐺會給我們一個警告。 請記住結構和其相似? 好了,我們基本上只是說: INT, 這是不是一個非常有幫助的行。 因此,讓我們聲明該類型的變量 給它起名字前的分號。 我們將調用該變量的學生。 現在,我們已經聲明了一個變量所謂的學生 由結構所給出的類型。 我們怎樣才能得到裡面的結構變量? 從技術上講,這些變量的名稱為 的成員。 要訪問任何特定成員的​​學生結構, 你追加一個點的變量名, 其次是你想要的成員的名稱。 所以在這裡,唯一有效的可能性 是student.age student.name。 我們可以做這樣的事情 student.age = 12 和student.name學生。 現在,如果我們想進行第二次的學生嗎? 你可能會認為複製和粘貼這些行 改變學生到學生2或東西, 將工作, 但在技術上,與學生,學生2 不具有相同的類型。 你看,你將無法將其分配給另一個。 這是因為,到目前為止, 你的結構是匿名的。 我們需要給它一個名字。 要做到這一點,我們插入了名的結構 後字結構。 學生, 其次由定義。 我們仍然可以立即聲明一個變量的類型 結構的學生,就像我們之前。 我們把它叫做S1 通過結構的名稱, 現在,我們可以使用struct學生 在幾乎相同的方式,我們將使用int。 因此,我們可以聲明一個變量的類型結構學生, 喜歡 結構學生S2。 像數組,結構提供了一個快捷的初始化語法, 所以我們可以說,結構學生S2 等於 左花括號3,S2。 在這裡,S2.age將是3, 和S2.name將指向S2。 把所有的事情你可以做一個int類型的 他們的大多數你可以做與結構學生類型。 作為函數參數的類型,我們可以使用一個struct學生。 我們可以使用一個新的結構的內部結構學生。 我們可以有一個指針,指向一個結構的學生。 我們可以做的結構尺寸學生。 結構學生是一種 就像是int類型。 我們也可以指定S1到S2 因為兩者都是相同的類型的,所以我們可以做 S1 = S2。 如果我們這樣做,會發生什麼事 S1.age = 10? 是否S2的變化呢? 同樣,認為就像常規整數的結構。 如果我們給一些int X的一些詮釋y, 如X = Y 然後改變X, 作為在X + +中, Ÿ改變呢? Y不改變這裡,也沒有S2以上。 S2.age仍然是3。 但是請注意,分配一個struct時, 所有的指針指向了同樣的事情, 因為他們只是複製。 如果你不想共享的指針, 你需要手動處理, 也許通過一個塊內存malicking其中一個指針以指向 以及將數據複製過來。 這可能是惱人的學生到處寫結構。 使用類型定義,我們可以做的 類型定義 結構 我們會打電話給學生。 現在,我們可以使用學生無處不在 我們使用使用struct的學生。 這種類型高清的匿名結構 並調用它的學生。 但是,如果我們也能保持學生的標識符 旁邊的字結構,typedef結構的學生, 我們可以同時使用的結構學生和學生互換。 他們甚至不必須具有相同的名稱。 我們可以鮑勃類型定義結構學生 然後STRUCT學生和Bob 將互換的類型。 不管類型高清 我們需要的標識下,以結構 如果定義的結構 是遞歸的。 例如, 類型定義結構節點 它被定義為一個int VAL 將有一個指針,指向另一個結構節點。 中節點*下。 然後,我們把它叫做節點。 這個結構是遞歸的, 自定義的結構節點包含在這 指針的struct節點。 請注意,我們不得不說結構節點下 內的struct節點的定義, 因為類型定義尚未完成,使我們能夠簡化這一 只是節點。 您將了解更多關於結構與此類似 在處理鍊錶和樹。 什麼結構的功能呢? 這也是完全有效的。 我們可以有 喪失功能 作為參數, 學生小號 並與學生做一些事情。 然後,我們可以通過它為學生結構像這樣。 功能從之前的S1。 該結構的行為 正是因為整數時傳遞給函數。 功能的S1收到一份 所以不能修改S1; 相反,只有副本中存儲的S. 如果你想要的功能可以修改S1, 功能將需要採取一個學生* S, 你必須通過S1的地址,像這樣。 學生* S,功能和S1。 還有另外一個原因,通過地址在這裡。 如果我們的結構中包含100個字段? 每一次我們給函數傳遞一個學生, 我們的程序需要所有這100場複製到函數的參數s, 即使它從來沒有使用他們的絕大多數。 因此,即使功能並不打算修改學生, 如果仍然是有價值的,通過地址。 好吧,如果我們想創建一個指向結構的指針? 我們可以做這樣的事情 學生* S 平等的malloc 大小的學生。 請注意,在這裡仍然起作用的大小。 所以,我們現在怎麼辦訪問歲成員 的塊的S點到? 首先,你可能會覺得這樣做 * S.age = 4, 但是這將不是那麼回事。 因為這真的會被解釋為 *括號中S.age = 4, 甚至不能編譯, 因為S是不是一個結構,或者是一個指向結構的指針, 點不會在這裡工作。 我們可以做 (* S)= 4歲。 但括號可以得到惱人的和混亂的。 值得慶幸的是,我們有一個特殊的箭頭操作符 看起來像 S-> = 4歲。 這2種方法的引用年齡 是等價的 和我們真的沒有以往任何時候都需要的箭頭操作符, 但它使事情看起來更漂亮。 由於S是一個指向一些內存塊,它包含結構, 你能想到的S>年齡為指針箭頭 並抓住時代成員。 那麼,為什麼我們應該使用結構? 這是絕對有可能只用原始的整數, 字符,指針和等 我們已經習慣了; 代替S1和S2之前, 我們可以有AGE1,平方,NAME1,NAME2 在單獨的變量。 這是罰款,只有2名學生, 但是,如果我們有10個,其中? 什麼,如果不是只有2個字段, 學生結構有100個字段? GPA,課程,發色,性別,等等。 10結構,而是我們需要1,000個獨立的變量。 另外,還要考慮功能 100個字段,它唯一的參數,該結構 並打印出所有的領域。 如果我們不使用結構, 我們每一次調用該函數, 我們需要通過在所有100個變量, 如果我們有學生1 100個變量, 學生2 100個變量, 我們需要確保我們不小心從學生的一些變量1 學生和一些變量。 這是不可能犯類似的錯誤使用結構, 因為所有的100個變量都​​包含在一個單一封裝。 只是一對夫婦的最後的注意事項: 如果你什麼都明白了這一點,偉大的。 其餘的視頻僅僅是為了完整起見。 由於結構可以持有任何類型的指針, 他們還可以保存函數指針。 如果你熟悉面向對象編程, 這提供了一種方法,使用結構程序在一個面向對象的風格。 在其他時間的函數指針。 此外,有時你可能有2結構 其定義依賴於另一個。 例如, 我們可以有結構A, 它被定義為 指針到一個struct B, B * X, 現在,我們可以有一個struct乙 它被定義為一個指針 一個結構A, A * Y. 但是,這不能編譯, 因為結構B不存在在結構A正在編制。 如果我們交換結構A和結構B, 然後我們就只是留下了同樣的問題; 這個時候,結構中有一個不存在的。 為了解決這個問題,我們可以這樣寫 結構B; 之前定義的結構A. 這就是所謂的前瞻性聲明。 這只是讓編譯器知道 結構B是一個有效的類型,將完全定義或其他地方。 我的名字是羅布·波頓,這是CS50。 [CS50.TV]