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

C語言柔性陣列(Flexible Array Member)完整指南

     編輯:關於C

什麼是柔性陣列?

C99 標準引入「柔性陣列成員」:結構體最後一個成員可宣告為未指定大小的陣列(type name[])。前提:結構體至少有一個其他成員。sizeof 不包含柔性陣列大小。配合 malloc 動態分配「結構體大小 + 柔性陣列預期大小」的記憶體,實現變長結構體。

不完全型別基礎

不完全型別缺乏足夠資訊描述完整物件(如長度)。常見:前向宣告 struct test;、未知長度陣列 extern int a[];。需補全才能實例化,僅能定義指標/參考。透過初始化補全:int a[] = {10, 20};。

結構體成員位址與偏移量

結構體成員在編譯期確定相對偏移量(含對齊填充)。例如 64 位系統:

struct test { int i; short c; char *p; };
// 偏移:i=0, c=4, p=8 (非 6,因對齊)

存取成員實為 base_address + offset,與實例位址無關。

柔性陣列誕生動機與演進

早期做法:結構體含指標指向動態字串,字串與結構體分離,操作不便。改進:分配 sizeof(struct) + strlen(str) + 1,字串緊接結構體後,透過 (char*)(p+1) 存取,但語法醜陋。GCC 擴展允許零長度陣列 char c[0];,C99 標準化為 char c[];(不完全型別),不佔空間且提供語法糖 p->c 直接存取。

標準寫法與使用範例

// C99 標準形式
struct s_test {
    int a;
    double b;
    char c[];  // 柔性陣列,必須是最後一個成員
};

// 分配與使用
struct s_test *p = malloc(sizeof(struct s_test) + 100);
p->a = 1; p->b = 2.0;
strcpy(p->c, "hello world");  // 直接像固定陣列一樣使用

// GCC 零長度陣列寫法(非標準)
struct s_test2 { int a; double b; char c[0]; };

GCC 文檔範例解析

#include <stdlib.h> #include <string.h>
struct line {
    int length;
    char contents[0];  // C99 應為 char contents[];
};
int main() {
    int this_length = 10;
    struct line *thisline = malloc(sizeof(struct line) + this_length);
    thisline->length = this_length;
    memset(thisline->contents, 'a', this_length);
    return 0;
}

意圖:動態分配不定長資料,length 記錄長度,contents 承載內容。

注意事項

  • VC++ 會警告 C4200: nonstandard extension used: zero-sized array in struct/union,需用 C99 寫法 char c[];。
  • 柔性陣列不限於 char,可為任意型別 float[] 等。
  • 包含柔性陣列的結構體不可作為陣列元素、不可宣告為static/extern無定義、不可直接宣告變數(僅能指標),因大小未知。
  • memcpy 複製結構體時不會複製柔性陣列內容,需手動處理。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved