結構
把幾個值綁成一個東西。 · ⏱ 約 30 分鐘
你會學到三件事
struct 把幾個變數包成一個
- C 宣告時一定要寫
struct 這個字
. 和 -> 的差別,以及為什麼有兩個
開始之前
一個點有 x 和 y。用兩個變數的話,它們只是碰巧放在一起——
函式要傳兩個、陣列要開兩個、改一個忘了另一個。
struct 讓它們變成一個東西。
一、定義一個型別
struct Point {
int x;
int y;
};
⚠️ 最後那個分號不能少。 這是 C 少數幾個「大括號後面要分號」的地方,
而漏掉它的錯誤訊息通常指向下一行——很難查。
這一段不會產生任何變數。它在說「以後有一種東西叫 Point,長這樣」。
二、🔴 用的時候要寫 struct
struct Point p;
⚠️ C 一定要寫那個 struct,而 C++ 可以省略成 Point p;。
這是 C 和 C++ 一個很表面、而每天都會遇到的差別。
(老程式碼常見 typedef struct { ... } Point; 就是為了省掉它。)
三、. 取成員
p.x = 3;
p.y = 4;
printf("%d %d\n", p.x, p.y);
和 C++ 完全一樣。
四、-> 是「透過指標取成員」
struct Point *q = &p;
printf("%d\n", q->x);
q 是一個指標,所以不能直接 q.x——要先去那個地址。
(*q).x // 先去 q 指的地方,再取 x
q->x // 一模一樣,只是好寫好讀
⚠️ -> 就是 (*). 的縮寫,沒有別的意思。
判準很簡單:
| 左邊是什麼 |
用哪個 |
| 一個結構 |
. |
| 一個指向結構的指標 |
-> |
⚠️ 用錯的話編譯器會攔你,所以這個錯不可怕——它只是煩。
五、為什麼結構常常用指標傳
void move(struct Point *p) {
p->x = p->x + 1;
}
兩個理由:
- 要改到本體(第 3 課那件事)
- 不用複製一整個結構——結構大的時候,傳值等於整份拷貝
所以 C 的慣例是:結構參數幾乎都傳指標。
完成的樣子
struct Point {
int x;
int y;
};
int main() {
struct Point p;
p.x = 3;
p.y = 4;
printf("%d %d\n", p.x, p.y);
struct Point *q = &p;
printf("%d\n", q->x);
return 0;
}
換你了
加一個 struct Point 的陣列(三個點),用迴圈填值再印出來。
再進階:寫一個函式算兩點的距離——參數用指標傳。
這一課你做了什麼
- 你定義了一個自己的型別
- 你知道 C 宣告時要寫
struct,而 C++ 不用
- 你分得出什麼時候用
.、什麼時候用 ->
如果卡住了
| 你看到 |
多半是因為 |
| 錯誤訊息指著結構定義的下一行 |
定義結尾的分號漏了 |
Point p; 說找不到型別 |
C 要寫 struct Point p; |
q.x 編譯錯誤 |
q 是指標,要用 q->x |
| 函式裡改了值外面沒變 |
參數傳的是複本。要傳指標 |
在編輯器打開這一課 →