57 lines
2.1 KiB
Markdown
57 lines
2.1 KiB
Markdown
|
---
|
|||
|
title: C函数指针
|
|||
|
date: '2017-10.28 10:59:10'
|
|||
|
tags:
|
|||
|
- 指针
|
|||
|
categories:
|
|||
|
- c语言
|
|||
|
abbrlink: 364cc1f5
|
|||
|
---
|
|||
|
当我们看到如下所示的代码怎么去理解它的意义呢。
|
|||
|
```C
|
|||
|
(* ( void (*) () ) 0) ()
|
|||
|
```
|
|||
|
解析这个函数需要下面几个知识
|
|||
|
|
|||
|
1. 函数申明包含返回值,函数名,参数列表。
|
|||
|
- 如返回值是'int' 函数名为'fun',参数列表为'void'。
|
|||
|
- ```C
|
|||
|
int fun(void);
|
|||
|
```
|
|||
|
2. 函数指针和返回值为指针的函数
|
|||
|
- 函数指针:函数指针pfun指向的是一个返回值为int类型,参数列表为空的函数。只要是符合这个'形状'的函数都可以吧地址赋给pfun。
|
|||
|
- ```c
|
|||
|
int (*pfun) (void);
|
|||
|
```
|
|||
|
- 返回值为指针的函数:返回值为int*类型的指针,参数列表为空的函数fun1。它表示fun1是一个确定的函数。不像pfun是可以指向任何符合模板的函数。
|
|||
|
- ```c
|
|||
|
int* fun1 (void);
|
|||
|
```
|
|||
|
所以在书写的时候必须注意是否需要加括号。
|
|||
|
3. 类型转化符。就像我们平时说的怎么把一个int强制转化为char呢,就是
|
|||
|
```C
|
|||
|
int a = 48;
|
|||
|
char b = (char) a;
|
|||
|
```
|
|||
|
我们怎么构建一个类型转化符呢,就是把目标类型用括号括起来,那么一个函数模板的类型转化符是怎么样的呢,就是把函数名去掉,然后用括号把他括起来。比如上面的函数指针pfun这个模板。我们只需要将pfun去掉,然后把剩下部分括起来。
|
|||
|
```C
|
|||
|
(int (*) (void) )
|
|||
|
```
|
|||
|
这就是一个返回值为int参数列表为空的函数指针的强制类型转化符。
|
|||
|
-----
|
|||
|
完成上述理解之后,我们着手理解一下
|
|||
|
```C
|
|||
|
(* ( void (*) () ) 0) ()
|
|||
|
```
|
|||
|
首先通过下面这个式子可以看出这是一个函数的调用,那么左括号里面的就是函名。
|
|||
|
```C
|
|||
|
( funname ) ()
|
|||
|
```
|
|||
|
也就是 ```C
|
|||
|
* (void (*) () ) 0 == funname
|
|||
|
```
|
|||
|
|
|||
|
把0强制类型转化为void (*) () 型的函数指针。也就是指向函数地址为0的指针 ```C
|
|||
|
(void (*) () ) 0
|
|||
|
```
|