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

C語言結構體完全指南:定義、指針、動態分配與鏈表實戰

     編輯:關於C

一、結構體定義與變量聲明

1. 基本語法

struct Student {
    int number;
    char name[10];
    float score;
}; // 分號不可省

2. 三種聲明方式

// 方式1: 先定義類型,再聲明變量
struct Student st1, st2, st3;

// 方式2: 定義類型同時聲明變量
struct Student {
    int number;
    char name[10];
    float score;
} st1, st2, st3;

// 方式3: 定義並初始化
struct Student st1 = {101, "wang", 87.5};

3. 結構體數組

struct Student stu[50] = {
    {101, "wang", 87.5},
    {102, "li", 90},
    // ...
};

二、結構體指針操作

1. 指針聲明

struct Student *p;          // 方式1: 需先見類型定義
struct Student { ... } *p;  // 方式2: 定義類型同時聲明指針

2. 指針賦值與成員訪問

struct Student st1 = {101, "wang", 87.5};
struct Student *p = &st1;

// 訪問成員三種等價形式
p->number;        // 推薦:箭頭運算符
(*p).number;      // 解引用後用點運算符
st1.number;       // 直接用變量

3. 指向結構體數組的指針

struct Student stu[10] = {...};
struct Student *p = stu; // 指向首元素

for (; p < stu + 10; p++) {
    printf("%d, %s", p->number, p->name);
}

p++ 自動按 sizeof(struct Student) 步進,體現指標運算的類型感知特性。


三、動態內存分配

函數原型用途
mallocvoid* malloc(size_t size)分配 size 字節,內容未初始化
callocvoid* calloc(size_t n, size_t size)分配 n 個 size 字節塊,自動清零
reallocvoid* realloc(void* ptr, size_t size)調整已分配塊大小,可能移動內存
freevoid free(void* ptr)釋放 malloc/calloc/realloc 分配的內存

典型用法

struct Student *p = (struct Student*)malloc(sizeof(struct Student));
if (!p) exit(1); // 檢查分配失敗

// 分配數組
struct Student *arr = (struct Student*)calloc(100, sizeof(struct Student));

free(p); // 用完必須釋放,防止內存洩漏

四、單鏈表實戰

節點定義

struct Student {
    char *name;
    struct Student *next; // 指向下一節點
};

建表代碼(帶頭節點)

struct Student *create_list(int n) {
    struct Student *head = NULL, *tail = NULL, *p = NULL;
    for (int i = 0; i < n; i++) {
        p = (struct Student*)malloc(sizeof(struct Student));
        if (!p) exit(1);
        p->name = NULL; // 這裡簡化,實際應分配字符串空間
        p->next = NULL;
        
        if (i == 0) head = tail = p;
        else { tail->next = p; tail = p; }
    }
    return head;
}

遍歷與釋放

void traverse(struct Student *head) {
    for (struct Student *p = head; p; p = p->next)
        printf("%s\n", p->name);
}

void free_list(struct Student *head) {
    struct Student *p = head, *tmp;
    while (p) {
        tmp = p->next;
        free(p->name); // 先釋放成員動態內存
        free(p);
        p = tmp;
    }
}

五、常見陷阱與最佳實踐

  • 結構體對齊:編譯器為對齊會插入填充字節,sizeof 可能大於成員大小之和。可用 #pragma pack 或屬性控制。
  • 柔性數組成員 (C99):結構體末尾聲明 char data[]; 配合 malloc(sizeof(Struct) + extra) 實現變長結構。
  • 指針失效:free 後指針不自動置 NULL,建議 free(p), p = NULL; 避免野指針。
  • 鏈表頭節點:引入不存數據的頭節點可統一插入/刪除邏輯,簡化邊界處理。

總結

結構體是 C 語言構建複雜數據模型的基石。熟練掌握定義、指針操作、動態內存管理、鏈表等鏈式結構實現,是系統級編程、數據結構構建的核心技能。

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