何为指针?
取地址操作符:
刚刚提过,变量的本质实际上是在内存中申请空间,图中int a在内存中申请4个字节,⽤于存放整数10,其中每个字节都有地址,这四个地址如图中红框所示
&a取出的实际上是a所占4个字节中地址较⼩的字节的地址。
我们只要知道了第⼀个字节地址,就可以依次找到剩下的地址。
指针变量与解引用操作符:
pa就是一个指针变量,指针变量也是⼀种变量,这种变量就是⽤来存放地址的,存放在指针变量中的值都会理解为地址。
这⾥pa左边写的是 int* , * 是在说明pa是指针变量,⽽前⾯的 int 是在说明pa指向的是整型(int) 类型的对象。再比如,如果创建了一个char类型的变量,存放该变量地址的指针就应该写成:
我们把地址存起来后,以后该如何取出来使用呢?这就需要解引用操作符
解引⽤操作符:
这里的 *pa 中的 * 就是解引用操作符(间接访问操作符),*pa 的意思就是通过pa中存放的地址,找到指向的空间,*pa其实就是a变量了;所以*pa = 0,这个操作符是把a改成了0.
既然是变量,指针变量也有大小,它的大小是由解决方案平台决定的。
指针变量大小:
x86是32位平台,x64是64位平台
指针+-整数:
我们发现,虽然 char*pc 与 int*pi 指向的是同一个地址但pc+1与pi+1的结果不同,pc+1指针跳过了一个字节,而pi+1则跳过了4个字节
void* 指针:
指针类型中有一种叫void*类型的指针,这种指针为无具体类型的指针(也叫泛型指针),这种类型的指针可以⽤来接受任意类型地址。但是也有局限性
void* 类型的指针不能直接进⾏指针的+-整数和解引⽤的运算。
const:
何为conset?我们知道,变量是可以进行修改的,如果把变量的地址交给⼀个指针变量,通过指针变量的也可以修改这个变量。
但是如果我们不想让这个变量进行修改,那么就要用到const:
const修饰变量:
这样子就会报错。
但是,我们还有一种方法去修改,那就是用指针变量修改:
这里我们绕过n,使⽤n的地址,就能去修改n。
但是,我们用const的本意实际上是不愿意要让该变量能进行修改的,那么该如何做,能够做到不能用指针进行修改呢?
const修饰指针:
⼀般来讲const修饰指针变量,可以放在*的左边,也可以放在*的右边,意义是不⼀样的。
如果*左右两边都加上const,那么p本身和*p都会被限制。
指针的运算:
指针可以进行三种运算:
1.指针+-整数
2.指针-指针
3.指针的关系运算(这个是指关系比较)
1.指针+-整数:
前面我们提到过,这里直接举例说明:
(我们知道,数组内部存放数据的时候,都是连续存放的)
注:指针类型决定了指针+1的步长,决定了指针解引用的权限。因为关于整型类型的地址,加一,向后移动一个整型大小
2.指针 - 指针:

3.指针的关系运算:
这个主要是指针间的比较,直接举例说明:
野指针:
定义
何谓野指针?就是指指针指向的位置是不可知的
导致野指针的三种情形:
1:指针未初始化
2:指针越界访问
3:指针指向空间释放
如何规避野指针?
1:指针初始化:如果不知道指针应该指向哪里,可以用NULL对指针赋值
但是NULL这个地址是无法使用的,直接读写地址会出错
2:注意是否越界
3:指针变量不再使用时,可以及时值为NULL,同时指针使用前要检查是否为NULL
4:不要返回局部变量的地址
这里我们再引入一个概念,叫assert断言:
assert断言:
我们经常用assert来断言指针的有效性(是否为空)

传值调⽤和传址调⽤:
为什么要引入指针这个概念,或者说指针有什么特别的作用呢?
我们来举个例子:



关于指针的介绍还有很多,由于篇幅过长,今天所介绍的是其中一部分,感兴趣的话,关于接下来的介绍请看深入理解指针(2)(♡>𖥦<)/