为什么这个C程序无法编译?它有什么问题?

5

为什么这个C程序不能编译?有什么问题吗?

我已经在wxDevC++和Turbo C++ 3.0上尝试过了。

Main.c

#include<stdio.h>
#include<conio.h>

const int SIZE = 5;

int main(int argc, char ** argv)
{    
    char array[SIZE] = {'A', 'B', 'C', 'D', 'E'};

    printf("Array elements are,\n");
    int i=0;

    for(i=0 ; i<SIZE ; ++i)
    {
        printf("%c  ", array[i]);
    }

    getch();

    return 0;
}

两个编译器的错误信息相似。

f:\_Source-Codes\main.c In function `main':

8 f:\_Source-Codes\main.c variable-sized object may not be initialized

6
错误是指在完成任务时出现的不正确的行为或结果。 - Andrey
1
你的编译器不允许使用可变大小的数组。只需将array[SIZE]替换为array[5],或者将const int SIZE = 5;替换为#define SIZE 5,它就可以编译(至少对于该错误而言)。 - Jason Coco
4
"pile of pooh" = 一大堆不太聪明的熊 - 这不是你想要在开发工具中看到的东西。 - Martin Beckett
6
Turbo C++ 3.0是我大约1992年使用的第一个C++编译器。这个问题一定是在开玩笑! - Daniel Earwicker
@Chapso,VS2008无法编译。错误1 错误C2057:预期常量表达式 f:_source-codes\main.c 8 ArrayInit__in__C - user366312
显示剩余5条评论
4个回答

15

C89/90语言中的数组大小必须由整数常量表达式指定(通常对于C99也是如此)。在C语言中,const int对象不是常量表达式,这就是为什么您不能使用它来指定数组大小的原因。注意:这是C和C ++之间一个显着的区别。

在C语言中,术语常量指的是字面值常量,即510.20xFF'a'等(枚举常量也是常量,确切地说)。再次强调,const int对象在C中不是常量,不能用于构建常量表达式。

如果您想要预先声明命名常量以在C中用作数组大小,则必须使用#defineenum。对于需要常量表达式的每个上下文,情况也是如此,包括case标签、位字段大小和其他每个上下文。

有关更多详细信息,请参见此处


在C++中允许这样做吗?如果我写const int SIZE = someFunction();,编译器在编译时就不知道char array[SIZE]需要多少栈空间了... - BlueRaja - Danny Pflughoeft
@BlueRaja: 在C++中,常量表达式可以使用用常量表达式初始化的 const对象。在您的情况下,您的 const对象未使用常量表达式进行初始化,这就是为什么它本身不是一个常量的原因。 - AnT stands with Russia
@Andrey:有关什么构成常量表达式的链接吗?如果someFunction()被定义为const int someFunction() { return 5; },那么SIZE是否被认为是用常量表达式初始化的? - BlueRaja - Danny Pflughoeft
@JMSA: const 只是意味着你不能在以后更改变量的值 - 初始值本身可能不是一个常量表达式。@BlueRaja: 我猜这取决于编译器是否决定将 someFunction 展开内联。 - casablanca
@JMSA:在C中,const关键字用于声明在运行时不应更改的对象(以及声明对对象进行常量限定的访问路径)。它不引入编译时常数,这就是为什么在C中它的使用范围比在C++中要有限得多。 - AnT stands with Russia
显示剩余2条评论

8
如果编译器将其视为'.c'文件,则int i声明需要放在任何可执行行之前,特别是在printf之前。
编辑一下,现在您已经显示了错误消息:
编译器在编译main时不认为SIZE是常量。您可以使用#define SIZE 5来解决问题。
根据K&R第2版的说法:
const的目的是宣布可以放置在只读存储器中的对象......除了应该对尝试更改const对象进行诊断之外,编译器可以忽略[const]限定符”。
因此,声明const int SIZE = 5并不会使SIZE成为constant-expression,而这是数组大小指定符要求的内容。

是的。但为什么const不起作用呢?ANSI标准说了什么? - user366312
正确的,声明必须在方法之前。 - Jamie Keeling
2
可能是因为Turbo C++ 3.0已经接近20年历史了。 - user177800
@fuzzy lollipop,好的,但我也在wxDevC++和VS2008上进行了测试。 - user366312
1
@AShelly:严格来说,你从K&R引用的内容与此无关。在C语言中,const对象永远不是 常量。在C中,“常量”的术语具有完全不同的含义。C++中我们称之为字面值(比如 50x1'a'),而C术语中的常量是指这个东西。在C中,const int对象不是一个常量,不能用于需要常量表达式的地方。无论编译器是否忽略“某些东西”,这始终如此。 - AnT stands with Russia
@AndreyT:深入研究K&R,我发现它也是这么说的。编辑我的答案以澄清。 - AShelly

5
尝试替换

const int SIZE = 5;

使用

#define SIZE 5

大多数C编译器不允许声明静态数组,其大小包含在变量中(即数组大小在运行时确定)。


大多数编译器允许声明“大小包含在变量中”的静态数组吗? - AnT stands with Russia
@AndreyT:只是想保险起见,不想出错。 - MAK

3

试试这个:

char array[] = {'A', 'B', 'C', 'D', 'E'};

@overslacked,这不是真的。大小首先取决于指定的常量。char array [2] = {'a','b','c'}; 会生成一个错误。char array [3] = {'a','b'}; 会生成一个3个元素的数组。仅当[]为空时,大小才从初始化列表中推断出来。 - AShelly

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接