關於C語言的陣列賦值和陣列下標越界問題

2021-10-25 09:50:27 字數 3939 閱讀 4832

陣列名就代表著該陣列的首位址,後面的所有元素都可以根據陣列名加上偏移量取到。

第乙個小例子:程式設計實現顯示使用者輸入的月份(不考慮閏年)擁有的天數。**

#include

#define months 12

intmain()

;int month;

// 1-12

dowhile

(month<

1|| month>12)

;// 處理不合法資料

// days陣列是從0-11

printf

("the number of days is %d\n"

, days[month-1]

);return0;

}

上面這個例子我們簡單的用一維陣列儲存了一年的年份。這個**的功能想必題目說得很清楚了,我就不再重複贅述。中間有一段while迴圈的**,那個是為了處理不合法資料的,因為當我們輸入的值在1-12之間的時候,這個迴圈我們是出不去的,會讓我們一直輸入月份。

在後面輸出對應月份的天數的時候,我們用的下標是month-1,因為陣列的下標是從0-11,我們輸入的是1-12,所以-1後才是我們對應需要的月份。

一維陣列比較簡單,我們來看二維陣列。下面是乙個二維陣列的小例子。

int

main()

,,,}

;printf

("%d, %d, %d\n"

, a[1]

[1], a[0]

[2], a[2]

[1])

;return0;

}// 陣列構造:

// 1 2 3

// 4 5 0

// 6 0 0

// 0 0 0

input:5,3,0

這個例子我們可以看出來,這個二維陣列,我們最初只是指定了列數,沒有指定行數,也就是說二維陣列可以只指定列數,行數可以在我們進行賦值的時候,自動確定。比如我這個例子,二維陣列給定了三列,裡面寫了4個小的一維陣列,所以最終這個二維陣列的維度是4行3列

我們再來看下面這個更有趣的例子。

int

main()

;return0;

}

這個例子中沒有乙個小括號,雖然前面的定義是乙個二維陣列,但是裡面的賦值就像乙個一維陣列一樣,有點兒奇怪?其實他的內****的。

123

4567

00

為什麼會這樣?因為他指定了三列,這是毋容置疑的,但是沒有指定行數,所以裡面的元素會按照三列的規則一行一行的排列下去,如果排到某一行,還有空的位置沒有元素,就會自動被賦值為0,這個二維陣列的維度就是3行3列

陣列的奇特賦值方式我想大家已經理解了,那麼我們來看陣列越界的問題。

#include

intmain()

printf

("\n a = %d, c = %d\n"

, a, c)

;return0;

}

執行結果如下:

這個ac的值明顯被改變了,我們下面來看一下陣列越界後,發生了什麼:

其實編譯器之所以在編譯的時候沒有報錯,是因為他的取值賦值是根據位址來做的。由於陣列名就是該陣列的首位址,也就是第乙個元素的位址,所以當你的索引變化的時候,雖然陣列已經沒有對應元素給他使用了,但是他依然會根據偏移量往後繼續找,這也就把後面跟著的 c 和 a 的值給修改了。(我的編譯器雖然在執行的時候沒有報錯,但是執行結束後還是出現了異常,提示關閉程式)

關於偏移量,我舉個簡單的例子:

比如,在c語言中 char 字元型別是佔乙個位元組的。

我們定義乙個一維陣列 char a[5];

假設首位址是 40,那我們去 a[5] ,這個元素的位址就是 40+5*1

因為字元型別乙個位置佔乙個位元組。

那個5就是偏移量,也就是說如果你定義的 int a[5],那麼後面就是 40+5*4 了。

因為在大多數編譯器中 int 佔4個位元組,當然也有佔2個位元組的。

上面是一維陣列的越界情況。

#include

intmain()

;printf

("%p\n"

, a)

;// 輸出首位址

a[0]

[0]=

0x01

;// 16進製制

a[1]

[0]=

0x10

; a[0]

[4]=

0x04

;// a[1][0]

a[1]

[4]=

0x05

;// a[2][0]

a[5]

[4]=

0x20

;// 完美剛好越界

a[5]

[5]=

0x30

;// 越界

for(i=

0; i<

6; i++

)printf

("\n");

}return0;

}input:10

0040

0050

0000

0000

0000

00

**中的注釋我們可以看到,在乙個二維陣列 arr[6][4]中,a[0][4] 和 a[1][0] 是同乙個元素,因為 a[0][4] 在第一排越界後,根據偏移量的計算,他跑到了第二列的第乙個。

a[6][4] 是乙個6行4列的二維陣列,一行4個

a[0][4] = 0*4 + 4 = 4

a[1][0] = 1*4 + 0 = 4

a[i][j] = i*4 + j

表示前面已經走過了 4*i 個位址,然後在 i+1 行走了 j 個位置。

計算出來就是最終的位址。

對了,0x表示的十六進製制的陣列,比如 0x10 換算成十進位制就是 16。

因為就像16進一一樣,在第二位有乙個1,說明就已經有個16了。

以上就是二維陣列越界的情況。

#include

#define months 12

intmain()

,// 平年};

// 閏年

int year, month;

// 1-12

dowhile

(month<

1|| month>12)

;// 處理不合法資料if(

((year%4==

0)&&(year%

100!=0)

)||(year%

400==0)

)else

return0;

}

C語言中陣列名和陣列下標

整理自 c陷阱與缺陷 陣列注意點 1.c陣列中只有一維陣列,陣列的大小必須在編譯期作為常數確定。但c陣列的元素可以是任何型別的物件,當然也可以是另乙個陣列,所以 出乙個多維陣列。不太明白為什麼要強調只有一維陣列,難道 模擬 出來的多維陣列和真正的多維陣列不一樣?2.對於乙個陣列,我們只能夠做兩件事 ...

C語言 關於指標陣列和陣列指標

一 指標陣列 按照語文的理解,我們知道指標陣列的中心詞是陣列,而指標是用來修飾陣列的定語。事實上在c語言中也確實是這樣,指標陣列,就是乙個陣列,乙個存放指標的陣列。它常用於指向若干字串,這樣使字串處理更加靈活方便。下面我們通過幾個例子來理解一下指標陣列 int arr1 10 char arr2 4...

c語言陣列賦值

最近在學c語言,把給陣列賦值的方式總結一下 1 利用malloc include include void main int a a int malloc 2 sizeof int int i 0 int j 1 a 0 i a 1 j int times for times 0 times 2 直...