耐人寻味的:关于C数组名的含义问题 和 大小端存储结构_Andy_Issta_新浪博客...

以下转载:http://hi.baidu.com/hackercasper/blog/item/a014dd32899041f31b4cff32.html

 

先来看下面一段代码

#include <stdio.h>

int main(void)
{

int a[5] = {1, 2, 3, 4, 5};
int *ptr1 = (int*)(&a + 1);
int *ptr2 = (int*)((int)a + 1);

printf("%x %x\n", ptr1[-1], *ptr2);

return 0;
}

有兴趣的朋友可以来猜测下输出的值会是多少=.=~

给出答案 "5 2000000"

这里面涉及了关于C数组名的含义问题大小端存储结构

首先来说第一个 ptr1

它是用来讲述C数组名的含义

我们知道数组名a 代表的是数组a的首地址

假如a的地址是 0x0012FF6C

那么 ptr1 = (int*)(&a) ptr1的值也是 0x0012FF6C

但是 ptr1 = (int*)(&a + 1) ptr1的值却是 0x0012FF80

我们也顺便看看内存情况吧

耐人寻味的:关于C数组名的含义问题 和 大小端存储结构_Andy_Issta_新浪博客...

简单说说吧从 0x0012FF6C 开始是数组int a[5]

里面分别存着值 1, 2, 3 ,4 ,5 可以看见哈~

0x0012FF80 存储了数组a的首地址 a[0] 0x0012FF6C

ptr1的值变成了 0x0012FF80

你能想明白为什么吗?

其实数组名a 还有一层含义

简单地这样来打个比方

const int *a;

a = (int*) malloc (5 * sizeof(int));

这就是我们的 int a[5] 的另一种版本

可以看出数组名a 还有一层含义是管辖了它自己所属的区域

&a + 1 可不是简简单单的 0x12FF6C + 1

也不是 0x12FF6C + 4(int)

而是 0x12FF6C + <数组a的范围>

即 0x12FF6C + 5*(int) -> 0x12FF6C + 0x14 = 0x12FF80

所以数组名a 在最初分配空间时也是给定了它的区域

&a + 1 中的 +1 则是跨度数组名a所管辖的空间大小

所以ptr1现在指向0x0012FF80

如果输出&(*ptr1)则是0x0012FF80

而最后的ptr[-1]便是0x0012FF80 - 4(int) = 0x0012FF7C

0x0012FF7C所存的值便是我们得到的 5

----------------------------------------------------------------------------------------------------

然后是第二个ptr2

输出为 2000000 很多人会觉得很奇怪自己明明并没有存这个值啊

所以要简单得了解下关于大端和小端存储模式

耐人寻味的:关于C数组名的含义问题 和 大小端存储结构_Andy_Issta_新浪博客...
耐人寻味的:关于C数组名的含义问题 和 大小端存储结构_Andy_Issta_新浪博客...

我们来看看内存情况再来分析

耐人寻味的:关于C数组名的含义问题 和 大小端存储结构_Andy_Issta_新浪博客...

从图中也可以看出是采用的小端存储模式

ptr2 = (int*)((int)a + 1)

首先(int)a 也就是数组a的首地址

但这里注意 &a 和 (int)a 的意义不同所以导致 +1 的意义也不同

(int)a的值是 0x0012FF6C 即指向 a[0]

a[0]的值是 1 内存分布的情况是

0x0012FF6A 00 00 01 00 00 00 02 00 00 00 03

然后 (int)a + 1 并没有第一种情况的区域跨度只是简单地+1Byte

所以 (int)a + 1 是0x0012FF6C + 1 = 0x0012FF6D

因为是指向的地址连续取 4Byte 作为值

ptr2现在指向的内存情况是

0x0012FF6A 00 00 01 00 00 00 02 00 00 00 03

因为是小端存储结构

所以输出自然成了 2000000

 

--------------------------------测试实验截图如下------------------------------------------------------

耐人寻味的:关于C数组名的含义问题 和 大小端存储结构_Andy_Issta_新浪博客...