1.指针变量和地址
其实在代码中定义一个局部变量,就是向内存中申请一块空间,这块空间的名称就叫做地址
而 地址==指针

1.1.指针的两个操作 & 和 *
&:取地址操作符
表示将a的地址取出来给p
*:解引用操作符
取出p指向地址中的值

int* p = &a;
int:在说明指向的对象是int
*:说明p是指针变量
1.2.指针变量的大小
也就是:
char*指向字符的指针
short*指向短整型的指针
int*指向整型的指针
float*指向单精度浮点型的指针
void*无具体类型的指针
的大小
2.指针变量类型意义
2.1.解引用
下面创建了一个int类型的a
第一次解引用是用int*来接受
第二次解引用是用char*来接受
但是对解引用的值进行改变的时候,int*可以改变4字节没问题,但是char*只能改变一个字节


2.2.决定了指针的步长
也是用char*和int*进行对比
p地址+1的时候加的是int的4个字节
q地址+1的时候加的是的char的1个字节

结论:
指针类型决定了指针的步长,就是向前/向后走一步走多大距离
type* p;
p+i 是跳过i个type类型的数据相当于跳过了i*sizeof(type)个字节
2.3.void*
3.count修饰
const本身的的作用是将可改变的变量修饰为不可改变的常变量,
但是,const修饰以后还是一个变量

const修饰指针
分为两种
1.const int * p:地址指向的内容本身不可以被修改

2.int * const p:地址本身不能被修改

4.指针之间的运算
5.野指针
5.1.野指针的形成
1. 指针未初始化


2. 指针越界访问

5.2.野指针的规避
1.初始化为NULL
6.assert断言
7.指针的使用
1.使用指针完成个strlen的功能
strlen的功能是求字符串⻓度,统计的是字符串中 \0 之前的字符的个数。

自我实现

8.指针与数组
8.1.数组名的理解
都知道数组名就代表数组的首元素地址,
但是

+1操作;
8.2.一维数组传参的本质
int arr[] 这种形式本质上等同于 int *arr,也就是它实际上是一个指向 int 类型的指针,并非真正的数组。
当你把数组作为参数传递给函数时,传递的其实是数组首元素的地址,而非整个数组的副本。

8.3数组指针
数组指针就是指向数组的指针,也是一种指针变量,用于存放数组的地址

8.4.二维数组传参本质
假设存放的是int
二维数组传参的本质是传递数组首元素的地址,但是首元素是一个int整形
二维数组传参的本质是传递数组首元素的地址,但是首元素是一个int类型的一维数组

int (*arr)[4]是一个指向包含 4 个int元素的一维数组的指针。

9.二级指针

10.字符指针变量
指向字符串常量 和 指向字符数组进行比较
1. 指向字符串常量
str 是一个字符指针变量,它指向了字符串常量 "akjfd"的首地址
字符串常量存储在只读内存区域,不能通过指针去修改它的值。如果尝试修改,会导致未定义行为

2.指向字符数组
指向了字符数组 arr 的首字符地址。与字符串常量不同,
字符数组存储在可读写的内存区域,可以通过指针修改数组中的字符

11.函数指针变量
函数指针变量的定义:

函数指针变量的使用:
x和y加上和不写上都是可以的

11.1.typedef关键字
函数指针这个变量名字过于冗余,所以使用typedef关键字对函数指针这个变量名字进行一个取别名的操作
语法格式:
![]()
实际调用:

