C語言 - 第三十一章 | struct - struct 簡介
struct 簡介
struct
是C
中用來組織資料的關鍵字,當使用struct
時,考慮的是一組資料擁有的相關性,例如學生會有學號、姓名、住址、電話等,若操作時經常都要傳遞同樣一組資料,可以使用struct
來定義一個Student
型態,這個型態中包括了學號、姓名、住址、電話等資訊,接著可以使用Student
來宣告新的資料,進行資料指定或取出等。
舉個實例來說,可以定義一個「球」的模子,考慮球有各種不同的顏色,以及球最基本的球半徑資訊,若這組資料經常在一起出現,這些資訊應該可以定義一個Ball
型態,在C
中要包裝這些資訊時,可以進行定義。
1 2 3 4
| struct Ball { char color[10]; double radius; };
|
最重要的是別忘了在最後加上分號,初學C
的新手很常犯這個錯誤;接下來要使用這個Ball
的話,可以如下建立實例並初始化。
1
| struct Ball ball1 = {"red", 5.0};
|
這樣的話,ball1
將包括color
與radius
兩個資料成員,以上的寫法將color
成員初始化為"red"
,而radius
初始化為5.0
;
也可以先宣告,後來再設定成員資料。
1 2 3
| struct Ball ball2; strcpy(ball2.color, "green"); ball2.radius = 10.0;
|
在建立實例並初始化時,也可以使用成員名稱,不一定要按照成員名稱的定義順序來指定。
1
| struct Ball ball1 = {.radius = 5.0, .color = "red"};
|
在存取struct
成員時,必須透過宣告的名稱加上.
運算子。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| #include <stdio.h> #include <string.h>
struct Ball { char color[10]; double radius; };
int main() { struct Ball ball1 = {"red", 5.0};
struct Ball ball2; strcpy(ball2.color, "green"); ball2.radius = 10.0;
printf("ball1: %s,\t%.2f\n", ball1.color, ball1.radius); printf("ball2: %s,\t%.2f\n", ball2.color, ball2.radius);
return 0; }
|
1 2 3
| ball1: red, 5.00 ball2: green, 10.00
|
亦可以在定義struct
時,直接宣告struct
實例。
1 2 3 4
| struct Ball { char color[10]; double radius; } ball1 = {"red", 5.0}, ball2;
|
如要宣告struct
陣列並初始化每個結構成員。
1 2 3 4 5 6 7 8 9
| struct Ball balls[] = { {"red", 3.0}, {"green", 5.0}, {"blue", 10.0} };
for(int i = 0; i < 3; i++) { printf("ball1: %s,\t%.2f\n", balls[i].color, balls[i].radius); }
|
方便起見,可以使用typedef
定義struct
的名稱,如此一來,宣告並產生實例時,就不用再寫struct
關鍵字。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| include <stdio.h> #include <string.h>
struct Ball { char color[10]; double radius; };
typedef struct Ball Sphere;
int main() { Sphere sphere1 = {"red", 5.0};
Sphere sphere2; strcpy(sphere2.color, "green"); sphere2.radius = 10.0;
printf("sphere1: %s,\t%.2f\n", sphere1.color, sphere1.radius); printf("sphere2: %s,\t%.2f\n", sphere2.color, sphere2.radius);
return 0; }
|
或者是這樣重新命名。
1 2 3 4
| typedef struct { char color[10]; double radius; } Ball;
|
可以直接使用指定運算子,將一個struct
的實例指定給另一個實例,這會將struct
實例的成員值,一個一個「複製」給另一個被指定的對象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| #include <stdio.h>
typedef struct { char color[10]; double radius; } Ball;
int main() { Ball ball1 = {"red", 5.0};
Ball ball2 = ball1; ball1.radius = 10.0;
printf("ball1: %s,\t%.2f\n", ball1.color, ball1.radius); printf("ball2: %s,\t%.2f\n", ball2.color, ball2.radius);
return 0; }
|
1 2 3
| ball1: red, 10.00 ball2: red, 5.00
|
同樣的道理,如果在函式的引數傳遞時,同樣也是將struct
的成員值一個一個「複製」給函式上的參數。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| #include <stdio.h>
typedef struct { char color[10]; double radius; } Ball;
void foo(Ball);
int main() { Ball ball = {"red", 5.0};
foo(ball); printf("ball: %s,\t%.2f\n", ball.color, ball.radius);
return 0; }
void foo(Ball ball) { ball.radius = 100.0; }
|
在程式的foo()
呼叫中,將ball
傳遞給foo()
上的參數,並在foo()
中改變radius
,但由於是複製成員值,這並不影響main()
當中的 ball
實例之成員值。
在struct
中,也可以再宣告struct
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| struct Student { char *name; int number;
struct { char *color; double radius; } ball; };
struct Student student1; student1.name = "caterpillar"; student1.number = 1; student1.ball.color = "red"; student1.ball.radius = 5.0;
|
可以看到,定義struct
時,不一定要定義struct
名稱,而可以直接在定義結構之後,直接宣告實例。
註:以上參考了
struct 簡介