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

C 語言結構體陣列與指標完整應用指南

     編輯:關於C語言

結構體將異質資料封裝為單一型別,陣列提供批量管理,指標實現動態存取與函式傳遞。三者結合是 C 語言資料處理的核心模式。本文系統講解結構體陣列初始化、結構體指標存取語法(. vs ->)、指標陣列與指向陣列的指標區別,並附贈通訊錄、成績統計兩大實戰範例。

結構體陣列:批量管理同質異構資料

定義與靜態初始化

struct Student {
    int num;
    char *name;   // 指向字串常數區
    char sex;
    float score;
};

struct Student class[5] = {
    {101, "Li ping",   'M', 45.0},
    {102, "Zhang ping",'M', 62.5},
    {103, "He fang",   'F', 92.5},
    {104, "Cheng ling",'F', 87.0},
    {105, "Wang ming", 'M', 58.0}
};  // 未指定長度時編譯器自動推導為 5

應用範例:全班成績統計

int main() {
    int i, fail = 0;
    float sum = 0;
    for (i = 0; i < 5; ++i) {
        sum += class[i].score;
        if (class[i].score < 60) ++fail;
    }
    printf("總分: %.1f  平均: %.1f  不及格: %d\n", sum, sum/5, fail);
    return 0;
}

結構體指標:三種等價存取形式

struct Student stu = {102, "Zhang ping", 'M', 78.5};
struct Student *p = &stu;

/* 三種寫法完全等價 */
printf("%d\n", stu.num);        // 1. 變數直接存取
printf("%d\n", (*p).num);       // 2. 解參考再用 .  (括號必要,. 優先級 > *)
printf("%d\n", p->num);         // 3. 箭頭運算子(語法糖,最常用)

口訣:變數用 .,指標用 ->,(*p).member 記得加括號。

動態配置結構體陣列(執行期決定大小)

int n;
printf("輸入人數: ");
scanf("%d", &n);

struct Student *class = malloc(n * sizeof(struct Student));
if (!class) return 1;

for (int i = 0; i < n; ++i) {
    class[i].name = malloc(20);
    printf("姓名: "); scanf("%19s", class[i].name);
    printf("學號 性別 成績: ");
    scanf("%d %c %f", &class[i].num, &class[i].sex, &class[i].score);
}

/* 使用完畢釋放 */
for (int i = 0; i < n; ++i) free(class[i].name);
free(class);

應用範例:通訊錄(動態陣列 + 字串處理)

#define MAX 100
struct Contact {
    char name[20];
    char phone[12];
};

int main() {
    struct Contact book[MAX];
    int n = 0, choice;
    while (1) {
        printf("\n1.新增 2.列印 3.查詢 4.離開: ");
        scanf("%d", &choice);
        if (choice == 4) break;
        if (choice == 1) {
            if (n >= MAX) { puts("已滿"); continue; }
            printf("姓名: "); scanf("%19s", book[n].name);
            printf("電話: "); scanf("%11s", book[n].phone);
            ++n;
        } else if (choice == 2) {
            for (int i = 0; i < n; ++i)
                printf("%-20s %s\n", book[i].name, book[i].phone);
        } else if (choice == 3) {
            char key[20]; printf("查詢姓名: "); scanf("%19s", key);
            for (int i = 0; i < n; ++i)
                if (strcmp(book[i].name, key) == 0)
                    printf("找到: %s\n", book[i].phone);
        }
    }
    return 0;
}

進階:指標陣列 vs 指向陣列的指標

宣告意義記憶體圖示
struct Student *ps[10];10 個指標的陣列,各自指向一個 Studentps[0] → Student
ps[1] → Student...
struct Student (*pa)[10];指向「10 個 Student 的陣列」的單一指標pa → [Student, Student, ...]
struct Student arr[10];
struct Student *ps[10];
for (int i=0;i<10;++i) ps[i] = &arr[i];  // 指標陣列指向陣列元素

struct Student (*pa)[10] = &arr;         // 指向整個陣列
(*pa)[3].num = 99;                       // 存取第 4 元素

函式傳遞結構體:值傳遞 vs 指標傳遞

void print_by_val(struct Student s) {  // 複製整個結構體(含指標成員)
    printf("%s\n", s.name);
}
void print_by_ptr(const struct Student *s) { // 僅複製指標,效率高、可加 const
    printf("%s\n", s->name);
}
void modify_score(struct Student *s, float new_score) {
    s->score = new_score;  // 修改原物件
}

原則:結構體超過 16 bytes 或需修改內容 → 傳指標;小型唯讀結構體可傳值。

常見陷阱

  1. scanf("%s", stu.name) 若 name 是 char* 未配置記憶體 → 崩潰。改用 char name[20] 或 malloc。
  2. struct Student *p; p->num = 1; 未 malloc 直接解參考 → 野指標。
  3. 結構體含指標成員時 free 順序:先釋放內部指標,再釋放結構體本身。
  4. typedef struct { ... } Student; 後直接用 Student 而非 struct Student。

總結

  • 結構體陣列 = 固定大小批量管理;動態配置 = 彈性大小。
  • 指標存取統一用 ->,變數存取用 .。
  • 函式傳遞優先用 const struct T*,兼顧效率與安全。
  • 字串成員務必確保記憶體已配置、長度受限。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved