所以我尝试在 C 中构建和使用结构数组,但遇到了一些无法解决的错误。我的代码是:
int numWords = 10;
typedef struct
{
char* word;
int count;
} wordsCount;
wordsCount words[numWords];
words[0].word = "Hello";
words[0].count = 1;
首先,在 Unix 中使用 gcc 编译器时,使用 -Wall -pedantic -ansi 标志进行编译时,我收到一条警告,其内容为
warning: ISO C90 forbids variable length array 'words' [-Wvla]
。对于我的代码片段的最后两行,我收到错误:error: expected identifier or '(' before '[' token
。
有人能告诉我为什么会出现这些错误吗?我在 Google 上搜索了许多不同的 typedef 和 struct 示例,我的示例反映了这些示例。
谢谢大家的建议。我决定编辑我的帖子,而不是回复每个单独的评论,以澄清我的问题。所以,我现在明白你不能在 C 中使用可变长度数组。我不能正式接受任何提供的答案,因为我的问题仍然存在,所以需要对我正在尝试做的事情进行更清晰的解释。
我正在创建一个程序,它计算文本文件中每个单词的出现次数并以 ASCII 顺序打印出来。例如,如果文本文件包含以下文本:
"Buffalo buffalo Buffalo buffalo buffalo buffalo Buffalo buffalo" is a grammatically correct sentence.
,则程序的输出应为:
Buffalo - 3
a - 1
buffalo - 5
correct - 1
sentence - 1
单词本身已经存储到数组中。所以我想创建一个包含单词和计数的结构数组。我修改了我的程序以考虑动态分配的内存。我更新的代码是:
typedef struct
{
char* word;
int count;
} wordsCount;
wordsCount** words = malloc(sizeof(*words) * numWords);
words[0]->word = "Hello";
words[0]->count = 2;
printf("%s - %d\n", words[0]->word, words[0]->count);
注意:
numWords
是一个整数,根据文本文件的大小而变化。
编译良好;但是,我在第一个赋值语句处收到了段错误
words[0]->word = "Hello";
。
我是否错误地假设我可以创建一个指向结构体指针的指针?我认为
->
运算符会引用结构体指针,然后指向成员“word”。我不明白为什么我会出现段错误。任何帮助将不胜感激。如果进行此编辑需要创建新线程,请告诉我,以便我可以移动它。谢谢。
我找到了问题所在——我对指针很满意,并且使用了太多的指针来做我想做的事情。我将
wordsCount** words = malloc(sizeof(*words) * numWords);
更改为wordsCount* words = malloc(sizeof(*words) * numWords);
。然后我意识到我在执行 words[0]->word = "Hello";
时正在进行必要的取消引用,因此我将其更改为 words[0].word = "Hello";
,并且效果完美。
#define NUM_WORDS 10
typedef struct
{
char* word;
int count;
} wordsCount;
wordsCount words[NUM_WORDS];
这将充分分配您开始赋值所需的内存。
编译器需要知道“words”数组应该有多大,因此当它遇到数组初始化时,它期望找到括号之间的大小。但它找到了“numWords”变量,并且无法使用它。预处理器不会将“numWords”替换为“10”。当你改变这个时它就会这样做
int numWords = 10;
到此
#define numWords 10
这应该可行。然后,预处理器会将代码中单词“numWords”的每个实例替换为“10”,以便数组初始化为:
wordsCount words[10];
主要有两个问题。
第一个,从其他答案中可以看出,您不能在全局范围内使用 VLA。 由于
numWords
是一个 int
变量,因此它不是常量,文件范围内的数组维度必须是常量。
我推荐:
enum { numWords = 10 };
另请参阅 C 中的
static const
与
#define
。
第二个问题是您正在全局范围内编写作业,这也是不允许的。 不过,您可以提供一个初始化程序:
enum { numWords = 10 };
typedef struct
{
char* word;
int count;
} wordsCount;
static wordsCount words[numWords] =
{
{ "Hello", 1 },
};
您不想让该文件外部的代码访问您的变量,对吗?