目录
1.认识指针
2.指针变量和地址
2.1取地址操作符(&)
2.2 指针变量和解引用操作符
2.3 指针变量的大小
3.指针类型的意义
3.1指针的解引用
3.2 指针+-整数
3.3 void*指针
1、认识指针
在生活中,一栋楼的每个房间都会有房间号
有了房间号,就能提高效率,很容易的找到房间
而在C语言中,也会有这样一个个的 “房间” ,我们将它称为地址,有了这些地址,我们就很容易找到我们所创建的变量
同时,在C语言中,我们给地址起了一个新的名字,也叫做--指针
指针==地址==内存编号
我们知道,CPU和内存之间是有大量的数据交互的
而内存也被划分为一个个的单元,1个内存单元大小是1个字节(1个字节拥有1个地址)
每个内存单元都会拥有一个编号,这个编号就是地址,C语言中也把地址称作为指针
回到C语言
我们在编程中,每一次创建新的变量,其实就是在向内存中申请新的空间
如下图:在我们 int a 时,因为 int 是4个字节,所以我们会向内存中申请四个字节的地址
而这四个字节中每一个字节都会有属于自己的地址
下图中 int 申请的四个字节中,地址分别是
0*000000765F4FFC34 0*000000765F4FFC35
0*000000765F4FFC36 0*000000765F4FFC37
2、指针变量和地址
2.1取地址操作符(&)
那么,如何在编程中取出我们的地址呢?
这时就要用到取地址操作符(&)
有了取地址操作符,我们就可以将变量的地址取出来,那么,&该如何使用呢,只需要在 & 后加入你想取出地址的变量,就可以取出变量的地址
如上图,&a就可以将变量a的地址取出来,取出来的地址会是4个字节中地址较小的字节的地址
虽然整型变量占用了4个字节,但是只要我们知道了第一个字节的地址,顺藤摸瓜访问到4个字节的数据也是可以的
2.2 指针变量和解引用操作符
2.2.1指针变量
既然我们可以将地址取出来,那么有没有一种方式,可以将我们的地址存放起来,方便我们以后利用这个地址呢?
其实是有的,那就是我们的指针变量
指针变量是一种专门用来存放地址的变量
比如:
在这里,我们利用指针变量pb,将a的地址存放在pb中,这样以后我们想利用 a 的地址时,我们只需要利用 pb 就可以访问到a的地址
2.2.2 如何理解指针变量
在指针变量 int * pb 中,*是在说明 pb 是一个指针,int 是在说明 pb 所指向的指针是整型类型的内容
*的位置并不重要,无论是int* pb,还是int *pb,在这里的意义都是等价的
指针变量pb,它的类型是 int* 类型,这就像 int a 中 a 的类型是int,去掉变量名就是变量的类型
2.2.3 解引用操作符
在指针变量中,我们可以利用地址来进行变量内容的更改,这种更改就需要运用解引用操作符(*)
通过解引用操作符(*),我们就可以实现变量内容的更改
比如:
这里就通过解引用操作符,实现了 a 内容的更改
通过解引用操作符,*pb 就等于从 a 的较小字节的地址开始,进行4个字节的解析,进而得到 a 的全部内容
通过指针对a的修改,就多了一种修改内容的途径,写代码就会更加灵活
2.3 指针变量的大小
32位平台下地址是32个bit位,指针变量大小是4个字节
64位平台下地址是64个bit位,指针变量大小是8个字节
无论是哪种类型的指针类型,它们的字节在平台下都是一致的
结论:
指针变量的大小和类型是无关的,只要指针类型的变量在相同的平台下,大小都是相同的
3. 指针类型的意义
3.1指针的解引用
调试后可以发现,上面的代码会将4个字节全部更改为0,而下面的代码只会将第一个字节更改为0
结论:指针的类型决定了,对指针解引用的时候有多大的权利(一次能操作几个字节)
比如对(char*)类型的解引用就操作了1个字节,对(int*)类型的解引用就操作了4个字节
这里 a 的数值是287454020,pa存放的是a的地址,pb存放的也是a的地址
但是对 pa 解引用就会访问4个字节的内容,但对 pb 解引用就只会访问1个字节的内容
这是因为 pa 与 pb 的指针类型不同
3.2 指针+-整数
指针+-整数运行代码如下
可以发现指针+-整数,得到的地址发生了改变
而不同类型的指针,+-整数所得到的地址,跳过的字节是不一样的
int*类型的指针变量+1或者-1都是跳过了4个字节,只不过+1是向前4个字节,-1是向后4个字节
char*类型的指针变量+1或者-1都是跳过了1个字节,只不过+1是向前1个字节,-1是向后1个字节
因此我们可以得出结论:
指针的类型决定了指针向前或者向后走一步有多大(距离 / 字节)
这里跳过的其实是n*sizeof(int)/ n*sizeof(char) ,这里n代表指针 +- 的整数(n)
通用公式为 n*sizeof(类型)
3.3 void*指针
当我们使用void指针时,通常是在实现函数功能时,所接受的地址不确定是什么类型的,有可能是int*类型,也有可能是char*类型,或者其他类型时,我们就会使用void*指针
比如:
这时函数不确定接受的指针类型,就可以使用 void* 指针
void*指针是无法实现指针+-整数的,因为void是没有字节大小的,所以无法确定跳过几个字节
当我们想要void*指针+-整数时,系统就会报错,比如 :
不过我们可以通过强制转化,间接实现指针+-整数,比如:
可以看到即是是 void* 类型的指针,它也确实存进去了a的地址
将void*强制转化为int*,是可以实现指针+-整数的