#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,也許能幫到你

程序小白,有錯的話請指出,謝謝


推薦閱讀:
相关文章