C語言編譯器不檢查陣列下標越界

2021-09-07 19:06:28 字數 1214 閱讀 7272

這兩天被人問了乙個問題說假如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語言好像沒有直接取得陣列長度的函式,只有取得陣列所佔記憶體大小,再除以乙個元素占用的記憶體大小來計算陣列長度。

1

int 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標準,而且在此基礎上各自作了一些擴充,使之更加方便 ...