微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 硬件工程师文库 > 周立功手把手教你学嵌入式编程:函数指针与指针函数的应用

周立功手把手教你学嵌入式编程:函数指针与指针函数的应用

时间:07-29 来源:ZLG致远电子 点击:

周立功教授数年之心血之作《程序设计与数据结构》以及《面向AMetal框架与接口的编程(上)》。书本内容公开后,在电子行业掀起一片学习热潮。经周立功教授授权,本公众号特对《程序设计与数据结构》一书内容进行连载,愿共勉之。

 

第二章为程序设计技术,本文为2.1.1 函数指针和2.1.2指针函数。

 

>>>> 2.1 函数指针与指针函数

 

>>> 2.1.1 函数指针 

 

变量的指针指向的是一块数据,指针指向不同的变量,则取到的是不同的数据。而经过编译后的函数都是一段代码,系统随即为相应的代码分配一段存储空间,而存储这段代码的起始地址(又称为入口地址)就是这个函数的指针,即跳转到某一个地址单元的代码处去执行。函数指针指向的是一段代码(即函数),指针指向不同的函数,则具有不同的行为。

 

因为函数名是一个常量地址,所以只要将函数的地址赋给函数指针即可调用相应的函数。如同数组名一样,我们用的是函数本身的名字,它会返回函数的地址。当一个函数名出现在表达式中时,编译器就会将其转换为一个指针,即类似于数组变量名的行为,隐式地取出了它的地址。即函数名直接对应于函数生成的指令代码在内存中的地址,因此函数名可以直接赋值给指向函数的指针。既然函数指针的值可以改变,那么就可以使用同一个函数指针指向不同的函数。如果有以下定义:

int (*pf)(int);                         // pf函数指针的类型是什么?

 

C语言的发明者K&R是这样解释的,"因为*是前置运算符,它的优先级低于(),为了让连接正确地进行,有必要加上括号。"这未免有些牵强附会了,解释来解释去反而将人搞晕了。因为声明中的*、()、[]都不是运算符,而运算符的优先顺序在语法规则中是在其它地方定义的。其详解如下:

int (*pf)(int a);                                       // pf是指向…的指针

int (*pf)(int a);                                       // pf是指向…的函数(参数为int)的指针

int (*pf)(int a);                                       // pf是指向返回int的函数(参数为int)的指针

 

即pf是一个指向返回int的函数的指针,它所指向的函数接受一个int类型的参数。 "int (*)(int)"类型名被解释为指向返回int函数(参数为int)的指针类型。如果在该定义前添加typedef,比如:

typedef int (*pf)(int a);

 

未添加typedef前,pf是一个函数指针变量;而添加typedef后,pf就变成了函数指针类型,习惯的写法是类型名pf大写为PF。比如:

typedef int (*PF)(int a); 

 

与其它类型的声明不同,函数指针的声明要求使用typedef关键字。另外,函数指针的声明与函数原型的唯一不同是函数名用(*PF)代替了,"*"在此处表示"指向类型名为PF的函数"。显然,有了PF类型即可定义函数指针变量pf1、pf2。比如:

PF pf1, pf2; 

 

虽然此声明等价于:

int (*pf1)(int a); 

int (*pf2)(int a);

 

但这种写法更难理解。既然函数指针变量是一个变量,那么它的值就是可以改变的,因此可以使用同一个函数指针变量指向不同的函数。使用函数指针必须完成以下工作:

● 获取函数的地址,比如,pf = add,pf = sub;

● 声明一个函数指针,比如,"int (*pf)(int, int);";

● 使用函数指针来调用函数,

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top