函数指针以及指针的高级用法

本文详细介绍了C语言中的函数指针用法,包括声明、类型转换符和实际应用。通过实例解析了如何声明函数指针,以及如何进行类型转换。强调了函数指针在数组、函数返回值等方面的一些限制和注意事项,并展示了初始化和使用函数指针的方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一.声明

1.首先需要更新一下对于声明的理解:

int *f;

我们可以将其看做两部分:一是数据类型,而是声明表达式。对声明表达式求值就会返回一个给定类型(这里为int类型)的值。

2.之后我们还要区分旧式的声明与新式的声明:以上给出的就是一个旧式的声明方式,而ANSI C要求要求我们使用完整的函数原型进行声明,使声明更为明确。即还需要给出函数的参数类型,如下例所示:

int *f(int, double);

3.如下代码,依据上文,我们要先对声明表达式进行求值,f先与()结合,说明它是一个函数,之后与*结合。函数与寻址操作符结合就是对函数进行寻址操作,即对函数的返回值进行寻址操作。

int *f();

4.如果a的属性为external或者作为函数参数,那么即使在声明时未注明长度,也任然是合法的。

int a[];

5.(*f)()为函数指针,就像上文提到的*与函数结合表示对函数的返回值进行寻址操作后会得到一个int类型的值

int *(*f)();

6.f是一个函数,它返回的是一个整型数组。但是这个声明是非法的,函数只能返回标量值,不能返回数组

int f()[]

7.f似乎是一个数组,它的类型是返回值为整型的函数。这个声明也是非法的,因为数组元素必须具有相同的长度,而函数显然可能具有不同的长度。

int f[]();

8.  首地址为0的函数

  1. (void(*)()) 对void(*)()添加括号即为类型转换符,将0转换为此类型函数的指针。
  2. *(void(*)()) 对函数寻址,即得到函数名(当然编译器在调用时函数转换为指针)。
  3. (*(void(*)())) 调用函数。
( *(void(*)())0 )();

9. 1.*f[]指针数组。 2.(*f[])() 数组中的指针指向的是函数类型 3.与*结合即对函数寻址后得到的是int类型的数据。即:所以这个声明创建了一个指针数组,指针所指向的类型是返回值为int类型的指针。

int *(*f[])();

二.类型转换符

根据一个已有的声明,只需要两步就可以得到类型转换符:

  1. 将 变量名 和 声明末尾的分号去掉。
  2. 再将剩余的部分用一个括号封装起来。

以下为声明:

float (*h)();

以下就是此类型的类型转换符:

(float (*)())

三.函数指针

1. 初始化函数指针时,对函数名&的操作是可选的。因为函数名被使用时总是由编译器转换为函数指针,&操作符只是显示地说明了编译器将隐式完成的任务。

2.  int  ( *(*f()) )[10];    int  ( *(*f)() )[10];

//函数指针(*func)()指向返回值是指向int类型数组的指针。
//返回值类型是指针而不是数组,所以是允许的。
int(*((*func)()))[10]; 

//函数返回二级指针,二级指针指向int类型数组。
//两个*之间的括号可以省略。
int(*(*f()))[10]{ } 

 

3. int  ( * ( (*x) [10] ) )();

(*x)   --->   指针
(*x)[10]   --->   数组指针
( * ( (*x) [10] ) )   --->   数组中保存的为指针类型
int  ( * ( (*x) [10] ) )()   --->   指针指向的是返回值为int类型的函数

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值