#include &

int main()
{
int n;

scanf("%d
",n);
int a[n];
}

编译命令:gcc t.c -ansi -o t

gcc t.c -ansi -o t


c语言没有但是gcc能编译过的东西多了,譬如说({1;2;3;4;5})表达式。


-ansi等效于-std=c90,但是并没有禁止所有GNU扩展。你可以加上-Wpedantic来禁用GNU扩展。不过GNU也其实没有保证一定能检查出所有不符合ISO规范的的地方,因为那需要许多额外的工作,而GCC只是编译器没有这个打算成为标准验证工具。


对于编译器来说,int a[n];中的a是automatic variable,要注意他的lifetime。这种变数只保证在第一次refer之前必须已经allocated好了的,但是,并没有规定死是在什么时候分配。所以,在执行scanf的时候,你可以理解成还没有在call stack中为他分配空间。

基于这个特点,如果一个函数中有多个自动变数,你也不能假定他们在栈中的相对位置跟声明的时候是一致的。

还可以对比一下global的数组,或者函数中的static数组,就不允许int b[n];这样的写法,数组的大小不能是变数,因为global和static变数在process layout中,是放在data或者BSS段的,编译的时候就要确定好数组的大小和存放的位置。

综上,这是自动变数和静态变数在数组上面体现出来的区别。

是不是这样的?


gcc的ansi默认应该是99以上,而且还有他自己的扩展。你如果要体验「最纯正」,最「old school」的c,加上-pedantic参数如果没记错的话,或者转用gcc 2.95.3。


现在的gcc默认都是c11了。


改变n,数组的长度(size(a))并不会发生变化。


理论上这个数组仍然是固定长度的数组,你后面再改变n也不会发生变化。

再换个说法是,数组后面的[]意思是规定预先把多少个这个类型的内存留住并且规定他们必定会互相挨著,所以一切只按第一次规定的结果来算,否则C的内存就乱套了。

所以gcc编译能过,但实际运行你是无法改变它的长度的。还有就是gcc能过的东西其实非常多,但实际运行的时候会出很多问题。你可以编译的时候加后缀 -Wall 来开启所有的warning,也许能帮到你

程序小白,有错的话请指出,谢谢


推荐阅读:
相关文章