下面這道經典易錯題出自《C陷阱與缺陷》,也一度被眾多互聯網公司作為面試題拿來考察,可見其易錯程度與重點程度,下面我就給大家詳細講解一下這道列題,希望對大家有所幫助:
作為面試題:
下面我們就以簡潔代碼形式給出,原理是一樣的,話不多說,上代碼:
#include <stdio.h>
int main()
{
int i = 0;
int arr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
//0~9
for (i = 0; i <= 12; i++)
{
arr[i] = 0;
printf("hehe\n");
}
return 0;
}
按常理來說,這個陣列只有10個元素,也只能列印10個“hehe”,這里卻是回圈13次,應該出現陣列越界導致的程式奔潰,如圖:

然而這里卻出現了無限死回圈:

這到底是為什么呢,下面就跟著我一起來除錯(很重要)分析:
1.如圖,當i=11時,arr[11]=0(先不考慮越界),這里注意arr[12]的值始終是和i的值是一樣的,都還是正常的,再下一步 ->

2. 當arr[12]的值被制為0時,i 的值也同時被制成0,接下來導致出現啦死回圈列印,

猜想: 到這一步不難猜到,arr[12]的地址和i 的地址應該是一模一樣的,只有這樣才會導致出現i的值變化始終和arr[12]的值變化是同步的,
下面我們來驗證猜想:(在監視視窗中取出兩個變數的地址)

果然,arr[12]和 i 的地址是一模一樣的,所以才會出現同步變化以及死回圈, 是為什么呢?
下面我們就來給出答案:
1.首先我們要知道,區域變數(i 和 arr)在記憶體中是放在堆疊區的,
堆疊區的使用習慣是: 先使用高地址空間,再使用低地址空間 (i在定義在前,arr定義在后)
2. 陣列元素的地址是:隨著下標的增長是由低到高變化的
這里博主畫了一幅圖幫助大家理解(畫的太丑了勿噴hhh):

所以由于堆疊區存放中 arr[12] 和 i 的地址相同 ,當 arr[12]被制成 0 時 i 也被制成 0 ,從而導致死回圈列印的出現, 至此,題目講解完畢,
補充 :
由于編譯器的差異這里相隔地址也會有所差異,并不是絕對的,下面我就給出幾個常見的差異,大家可以選擇性記憶:
1.在 vc6.0 和 vs2017 中 arr和 i 是 緊挨著放的,
2. vs 2013-2019 (除去2017) arr 和 i 中間有2個元素,列如此題,
3. gcc 中 arr和 i 之間放一個元素,
如果覺得文章對自己有幫助,歡迎大家多多點贊評論收藏,這對博主來說是很大的鼓勵 !!
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/292086.html
標籤:其他
