C 語言初學教材 - 第四章 不同資料型態的集合體

陣列是相同型態資料的集合體,這也是說,陣列是同質的資料結構。所謂的資料結構是指如何將資料組織儲存到電腦中的方法,寫程式時需要給準備用來存取資料的資料結構一個入口,這個入口通常會是一個變數名稱,如使用陣列所用的變數名稱,如

int a[10];
int i;

a[0] = 1;
for (i = 1; i < 10; i++) {
    a[i] = i + 2;
} 


陣列名稱 a 亦即存取具有 10 個整數型態的資料結構入口,我們要利用這個資料結構,就得透過 a 這個變數名稱。


有同質的資料結構,自然也會有異質的資料結構,所謂異質的資料結構就是指不同資料型態的集合體。 C 語言用結構這個詞稱呼程式自訂的異質資料結構,定義結構的格式如下



關鍵字 struct 被用來定義結構,其後一個空格,然後緊接自行定義的結構名稱。後面在接上一組大括號,大括號裡頭可以定義任何數量任何資料型態的變數,這些變數被稱為結構的成員,最後須注意,結尾的右大括號後須接分號 ; 。


我們先用一個簡單的例子說明結構的使用
#include <stdio.h>

struct point {
    int x;
    int y;
    float h;
    char *p;
};

int main(void)
{
    struct point t1 = {5, 12, 13.0, "(5, 12)"};
    struct point *t1Ptr = &t1;
    
    printf("點 t1 的 x 座標為 %d\n", t1.x);
    printf("點 t1 的 y 座標為 %d\n", t1.y);
    printf("點 t1 到原點的距離為 %f\n", t1.h);
    printf("點 t1 以字串表示為 %s\n", t1.p);
    
    t1Ptr->x = 7;
    t1Ptr->y = 24;
    t1Ptr->h = 25.0;
    t1Ptr->p = "(7, 24)";
    
    printf("\n點 t1 的 x 座標為 %d\n", t1.x);
    printf("點 t1 的 y 座標為 %d\n", t1.y);
    printf("點 t1 到原點的距離為 %f\n", t1.h);
    printf("點 t1 以字串表示為 %s\n", t1.p);
    
    return 0;
}

/* 《程式語言教學誌》的範例程式
    http://pydoing.blogspot.com/
    檔名:structtest.c
    功能:示範結構的使用
    作者:張凱慶
    時間:西元2010年7月 */ 


這個例子中,我們定義了平面幾何中點座標的結構 point ,共有四個成員,整數型態成員 x 及 y 分別記錄點的 x 座標及 y 座標,浮點數型態的成員 h 記錄到原點的距離,字元指標 *p 指向表示這個點的字串。


第 13 行及第 14 行,宣告結構 point 型態的變數 t1 ,以及另一個指向結構 point 型態的變數 t1Ptr
struct point t1 = {5, 12, 13.0, "(5, 12)"};
struct point *t1Ptr = &t1;


第 13 行同時說明,結構變數宣告後可以直接給初值,利用大括弧把要給 t1 的值圍起來,以逗號 , 區分每個成員的值,然後利用指派陳述即可。這裡須留意,宣告結構變數要連用 struct ,也可以使用另一個關鍵字 typedef ,替結構取一個型態名稱,然後就可以直接用索取的型態名稱宣告結構變數。


如將下面的陳述放到 struct 的定義之後,以後就能直接用 Point 宣告
typedef strcut point Point;


也可以將 typedef 直接寫到 struct 的定義的地方,這時要把 typedef 放在開頭,然後空格,然後才是 struct ,如
typedef struct {
    int x;
    int y;
    float h;
    char *p;
} Point; 


注意,這時候 struct 後的結構名稱可有可無,新的型態名稱要放到右大括弧的後面,結尾再加上分號。


另外,結構有兩個專屬的運算子,一個是結構成員運算子,用英文的句點 . 當符號,另一個是結構指標運算子,一個減號加上一個大於符號 -> ,用於指向結構的指標。上例中第 15 行到第 18 行(跟第 25 行到第 28 行相同)
printf("點 t1 的 x 座標為 %d\n", t1.x);
printf("點 t1 的 y 座標為 %d\n", t1.y);
printf("點 t1 到原點的距離為 %f\n", t1.h);
printf("點 t1 以字串表示為 %s\n", t1.p);


便是利用結構成員運算子取得結構成員的值。


第 20 行到第 23 行
t1Ptr->x = 7;
t1Ptr->y = 24;
t1Ptr->h = 25.0;
t1Ptr->p = "(7, 24)";


由於 t1Ptr 為指向 t1 的指標,因此利用 t1Ptr 存取 t1 的成員都必須用結構指標運算子。


編譯執行這個例子,如下



問題與討論
  1. 請說明定義結構的方式。
  2. 陣列和結構有什麼不同?
  3. 結構成員運算子和結構指標運算子有什麼不同?
  4. 利用 typedef 取新型態名稱,有什麼方便的地方?




沒有留言: