首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C Primer Plus 第 14 章:結構、聯合、列舉與 typedef 進階應用

     編輯:關於C語言

第 14 章 結構與其他資料形式

14.1 結構宣告

struct book {
    char title[MAXTITL];
    char author[MAXAUTL];
    float value;
};
struct book library;  // 宣告變數

結構標籤 book 為可選。成員可為任何型別,含巢狀結構。花括號後分號結束宣告。

14.2 結構變數定義與初始化

struct book library = { "The Pirate", "Rense Vio", 1.95f };
// C99 指定初始化(順序任意、最後賦值生效)
struct book lib2 = { .value = 10.99f, .title = "New Book" };

靜態儲存期結構初始化值必須為常數運算式。

14.2.2 存取成員

使用成員運算子 .:library.value。

14.3 結構陣列

struct book library[MAXBKS];
library[0].value = 5.99f;

大型結構陣列若為自動儲存類別可能耗盡堆疊,改用 static 或外部連結,或動態配置。

14.3.2 範例輸入迴圈

while (count < MAXBKS && gets(library[count].title) && library[count].title[0] != '\0') {
    // ...
    while (getchar() != '\n') continue; // 清空輸入緩衝區殘留換行
}

14.4 巢狀結構


struct names { char first[LEN]; char last[LEN]; };
struct guy {
    struct names handle;
    char job[LEN];
    float income;
};
struct guy fellow = { {"Ewen", "Villard"}, "salmon", 58112.00f };
// 存取:fellow.handle.first

14.5 指向結構的指標


struct guy *him = &barney;
// 兩種存取方式等價
(*him).income = 50000.0f;
him->income = 50000.0f;  // 箭頭運算子,慣用寫法

14.6 傳遞結構給函式

方式優點缺點
傳值資料安全(副本)、風格清晰舊版 C 不支援、耗時耗空間
傳址(指標)相容舊版、速度快、可修改原值需自行保護資料(可用 const)

// 傳指標配合 const 保護
double sum(const struct guy *me);
// 傳值
double sum(struct guy me);

14.6.4 結構中字串成員:陣列 vs 指標

若結構需儲存字串,優先使用字元陣列。指標成員未初始化指向隨機位址,使用時極易覆寫記憶體。

14.6.5 結構、指標與 malloc() 結合


struct namect { char *fname; char *lname; int letters; };
void getinfo(struct namect *pst) {
    char temp[81];
    gets(temp);
    pst->fname = (char*)malloc(strlen(temp) + 1);
    strcpy(pst->fname, temp);
    // 同理處理 lname
}

動態配置字串空間,指標成員指向有效記憶體,用畢 free()。

14.6.6 複合字面值建立結構 (C99)


struct book lib3 = (struct book){"Hello", "You", 6.99f};

14.6.7 伸縮性陣列成員 (C99)


struct flex {
    int count;
    double average;
    double scores[];  // 最後一個成員、方括號留空、結構至少另有一成員
};
struct flex *pf = malloc(sizeof(struct flex) + 5 * sizeof(double));
// pf->scores[0]...pf->scores[4] 可用

14.7 聯合


union hold { int digit; double bigfl; char letter; };
union hold u;
u.digit = 42;      // 僅佔用同一記憶體空間
u.bigfl = 3.14;    // 覆寫 digit

初始化規則:1) 指定同類型聯合;2) 初始化第一個成員;3) C99 指定初始化項目。同一時刻僅能儲存一個值。

14.8 列舉型別


enum spectrum { red, orange, yellow, green, blue, violet };
enum spectrum color = blue;  // 列舉常數為 int 型別
// 預設值 0,1,2... 可指定:enum feline { cat, lynx=10, puma, tiger }; // puma=11, tiger=12

C 允許對列舉變數 ++,C++ 不允許。

14.9 typedef

  • 為型別建立別名(非新型別),由編譯器處理(非預處理器)。
  • 可與其他說明符組合:typedef unsigned char BYTE; BYTE x, y[10], *z;
  • 連續宣告型別一致:typedef int* IntPtr; IntPtr a, b; 皆為 int*;#define 宏展開則不保證。

14.10 函式指標


void ToUpper(char *str);
void (*pf)(char *) = ToUpper;  // pf 指向 ToUpper
pf("hello");                   // 呼叫:(*pf)("hello") 或 pf("hello")

// 作為參數
void show(void (*fp)(char *), char *str) { fp(str); }
show(ToUpper, "test");

宣告語法:回傳型別 (*指標名)(參數列表)。指標指向函式程式碼起始位址。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved