2

参考文章

C语言(彻底理解指针和地址,彻底!)

地址

地址是内存中每个字节的编号。

假设现有一个 4G 容量的内存,换算成字节为:

4G  = 4 * 1024 * 1024 * 1024
    = 4294967296 Byte

由于地址是从 0 开始算的,所以其能够表示的范围(十进制)为 0 - 4294967295

在计算机领域内不会使用10进制,而是使用二进制,范围为:

0000 0000 0000 0000 0000 0000 0000 0000
<->
1111 1111 1111 1111 1111 1111 1111 1111

为什么用如上的方式表示呢??而不是用 0 - 1111 1111 1111 1111 1111 1111 1111 1111 来表示呢??实际这么做也是可以的!不过最好推荐是使用如上的方式表示,为什么这么推荐呢??例如现在有一个 1000 人参赛的赛场,需要对参赛的 1000 人分配编号,你会怎么分配??是使用 0 - 999 进行分配还是使用 000 - 999 进行分配??肯定是使用 000 - 999 进行分配吧,同理可得。

但显然使用二进制的方式表示足足有 32bit 的长度!!太长了,所以人们实际上使用的是16进制来表示地址!范围是:

0x00000000 <-> 0xFFFFFFFF

指针

指针是保存地址的变量

联系

地址可以保存在指针中;指针仅保存地址。

区别

地址是字节编号,是一串 16进制 数字;指针是保存地址的变量。

使用地址的范例

int a[3] = {1 , 2 , 3};

// 由于 a 变量存在 main 函数内
// 所以是存储在 栈区 的局部变量
// 在函数调用完毕后会被释放(取消内存占用,
// 该片内存区域可被任意修改)
// 程序结束时被 os 回收
// 下次调用时,栈会被重建,所以变量
// 对应的内存地址也会发生变化
// 所以,这边仅展示某一次运行时的结果

// 以下结果是某次运行时的结果.
printf("&a[0] = %p\n" , &a[0]); // 000000218F4FF768
printf("&a[1] = %p\n" , &a[1]); // 000000218F4FF76C
printf("&a[2] = %p\n" , &a[2]); // 000000218F4FF770

从这边可以发现数组相邻元素地址相差 4,通过上述对地址的认知后,可以理解:

地址表示的是内存字节的编号。&a[0] 表示的是 数组a 第一个元素第一个字节的编号 000000218F4FF768&a[1] 是数组a 第二个元素第一个字节的编号 000000218F4FF76C,他们相差 4

为什么是相差 4 呢??这个是 4 有什么含义吗??

我们都知道无论是 32bit/64bit 系统中,int4 Byte,而地址表示的字节编号,所以有:

a[0] 第一个字节编号 000000218F4FF768
a[0] 第二个字节编号 000000218F4FF769
a[0] 第三个字节编号 000000218F4FF76A
a[0] 第四个字节编号 000000218F4FF76B

a[1] 第一个字节编号 000000218F4FF76C
a[1] 第二个字节编号 000000218F4FF76D
a[1] 第三个字节编号 000000218F4FF76E
a[1] 第四个字节编号 000000218F4FF76F

由上可知他们必然会相差 4,这个相差 4 没有什么特别的含义,就是在编号上相差 4 的意思。

使用指针的范例

int a[3] = {1 , 2 , 3};
int *p_a = a;

printf("p_a + 0 = %p\n" , p_a); // 000000218F4FF768
printf("p_a + 1 = %p\n" , p_a); // 000000218F4FF76C
printf("p_a + 2 = %p\n" , p_a); // 000000218F4FF770

这边要理解下指针运算,p_a + 0,在地址体现上是 p_a + 0 * sizeof(int)

其他同地址范例。


灰色v碰触
2.9k 声望42 粉丝

爱技术,爱生活


« 上一篇
二进制运算