大家对地址都不陌生,就像在生活中住酒店如何找到房间?那不就通过房卡上的房间号先确定楼层在确定房间。而这些房间号我们也叫地址。 把内存划分为一个个内存单元,一个单元为一个字节,而计算机中都是以一个比特位存储一个2进制位,一个字节也就是8个比特位。 这使得每个内存单元都有一个编号,通过这个编号,就能迅速找到这个内存空间。 在C语言中给地址起了新名叫:指针
所以我们理解的:内存单元的编号 == 地址 == 指针
在C语言中创建变量其实就是在向内存申请空间。就像这样:
#include <stdio.h>
int main()
{
int a = 5;
return 0;
}
创建了整型变量a,内存中就申请了4个字节,用来存放整数5。每个字节都有地址,而上面申请的4个字节的地址分别在下面划红线四个。
如果我们想得到a的地址,就需要用到取地址操作符&。 像下面这样就可,但值得注意的是我们打印的是地址用到的是**%p**。
#include <stdio.h>
int main()
{
int a = 5;
&a;
printf("%p\n", &a);
return 0;
}
我们通过取地址操作符&,得到的仅仅是地址,它就只是一个数值,有时候为了方便使用,我们把它用指针变量存储。
#include <stdio.h>
int main()
{
int a = 5;
int* p = &a;
return 0;
}
指针变量也是一种变量,不过是用来存放地址,存放在指针变量中的值被理解为指针。
指针也是有类型的。 就像前面所写的:
int a = 5;
int* p = &a;
在p的左边就是int*
,*
说明的是p为指针变量,而前面的int
就是说明p指向的是整型(int)类型的对象。
同理指向char
型的指针变量就是char*
。
char b = 'a';
char* p = &b;
在C语言中,我们找到地址,就可以对地址所指向的对象,而此时所要用到的就是解引用操作符(*)。
#include <stdio.h>
int main()
{
int a = 5;
int* p = &a;
*p=0;
return 0;
}
而在上面的代码中,原来a为5,我们通过指针拿到了a的地址,然后通过解引用操作*p=0将原来a的5改为0。
32位机器假设有32根地址总线,每根地址线出来的电信号转换成数字信号后是1或者0,那我们把32根地址线产⽣的2进制序列当做⼀个地址,那么⼀个地址就是32个bit位,需要4个字节才能存储。 如果指针变量是⽤来存放地址的,那么指针变的⼤⼩就得是4个字节的空间才可以。 同理64位机器,假设有64根地址线,⼀个地址就是64个⼆进制位组成的⼆进制序列,存储起来就需要8个字节的空间,指针变的⼤⼩就是8个字节。
#include <stdio.h>
int main()
{
printf("%zd\n", sizeof(char *));
printf("%zd\n", sizeof(short *));
printf("%zd\n", sizeof(int *));
printf("%zd\n", sizeof(double *));
printf("%zd\n", sizeof(float *));
return 0;
}
32位平台下地址,指针变量大小是4个字节
64位平台下地址,指针变量大小是8个字节
结论: