C基础——函数和指针
### (1)函数指针的作用
通常作为函数的参数,告诉该函数应该使用哪一个函数
### (2)函数指针
函数的实现由载入内存的代码组成,所以函数也有地址。函数指针中存储的就是函数代码的起始处的地址。
声明一个函数指针,必须指明函数的签名:函数返回值类型和形参类型
```C
void ToUpper(char *); //函数声明:将字符串中的字符转换成大写
void (*pt)(char *); //函数指针声明:pt是一个指针,指向一个无返回值、形参类型为char *的函数
```
如以上代码,将函数名直接替换为指针,是创建函数指针最简单的方式。因此,要声明一个指向某个函数的指针,可以先声明该函数,再将函数名替换为指针。
在声明了函数指针后,可以将类型匹配的函数的地址赋值给它。
```C
void ToUpper(char *);
void ToLower(char *);
int round(double)
void (*pf)(char *);
pf = ToUpper;
pf = ToLower; //在这种上下文中,函数名代表函数的地址
pf = ToLower(); // 注意 !!!!!!
//这种赋值是无效的,因为ToLower()不是地址
//并且ToLower()一个无返回值的函数,不能用在赋值运算符右侧。
```
### (3)函数指针访问函数
```C
void ToUpper(char *);
void ToLower(char *);
void (*pf)(char *);
char str[] = "Hello World"
```
有以上声明,则
```C
//方法1
pf = ToUpper;
(*pf)(str); //使用ToUpper()函数转换字符串str
//方法2
pf = ToLower;
pf(str); //使用ToLower()函数转换字符串str
```
以上两种利用pf访问函数的方法都是正确的。
第1种方法,因为pf是指向ToUpper()的指针,所以*pf就代表ToUpper(),所以(*pf)(str)即等价于ToUpper(str)。这一点在函数指针声明中有所体现:(*pf)与ToUpper是等价的。
第2种方法,因为函数名即是指针,所以ToLower与pf等价,这一点在赋值中有所体现:pf = ToLower,所以pf(str)与ToLower(str)等价。
### (4)使用函数指针作为形参
假设有以下函数声明:
```C
void show(void (*pf)(char *), char *);
//函数有2个参数
//第1个参数接收指向无返回值、形参为char *的函数的指针
//第2个参数接收指向char类型的指针
```
则有
```C
show(ToUpper, str);
show(pf, str);
```