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

C99 指定初始化器:結構體陣列的「Python 風格」賦值

     編輯:關於C語言

發現:Linux 內核中的奇特語法

閱讀 Linux 內核源碼時,在 init_pid_ns 結構體初始化中看到:


struct pid_namespace init_pid_ns = {
    .kref = { .refcount = ATOMIC_INIT(2) },
    .pidmap = { [0 ... PIDMAP_ENTRIES-1] = { ATOMIC_INIT(BITS_PER_PAGE), NULL } },
    .last_pid = 0,
    .level = 0,
    .child_reaper = &init_task,
};

關鍵點:[0 ... PIDMAP_ENTRIES-1] —— **範圍指定初始化器**,將陣列連續區間一次性賦值。

C99 標準:指定初始化器

允許在初始化列表中使用 .field = value(結構體)或 [index] = value(陣列),順序任意、可跳過、可重複(後蓋前)。

語法元素

形式適用對象說明
.member = val結構體/聯合指定成員名,不依賴宣告順序
[index] = val陣列指定單一索引
[first ... last] = val陣列**GNU 擴展**(非標準 C),指定連續範圍

標準 C99 範例


struct Point { int x, y; };
struct Point p = { .y = 10, .x = 5 };          // 亂序初始化
int arr[10] = { [5] = 99, [2] = 77 };          // 稀疏初始化,其餘為 0
int zeros[100] = { 0 };                        // 全零(舊寫法同樣有效)

GNU 擴展:範圍初始化器

僅 GCC/Clang 支援,MSVC 不支援。Linux 內核專用 GCC,故大量使用。


struct Item { int val; void *ptr; };
struct Item items[10] = {
    .val = 1,                     // 結構體指定初始化
    .id = { [0 ... 9] = { 2, NULL } } // 陣列範圍初始化(GNU)
};

等效於:


struct Item items[10];
for (int i=0; i<10; i++) { items[i].val = 2; items[i].ptr = NULL; }
items[0].val = 1; // 後蓋前

實測驗證


#include <stdio.h>
struct Pid { int val; void *fn; };
struct Str { int val; struct Pid id[10]; };

struct Str init_str = {
    .val = 1,
    .id = { [0 ... 9] = { 2, NULL } } // 需 GCC/Clang 編譯
};

int main() {
    for (int i=0; i<10; i++)
        printf("init_str.id[%d].val = %d\n", i, init_str.id[i].val);
    return 0;
}
// 輸出:全部為 2

移植性與最佳實踐

  • 標準 C99 指定初始化器:廣泛支援(GCC, Clang, MSVC 19.2+),**推薦在現代 C 專案全面使用**,提升可讀性與維護性。
  • 範圍初始化器 [a ... b]:屬 GNU 擴展,**避免在需跨編譯器專案使用**;可用巨集或靜態循環生成代碼替代。
  • 結構體陣列批量賦值:若無 GNU 擴展,改用靜態 const 陣列 + memcpy,或 C++11 std::array + 列表初始化。

總結

指定初始化器是 C99 引入的「殺手級特性」,讓結構體/陣列初始化從「位置依賴」進化為「名稱/索引依賴」,大幅降低維護風險。Linux 內核展示了其極致用法(含 GNU 範圍擴展),理解後可在自有代碼中靈活採用標準子集,享受清晰、安全的初始化體驗。

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