码迷,mamicode.com
首页 > 编程语言 > 详细

C语言中数组使用负数值的标记

时间:2018-11-17 22:14:57      阅读:181      评论:0      收藏:0      [点我收藏+]

标签:display   分享图片   一维数组   就是   e30   png   多维数组   play   size   

·引 对数组的认知

在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)
显然这意味着这是内存空间中连续的地址,也就是说二维数组真正的储存方式任然是线性的,一维的,同理我们可以得知对于三维,乃至更高维的数组,它其实也无法跳出维度的限制,其实他们都是一维
所以我们应该这样认识多维数组

技术分享图片

(其实这些都是很简单的东西,但是为此总结一下深化一下印象。因为很多时候第一印象往往是错的,正如二维数组并不是二维)

 

 

 

 

C语言中数组使用负数值的标记

标签:display   分享图片   一维数组   就是   e30   png   多维数组   play   size   

原文地址:https://www.cnblogs.com/whitesad/p/9975647.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!