C語言中數組使用負數值的標記


·引 對數組的認知

在c語言中,我們經常使用的一個結構便是數組,在最開始學習數組的時候,它被描述成這樣(以一維二維數組為例):
一維數組是若干個數連續排列在一起的集合,我們可以通過0-N的標記(N為數組的長度)來訪問每一個元素。
二維數組則是一維數組的集合。
所以在最開始我們對二維數組的概念是這樣的:

然后推而廣之到三維數組

很合理的,我們通過**空間結構**去類比數組的一維與二維,那么問題來了,在計算機當中它又是怎么“類比”這些數組的呢?
我們先看一些代碼

#include <stdio.h>
int main(void)
{
	int a[5][5];
	for(int i=0,num=0;i<5;i++)
		for(int j=0;j<5;j++,num++)
			a[i][j]=num;
	for(int i=0;i<5;i++){
		for(int j=0;j<5;j++)
			printf("%5d",a[i][j]);
		printf("\n");
	}
	printf("\na[ 1][ 1]=%2d  %p\n",a[1][1],&a[1][1]);
	printf("a[ 1][ 2]=%2d  %p\n",a[1][2],&a[1][2]);
	printf("a[ 1][ 3]=%2d  %p\n",a[1][3],&a[1][3]);
}
```

```
運行結果:
    0    1    2    3    4
    5    6    7    8    9
   10   11   12   13   14
   15   16   17   18   19
   20   21   22   23   24

a[ 1][ 1]= 6  000000000062FDE8
a[ 1][ 2]= 7  000000000062FDEC
a[ 1][ 3]= 8  000000000062FDF0

 這個結果是顯而易見的,而通過對地址的觀察,我們發現每兩個相鄰的數其間距為4個字節,也驗證了我們認為它是連續的這一認知。而按照約定進行訪問也是我們一般的使用方法。

· 擴展

接下來我們將輸出本部分替換成以下代碼

 

//這里我們將研究標記如果使用負數將會是什么情況
	printf("a[ 0][ 0]=%2d  %p\n",a[0][0],&a[0][0]);
	printf("a[ 0][-1]=%2d  %p\n",a[0][-1],&a[0][-1]);
	printf("a[-1][ 0]=%2d  %p\n",a[-1][0],&a[-1][0]);
	printf("a[-1][-1]=%2d  %p\n",a[-1][-1],&a[-1][-1]);
```
一次運行實例
```
	a[ 0][ 0]= 0  000000000062FDD0
	a[ 0][-1]= 0  000000000062FDCC
	a[-1][ 0]= 0  000000000062FDBC
	a[-1][-1]= 0  000000000062FDB8
```
或者我們再對a[4][4]進行越界研究,代碼:

```
		printf("a[ 4][ 4]=%2d  %p\n",a[4][4],&a[4][4]);
		printf("a[ 4][ 5]=%2d  %p\n",a[4][5],&a[4][5]);
		printf("a[ 5][ 4]=%2d  %p\n",a[5][4],&a[5][4]);
		printf("a[ 5][ 5]=%2d  %p\n",a[5][5],&a[5][5]);
```
一次運行實例

```
a[ 4][ 4]=24  000000000062FE30
a[ 4][ 5]= 0  000000000062FE34
a[ 5][ 4]= 5  000000000062FE44
a[ 5][ 5]=25  000000000062FE48
```

 

 實際上這些結果是恰恰符合我們的預期的,因為他們使用的下標超出了數組范圍,所以自然訪問到了數組外內存中的數,這些數是大部分是隨機的。
就像這樣


但是對於以下這些代碼:

```
	printf("a[ 1][ 0]=%2d  %p\n",a[1][0],&a[1][0]);
	printf("a[ 1][-1]=%2d  %p\n",a[1][-1],&a[1][-1]);
	printf("a[ 1][-2]=%2d  %p\n",a[1][-2],&a[1][-2]);
```

 其輸出結果為

```
	a[ 1][ 0]= 5  000000000062FDE4
	a[ 1][-1]= 4  000000000062FDE0
	a[ 1][-2]= 3  000000000062FDDC
```

 考慮之前的類比,這樣的結果顯然是不合理的,因為如果是二維結構,那么我們所輸出的結果應該為一個內存中的隨機值,但是根據觀察原數組:

```
    0    1    2    3    4
    5    6    7    8    9
   10   11   12   13   14
   15   16   17   18   19
   20   21   22   23   24
```

 我們恰恰可以發現它a[1][-1]與a[1][-2]輸出的恰恰是a[0][4]與a[0][3]的內容。也就是說我們退回了上一行
其實這些問題的答案在觀察數組的地址時就能找到答案:
000000000062FDE0 - 000000000062FDE4= 4 = sizeof(int)
顯然這意味着這是內存空間中連續的地址,也就是說二維數組真正的儲存方式任然是線性的,一維的,同理我們可以得知對於三維,乃至更高維的數組,它其實也無法跳出維度的限制,其實他們都是一維
所以我們應該這樣認識多維數組

(其實這些都是很簡單的東西,但是為此總結一下深化一下印象。因為很多時候第一印象往往是錯的,正如二維數組並不是二維)

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM