《C程式語言》筆記 六 結構

2022-02-02 23:53:08 字數 3486 閱讀 2540

結構是乙個或多個變數的集合,這些變數可能為不同的型別,為了處理的方便而將這些變數組織在乙個名字之下

結構可以拷貝、賦值、傳遞給函式,函式也可以返回結構型別的返回值

自動結構和陣列現在也可以進行初始化

struct point

關鍵字struct引入結構宣告

結構宣告由包含在花括號內的一系列宣告組成

關鍵字struct後面的名字是可選的,稱為結構標記

結構標記用於為結構命名,在定義結構後,結構標記就代表花括號內的宣告,可以用它作為宣告的簡寫形式

結構中定義的變數稱為成員

結構成員、結構標記、和普通變數可以採用相同的名字,不會衝突

struct宣告定義了一種資料型別

在標記結構成員結束的右花括號之後可以跟乙個變數表

struct x,y,z;

這和int x,y,z

具有類似的意義,這兩個宣告都將x、y與z宣告為指定型別的變數,並分配儲存空間

如果結構宣告後面不帶變數表,則不需要為它分配儲存空間,它僅僅描述了乙個結構的模板

如果結構宣告中帶有標記,那麼在以後定義結構實列時便可以使用該標記定義

struct point pt;

在表示式中可以通過下列形式引用某個特定的結構中的成員

結構名.成員

結構可以巢狀

結構的合法操作只有幾種:

作為乙個整體複製和賦值

通過&運算子去 位址,訪問其成員

複製和賦值包括向函式傳遞引數以及從函式返回值

結構之間不可以進行比較

可以用乙個常量成員值列表初始化結構

自動結構也可以通過賦值初始化

如果傳遞給是的結構很大,使用指標的效率通常比複製整個結構的效率高

結構指標類似於普通變數指標 宣告

struct point *pp;

將定義乙個指向struct point型別的指標

如果pp指向乙個point結構,那麼*pp即為該結構

而*(pp).x和*(pp).y則是結構成員

*(pp).x中圓括號是必須的,因為結構成員運算子"." 的優先順序比"*"的優先順序高

表示式 *pp.x含義等於 *(pp.x) ,x不是指標,所以是非法的

結構指標的使用頻率非常高,為了方便,c語言提供另一種簡寫

p->結構成員

在所有的運算子中4個優先順序最高:

結構運算子. 和->

函式呼叫的()

已經下標

表示式 ++pt->len

將增加len的值,而不是增加pt的值,其中隱含的括號關係 ++(pt->len)

陣列的長度在編譯時已經完全確定,它等於陣列項的長度乘以項數

c語言提供了乙個編譯時計算任一物件的長度的運算子 sizeof

表示式

sizeof 物件

或 sizeof(型別名)

將返回乙個整形值,他等於指定物件或型別占用的空間位元組數

嚴格來說sizeof返回的是無符號整形,其型別為size_t

條件編譯語句#if中不能使用sizeof,因為預處理器不對型別名進行分析

但預處理器並不計算#define語句中的表示式,因此 #define中使用sizeof是合法的

千萬不要認為結構的長度等於各成員長度的和。因為不同的物件有不同的對齊要求。

所以結構中可能會出現未命名的"空穴"(hole)

例如:

struct

可能需要8位元組的儲存空間,而不是5位元組。使用sizeof可以返回正確的物件長度

struct tnode

乙個包含其自身實列的結構是非法的

但是,下列宣告是合法的

struct tnode *left;

它將left宣告為指向tnode的指標,而不是tnode本身

雜湊查詢法: 將輸入的名字轉換為乙個小的非負整數,該整數隨後將作為乙個指標陣列的下標

陣列的每個元素指向某個鍊錶的表頭,鍊錶中的各個塊用於描述具有該雜湊值的名字,如果沒有名字雜湊到該值,則陣列元素的值為null

unsigned hash(char *s)

