将函数指针强制转换类型

4

我知道这是一个重复的问题。我已经搜索过,但没有解决我的问题。

注意为了减少混淆,我尝试简化了原始类型转换。希望它不会产生未定义的行为。

声明函数指针。

Int (*funcPtr)(void*,void*);

strcmp声明

int strcmp (char *, char *);

函数指针的类型转换

FuncPtr = (int (*)(void*, void*))strcmp

这就是让我感到困惑的地方。我理解创建函数指针的类型转换。所以对于例如FuncPtr的类型转换只是改变了funcPtr可以指向哪种类型的函数。我也读过函数名本身就是指向其自身的函数指针,因此如果按照上述理解进行类型转换strcmp
int (*)(void*, void*))strcmp 

strcmp现在可以指向一个接受两个void指针并返回int的函数,这显然是错误的,就像数组一样,我认为函数名不能是指向另一个函数的指针。

由于我对上述内容的理解,我不明白如何使用以下类型转换将strcmp的地址分配给FuncPtr

FuncPtr = (int (*)(void*, void*))strcmp

更改函数指针strcmp所指向的内容并不会改变strcmp的参数和返回类型。
我真的很感激获得这些知识,我只是有些困惑。

3
仅仅因为你有能力做某事,并不意味着这是一个好主意。我可以把我的车撞进树里,但是...... - ThingyWotsit
1
任何函数指针都可以指向任何函数,但是除非指向的类型与被指向的函数完全匹配,否则不允许通过指针调用该函数。 - M.M
如果问题仅仅是“我能否获得一个类型为int (*)(void*, void*))的函数指针,然后将strcmp的地址强制转换为该类型?”那么我可以回答它。但是你问题中的其他内容让它变得不明确。还有,为了记录,strcmp的格式如下,这在这里很重要:int strcmp(const char *s1, const char *s2); - Lundin
简单来说,对我而言,Funcptr = (int ()(void, void*))strcmp 与 Funcptr = strcmp 在逻辑上是等价的,因为我无法看出将 strcmp 进行类型转换如何改变其参数和返回类型以匹配 Funcptr 的赋值。 - Simple
不,对我来说无所谓。 - Simple
显示剩余6条评论
1个回答

10

有函数和函数指针两种东西。strcmp是一个与你的项目链接的函数。当在表达式中使用标识符strcmp时,将得到指向该函数的函数指针。但是你不能改变"strcmp指向何处",因为strcmp是一个函数而不是一个指针。

C允许在不同的函数指针类型之间进行转换。但是,如果你尝试通过不兼容类型的函数指针调用函数,就会引发未定义行为。

int (*funcPtr)(void*,void*);

不兼容 strcmp,其格式如下:

int strcmp(const char *s1, const char *s2);

含义:

funcPtr = (int(*)(void*, void*))strcmp; // this is ok but not very meaningful
funcPtr(); // this is NOT ok, invokes undefined behavior

为了通过函数指针实际调用strcmp函数,您需要将其强制转换回正确的类型,即int (*)(const char*, const char*)

“函数名(标签)被转换为指向其本身的指针。” http://denniskubes.com/2013/03/22/basics-of-function-pointers-in-c/ 的最后一章讨论了这个问题。 - Simple
我仍然对cast (int()(void, void*)) 对strcmp函数的作用感到困惑。它是否会将参数类型更改为void,返回类型更改为int? - Simple
@Simple 它对strcmp没有任何影响,原因与int x=0; char* ptr = &x;不同。指针保存指向的项目的地址。仅仅因为你让一个不同类型的指针指向你的变量,并不能改变变量本身的类型。 - Lundin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接