Semorphe

結構

把幾個值綁成一個東西。 · ⏱ 約 30 分鐘

你會學到三件事

  1. struct 把幾個變數包成一個
  2. C 宣告時一定要寫 struct 這個字
  3. .-> 的差別,以及為什麼有兩個

開始之前

一個點有 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;
}

兩個理由:

  1. 要改到本體(第 3 課那件事)
  2. 不用複製一整個結構——結構大的時候,傳值等於整份拷貝

所以 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 的陣列(三個點),用迴圈填值再印出來。

再進階:寫一個函式算兩點的距離——參數用指標傳

這一課你做了什麼

如果卡住了

你看到 多半是因為
錯誤訊息指著結構定義的下一行 定義結尾的分號漏了
Point p; 說找不到型別 C 要寫 struct Point p;
q.x 編譯錯誤 q 是指標,要用 q->x
函式裡改了值外面沒變 參數傳的是複本。要傳指標
在編輯器打開這一課 →