C 語言程式設計教學:結構 (Struct)

PUBLISHED ON JUL 31, 2018 — PROGRAMMING

相對於基礎型別,結構 (struct) 是一種複合型別;在我們先前的程式中,大多都僅使用基礎型別,透過結構,我們可以創造新的型別。由於 C 沒有內建的物件導向語法,使用指向結構的指標來模擬 C++ (或 Java) 的 this 指標是相當常見的手法。

宣告結構

使用 struct 保留字可以宣告結構,如下例:

struct person {
    char *name;
    unsigned age;
};

int main(void)
{
    struct person p = { "Michael", 37 };  
    
    return 0;
}

但這種初始化結構的方式需記憶該結構的屬性的位置,若屬性有更動需一併更動相關程式碼,在軟工觀點上不佳。可以改用以下的方法來初始化結構:

struct person {
    char *name;
    unsigned age;
};

int main(void)
{
    struct person p = { 
        .name = "Michael", 
        .age = 37
    };  
    
    return 0;
}

可以搭配 typedef 來簡化結構的型別名稱:

// Forward declaration.
typedef struct person Person;

struct person {
    char *name;
    unsigned age;
};

int main(void)
{
    Person p = { 
        .name = "Michael", 
        .age = 37
    };  
    
    return 0;
}

如果想節省命名空間可改用以下方式來宣告結構:

typedef struct {
    char *name;
    unsigned age;
} Person;

存取結構內屬性

使用 . (點號) 可存取結構內的屬性,如下例:

#include <assert.h>

typedef struct point Point;

struct point {
    double x;
    double y;
};

int main(void)
{
    Point pt = {
        .x = 3.0,
        .y = 4.0
    };
    
    assert(pt.x == 3);
    assert(pt.y == 4);
    
    return 0;
}

內嵌在結構內的結構

由於結構也是一種型別,我們可以在結構內嵌入另一個結構,如下例:

#include <assert.h>
#include <string.h>

typedef struct person Person;

struct person {
    char *name;
    unsigned age;
};

typedef struct employee Employee;

struct employee {
    Person p;
    double salary;
};

int main(void)
{
    Employee ee = {
        { .name = "Michael", .age = 37 },
        .salary = 100.0
    };
    
    assert(strcmp(ee.p.name, "Michael") == 0);
    assert(ee.p.age == 37);
    assert(ee.salary == 100.0);

    return 0;
}

但結構內不能嵌入同一個結構,需注意。

儲存結構的陣列

由於結構視為一個型別,我們可以用陣列來儲存多個結構,如下例:

#include <assert.h>
#include <stddef.h>
#include <stdio.h>

typedef struct point Point;

struct point {
    double x;
    double y;
};

int main(void)
{
    Point pts[] = {
        { .x = 0.0, .y = 0.0 },
        { .x = 1.0, .y = 2.0 },
        { .x = 3.0, .y = 4.0 }
    };
    
    for (size_t i = 0; i < 3; i++) {
        printf("(%.2f, %.2f)\n", pts[i].x, pts[i].y);
    }

    return 0;
}
TAGS: C 語言, STRUCT
comments powered by Disqus