簡體   English   中英

C 編程 - 靈活數組成員的非靜態初始化

[英]C Programming - Non static initialization of a flexible array member

我認為我的英語很難理解其他關於此的文章。 但不管怎么說:

我只是想我可以編寫一個程序(用 C 語言),它可以存儲一組卡片。 並不復雜,只需存儲卡片的值和名稱並打印出來。 我是 C 的初學者,因為我在我的書中的“結構中的字符串”部分,我想自己嘗試結構。 到目前為止,這是我的代碼:

#include <stdio.h>

struct card
{
    int value;
    char name[];
};

int main(void)
{
    const struct card heart[13] = { {2,"two"}, {3,"three"}, {4,"four"}, {5,"five"}, {6,"six"}, {7,"seven"}, {8,"eight"}, {9,"nine"}, {10,"ten"}, {11,"jack"}, {12,"queen"}, {13,"king"}, {14,"ace"} };
    int i;

    for (i = 0; i < 13; ++i)
    {
        printf("The card heart-%s has the value of %i", heart[i].name, heart[i].value);
    }

return 0;

}

我只是想測試它是否有效,所以我只是在代碼中編寫了心卡。 如果我想編譯這個文件,我的編譯器 (gcc/mingw) 會遇到 26 個錯誤。 它說:“(心臟[0]的近初始化)”“靈活數組成員的非靜態初始化”我不太明白這一點。 在書中,一切都按預期進行。 我試圖重建書中的代碼並更改名稱,但它不起作用。 我認為這是字符串的問題,因為如果我只使用整數,一切正常。 在另一篇文章中已經讀過,每個字符串都應該手動分配,並且有一個代碼示例,但我不知道所有行應該是什么意思,我想了解我的代碼是做什么的,所以我不復制+ 粘貼。

你能解釋一下為什么這不起作用嗎? PS:我目前是在windows下寫的,所以請不要用bash命令解釋之類的。 我也是德國人,我的英語不是“雞蛋的黃色”,請嘗試在不使用復雜的“句子結構”(我希望你知道我的意思:D)和不尋常的詞的情況下進行解釋。

感謝大家的幫助!

您需要為每張卡的名稱創建一些空間。 最簡單的方法是將您的struct card定義更改為:

struct card
{
  int value;
  char name[16];  // doesn't have to be 16, but make sure it's large enough to hold each card name plus a '\0' terminator
};

先前的答案建議為您的姓名分配固定長度。 這有局限性,甚至是危險的。 一起避免這一切總是一個好主意。

例如,您想在游戲過程中更改名稱,例如“Ace (Trump Card)”,但這可能會太長,甚至會覆蓋內存。 (代碼中的許多已知漏洞都是由緩沖區溢出引起的)

你也在建立一個限制; 如果您的游戲需要翻譯成另一種語言怎么辦?

通過使用指針,您無需求助於可變長度結構或固定字符串長度。

您還添加了添加設置數據的 API 訪問函數的功能,允許在寫入之前進行檢查,防止緩沖區溢出。

您應該在結構中使用指針,而不是使用字符數組(又名字符串)。 如果您點擊底部的鏈接,我會進一步了解並使用指向結構本身的指針。

由於指針存儲大小永遠不會改變你的名字可以是任何長度,甚至可以在以后改變,也許隨着游戲的進行。

你的卡可能看起來像

typedef struct card
{
    int value;
    char * name;
}

現在初始分配可以這樣完成

card_t card_ace = {14, "Ace"};

並且這些值不是固定的(除非這是您想要的,否則您將它們設為 const)。

card_ace.value = 200;
card_ace.name = "Trump card";

或者像這樣的一系列卡片

card_t suit_hearts[] = {{2,"two"}, {3,"three"}, {4,"four"}, {5,"five"}, {6,"six"}, {7,"seven"}, {8,"eight"}, {9,"nine"}, {10,"ten"}, {11,"jack"}, {12,"queen"}, {13,"king"}, {14,"ace"}}

使用指針更好地完成整個事情

typedef card_t * cards_t;

cards_t mysuit = &(card_t){2,"two"}, &(card_t){3,"three"}, ...

也許考慮把西裝做成一個結構。

typedef struct 
{
    char * name;
    card_t ** cards;
} suit_t;

typedef card_t * cards_t[];

suit_t mysuit = {
    .name = "Hearts",
    .cards = (cards_t){&(card_t){2,"two"}, &(card_t){3,"three"},....}
}

* 對於后者的完整工作示例,演示使用指針數組來回避固定數組的可變長度成員的限制,請參閱github 上的此要點

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM