🌀 复杂类型说明
int p;
这是一个普通的整型变量。
int *p;
首先从 p 处开始,先与 * 结合,所以说明 p 是一个指针, 然后再与 int 结合, 说明指针所指向的内容的类型为 int 型。所以 p 是一个返回整型数据的指针。
int p[3];
首先从 p 处开始,先与 [] 结合,说明 p 是一个数组, 然后与 int 结合, 说明数组里的元素是整型的, 所以 p 是一个由整型数据组成的数组。
int *p[3];
首先从 p 处开始, 先与 [] 结合,因为其优先级比 * 高,所以 p 是一个数组, 然后再与 * 结合, 说明数组里的元素是指针类型, 然后再与 int 结合, 说明指针所指向的内容的类型是整型的, 所以 p 是一个由返回整型数据的指针所组成的数组。
int (*p)[3];
首先从 p 处开始, 先与 * 结合,说明 p 是一个指针然后再与 [] 结合(与"()"这步可以忽略,只是为了改变优先级), 说明指针所指向的内容是一个数组, 然后再与int 结合, 说明数组里的元素是整型的。所以 p 是一个指向由整型数据组成的数组的指针。
int **p;
首先从 p 开始, 先与 * 结合, 说是 p 是一个指针, 然后再与 * 结合, 说明指针所指向的元素是指针, 然后再与 int 结合, 说明该指针所指向的元素是整型数据。由于二级指针以及更高级的指针极少用在复杂的类型中, 所以后面更复杂的类型我们就不考虑多级指针了, 最多只考虑一级指针。
int (*pa[10])[5];
首先 pa 和 [] 进行结合了, pa 所接收的数组是10个。这里的 pa 是一个存储数组指针的数组,该数组能够存放10个数组指针,每个数组指针能够指向①个数组,数组⑤个元素,每个元素是int类型。
💥 一级指针传参
用一级指针接收数组名(首元素地址),写个函数把一级指针变量传递过去。打印出 arr 数组名当中的内容。函数当中传参是一级指针,所以也被称之为一级指针的传参。那么在实参当中我们就可以拿指针变量去接收传参当中的一级指针。
💥重点核心:一级指针传参就用一级指针来进行接收!
示例,如下代码所示 👇
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
void print(int* p2, int sz)
{
printf("p2 = %p\n", p2);
printf("*p2 = %p\n", *p2);
printf("&(*p1) = %p\n", &(*p2));
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%d ", *(p2 + i));
}
}
int main(void)
{
int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int sz = sizeof(arr) / sizeof(arr[0]);
int* p1 = arr;
printf("p1 = %p\n", p1);
printf("arr = %p\n", arr);
printf("&(*p1) = %p\n", &(*p1));//先获取值再转换地址
printf("*p1 = %p\n", *p1);
print(p1, sz);
return 0;
}
💥 二级指针传参
取出 &a 的地址,存放到指针变量 pa,pa 此时此刻就是一级指针变量。对于一级指针变量来说,取出 pa 的地址就要用个二级指针来进行存放 ppa。这个时候我们把二级指针传参到自定义函数当中,这样我们就把二级指针给进行传参。形参当中那么就需要用到二级指针来接收。
💥注意:二级指针是专门存放一级指针变量的地址的。
示例,如下代码所示 👇
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
void print(int** ppa)
{
*ppa = 20;
}
int main(void)
{
int a = 0;
int *p = &a;
int **ppa = &p;
print(ppa);
printf("a = %d", p);
printf("a = %d", a);//a是不会改变的
return 0;
}
编译运行结果:p = 20
从上述结果可以得知,我们通过二级指针改变了原本整形指针 p 的结果。
🔥 指针的类型
从语法的角度看,你只要把指针声明语句里的指针名字去掉,剩下的部分就是这个指针的类型。这是指针本身所具有的类型。
1、int *p; 指针的类型是 int*
2、char *p; 指针的类型是 char*
3、int **p; 指针的类型是 int**
4、int (*p)[2]; 指针的类型是 int(*)[2]
5、int *(*p)[4]; 指针的类型是 int*(*)[4]
🔥 指针所指向的类型
当你通过指针来访问指针所指向的内存区时,指针所指向的类型决定了编译器将把那片内存区里的内容当做什么来看待。
从语法上看,你只须把指针声明语句中的指针名字和名字左边的指针声明符*去掉,剩下的就是指针所指向的类型。
1、int*ptr; 指针所指向的类型是 int
2、char*ptr; 指针所指向的的类型是 char
3、int**ptr; 指针所指向的的类型是 int*
4、int(*ptr)[3]; 指针所指向的的类型是 int()[3]
5、int*(*ptr)[4]; 指针所指向的的类型是 int*()[4]
在指针的算术运算中,指针所指向的类型有很大的作用。