From Gossip@caterpillar

C Gossip: 結構與指標

您可以使用structs定義的自訂型態來宣告指標變數,例如:
#include <stdio.h>

struct Ball {
char color[10];
double radius;
};

int main(void) {
struct Ball ball = {"red", 4.0};
struct Ball *ptr;
ptr = &ball;

printf("ball: %s\t%.2f\n", ptr->color, ptr->radius);

return 0;
}

這個例子示範了如何宣告struct指標,以及如何使用&對struct實例取位址值,如果使用struct的指標來存取其成員,則必須使用->運算子,執行結果如下:
ball: red       4.00

 struct 簡介 曾經談過,如果要將struct實例作為引數傳遞,則會直接進行成員值的複製,如果您並不想要複製實例,您可以直接傳遞struct實例的位址值,例如:
struct Ball {
char color[10];
double radius;
};

void show(struct Ball *ball);

int main(void) {
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);
}

執行結果如下:
ball: red       4.00

注意到,以下的語法取得的是struct實例的成員位址值,而不是struct實例的位址值:
struct Ball ball = {"red", 4.0};
printf("%X\n", &ball.color);

為了避免誤會,建議加上括號比較清楚:
struct Ball ball = {"red", 4.0};
printf("%X\n", &(ball.color));

類似的,如果ptr是struct的指標,並儲存某個實例的位址值,那麼以下取得的是實例的成員位址值,而不是實例的位址值,建議還是如第二行的,加上括號比較清楚:
printf("%X\n", &ptr->color);
printf("%X\n", &(ptr->color));

struct指標的應用之一,可以參考 
堆疊 - 使用鏈結實作(C 語言動態記憶體宣告) 佇列 - 使用鏈結實作(C語言動態記憶體宣告),當中的鏈結資料結構,即使用struct指標來連結下一個節點實例。

下面這個例子是個比較進階的例子,程式中使用 函 式指標,讓 structs 實例擁有可操作的函式,而在操作struct實例所擁有的函式時,傳入實例的位址值,如此該函式可以取得實例成員值並進行運算,這是在
模擬物件導向中,物件實例擁有屬性及方法(method)的特性:
#include <stdio.h>

typedef struct Ball CBall;
struct Ball {
char *color;
double radius;
double (*volumn)(CBall*); // 函式指標
};

// 計算實例體積
double volumn(CBall *this) {
double r = this->radius; // 模擬 this 指標 的行為
return r * r * 3.14;
}

void initBall(CBall *ball, char *color, double radius) {
ball->volumn = volumn; // 連結函式
ball->color = color;
ball->radius = radius;
}

int main(void) {
CBall ball;
initBall(&ball, "red", 5.0);

printf("ball 實例的體積: %.2f\n", ball.volumn(&ball));

return 0;
}

執行結果:
ball 實例的體積: 78.50