結構體與共用體01
目錄
- 概述
- 定義結構體型別變數的方法
- 結構體變數的引用
- 結構體變數的初始化
- 結構體陣列
- 指向結構體型別資料的指標
- 用指標處理連結串列
- 共用體
- 列舉型別
- 用typedef定義型別
1.概述
問題定義:有時需要將不同型別的資料組合成一個有機的整體,以便於引用。
如:一個學生有學號/姓名/性別/年齡/地址等屬性 int num; char name[20]; char sex; int age; int char addr[30];
定義一個結構的一般形式為:
struct 結構名
{
成員表列
};
成員表列由若干個成員組成,每個成員都是該結構的一個組成部分。對每個成員也必須作型別說明,其形式為:型別說明符 成員名;
struct student { int num; char name[20]; char sex; int age; float score; char addr[30]; }
2.定義結構體型別變數的方法
可以採取以下3種方法定義結構體型別變數:
(1)先宣告結構體型別再定義變數名
例如:struct student
| | | |
型別名 結構體 變數名 變數名
定義了student1和student2為struct student型別的變數,即它們具有struct student型別的結構.
struct student { int num; char name[20]; char sex; int age; float score; char addr[30]; } student1, student2
在定義了結構體變數後,系統會為之分配記憶體單元。例如: student1和student2在記憶體中各佔 ? 個位元組。( 4 + 20 + 1 + 4 + 4 + 30 = 67 )。不會佔用67個位元組,涉及到編譯優化問題。
(2)在宣告型別的同時定義變數
這種形式的定義的一般形式為:
struct 結構體名
{
成員表列
}變數名錶列;
例如:
struct student { int num; char name[20]; char sex; int age; float score; char addr[30]; }student1,student2;
(3) 直接定義結構體型別變數
其一般形式為:
struct
{
成員表列
}變數名錶列;
即不出現結構體名。
看圖下定義:
結論:這是一個巢狀的定義
首先定義一個結構date,由month(月)、day(日)、year(年) 三個成員組成。
在定義並說明變數 boy1 和 boy2 時,其中的成員birthday被說明為date結構型別。成員名可與程式中其它變數同名,互不干擾。
struct date { int month; int day; int year; }; struct { int num; char name[20]; char sex; struct date birthday; float score; }boy1, boy2;
3.結構體變數的引用
在定義了結構體變數以後,當然可以引用這個變數。但應遵守以下規則:
(1) 不能將一個結構體變數作為一個整體進行輸入和輸出。
例如: 列印student1的各個變數的值。不可以這樣:printf(″%d,%s,%c,%d,%f,%\n″,student1);
正確引用結構體變數中成員的方式為:結構體變數名.成員名
student1.num表示student1變數中的num成員,即student1的num(學號)項。可以對變數的成員賦值,例如:student1.num=100;
“.”是成員(分量)運算子,它在所有的運算子中優先順序最高,因此可以把student1.num作為一個整體來看待。上面賦值語句的作用是將整數100賦給student1變數中的成員num。
例子:
#include <stdio.h> void main() { struct student { int num; char *name; char sex; float score; } boy1, boy2; boy1.num = 007; boy1.name = "Jane"; printf("Please input sex and score\n"); scanf("%c %f", &boy1.sex, &boy1.score); boy2 = boy1; printf("Number = %d\nName = %s\n", boy2.num, boy2.name); printf("Sex = %c\nScore = %f\n", boy2.sex, boy2.score); }
(2) 如果成員本身又屬一個結構體型別,則要用若干個成員運算子,一級一級地找到最低的一級的成員。只能對最低階的成員進行賦值或存取以及運算。
對上面定義的結構體變數student1, 可以這樣訪問各成員:
student1.num
student1.birthday.month
/***********************************************************************************************/ /* 注意: */ /* 不能用student1.birthday來訪問student1變數中的成員birthday,因為birthday本身是一個結構體變數。*/ /***********************************************************************************************/ #include <stdio.h> void main() { struct date { int month; int day; int year; }; struct { int num; char name[20]; char sex; struct date birthday; float score; } boy1, boy2; printf("Please input birthday(YY:) "); scanf("%d", &boy1.birthday.year); printf("Please input birthday(MM:) "); scanf("%d", &boy1.birthday.month); printf("Please input birthday(DD:) "); scanf("%d", &boy1.birthday.day); printf("\n"); boy2 = boy1; printf("boy1's birthday is %d-%d-%d\n", boy1.birthday.year, boy1.birthday.month, boy1.birthday.day); printf("boy2's birthday is %d-%d-%d\n", boy2.birthday.year, boy2.birthday.month, boy2.birthday.day); }
(3) 對結構體變數的成員可以像普通變數一樣進行各種運算(根據其型別決定可以進行的運算)。
例如:
student2.score = student1.score;
sum = student1.score + student2.score;
student1.age++;
++student2.age;
(4) 可以引用結構體變數成員的地址,也可以引用結構體變數的地址。
例子:
#include <stdio.h> void main() { struct student { int num; char *name; char sex; float score; } boy1; boy1.num = 007; boy1.name = "Jane"; printf("The address of struct is %o :\n", &boy1 ); printf("The address of num is %o :\n", &boy1.num ); }
結果:地址相同,結構體的地址同首個結構體變數地址,類似陣列。
但不能用以下語句整體讀入結構體變數:
scanf(″%d,%s,%c,%d,%f,%s″,&student1);
結構體變數的地址主要用作函式引數,傳遞結構體變數的地址。