超精细指针难点详解(指针数组,数组指针,函数指针数组)

指针难点(指针数组,数组指针,函数指针,函数指针数组)


前言

关于简单的整型/字符指针就不过多赘述,在这详解一下我个人认为指针的难点问题


提示:以下是本篇文章正文内容,下面案例可供参考

一、指针数组

首先,我们要知道数组指针,它是个数组,因为它和后面要介绍的数组指针名字相似,所以在这做一个强调。

代码例子:

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;
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值