指针定义:指针就是内存地址
指针定义格式: 数据类型 变量名 int * p
指针占用内存大小 与编译器有关,32位的编译器,指针占用的内存位4字节
指针注意点: 不同类型的指针,不能互相赋值
int a = 100;
int *p1 = &a;
*p1 //编译器知道p1所指向的类型是int,所以*p1取四个字节,解释为int
char *p2 = p1;
*p2 //编译器知道p2所指向的类型是char,所以*p2取一个字节,解释为char
-->所以不同类型的指针互相赋值,虽然俩个不同类型的指针所保存的地址是一样的,但由于所指向的数据类型的不同,会造成通过同一地址解引用出来的数据不同
指针作用:
- 获取数据进行读写
char a = '3';
char *p = &a;
printf("%c", *p); //3
*p = ‘!’;
printf("%c", *p); //!
printf("%c", a); //!
- 函数返回多个值
//函数:求一个数组最大值和最小值
bool GetArrMaxAndMin(int arr[], int len, int *max, int *min)
{
if (arr == NULL || max == NULL; min ==NULL)
{
return false;
}
*max = arr[0];
for(int i = 1; i < len; i++)
{
if(arr[i] > *max)
{
*max = arr[i];
}
}
*min = arr[0];
for(int i = 1; i < len; i++)
{
if(arr[i] > *min)
{
*min = arr[i];
}
}
return true;
}
- 把函数的结果和计算状态分开 返回值表示状态
//函数:获取俩数相除的余数
bool GetRemainder(int num1, int num2, int *res)
{
if (num2 == 0)
{
return false;
}
*res = num1 % num2;
return true;
}
int a = 10;
int b = 4;
int res = 0;
if (GetRemainder(a, b, &res))
{
printf("%d\n", res);
}
指针高级:
-
指针的运算
-
指针跟整数进行加,减的操作(每次移动N个步长)
-
指针跟指针进行减操作(间隔步长 获取地址值的差值 / 指针所指向数据类型的字节数) 步长:指针移动一次,走了多少个字节,取决于指针所指向的数据类型 char : 1 int : 4 double : 8
//与整数的加减
int a = 8;
int *p = &a; //p:0x05
p + 1; //p: 0x09
p - 1; //p: 0x01
//指针之间的减法
int a[] = {1, 2, 3, 4, 5};
int *p1 = &a[0];
int *p2 = &a[4];
int interval = p2 - p1; //4
- 野指针与悬空指针 野指针:所指向的空间未被分配 悬空指针:指针所指向的空间被释放了
int a = 10;
int *p1 = &a;
int *p2 = p1 +10; //p2野指针
int *func(void)
{
int num = 10;
return #
}
int *p3 = func(); //p3悬空指针
-
void类型的指针 注意点:void *,无步长概念,无法获取地址下的数据以及进行运算 作用:可以接收任意数据类型的指针所记录的内存地址
-
二级指针与多级指针 定义格式: 数据类型 变量名; int ** pp;
作用:获取一级指针记录的地址(*) 获取变量所记录的数据(**)
- 数组和指针 数组指针:指向数组的指针 数组指针作用:方便操作数组中的各个数据 利用指针遍历数组,遍历数组的目的是获取到数组中的每个元素
int arr[] = {1, 2, 3, 4, 5};
int *p = arr;//数组指针:定义一个指针,记录数组的首地址
for(int i = 0; i < 5; i++)
{
*p++//每次循环就获取到了数组中的一个元素
}
- 函数指针
//灵活操作函数
void method1(void)
{
printf("method1\n");
}
int method2(int num1, int num1)
{
printf("method1\n");
return num1 + num2;
}
void (*p1)(void) = method1;
int (*p2)(int num1, int num2) = method2;
p1(); //相当于调用函数method1
p2(10, 20); //相当于调用method2
//回调函数
下层:提供注册接口
typedef void (*uasrt_callback_t)(void);
uasrt_callback_t usart_callback;
void usart_callback_resgister(asrt_callback_t callback)
{
usart_callback = callback;
}
上层:注册入具体的业务