您的位置:首页 > 编程语言 > C语言/C++

【C语言复习(十九)】函数与指针

2014-06-19 22:24 274 查看

1、函数的类型

C语言中函数有自己特定的类型

函数类型由返回值、函数参数、参数个数共同决定:

例如:int func(int i,int j);类型为:int(int,int)

C语言中通过typedef为函数类型重命名:

typedef type name(parameter list)

例如:typedef int INT(int,int)

2、函数指针

函数指针用于指向一个函数;

函数名是执行函数体的入口地址;

可通过函数类型定义函数指针:funcType* pointer;

可直接定义函数指针:type (*pointer)(parameter list);

Pointer 为函数指针变量名;

Type 为指向函数的返回值类型;

Parameter list 为指向函数的参数类型列表;

3、函数指针的本质与使用

#include <stdio.h>

typedef int FUNC(int);//给函数类型int(int)定义别名

int func(int num)
{
return num*num;
}

void fun()
{
printf("函数fun执行过...");
}
int main()
{

FUNC* p=func;//用定义的别名FUNC定义指向int(int)型函数的指针,函数名代表入口地址
void(*pf)()=&fun;
//也可这么定义函数指针,取地址符&作用与函数名得到的也是函数入口地址,这点和数组不同

printf("%d\t%d\n",p(5),(*p)(5));
pf();
(*pf)();
//以上的调用方式本质上是一样的,都能调用函数
return 0;
}


4、回调函数

回调函数是利用函数指针实现的一种调用机制;

回调机制原理:

调用者不知道具体事件发生时需要调用的具体函数;

被调函数不知道何时被调用,只知道被调用后需要完成的任务;

当具体事件发生时,调用者通过函数指针调用具体函数;

回调机制将调用者和被调函数分开,互不依赖;

本质上,回调函数就是通过指向函数的指针动态的调用类型相同,函数体不同的函数;

示例:

#include <stdio.h>

typedef int(*FUNCTION)(int);//定义别名

//接收函数指针
int g(int n, FUNCTION f)
{
int i = 0;
int ret = 0;

for(i=1; i<=n; i++)
{
ret += i*f(i);
}

return ret;
}

int f1(int x)
{
return x + 1;
}

int f2(int x)
{
return 2*x - 1;
}

int f3(int x)
{
return -x;
}

int main()
{
printf("x * f1(x): %d\n", g(3, f1));//注册函数f1
printf("x * f2(x): %d\n", g(3, f2));//注册函数f2
printf("x * f3(x): %d\n", g(3, f3));//注册函数f3
}


5、指针的阅读技巧

右左法则:

从最里层的圆括号中未定义的标识符看起;
首先往右看,再往左看;
当遇到圆括号或者方括号时,可以先确定部分类型,然后调转方向继续看;
重复2--3步骤,知道阅读结束;

举例:

阅读下列复杂指针:

int (*p2)(int*, int (*f)(int*));

未定义的标识符为p2,接着往右看,遇到圆括号,调转方向往左看,得到:(*p2),可知这是一指针,然后从原表达式中去掉它,得到:int (int*, int (*f)(int*)); 接着往右看;

看到括号’(’,看完,可以确定部分类型,得知p2应该指向一个函数,那么这函数是什么类型呢?继续看可知,该函数返回值为int,第一个参数为int*型指针,第二个参数是int(int*)型函数指针。

int (*p3[5])(int*);

未定义的标识符为p3,往右看,看到方括号,可以确定部分类型:p3[5],得知p3是一个数组,然后删去这一部分,得到:int (*)(int*); 接着看到了圆括号,得到:”(*)”可以确定部分类型,原来p3是一个指针数组,有5个元素,接着去掉这一部分:int (int*); 可知这是一函数类型,返回值为int,参数为int*型指针,即是p3是一个指向int(int*)类型的函数指针数组,有5个元素;

int (*(*p4)[5])(int*);

未定义的标识符为p4,向右看遇到圆括号,方向得到:(*p4),得知p4是一个指针,然后去掉此部分:int (*[5])(int*); 继续往右看,看到方括号,得到:[5]得知p4为数组指针,数组中有5个元素,再去掉此部分:int (*)(int*); 继续往右看,得到:(*)可以确定部分类型,得知p4的数组元素为指针,然后去掉此部分:int (int*);得知这是一个函数类型,因此p4为一个数组指针,这个数组每个元素也为指针,且指向类型为int (int*)的函数

int (*(*p5)(int*))[5];

为定义的标识符为:p5,向右看到圆括号,调转方向继续看,得到:(*p5),得知p5为一个指针;去掉此部分:int (*(int*))[5]; 接着向右看,看到圆括号,得到:(int*)得知p5为一个函数指针,且参数为一个int*型指针;那么返回值是什么呢?去掉此部分,继续看:

int (*)[5];得到:(*)可知返回值为指针,然后去掉此部分:int[5]这是一个数组类型,即是返回值为int(*)[5]的数组指针;即是:p5是一个函数指针,函数的返回值为int(*)[5]类型的数组指针,参数为int*型指针
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: