用变量n定义数组int a[n]; 用gcc编译通过,运行正常

brookmill 2009-02-27 01:35:03
刚看到一位网友的代码,差不多是这样的:
int n;
scanf("%d", &n);
int a[n];
我的第一个反应是,这怎么能行呢?没想到用gcc编译,连个警告都没有
用VS2005编译就会报错。

又多写了几行:
#include <stdio.h>

int main()
{
int n;
scanf("%d", &n);
int a[n];
int i;
char s[n];
int j;

printf("n: %p\n", &n);
printf("a: %p\n", a);
printf("i: %p\n", &i);
printf("s: %p\n", s);
printf("j: %p\n", &j);

#if 0
for (i=0; i<n; i++)
a[i] = i;
for (i=0; i<n; i++)
printf("%d ", a[i]);
#endif
return 0;
}

用gcc4.3.2编译,然后运行:
[code=BatchFile]$ gcc -Wall test.c
$
$ ./a.out
256
n: 0x7fffe2c9e1e4
a: 0x7fffe2c9ddb0
i: 0x7fffe2c9e1e0
s: 0x7fffe2c9dca0
j: 0x7fffe2c9e1dc
$
$ ./a.out
4096
n: 0x7fff5df804c4
a: 0x7fff5df7c490
i: 0x7fff5df804c0
s: 0x7fff5df7b480
j: 0x7fff5df804bc
[/code]
可以看出,main里面首先给n、i、j连续分配了空间,然后根据n的大小给a和s动态分配了空间

请高手指点。
...全文
627 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
piginthetree 2009-03-03
  • 打赏
  • 举报
回复
现在都2009了 过了10年了哦 vs太不厚道了
changyawu 2009-03-03
  • 打赏
  • 举报
回复
c99标准。

另:GCC的编译器怪异的选项多呢
疯哥哥 2009-02-28
  • 打赏
  • 举报
回复
GCC对标准的支持的确很好,比VC好.几乎是最好的.
brookmill 2009-02-28
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 xuguod20042576 的回复:]
vs2005当然会报错的,它的main函数必须这样写int main(int argv,char argc[]){}
[/Quote]
不敢苟同。不用命令行参数的时候我从来都是写int main()的
brookmill 2009-02-28
  • 打赏
  • 举报
回复
谢谢各位
zenny_chen 2009-02-27
  • 打赏
  • 举报
回复
这是C99的一个特性。但是访问动态分配的数组效率可能会降低,因为一般访问一个函数中的数组可以通过栈帧基地址+偏移×数组元素大小的方式进行寻址,而如果使用动态分配的数组后,由于数组的长度依赖于一个变量,因此这时候(偏移量×数组元素大小)将无法作为常量,必须损耗一个寄存器来存放偏移量。
fox000002 2009-02-27
  • 打赏
  • 举报
回复
gcc 扩展蛮多的
ForestDB 2009-02-27
  • 打赏
  • 举报
回复
C99啊,C也是不断进步的。
waizqfor 2009-02-27
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 brookmill 的回复:]
C99上好像是说,在这里可以用变量甚至表达式
多年来的观念就这样被颠覆了……
[/Quote]
GCC支持 C99啊 别的编译器不知道
VC是不支持的
GCC有挺过功能 都很特殊的 LZ可以去看看C语言核心技术 后面讲编译器那一点 都是讲GCC的
xuguod20042576 2009-02-27
  • 打赏
  • 举报
回复
vs2005当然会报错的,它的main函数必须这样写int main(int argv,char argc[]){}
Sevenlight_x 2009-02-27
  • 打赏
  • 举报
回复
学习了
hhyttppd 2009-02-27
  • 打赏
  • 举报
回复
呵呵,我也不知道C99,也不关心这个,不过知道有VLA一说。
能编译就让它编吧,只是希望别把自己搞死了。
  • 打赏
  • 举报
回复
这个是GCC的一个扩展,使用C98模式下有这个扩展
C99直接有这个功能

VC不支持C99.所以编译不过去
nineforever 2009-02-27
  • 打赏
  • 举报
回复
VC不支持C99
yangch_nhcmo 2009-02-27
  • 打赏
  • 举报
回复
Variable length arrays 是C99的特性,而不是 C++98 的,关于c99标准的变长数组, 在标准的6.7.5.2 Array declarators里面有这样的说明:
2.Only ordinary identifiers (as defined in 6.2.3) with both block scope or function prototype scope and no linkage shall have a variably modified type. If an identifier is declared to be an object with static storage duration, it shall not have a variable length array type.
换而言之, 变长数组不能是在静态存储区(包括全局变量和静态变量)中的。
另外,VLA 需要支持 sizeof 运算, 动态sizeof 也是C99的一个特有特性。
目前很多C++编译器尚不能支持动态数组特性(VC++2005不支持此特性, GCC3.2之后支持,之前的版本没有调查,不知道是从哪个版本开始支持此特性的)。gcc的文档里面说:Variable-length automatic arrays are allowed in ISO C99, and as an extension GCC accepts them in C89 mode and in C++。所以,使用GCC,即使你打开 -ansi (等价于 --std=c89)选项,也仍然可以使用动态数组。
其实C99的VLA也不是真正意义上的变长数组—它只是在运行时可以根据一个变量生成一个数组,此数组此后并不会变化,而真正意义的变长数组可以在实际使用时可以动态伸缩。
brookmill 2009-02-27
  • 打赏
  • 举报
回复
C99上好像是说,在这里可以用变量甚至表达式
多年来的观念就这样被颠覆了……
Darkneece 2009-02-27
  • 打赏
  • 举报
回复
gcc连函数嵌套定义都支持
hityct1 2009-02-27
  • 打赏
  • 举报
回复
mark。的确有的编译器能通过。
brookmill 2009-02-27
  • 打赏
  • 举报
回复
刚才又加了两行代码,看sizeof(a)和sizeof(s),结果分别是n*4和n

C99的6.7.5.2有一段好像是讲这个的,还没看懂

69,374

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