這兩天被人問了乙個問題說假如c/c++訪問下表越界的陣列元素會報錯麼,於是充滿好奇心的我動手試了一下,wtf,果然沒有報錯,但是會給程式帶來莫名其妙的結果(比如十次的迴圈但是變成了死迴圈,但八次卻可以)
例:
1 #include2 #include34//程式結果:int a[5]=;
5int
main()6;
8//int *a=(int*)calloc(5,sizeof(int));
9for(int i=0;i<8;++i)
1014
15return0;
16 }
c語言的編譯器是不檢查下標越界的,以前知道這個問題,可是沒有想過是什麼原因?
總結如下:
1,不檢查下標是否越界可以有效提高程式執行的效率,因為如果你檢查,那麼編譯器必須在生成的目標**中加入額外的**用於程式執行時檢測下標是否越界,這就會導致程式的執行速度下降,所以為了程式的執行效率,c/c++才不檢查下標是否越界。
2,不檢查下標是為了給程式設計師更大的空間,也為指標操作帶來更多的方便。如果有這個檢查的話指標的功能將會大大被削弱,c的陣列識別符號,裡面並沒有包含該陣列長度的資訊,只包含位址資訊,所以語言本身無法檢查,只能通過編譯器檢查,而早期的c語言編譯器也不對陣列越界進行檢查,只能由程式設計師自己檢查確保。以及在早期的crt函式中也不對字串指標或陣列進行越界檢查,都是要求程式設計師確保空間足夠,因此也才也才有了在vs2005之後微軟提供的安全的crt函式版本。
自己寫了一段檢測程式測試這個問題,發現如果陣列下標越界了,那麼它會自動接著那塊記憶體往後寫。想了一下明白了,以前說不允許陣列下標越界,並不是因為界外沒有儲存空間,而是因為界外的內容是未知的。也就是說如果界外的空間暫時沒有被利用,那麼我們可以占用那塊記憶體,但是如果之前界外的記憶體已經存放了東西,那麼我們越界過去就會覆蓋那塊記憶體,導致錯誤的產生。。。
這樣就明白了,所以我們還是需要好好規劃陣列的下標滴。
c語言好像沒有直接取得陣列長度的函式,只有取得陣列所佔記憶體大小,再除以乙個元素占用的記憶體大小來計算陣列長度。
1int a[8
];2 printf("
%d",sizeof(a)/sizeof(a[0
]));
C 語言 編譯器
c 語言是高階程式語言,人們在使用 c 語言工作的時候不必用數字碼表示指令,大大簡化了對於計算機底層暫存器的操作,人們可以把工作的重點放在 設計和具體功能的實現,編寫出更易讀易懂的 可是計算機的工作和人類正好相反,c 語言編寫的 對於計算機而言就好比是天書且沒有意義可言,因為計算機是識別機器語言的,...
關於C語言的陣列賦值和陣列下標越界問題
陣列名就代表著該陣列的首位址,後面的所有元素都可以根據陣列名加上偏移量取到。第乙個小例子 程式設計實現顯示使用者輸入的月份 不考慮閏年 擁有的天數。include define months 12 intmain int month 1 12 dowhile month 1 month 12 處理不...
C語言的編譯器
c語言的常用編譯器 目前最流行的c語言編譯器有以下幾種 gnu compiler collection 或稱 gcc microsoft c 或稱 ms c borland turbo c 或稱 turbo c 這些c語言版本不僅實現了ansi c標準,而且在此基礎上各自作了一些擴充,使之更加方便 ...