地址是内存中每一个字节的编号。
假设现有一个 4G
容量的内存,换算成字节为:函数
4G = 4 * 1024 * 1024 * 1024 = 4294967296 Byte
因为地址是从 0 开始算的,因此其可以表示的范围(十进制)为 0 - 4294967295
。.net
在计算机领域内不会使用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
进行分配吧,同理可得。code
但显然使用二进制的方式表示足足有 32bit
的长度!!太长了,因此人们实际上使用的是16进制来表示地址!范围是:blog
0x00000000 <-> 0xFFFFFFFF
指针是保存地址的变量
地址能够保存在指针中;指针仅保存地址。内存
地址是字节编号,是一串 16进制 数字;指针是保存地址的变量。get
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
,经过上述对地址的认知后,能够理解:it
地址表示的是内存字节的编号。&a[0]
表示的是 数组a
第一个元素第一个字节的编号 000000218F4FF768
,&a[1]
是数组a
第二个元素第一个字节的编号 000000218F4FF76C
,他们相差 4
。变量
为何是相差 4
呢??这个是 4
有什么含义吗??
咱们都知道不管是 32bit/64bit
系统中,int
占 4 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)
。
其余同地址范例。