C語言 - 第三十二章 | struct - 結構與指標
結構與指標
示範了如何宣告struct
指標,以及如何使用&
對struct
實例取位址值,如果使用struct
的指標來存取其成員,則必須使用->
運算子。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| #include <stdio.h>
struct Ball { char color[10]; double radius; };
int main() {
struct Ball ball = {"red", 4.0}; struct Ball *ptr; ptr = &ball;
printf("ball: %s\t%.2f\n", ptr->color, ptr->radius);
return 0; }
|
在C語言 - 第三十一章 | struct - struct 簡介 說過,如果要將struct
實例作為引數傳遞,則會直接進行成員值的複製,如果並不想要複製實例,可以直接傳遞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>
struct Ball { char color[10]; double radius; };
void show(struct Ball *ball);
int main() {
struct Ball ball = {"red", 4.0};
show(&ball);
return 0; }
void show(struct Ball *ball) { printf("ball: %s\t%.2f\n", ball->color, ball->radius); }
|
想要傳遞struct
實例的位址值,一是情況是函式想改變的是被傳遞的struct
實例本身,而不是實例的複本,另一個情況效率考量,如果 struct
實例本身很龐大,若不想有複製整個struct
實例負擔時,也可採用傳遞struct
實例位址值的方式。
注意到,以下的語法取得的是struct
實例的成員位址值,而不是struct
實例的位址值。
1 2
| struct Ball ball = {"red", 4.0}; printf("%p\n", &ball.color);
|
為了避免誤會,建議加上括號比較清楚。
1 2
| struct Ball ball = {"red", 4.0}; printf("%p\n", &(ball.color));
|
類似的,如果ptr
是struct
的指標,並儲存某個實例的位址值,那麼以下取得的是實例的成員位址值,而不是實例的位址值,建議還是如第二行的,加上括號比較清楚。
1 2
| printf("%p\n", &ptr->color); printf("%p\n", &(ptr->color));
|
下面這個例子是個比較進階的例子,程式中使用 函式指標,讓struct
實例擁有可操作的函式,而在操作struct
實例擁有的函式時,傳入實例的位址值,如此該函式可以取得實例成員值並進行運算,這是在模擬物件導向中,物件實例擁有屬性及方法(method
)的特性。
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
| #include <stdio.h> #include <stdlib.h>
typedef struct Ball { char *color; double radius; double (*volumn)(struct Ball*); } Ball;
double volumn(Ball *this) { double r = this->radius; return r * r * 3.14; }
Ball* new_ball(char *color, double radius) { Ball *ball = (Ball*) malloc(sizeof(Ball)); ball->volumn = volumn; ball->color = color; ball->radius = radius; return ball; }
int main() { Ball *ball = new_ball("red", 5.0); printf("ball 實例的體積: %.2f\n", ball->volumn(ball));
return 0; }
|
struct
指標的應用之一,可以參考堆疊 - 使用鏈結實作(C 語言動態記憶體宣告)與佇列 - 使用鏈結實作(C語言動態記憶體宣告),當中的鏈結資料結構,就使用struct
指標來連結下一個節點實例。
註:以上參考了
結構與指標
佇列 - 使用鏈結實作(C語言動態記憶體宣告)
堆疊 - 使用鏈結實作(C 語言動態記憶體宣告)