指针难点(指针数组,数组指针,函数指针,函数指针数组)
前言
关于简单的整型/字符指针就不过多赘述,在这详解一下我个人认为指针的难点问题
提示:以下是本篇文章正文内容,下面案例可供参考
一、指针数组
首先,我们要知道数组指针,它是个数组,因为它和后面要介绍的数组指针名字相似,所以在这做一个强调。
代码例子:
int* arr1[10]; /整形指针的数组
char *arr2[4]; /一级字符指针的数组
char **arr3[5];/二级字符指针的数组
指针数组理解起来不难,一个图就可以 就是创建一个数组,里面存放的是指针。
但它如何使用呢? 我们依然用一个简单代码解释
int* p[5];/创建一个指针数组p
int a = 4;/在创建一个变量a=4
p[0] = &a;/在这里,因为p是一个指针数组,所以里面应当存放指针,而我们知道指针内 存放的是地址
所以我们令数组p的第一个元素(指针)指向a的地址。
printf("%d", *(p[0]));/在这里p[0]可以看成指向a的指针,对它解引用,得到的值就是a=4
指针数组相对简单,我们先解释到这。
二、数组指针
首先,我们要知道数组指针,它是个指针
先提一个问题
int *p1[10];
int (*p2)[10];
你能看出他们哪个是数组指针吗?
答案:p1是指针数组,p2是数组指针。
因为当括号阔上星p2时,p2先和星号结合了,说明p是一个指针变量,然后指向后面一个大小为10的数组,所以p是一个指针,指向一个数组,叫数组指针。
这里要注意:[ ]的优先级要高于星号的,所以必须加上()来保证p先和*结合。
理解上我们依旧用图理解会更好理解 p是一个指针,指向了一个大小为10的数组,p里面存的是 &数组名(注意不是数组名!),简而言之就是,p存的不是数组首元素的地址,而是数组的地址,接下来详解。 数组名与&数组名的区别 看这样一段代码 #include <stdio.h>
int main()
{
int arr[10] = { 0 };
printf("arr = %p\n", arr);
printf("&arr= %p\n", &arr);
printf("arr+1 = %p\n", arr+1);
printf("&arr+1= %p\n", &arr+1);
return 0;
}
他的结果是 我们见到arr与&arr打印出来的结果是一样的,但是arr+1与&arr+1的结果不一样。 因为我们知道,arr是数组名,代表数组的首元素地址,首元素的地址加一,就是第二个元素的地址。但是&arr它代表的是数组的地址,当它加一,就是跳过了整个数组的大小,而不是一个元素的大小。
用图来说就是
三.函数指针 首先我们要知道,函数也有地址,对函数地址解引用就等于使用这个函数 函数指针的格式: 返回类型 (*指针名)(形参类型)
例如void (*sp)(int,int);
记住这里的形参类型,一定要和你想指向的那个函数的形参类型相对应。
void sr(int x,int y)
{
printf("1");
}
int main()
{
sr(1,1)/这是一般的用法
void (*sd)(int, int) = sr;/这是函数指针的用法,创建一个函数指针sd指向sr
(*sd)(1,1)/对sd解引用;
}
四.函数指针数组 数组是一个存放相同类型数据的存储空间,那我们已经学习了指针数组, 比如 int *arr[10];
那么函数指针数组就是 int (*parr1[10])(void);
就是在函数指针的基础上,在函数指针名后面加了一个[ ] 那么,函数指针数组如何使用呢? 假设我们自定了三个函数,名为:A,B,C.并且,他们的形参类型都为int,返回类型都为void。 例如 void A(int x)
那么我们把他放进函数指针数组中 void (*parr1[3])(int)={A,B,C};
那么我们使用它的时候就可以 *p[0](1); /这操作等于A(1);
*p[1](1); /这操作等于B(1);
*p[2](1); /这操作等于C(1);
|