函数类型
1、C语言中的函数有自己的特定类型
2、函数的类型由返回值,参数类型和参数个数共同决定
int add(int i, int j)的类型为int (int , int )
3、C语言中通过typedef为函数类型重命名
typedef type name(parameter list)
4、例:
typedef int f(int, int);
typedef void p(int);
函数指针
1、函数指针用于指向一个函数
2、函数名是执行函数的入口地址
3、可通过函数类型定义函数指针:FuncType* pointer
4、也可以直接定义:type(*pointer)(parameter list);
1)、pointer为函数指针变量名
2)、type为所指函数的返回值类型
3)、parameter list 为所指函数的参数类型列表
例题分析:
#include <stdio.h>
typedef int(FUNC)(int); //重命名一个函数类型
int test(int i)
{
return i * i;
}
void f()
{
printf("Call f()...\n");
}
int main()
{
FUNC* pt = test; //函数的入口地址
void(*pf)() = &f; //函数的入口地址
printf("pf = %p\n", pf);
printf("f = %p\n", f);
printf("&f = %p\n", &f);
pf();
(*pf)(); //老式写法
printf("Function pointer call: %d\n", pt(2));
return 0;
}
回调函数
1、回调函数是利用函数指针实现的一种调用机制
2、回调机制
1)、调用者不知道具体事件发生时需要调用的具体函数
2)、被调用函数不知道何时被调用,只知道需要完成的任务
3)、当具体事件发生时,调用者通过函数指针调用具体函数
3、回调机制中的调用者和被调函数互不依赖;
例题分析:
#include <stdio.h>
typedef int(*Weapon)(int); //重命名一个函数类型的指针
void fight(Weapon wp, int arg)
{
int result = 0;
printf("Fight boss!\n");
result = wp(arg); //回调机制 可以调用 Weapon类型指针指向的函数
printf("Boss loss: %d\n", result);
}
int knife(int n)
{
int ret = 0;
int i = 0;
for(i=0; i<n; i++)
{
printf("Knife attack: %d\n", 1);
ret++;
}
return ret;
}
int sword(int n)
{
int ret = 0;
int i = 0;
for(i=0; i<n; i++)
{
printf("Sword attack: %d\n", 5);
ret += 5;
}
return ret;
}
int gun(int n)
{
int ret = 0;
int i = 0;
for(i=0; i<n; i++)
{
printf("Gun attack: %d\n", 10);
ret += 10;
}
return ret;
}
int main()
{
fight(knife, 3);
fight(sword, 4);
fight(gun, 5);
return 0;
}
小结
1、C语言中的函数都有特定的类型
2、可以使用函数类型定义函数指针
3、函数指针是通过实现回调机制的关键技术
4、通过函数指针可以在C程序中实现固定地址的跳转
指针阅读技巧分析
指针阅读技巧解析
1、右左法则
1)、从最里层的圆括号中未定义的标识符看起
2)、首先往右看,再往左看
3)、遇到圆括号或者方括号时可以确定部分类型,并调转方向
4)、重复2,3步骤,直到阅读结束
例题分析
#include <stdio.h>
int main()
{
int (*p1)(int*, int (*f)(int*)); //p1为指针,指向函数,指向的函数有两个参数,分别是int*,(f为第二个参数 ,指向的函数,函数的参数是int*, 返回类型为int类型)返回类型为int类型。
int (*p2[5])(int*); //p2为数组,有5个元素,这五个元素为指针,指向函数,函数的类型为int(int*)
int (*(*p3)[5])(int*); //p3为指针(数组指针),指向的数组有5个元素,这五个元素为指针,指向函数指针,函数的类型为int(int*)
int*(*(*p4)(int*))(int*);//p4为指针,函数指针,参数为int*,返回值为指针,是函数指针,int*(int*)
int (*(*p5)(int*))[5];//p5为指针,函数指针,参数为int*,返回值为指针,指向的数组类型为int[5]
typedef int(ArrayType)[5]; //重定义数组类型为ArrayType
typedef ArrayType* (FuncType) (int*)
FuncType* p5;
return 0;
}
小结
1、右左法则总结于编译器对指针变量的解析过程
2、指针阅读练习的意义在于理解指针的组合定义
3、可通过typedef简化复杂指针的定义