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

C 語言結構體進階(十一):結構數組與結構指針深度解析

     編輯:關於C語言

前言

結構體作為自定義類型,同樣支援數組與指針兩種核心聚合機制。本文系統講解結構數組的定義、初始化、二維等效認知、成員訪問語法,以及結構指針的聲明、賦值、成員訪問(點運算符 vs 箭頭運算符)、動態分配陣列等實戰技巧。

一、結構數組:同質實體集合

1. 定義兩種等價寫法

/* 匿名結構標籤,直接定義數組 */
struct {
    char name[8];
    char sex[2];
    int age;
    char addr[40];
} student[40];

/* 命名結構標籤,分離類型與變量 */
struct Student {
    char name[8];
    char sex[2];
    int age;
    char addr[40];
};
struct Student student[40];

推薦第二種:類型可復用、便於聲明指針/函數參數、調試器顯示類型名。

2. 成員訪問:雙重下標語法

student[0].name      // 第 1 位學生姓名
student[30].age      // 第 31 位學生年齡
/* 形式:結構數組變量[下標].成員名 */

3. 二維等效認知

  • 第一維:數組下標(第 N 個實體)。
  • 第二維:結構成員(實體的屬性)。
  • 記憶體中**按行優先**連續存放:student[0] 所有成員 → student[1] 所有成員 → ...

4. 成員本身可以是數組

struct A {
    int m[3][5];   // 成員是二維陣列
    float f;
    char s[20];
} y[4];            // y 有 4 個元素,每元素含 3×5 int 陣列

/* 訪問 y[2] 的 m[1][4] */
y[2].m[1][4];

5. 初始化

struct Student class[3] = {
    { "Alice", "F", 18, "Addr1" },
    { "Bob",   "M", 19, "Addr2" },
    { "Carol", "F", 17, "Addr3" }
};
/* 完全初始化時可省略數組長度 */

二、結構指針:操作結構的間接引用

1. 聲明語法

struct Student *pstu;  /* 指向 Student 類型的指針 */

可在結構定義時同步聲明:struct Student { ... } stu1, *pstu;

2. 賦值規則:只能賦**結構變量地址**,不能賦結構標籤

struct Student stu1, *pstu;
pstu = &stu1;   // 正確
// pstu = &Student; // 錯誤:標籤無地址,編譯器不分配存儲空間

3. 成員訪問:三種等價形式

形式代碼備註
結構變量直接訪問stu1.name基準形式
指針解引用 + 點運算符(*pstu).name括號**不可省略**,. 優先級高於 *
箭頭運算符 (語法糖)pstu->name最常用、可讀性最佳

4. 綜合範例

struct Student {
    int num;
    char *name;
    char sex;
    float score;
} boy1 = {102, "Zhang ping", 'M', 78.5}, *pstu;

main() {
    pstu = &boy1;
    printf("Num=%d Name=%s\n", boy1.num, boy1.name);
    printf("Num=%d Name=%s\n", (*pstu).num, (*pstu).name);
    printf("Num=%d Name=%s\n", pstu->num, pstu->name);
    /* 三種形式輸出完全一致 */
}

5. 動態分配結構數組

struct Student *class;
int n = 100;
class = (struct Student*)malloc(n * sizeof(struct Student));
if (!class) exit(1);

for (int i = 0; i < n; i++) {
    class[i].num = i + 1;          // 箭頭/下標混用
    sprintf(class[i].name, "Stu%d", i);
}
free(class);

優勢:運行時決定大小、非連續記憶體友好、可釋放單元素(配合鏈表)。

三、指針算術與結構大小

  • pstu + 1 增加 sizeof(struct Student) 位元組,指向下一結構。
  • sizeof(*pstu) 等於結構大小(含填充)。
  • 結構指針遵循**類型感知算術**,與普通指針一致。

四、常見錯誤速查

錯誤後果修正
pstu->num 但 pstu 未初始化野指針,崩潰/亂寫賦值後使用,或初始化為 NULL
*pstu.num 缺少括號解析為 *(pstu.num),編譯錯誤改為 (*pstu).num 或 pstu->num
malloc(sizeof(pstu))僅分配指針大小 (4/8B)malloc(sizeof(*pstu)) 或 malloc(sizeof(struct Student))
結構數組作為函數參數退化為指針函數內 sizeof(arr) 失效額外傳遞長度參數

總結

結構數組適合**固定規模、連續存儲、隨機訪問**的同質集合;結構指針配合動態分配適合**規模未知、頻繁增刪、需構建鏈表/樹/圖**的場景。掌握 .、->、(*p).m 三種訪問等價性、正確賦值規則、指針算術與動態分配模式,是 C 語言工程化編程的必備基本功。

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