Ben*_*ois 32 c pointers compilation
我刚刚在这里阅读了一个有趣的问题,让我想到了另外两件事:
void *
或是否持有更丰富的信息(如返回类型,论点和论据类型的号码?)Sto*_*ica 36
为什么要比较函数指针?这是一个例子:
#include <stdbool.h>
/*
* Register a function to be executed on event. A function may only be registered once.
* Input:
* arg - function pointer
* Returns:
* true on successful registration, false if the function is already registered.
*/
bool register_function_for_event(void (*arg)(void));
/*
* Un-register a function previously registered for execution on event.
* Input:
* arg - function pointer
* Returns:
* true on successful un-registration, false if the function was not registered.
*/
bool unregister_function_for_event(void (*arg)(void));
Run Code Online (Sandbox Code Playgroud)
身体register_function_for_event
只能看到arg
.它没有看到任何函数名称.它必须比较函数指针以报告某人两次注册相同的函数.
如果你想支持unregister_function_for_event
上述内容,你唯一的信息就是函数地址.因此,您需要再次传递它,并与之进行比较,以允许删除.
至于更丰富的信息,是的.当函数类型包含原型时,它是静态类型信息的一部分.请注意,在C中,可以在没有原型的情况下声明函数指针,但这是一个过时的功能.
Aja*_*iya 19
为什么有人会比较指针?请考虑以下情况 -
你有一个函数指针数组,比如它是一个回调链,你需要调用它们中的每一个.该列表以NULL
(或标记)函数指针终止.您需要通过与此哨兵指针进行比较来比较是否已到达列表的末尾.此外,这种情况证明以前的OP担心不同的函数应该有不同的指针,即使它们是相似的.
编译器是否以不同方式看待它们 是.类型信息包括有关参数和返回类型的所有信息.
例如,编译器将拒绝以下代码 -
void foo(int a);
void (*bar)(long) = foo; // Without an explicit cast
Run Code Online (Sandbox Code Playgroud)R S*_*ahu 18
- 为什么有人应该比较函数指针,因为通过概念,函数的唯一性由它们的不同名称来保证?
函数指针可以指向程序中不同时间的不同函数.
如果你有一个变量,如
void (*fptr)(int);
Run Code Online (Sandbox Code Playgroud)
它可以指向任何接受int
输入并返回的函数void
.
假设你有:
void function1(int)
{
}
void function2(int)
{
}
Run Code Online (Sandbox Code Playgroud)
您可以使用:
fptr = function1;
foo(fptr);
Run Code Online (Sandbox Code Playgroud)
要么:
fptr = function2;
foo(fptr);
Run Code Online (Sandbox Code Playgroud)
您可能希望foo
根据是fptr
指向一个函数还是另一个函数来执行不同的操作.因此,需要:
if ( fptr == function1 )
{
// Do stuff 1
}
else
{
// Do stuff 2
}
Run Code Online (Sandbox Code Playgroud)
- 编译器是否将函数指针视为特殊指针?我的意思是它会看到它们,比方说,指向void*或者它是否包含更丰富的信息(如返回类型,参数数量和参数类型?)
是的,函数指针是特殊指针,不同于指向对象的指针.
函数指针的类型在编译时具有所有信息.因此,给出一个函数指针,编译器将拥有所有那些信息 - 返回类型,参数数量及其类型.
关于函数指针的经典部分已经在其他答案中讨论过:
void *
也不是C语言)。但是C具有(旧式)函数声明模式。除了声明返回类型和所有参数的类型的完整原型模式外,C还可以使用所谓的参数列表模式,即旧的K&R模式。在这种模式下,声明仅声明返回类型:
int (*fptr)();
Run Code Online (Sandbox Code Playgroud)
在C语言中,它声明一个指向函数的指针,该函数返回an int
并接受任意参数。只是将它与错误的参数列表一起使用将是未定义的行为(UB)。
所以这是合法的C代码:
#include <stdio.h>
#include <string.h>
int add2(int a, int b) {
return a + b;
}
int add3(int a, int b, int c) {
return a + b + c;
}
int(*fptr)();
int main() {
fptr = add2;
printf("%d\n", fptr(1, 2));
fptr = add3;
printf("%d\n", fptr(1, 2, 3));
/* fprintf("%d\n", fptr(1, 2)); Would be UB */
return 0;
}
Run Code Online (Sandbox Code Playgroud)
不要假装我已建议您这样做!现在,它被视为过时的功能,应避免使用。我只是警告你反对。恕我直言,它只能有一些特殊的可接受的用例。