[英]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.