struct
定義與使用
如果要使用多種資料型態做運算而且資料間又有關係
可以使用struct來包裝不同型態的資料
struct通常用來定義儲存檔案的紀錄,或者各種資料結構
struct宣告語法如下:
1 2 3
| struct 結構名稱{ 資料型態 變數名稱; };
|
例如你可以這樣定義一個員工的資料,別忘了在最後加上分號’;’
1 2 3 4 5 6 7 8
| struct Employee{ char name[30]; int age; char gender; double salary; };
struct Employee employee;
|
接下來就是初始化變數了,你可以這樣初始化變數
1
| struct Employee employee = {"gundam",20,'M',81000};
|
如果想指定其中一個變數,在變數後面加上小數點再接上成員名稱就可以了,例如
struct可以直接透過指定運算子’=’來指定,以下是範例程式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| #include <stdio.h>
struct Employee{ char name[30]; int age; char gender; double salary; };
int main(void) { struct Employee employee1 = {"gundam",20,'M',81000}; struct Employee employee2 = {"提摩",40,'M',66000}; printf("name\t%s\n",employee1.name); printf("age\t%d\n",employee1.age); printf("gender\t%c\n",employee1.gender); printf("salary\t%.2f\n",employee1.salary); puts(""); strcpy(employee1.name, "GGininder"); employee1.age = 30; employee1.salary = 22000.0; printf("name\t%s\n",employee1.name); printf("age\t%d\n",employee1.age); printf("gender\t%c\n",employee1.gender); printf("salary\t%.2f\n",employee1.salary); puts(""); employee1 = employee2; printf("name\t%s\n",employee1.name); printf("age\t%d\n",employee1.age); printf("gender\t%c\n",employee1.gender); printf("salary\t%.2f\n",employee1.salary); return 0; }
|
執行結果
name gundam
age 20
gender M
salary 81000.00
name GGininder
age 30
gender M
salary 22000.00
name 提摩
age 40
gender M
salary 66000.00
struct是不能用==跟!=來判斷是否相等的
因為struct的成員變數在記憶體空間裡面有可能是不連續的
struct與指標
struct是不能含有自己的,但是可以包含指標,例如
1 2 3 4 5 6 7
| struct Employee{ char name[30]; int age; char gender; double salary; struct Employee *ptr; };
|
這樣含有指標的struct稱為自我參考,這在後期的資料結構會提到
在使用指標的時候,C語言提供結構指標運算子’->’來存取成員變數
結構指標運算子’->’跟’(*指標).成員變數’是相等的,只是’->’比較方便使用
以下是範例程式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| #include <stdio.h>
struct Employee{ char name[30]; int age; char gender; double salary; };
void initEmployee(struct Employee*,char[],int,char,double);
int main(void) { struct Employee employee; initEmployee(&employee,"gundam",20,'M',81000); printf("name\t%s\n",employee.name); printf("age\t%d\n",employee.age); printf("gender\t%c\n",employee.gender); printf("salary\t%.2f\n",employee.salary); return 0; }
void initEmployee(struct Employee *employee,char name[],int age,char gender,double salary){ strcpy(employee->name, name); employee->age = age; employee->gender = gender; employee->salary = salary; }
|
執行結果
name gundam
age 20
gender M
salary 81000.00
typedef
typedef保留字可以為資料型態建立別名,例如
之後uint就會被當作unsigned來看待
所以以下語法可以讓我們用更簡單的語法宣告變數
1 2 3
| typedef struct Employee Emp;
Emp employee;
|
這樣前面就可以不用加上struct了,程式的可讀性也可以提升
你也可以省略struct標籤直接寫別名
1 2 3 4 5 6 7
| typedef struct{ char name[30]; int age; char gender; double salary; struct Employee *ptr; }Emp;
|
而特別要注意的是函數指標的別名,例如
1
| typedef int (*CMP)(int,int);
|
這樣是宣告一個別名叫CMP,型態是回傳值為int,參數列為(int,int)的函數指標
位元欄位
位元欄位(Bit fields)使用時機在於記憶體空間跟配合硬體實作
位元欄位的宣告方式是在unsigned或int的成員後面加上冒號’:’以及欄位寬度
宣告語法如下:
1 2 3 4 5 6
| struct File { unsigned int modified : 1; unsigned int mode : 2; unsigned int owner : 3; unsigned int group : 3; };
|
以下是範例程式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| #include <stdio.h>
struct File { unsigned int modified : 1; unsigned int mode : 2; unsigned int owner : 3; unsigned int group : 3; };
void initFile(struct File*,int,int,int,int);
int main(void) { struct File file; initFile(&file,0,0,7,7); printf("modified\t%d\n",file.modified); printf("mode\t\t%d\n",file.mode); printf("owner\t\t%d\n",file.owner); printf("group\t\t%d\n",file.group);
puts(""); initFile(&file,0,0,7,8);
printf("modified\t%d\n",file.modified); printf("mode\t\t%d\n",file.mode); printf("owner\t\t%d\n",file.owner); printf("group\t\t%d\n",file.group); return 0; }
void initFile(struct File* file,int modified,int mode,int owner,int group){ file->modified = modified; file->mode = mode; file->owner = owner; file->group = group; }
|
執行結果
modified 0
mode 0
owner 7
group 7
modified 0
mode 0
owner 7
group 0
union
union跟struct一樣,都是產生一種新的資料型態,只是不同的是
struct是每個成員變數都配置一段空間,union則是共用一段記憶體空間
union所需的記憶體空間大小由最大的成員變數覺得,例如以下union的大小為8位元組
1 2 3 4 5
| union var{ char ch; int num1; double num2; };
|
union能執行的操作跟struct一樣
例如指定、取址、使用結構成員運算子’.’跟使用結構指標運算子’->’
以下是union的範例程式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| #include <stdio.h>
union Var{ char ch; int num1; double num2; };
int main(void) { union Var var = {'x'}; printf("var.ch = %c\n",var.ch); printf("var.num1 = %d\n",var.num1); printf("var.num2 = %.3f\n\n",var.num2); var.num1 = 123; printf("var.ch = %c\n",var.ch); printf("var.num1 = %d\n",var.num1); printf("var.num2 = %.3f\n\n",var.num2); var.num2 = 456.789; printf("var.ch = %c\n",var.ch); printf("var.num1 = %d\n",var.num1); printf("var.num2 = %.3f\n\n",var.num2); return 0; }
|
執行結果
var.ch = x
var.num1 = 120
var.num2 = 0.000
var.ch = {
var.num1 = 123
var.num2 = 0.000
var.ch = ?
var.num1 = -1099511628
var.num2 = 456.789
enum
C語言提供最後一種自定型態為enum,是一組由識別字所代表的整數常數
除非特別指定,不然都是由0開始,接下來遞增1,例如以下語法:
1
| enum week{Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday};
|
以上從Sunday開始,各個識別字被依序設定為0到6,你也可以指定數值
1
| enum week{Monday=1,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday};
|
這樣數字就會被指定1到7,以下是enum的範例程式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| #include <stdio.h>
enum week{Monday=1,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday};
int main(void) { enum week w; const char *day_name[] = { "","Monday","Tuesday","Wednesday", "Thursday","Friday","Saturday","Sunday" }; for(w=Monday; w <= Sunday; w++) printf("%s\n",day_name[w]); return 0; }
|
執行結果
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
Sunday
參考
- C語言
- struct 簡介
- 結構與指標
- 位元欄位
- enum
- union