函数名在C语言中的本质
在C语言中,函数名确实具有指针的特性,但它与普通指针有一些重要区别。
一、函数名的指针特性
1. 函数名作为函数指针
在大多数情况下,函数名会被编译器隐式转换为指向该函数的指针:
#include <stdio.h>
void func()
{
printf("hello\n");
}
int main()
{
// 此处函数名func会被编译器隐式转化为指向该函数的指针
void (*ptr)() = func;
// 通过指针调用和通过函数名调用,结果一致。
func();
ptr();
return 0;
}
hello
hello
2. 函数名与取地址运算符
对函数名使用&运算符是允许的,但结果与不使用&相同:
void (*fp1)() = func; // 直接赋值
void (*fp2)() = &func; // 使用&运算符
// fp1和fp2完全相同
二、函数名与普通指针的区别
|
特性 |
函数名/函数指针 |
普通数据指针 |
|
类型 |
指向函数的指针 |
指向数据的指针 |
|
解引用方式 |
可以直接调用( |
需要使用 |
|
运算 |
不能进行算术运算 |
可以进行指针算术 |
|
sizeof |
通常返回1(不表示大小) |
返回指针大小(4/8字节) |
|
赋值目标 |
只能指向函数 |
可以指向各种数据 |
三、函数指针的声明与使用
1. 函数指针声明语法
返回类型 (*指针变量名)(参数列表);
2. 实际使用示例
#include <stdio.h>
int add(int a, int b)
{
return a + b;
}
int main()
{
int (*add_ptr)(int, int) = add; //声明并初始化函数指针
int result = add_ptr(3, 4); // 通过指针调用函数
printf("3 + 4 = %d\n", result); // 输出7
return 0;
}
四、函数指针的高级用法
1. 函数指针数组
#include <stdio.h>
int add(int a, int b)
{
return a + b;
}
int sub(int a, int b)
{
return a - b;
}
// 函数指针数组的使用方式
int main()
{
int (*oprators[2])(int, int) = {add, sub}; //声明并初始化函数指针数组
int result = oprators[0](4, 3); // 通过指针数组中的第一个元素,调用add函数
int result1 = oprators[1](4, 3); // 通过指针数组中的第二个元素,调用sub函数
printf("4 + 3 = %d\n", result); // 输出7
printf("4 - 3 = %d\n", result1); // 输出1
return 0;
}
2. 作为函数参数
#include <stdio.h>
void caller(void (*func)())
{
func();
}
void hello()
{
printf("Hello, world\n");
}
// 函数名作为函数参数使用,此时函数名会被隐式转换为函数指针(即指向该函数的指针)
int main()
{
caller(hello); // 传递函数指针
return 0;
}
Hello, world
3. 返回函数指针的函数
int (*get_operation(char op))(int, int) {
switch(op) {
case '+': return add;
// 其他操作...
}
}
#include <stdio.h>
int add(int a, int b)
{
return a + b;
}
int sub(int a, int b)
{
return a - b;
}
/*
返回函数指针的函数,
该函数输入为char op。
回值是指向函数(此处暂时称为函数A)的指针,其中函数A,输入为两个int,返回值也是int.
*/
int (*get_operation(char op))(int, int)
{
switch(op)
{
case '+' : return add;
case '-' : return sub;
default:
return NULL;
}
}
int main()
{
// 通过返回函数指针的函数给opt1,以及opt2,初始化赋值. 此处还可以把opt1,opt2放到同一个函数指针数组中
int (*opt1)(int, int) = get_operation('+');
int (*opt2)(int, int) = get_operation('-');
int ret1 = opt1(4, 3);
int ret2 = opt2(4, 3);
printf("4 + 3 =%d\n", ret1);
printf("4 - 3 =%d\n", ret2);
return 0;
}
4 + 3 =7
4 - 3 =1
五、重要注意事项
类型安全:函数指针必须与目标函数类型完全匹配
int (*wrong)() = (int (*)())func; // 强制转换危险!
NULL检查:调用前应检查函数指针是否为NULL
if (fp != NULL) {
fp();
}
不可修改性:函数名不是左值,不能赋值
func = other_func; // 错误!
可读性:使用typedef提高代码可读性
typedef void (*FuncPtr)();
FuncPtr fp = func;
总结来说,在C语言中函数名确实表现为指向函数的指针,但它是一种特殊的指针类型,具有与普通数据指针不同的特性和使用规则。理解这种区别对于正确使用函数指针至关重要。
1万+

被折叠的 条评论
为什么被折叠?



