[轉]struct 簡介

From Gossip@caterpillar

C Gossip: struct 簡介

struct 是C中用來包裝資料的關鍵字,當您使用struct來包資料時,您考慮這些件可能擁有的相關性,將之包裝在一起,例如學生會有學號、姓名、住址、電話等, 您可以使用struct來定義一個Student型態,這個型態中包括了學號、姓名、住址、電話等資訊,接著您可以使用Student來宣告新的資料,進 行資料指定或取出等。

舉個實例來說,您可以定義一個「球」的模子,考慮球有各種不同的顏色,以及球最基本的球半徑資訊,您想到這些資訊應該可以定義一個Ball資料型態並從中取得,當您在C中要包裝這些資訊時,您可以如下進行定義: 

  • CustomType.h
struct Ball {
    char color[10];
    double radius;
};

struct是C中用來定義struct的關鍵字,Ball是自定義的資料型態名稱: 

struct Ball { 
    // 成員定義
};

最重要的是別忘了在最後加上分號,初學C的新手很常犯這個錯誤;接下來如果要使用這個Ball的話,可以如下建立實例並初始化:

struct Ball ball1 = {“red”, 5.0};

這樣的話,ball1將包括color與radius兩個資料成員,以上的寫法將color成員初始化為”red”,而radius初始化為5.0,您也可以先宣告,後來再設定成員資料,例如:

struct Ball ball2;
strcpy(ball2.color, “green”);
ball2.radius = 10.0;

在存取struct成員時,必須透過所宣告的名稱加上 . 運算子,以下寫個示範程式,看看Ball的使用:

  • main.c
#include <stdio.h>
#include <string.h>
#include "CustomType.h"

int main(void) {
    struct Ball ball1 = {"red", 5.0};

    struct Ball ball2;
    strcpy(ball2.color, "green");
    ball2.radius = 10.0;
    
    printf("ball1: %s,t%.2fn", ball1.color, ball1.radius);
    printf("ball2: %s,t%.2fn", ball2.color, ball2.radius);    
            
    return 0;
}

執行結果:

ball1: red,     5.00
ball2: green,   10.00

您也可以在定義struct時,直接宣告struct實例,例如:

struct Ball {
    char color[10];
    double radius;
} ball1 = {“red”, 5.0}, ball2;

如果要宣告struct陣列並初始化每個結構成員,則可以如下:

struct Ball balls[] = {{“red”, 3.0}, 
                       {“green”, 5.0}, 
                       {“blue”, 10.0}};int i;                       
for(i = 0; i < 3; i++) {
    printf(“ball1: %s,t%.2fn”, balls[i].color, balls[i].radius);
}

為了方便起見,您可以使用typedef定義structs的名稱,如此一來,宣告並產生實例時,就不用再寫struct關鍵字,例如:

#include <stdio.h>
#include <string.h>

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

int main(void) {
    CBall ball1 = {"red", 5.0};

    CBall ball2;
    strcpy(ball2.color, "green");
    ball2.radius = 10.0;
    
    printf("ball1: %s,t%.2fn", ball1.color, ball1.radius);
    printf("ball2: %s,t%.2fn", ball2.color, ball2.radius);    

    return 0;
}

或者是這樣重新命名:

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

您可以直接使用指定運算子,將一個struct的實例指定給另一個實例,這會將struct實例的成員值,一個一個「複製」給另一個被指定的對象,例如:

#include <stdio.h>

#include <stdio.h>

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

int main(void) {
    Ball ball1 = {"red", 5.0};

    Ball ball2 = ball1; // 指定運算子'='會複製成員值
    ball1.radius = 10.0; // 改變ball1成員值並不會改變ball2成員值
    
    printf("ball1: %s,t%.2fn", ball1.color, ball1.radius);
    printf("ball2: %s,t%.2fn", ball2.color, ball2.radius);       
    
    return 0;
}

執行結果:

ball1: red,     10.00
ball2: red,     5.00

同樣的道理,如果在函式的引數傳遞時,同樣也是將struct的成員值一個一個「複製」給函式上的參數,例如:

#include <stdio.h>

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

void foo(Ball);

int main(void) {
    Ball ball = {"red", 5.0};

    foo(ball);
    printf("ball: %s,t%.2fn", ball.color, ball.radius);
    
    return 0;
}

void foo(Ball ball) { // ball 成員值被複製過來 
     ball.radius = 100.0;
}

在程式的foo()呼叫中,將ball傳遞給foo()上的參數,並在foo()中改變radius,但由於是複製成員值,這並不影響main()當中的ball實例之成員值。

在struct中,也可以再宣告struct,例如:

struct Student {
    char *name;
    int number;
    
    struct {
        char *color;
        double radius;
    } ball;
};


struct Student student1;
student1.name = “caterpillar”;
student1.number = 1;
student1.ball.color = “red”;
student1.ball.radius = 5.0;

您也可以看到,定義struct時,不一定要定義struct名稱,而可以直接在定義結構之後,直接宣告實例。

  

未經允許不得轉載:GoMCU » [轉]struct 簡介