由於在雜湊計算時採用的是無符號算術運算,因此保證了雜湊值非負

c語言提供了乙個typedef的功能,用來建立新的資料型別名

例如:typedef int length;

將length 定義為何int具有同等意義的名字。

型別length可用於型別什麼、型別轉換等

類似於typedef char *string

將string定義為和char *或字元指標同義,此後,便可以在型別宣告和型別轉換中使用string

typedef中宣告的型別在變數名的位置出現,而不是緊接著typedef之後

從任何意義上講,typedef宣告並沒有建立乙個新型別,它只是為某個已存在的型別增加了乙個新的名字

實際上typedef類似於#define語句,但由於typedef是編譯器解釋的,因此他的文字替換功能要超過預處理的能力

除了表示式更簡潔外,typedef使用還有兩個重要原因

首先它可以是程式引數化,以提高程式的可移植性

第二是一位程式提供更好的說明性---treeptr型別顯然比乙個宣告為指向複雜結構的指標更容易讓人理解

聯合是可以在不同時刻儲存不同型別和長度的物件的變數,編譯器負責跟蹤物件的長度和對齊要求。

聯合提供了一種方式,在單塊儲存區中管理不同型別的資料,而不需要程式中嵌入任何機器有關的資訊

例如:union u_tag u;

變數u必須足夠大,以儲存3種型別中最大的一種,具體長度同具體的實現有關

這些型別中的任何一種型別的物件都可以賦值給u,且可使用在隨後的表示式中,但必須保證是一致的:

讀取的型別必須是最近一次存入的型別。

程式設計師負責跟蹤當前儲存在聯合中的型別

如果儲存的型別和讀取的型別不一致,其結果取決於具體的實現

聯合可以使用在結構和陣列中,反之亦可

實際上,聯合就是乙個結構,他的所有成員相對於基位址偏移量都為0

此結構空間要大到足夠容納最寬的成員。

並且,其對齊方式要適合聯合中所有的型別的成員。

對聯合允許的操作與對結構允許的操作相同:

作為乙個整體單元進行複製 賦值 取位址及訪問成員

聯合只能用第乙個成員型別的值進行初始化,因此,聯合u只能用整數進行初始化

在儲存空間很寶貴的情況下,有可能需要將多個物件儲存在乙個機器字中。一種常用的方法是,使用類似於編譯器符號表的單個二進位制位標誌集合。

外部強加的資料格式也經常需要從字的部分位中讀取資料

考慮編譯器中符號表操作的有關細節

程式中的每個識別符號都有與之相關的特定資訊

c語言提供了一種直接定義和訪問乙個字中的位字段的能力,而不需要通過按位操作

位欄位(bit-field)或簡稱字段,是字中相鄰位的集合

某些機器上字段的分配是從字的左端至右端進行的,而某些機器相反。

《C程式語言》讀書筆記(六) 結構

結構的初始化只能緊跟在結構型別的變數宣告後面,必須對所有結構成員進行初始化,且初始化的值必須為常量。比如 struct abc x 或者 struct abc y 或者 struct abc z z.a 200 z.b 300 而不允許 struct abc y y 1.在函式中可以呼叫結構,也可以...

程式設計入門 C語言(六)

乙個多項式可以表達為x的各次冪與係數乘積的和,比如 2x6 3x5 12x3 6x 20 現在,你的程式要讀入兩個多項式,然後輸出這兩個多項式的和,也就是把對應的冪上的係數相加然後輸出。程式要處理的冪最大為100。輸入格式 總共要輸入兩個多項式,每個多項式的輸入格式如下 每行輸入兩個數字,第乙個表示...

C語言程式設計 學習筆記 結構 型別定義

結構體基本 struct structname 分號不要忘了指向結構的指標 struct date myday date p myday 賦值 p month 2 更簡便的方式 p month 2 用例 指標引數 struct point getstruct struct point p int m...