一文攻破结构体-C语言
一文攻破結構體-C語言
1 什么是結構體
1.1 結構體類型
結構體(structure)是由不同類型數據組成的組合型的數據結構,可以看做變量的集合。結構體也是一個數據類型,就像和 int、char一樣的數據類型,只不過 int 等數據類型是系統已經聲明好的,而結構體數據類型是由用戶根據需要在程序中指定的,并且可以聲明很多種。
1.2 結構體類型的聲明
聲明一個結構體類型的一般形式:
struct 結構體名 {成員表列 };花括號內是該結構體所包括的子項,稱為結構體的成員(member),成員可以是一種結構體類型(當前結構體類型或其他結構體類型)的變量。
注意:結構體類型的名字是由一個關鍵字 struct 和結構體名組合而成的(例如 struct Info)。結構體名是由用戶指定的,又稱為“結構體標記”(structure tag),以區別于其他結構體類型,即可以設計出許多種結構體類型,而并非只有一種。
struct Info {int id;char name[10];int age;char sex; };1.3 定義結構體類型變量
(1)先聲明結構體類型,再定義該類型的變量
struct Info info1, info2;- struct Info:結構體類型名
- info1, info2:結構體變量名
(2)在聲明類型的同時定義變量,但是這樣定義的變量是全局變量
struct Info {int id;char name[10];int age;char sex; } info;(3)不指定類型名而直接定義結構體類型變量
struct {成員表列 } 變量名表列;對于這種方式,將不能再以此結構體類型去定義其他變量。
(4)使用關鍵字 typedef 定義結構體變量
- typedef:指定新的類型名來代替已有的類型名
- 使用格式:typedef {已有的類型名} {新的類型名}
-
根據 typedef 的用法,可以得出以下代碼段相當于 {已有的類型名}
struct Info {int id;char name[10];int age;char sex; } -
info 相當于 {新的類型名}
接下來,我們便可以使用結構類型 info 來定義結構體變量,如 info info1
1.4 結構體數據類型變量所占內存
在定義好了結構體變量后,系統會為之分配內存單元。不同的編譯系統對結構體變量在內存中分配空間有不同的規定。
在 Visual C++ 中結構體變量所占內存大小就是其各個成員所占內存大小的和,如下這個結構體變量:
struct Info {int id;char name[10];int age;char sex; } info;其成員變量所占的內存大小為 4 + 10 + 4 + 1 = 19,即理論上該結構體變量所占內存大小為 19,實際上其所占內存大小為 20。即當運行 sizeof(info) 時,其輸出結果為 20。
由于計算機對內存的管理是以“字”為單位的(許多計算機系統以 4 個字節為一個“字”)。如果在一個“字”中只存放了一個字符,雖然只占一個字節,但該“字”中的其他 3 個字節不會接著存放下一個數據,而是從下一個“字”開始存放其他數據,所以用 sizeof 運算符測量變量的長度時,其輸出的所占內存大小是 4 的倍數。
2 操作結構體
2.1 結構體變量的初始化
(1)在定義結構體變量時對它的成員初始化
struct Info {int id;char name[10];int age;char sex; } info = {201807103142, "tianyvHon", 23, 'M'};(2)通過引用的方式進行初始化
struct Info info = {.id = 201807103142;.name = "tianyvHon";.age = 23;.sex = 'M' };.name 隱含代表結構體變量 info 中的成員 info.name,如果有未被指定初始化的變量,那么數值型成員被系統初始化為 0,字符型成員被系統初始化為 \0,指針型成員被系統初始化為 NULL。
2.2 訪問結構體成員
結構體成員的訪問有點不同于以往的任何變量,它是采用點號運算符·來訪問成員的。比如,info.name就是引用 info結構體的 name成員,是一個字符數組,而info.gae則引用info結構體的age成員,是個整型。
(1)在程序中對結構體變量的成員賦值
struct Info {int id;char name[10];int age;char sex; } info;info.id = 1; info.name = "tianyvHon"; info.age = 20; info.sex = 'M';(2)在程序中輸出結構體變量的成員的值
struct Info {int id;char name[10];int age;char sex; } info = {201807103142, "tianyvHon", 23, 'M'};printf("%d\n", info.id);2.3 操作結構體時需要注意的事項
(1)不能企圖通過輸出結構體變量名來達到輸出結構體變量所有成員的值。
- printf("%s\n", info);(錯誤)
(2)同類的結構體變量可以互相賦值
- info1 = info2;
(3)可以引用結構體變量成員的地址,也可以引用結構體變量的地址
- scanf("%d", &info.id);
- printf("%o", &info);
(4)對結構體變量的成員可以像普通變量一樣進行各種運算(根據其類型決定可以進行的運算)
- info2.age = info1.age;
- info1.age++;
3 結構體數組
結構體數組與之前數值型數組的不同之處在于每個數組元素都是一個結構體類型的數據,它們分別包括各個成員項。
定義結構體數組的一般形式:
-
struct 結構體名
{成員表列} 數組名[數組長度];
struct Info {int id;char name[10];int age;char sex; } info[3]; -
先聲明結構體類型,然后以此類型定義結構體數組
結構體類型 數組名[數組長度];
struct Info {int id;char name[10];int age;char sex; }; struct Info info[3];
初始化結構體數組:
-
在定義數組的后面加上 = {初值表列}
struct Info {int id;char name[10];int age;char sex; } info[3] = {1, "Hon", 20, 'M', 2, "Wong", 21, 'M', 3, "Tv", 22, 'M'}; struct Info {int id;char name[10];int age;char sex; }; struct Info info[3] = {1, "Hon", 20, 'M', 2, "Wong", 21, 'M', 3, "Tv", 22, 'M'};
4 結構體指針
結構體指針就是指向結構體變量的指針,一個結構體變量的起始地址就是這個結構體變量的指針。如果把一個結構體變量的起始地址存放在一個指針變量中,那么這個指針變量指向該結構體變量。
(1)指向結構體變量的指針
指針變量的基類型必須與結構體變量的類型相同。定義結構體變量指針的一般格式:struct Info *pi;
struct Info {int id;char name[10];int age;char sex; } info;struct Info *pinfo; // 定義指向 struct Info 類型數據的指針變量 pinfo pinfo = &info; // pinfo 指向 info/*************************** 初始化結構體變量 ***************************/ // 第一種方式 info.id = 2022; info.name = "tianyHon"; info.age = 23; info.sex = 'M';// 第二種方式 (*pinfo).id = 2022; (*pinfo).name = "tianyvHon"; (*pinfo).age = 23; (*pinfo).sex = 'M';// 第三種方式 pinfo->id = 2022; pinfo->name = "tianyvHon"; pinfo->age = 23; pinfo->sex = 'M';- pinfo = &info;,將結構體變量 info 的起始地址賦給指針變量 pinfo
在 C 語言中,如果 p 指向一個結構體變量 info,有如下 3 種等價用法:
- info.成員名
- (*p).成員名
- p->成員名
(2)指向結構體數組的指針
可以用指針變量指向結構體數組的元素。
struct Info {int id;char name[10];int age;char sex; };struct Info info[3] = {1, "Hon", 20, 'M', 2, "Wong", 21, 'M', 3, "Tv", 22, 'M'}; struct Info *pinfo;for (pinfo = info; pinfo < info + 3; pinfo++) {printf("%1d %-20s %2d %2c\n", p->id, p->name, p->age, p->sex); }- pinfo = info表示 pinfo 的初值為數組 info 序號為 0 的元素的起始地址。
- pinfo++表示 pinfo 自加 1,執行 pinfo++ 之后 pinfo 的值等于 info + 1,意味著 pinfo 所增加的值為結構體數組 info 的一個元素所占的字節數(在 Visual C++ 中,理論上等于 19,實際上等于 20)。
注意點:
- (++pinfo)->id:先使 pinfo 自加 1,然后得到 pinfo 指向的元素中的 id 成員值
- (pinfo++)->id:先求得 pinfo->id 的值,然后再使 pinfo 自加 1,指向 info[1]
- 指向結構體數組的指針是用來指向結構體類型的對象(結構體數組中的一個元素的起始地址,如 info[0]),而不應用來指向結構體數組元素中的某一成員,如 pinfo = info[1].name;(錯誤的使用方法),info[1].name 是 info[1] 元素中的成員 name 的首字符的地址。如果一定要將某一成員的地址賦給 pinfo,可以使用強制類型轉換,即 pinfo = (struct Info *)info[0].name;。
總結
以上是生活随笔為你收集整理的一文攻破结构体-C语言的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: PR 简单使用(一)
- 下一篇: 修改 pip 下载源