2012-03-11 197 views
1

我想创建一个结构数组,其中的数组大小由程序中的用户定义。例如。 P [0],P [1],P [2] .....动态分配结构数组

typedef struct 
{ 
int score; 
}player; 

void main() 
{ 
    int numPlayers; 

    printf ("\nEnter number of players (1 - 4)\n"); 
    scanf ("%d", &numPlayers); 

} 

我试着与两个

player p[numPlayers]; 

player *p=malloc(numPlayers*sizeof(player)); 

但这样做两者都不会编译。 任何人都可以看到这里出了什么问题吗?

编辑:我正在使用VS2010。 我得到了第一个“表达式必须有一个常数值”,并且“void *”类型的值不能用于初始化第二个类型为“player *”的实体。

+0

你得到了什么编译错误? – 2012-03-11 20:45:45

+0

什么编译器和编译器错误是什么? – hmjd 2012-03-11 20:45:51

回答

1

player p[numPlayers];方法调用“可变长度数组”。这是一项在GNU C方言中出现的功能,并且在1999年被采用到C语言中。为了编译,您需要一个编译器,将其识别为扩展或C99编译器。可变长度数组有一个缺点:它们通常通过在堆栈上分配内存来实现。没有办法检测是否有足够的内存。

你有malloc的调用语法是罚款:

player *p=malloc(numPlayers*sizeof(player)); 

但是,如果你想要写在你的函数这在任何地方,你需要使用一个C99编译器,或者编译器接受相互杂糅语句和声明(比如GNU C在C99之前已经将它作为C99的扩展并在默认情况下接受它)。在C90中,您必须在函数顶部的声明块或声明中声明指针: player *p = NULL;。然后,在玩家人数已知之后,分配给它​​。

你应该发布不能编译的实际程序。没有这个,我们只是猜测!

此外,你有一些问题。首先,如果你想要调用malloc,你应该在头文件<stdlib.h>中声明malloc。

其次,main应返回类型int而不是void

另外,请检查返回值scanfscanf功能对交互式输入不利。例如,如果用户点击回车,scanf一直在等待输入,寻找那些不友好的数字字符。scanf也没有错误检查%d。如果您输入的数字不符合int类型,则该行为仅为未定义。这种类型的输入处理仅适用于为作者自己使用而编写的快速而肮脏的“一次性”程序。

+0

“...在1991年”?真? “1999”也许? – 2012-03-11 20:56:48

+0

感谢您的详细回复。我确实在scanf之后调用malloc。尽管它仍然无法正常工作,但即使改变了这些情况我将hmjd的代码放在下面的空白项目中,我仍然遇到我提到的第二个错误。 – karoma 2012-03-11 21:29:27

+0

这可能是因为你实际上是用C++编写的。在C++中,你不能将'void *'类型的指针赋给'player *'。这不是一种类型安全的转换。规则在C中放宽了(尽管'void'类型最初来自C++!)。在C++中,你需要像'player * p =(player *)malloc(...)'这样的演员。你有没有用'.cpp'后缀保存你的文件?无论如何,如果你在C++中工作,请为你的问题标记C++。 – Kaz 2012-03-11 22:01:33

1

一种可能是你忘记了#include <stdlib.h>如果没有它的原型,编译器会假定malloc返回一个int,它不会转换为没有转换的指针(但不使用转换 - 包含正确的头文件,因此编译器知道返回类型代替)

编辑:。这是不相关的,但FWIW,main应该返回int,不void

+1

如果碰巧是一个C++编译器,它会拒绝该程序,因为该函数未声明。 – Kaz 2012-03-11 20:56:14

+0

'main'完全相关,因为编译器可以拒绝'void main'。你永远不会知道;这位新手可能已经被老师告知要用'-Werror'来使用gcc。 :) – Kaz 2012-03-11 21:02:20

+1

@Kaz:理论上,是的。根据他的评论,不。 – 2012-03-11 21:04:48