函数指针
一、什么是函数指针
1.函数类型:函数类型由其返回类型与参数列表共同确定(与函数名无关),其格式为: return_type ()(parameter_list…); 声明函数对象:
int (function)(int a, int b);//括号可省略
由此可见:函数的类型确定应由内向外->函数名前:返回类型,函数名后:形参列表。
2.函数指针:即函数类型的指针,其格式为: return_type(*)(parameter_list…); 声明函数指针:
int (*function)(int a, int b);
二、函数指针的使用
1.函数指针的使用: 1.使用函数名为函数指针赋值时,函数自动转换为指针; 2.可在未进行解引用的前提下,使用函数指针调用其对应的函数; 3.指向不同函数类型的函数指针之间不存在转换规则; 4.可将函数指针赋值为nullptr(c++11)或值为0的常量表达式,表示该指针无指向;
2.函数指针类型的确定: 由内向外:->变量名前有’ * '和类型(返回类型),表示其为指针; ->后有参数列表:表示其为函数指针.
3.注意: 函数指针指向的是函数,而非对象; 函数指针指向某种特定类型; return_type (*p_func)(parameters…)中’ * '必须位于括号内,若无括号: return_type *p_func(parameters…)表示一个返回return_type类型指针的函数,而非函数指针。
三、实例代码
1.函数指针
#include <iostream>
int add(const int &a, const int &b)
{
return a + b;
}
int sub(const int &a, const int &b)
{
return a - b;
}
int multi(const int &a, const int &b)
{
return a * b;
}
int divide(const int &a, const int &b)
{
if(0 == b)
{
return -1;
}
return a / b;
}
//函数类型与函数指针类型
typedef int (func_t)(const int&, const int&);
typedef int (*pfunct_t)(const int&, const int&);
int main(int argc, char **argv)
{
//定义普通的函数指针
int (*pFunc)(const int&, const int&);
int a = 10, b = 5;
pFunc = add;
std::cout << " " << a << "+" << b << " = " << pFunc(a, b) << std::endl;
pFunc = sub;
std::cout << " " << a << " - " << b << " = " << pFunc(a, b) << std::endl;
pFunc = multi;
std::cout << " " << a << " * " << b << " = " << pFunc(a, b) << std::endl;
pFunc = divide;
std::cout << " " << a << " / " << b << " = " << pFunc(a, b) << std::endl;
func_t *l_add = add;
std::cout << " 10 + 20 = " << l_add(10, 20) << std::endl;
pfunct_t l_add2 = add;
std::cout << " 20 + 30 = " << l_add2(20, 30) << std::endl;
return 0;
}
2.函数指针作为参数
#include <iostream>
void fun()
{
std::cout << "Hello world. " <<std::endl;
}
void test(void (*function)())
{
function();
}
int main()
{
test(fun);
}
3.函数指针作为返回值
#include <iostream>
#include <string.h>
#include <stdlib.h>
typedef struct _human_t huamn_t, *phuman_t;
struct _human_t{
char name[20];
int age;
char sex[10];
char phone[20];
};
int nameCompare(void *l_value, void *r_value);
int ageCompare(void *l_value, void *r_value);
int (*getCompareFunc(const char *type))(void *l_value, void *r_value)
{
if(0 == strcmp(type, "name"))
{
return nameCompare;
}
else if(0 == strcmp(type, "age"))
{
return ageCompare;
}
else
{
return ageCompare;
}
}
//c++11
auto getCompareFunc1(const char *type) -> int (*)(void *l_value, void *r_value)
{
return getCompareFunc(type);
}
//c
typedef int func_t(void *l_value, void *r_value);
typedef int (*pfunc_t)(void *l_value, void *r_value);
func_t *getCompareFunc2(const char *type)
{
return getCompareFunc(type);
}
pfunc_t getCompareFunc3(const char *type)
{
return getCompareFunc(type);
}
//c++
using func = int(void *l_value, void *r_value);
using pfunc = int(*)(void *l_value, void *r_value);
func *getCompareFunc4(const char *type)
{
return getCompareFunc(type);
}
pfunc getCompareFunc5(const char *type)
{
return getCompareFunc(type);
}
int nameCompare(void *l_value, void *r_value)
{
std::cout << " ---------- name compare ---------- " << std::endl;
return strcmp(((phuman_t)l_value)->name, ((phuman_t)r_value)->name);
}
int ageCompare(void *l_value, void *r_value)
{
std::cout << " ---------- age compare ---------- " << std::endl;
return ((phuman_t)l_value)->age - ((phuman_t)r_value)->age;
}
int main(int argc, char **argv)
{
phuman_t h1 = (phuman_t)malloc(sizeof(huamn_t));
if(NULL == h1)
{
std::cout << "Malloc memory failed for h1. " << std::endl;
return -1;
}
phuman_t h2 = (phuman_t)malloc(sizeof(huamn_t));
if(NULL == h2)
{
std::cout << "Malloc memory failed for h2. " << std::endl;
free(h1);
return -1;
}
strcpy(h1->name, "huamn1");
h1->age = 21;
strcpy(h1->sex, "female");
strcpy(h1->phone, "15819308871");
strcpy(h2->name, "huamn2");
h2->age = 22;
strcpy(h2->sex, "male");
strcpy(h2->phone, "15819304583");
std::cout << getCompareFunc("age")(h1, h2) << std::endl;
std::cout << getCompareFunc1("name")(h1, h2) << std::endl;
std::cout << getCompareFunc2("balabala")(h2, h1) << std::endl;
std::cout << getCompareFunc3("age")(h1, h2) << std::endl;
std::cout << getCompareFunc4("name")(h1, h2) << std::endl;
std::cout << getCompareFunc5("balabala")(h2, h1) << std::endl;
return 0;
}
四、其他
1.关于函数指针作为返回值 int (*getCompareFunc(const char *type))(void *l_value, void *r_value); 图中红色部分为共同构成指针类型:int ( * )(int,int); 蓝色部分为函数名称:function。
参考声明函数指针的格式:在’ * '符号后。 返回值类型:int ( * ) (void *, void *); 函数名称:getCompareFunc; 函数参数类型:const char *。
2.一个小错误
void fun()
{
std::cout << " Hello World. " << std::endl;
}
int main(int argc, char **argv)
{
void test();
test = fun;//错误:当将函数作为值使用时,自动转换为指针,此处等号两边类型不匹配。
//或
test = *fun;//错误:此处理解为人为解引用,即:认为将fun解引用为函数指针,等号两边类型不匹配。
//即:当函数作为值使用时->fun 与 *fun 都是函数指针类型,不能为函数变量赋值。
}
3.函数对象不可在函数体内进行初始化,即:定义函数。
#include<iostream>
int main()
{
//声明函数对象:返回值为void类型,参数列表为空。
void test();
(*test)();
}
void test()
{
std::cout << "good" << std::endl;
}
文中不当之处,欢迎留言指正,共同学习。