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

C 語言結構體完全指南:定義、存取、指標、函數傳遞與位域整合

     編輯:C 語言入門

C 語言結構體深度解析:從基礎定義到進階記憶體模型

結構體是 C 語言實現資料抽象的核心機制,允許將不同型別的資料聚合為單一邏輯單元。本文系統性介紹結構體定義、成員存取、指標操作、函數傳遞策略、巢狀結構、位域整合,並提供完整範例碼與最佳實務建議。

基本定義與宣告

struct [標籤] {
    成員定義;
    ...
} [變數列表];

範例:書籍資訊結構體

struct Books {
    char title[50];
    char author[50];
    char subject[100];
    int book_id;
} book;  // 可選:直接宣告變數

較佳實務:分離型別定義與變數宣告,並搭配 typedef:

typedef struct {
    char title[50];
    char author[50];
    char subject[100];
    int book_id;
} Book;

成員存取:點運算子與箭頭運算子

  • 結構體變數.成員:實體變數
  • 結構體指標->成員:指標變數(等同 (*指標).成員)

完整範例:多變數操作

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

typedef struct {
    char title[50];
    char author[50];
    char subject[100];
    int book_id;
} Book;

int main() {
    Book book1, book2;

    strcpy(book1.title, "C Programming");
    strcpy(book1.author, "Nuha Ali");
    strcpy(book1.subject, "C Programming Tutorial");
    book1.book_id = 6495407;

    strcpy(book2.title, "Telecom Billing");
    strcpy(book2.author, "Zara Ali");
    strcpy(book2.subject, "Telecom Billing Tutorial");
    book2.book_id = 6495700;

    printf("Book 1 title : %s\n", book1.title);
    printf("Book 1 author : %s\n", book1.author);
    printf("Book 1 subject : %s\n", book1.subject);
    printf("Book 1 book_id : %d\n", book1.book_id);

    printf("Book 2 title : %s\n", book2.title);
    printf("Book 2 author : %s\n", book2.author);
    printf("Book 2 subject : %s\n", book2.subject);
    printf("Book 2 book_id : %d\n", book2.book_id);

    return 0;
}

結構體作為函數參數:傳值 vs 傳址

傳值呼叫:複製整個結構體

void printBook(Book book) {  // 參數為結構體實體
    printf("Book title : %s\n", book.title);
    // ...
}

int main() {
    Book book1 = { ... };
    printBook(book1);  // 複製 book1 到參數
}

優點:簡單、無副作用。缺點:大型結構體複製開銷大,無法修改原始資料。

傳址呼叫:傳遞指標(推薦)

void printBook(const Book *book) {  // 唯讀指標
    printf("Book title : %s\n", book->title);
    // ...
}

int main() {
    Book book1 = { ... };
    printBook(&book1);  // 傳遞位址
}

優點:無複製開銷、可修改原始資料(去除 const 時)、支援多型基礎。現代 C 開發首選方式。

指向結構體的指標:動態配置與連結資料結構

Book *ptr = &book1;           // 指向現有變數
Book *dyn = malloc(sizeof(Book)); // 動態配置
if (dyn) {
    strcpy(dyn->title, "Dynamic Book");
    free(dyn);
}

指標是實現連結串列、樹、圖等動態資料結構的基礎:

typedef struct Node {
    int data;
    struct Node *next;  // 自參考指標
} Node;

位域整合:結構體內的位元級控制

結構體成員可宣告為位域,實現緊湊旗標儲存:

struct DeviceStatus {
    unsigned int power_on    : 1;
    unsigned int error_flag  : 1;
    unsigned int mode        : 3;  // 0-7
    unsigned int reserved    : 29; // 填充至 32 位
};

位域規則:

  • 型別限定為 int/unsigned int/signed int(C99 含 _Bool)
  • 寬度 ≤ 型別位元寬度
  • 不可取址(&status.power_on 非法)
  • 跨平台位元排序未定義,硬體映射需謹慎

進階主題

巢狀結構體

typedef struct {
    int day, month, year;
} Date;

typedef struct {
    char name[50];
    Date birth_date;  // 巢狀結構體
    Date hire_date;
} Employee;

柔性陣列成員

typedef struct {
    size_t len;
    char data[];  // C99 柔性陣列,必須為最後一個成員
} Buffer;

Buffer *buf = malloc(sizeof(Buffer) + 100);
buf->len = 100;

對齊與填充控制

// 查詢對齊需求
printf("alignof(Book) = %zu\n", _Alignof(Book));

// 強制對齊 (C11)
typedef struct alignas(16) { ... } AlignedStruct;

// 封裝控制 (GCC/Clang)
#pragma pack(push, 1)
typedef struct { char c; int i; } PackedStruct;
#pragma pack(pop)

最佳實務總結

  1. 一律使用 typedef 簡化型別名稱
  2. 函數參數優先使用 const struct Type*,需修改時移除 const
  3. 動態配置記憶體時檢查 malloc 回傳值,使用後 free
  4. 大型結構體考慮記憶體對齊優化,將大型別成員置前
  5. 位域僅用於旗標/硬體映射,一般整數運算優先使用標準型別
  6. 跨模組介面避免直接暴露結構體佈局,提供存取函數(不透明指標模式)

總結

結構體是 C 語言資料建模的基石,掌握其定義、存取、傳遞、指標操作與進階特性,對於編寫高效、可維護的系統級程式至關重要。結合位域、柔性陣列、不透明指標等技術,可構建專業級的 C 程式架構。

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