我正在编写这段 C 代码,其中涉及传递大量函数指针,有时在定义将其作为参数的函数时编写函数指针所采用的所有参数可以显着增加函数定义的长度,从而减少它的可读性。例如,假设我有一个foo需要三个ints 和一个函数指针来执行特定操作的函数。声明函数的典型方法foo如下:
int foo(int a, int b, int c, int (*operation) (int, int, int));
Run Code Online (Sandbox Code Playgroud)
我想知道是否有一种方法可以避免在函数指针类型中再次重新提及变量类型的冗余。
这个问题的答案表明可以只使用空括号(),在上面的例子中翻译为:
int foo(int a, int b, int c, int (*operation) ());
Run Code Online (Sandbox Code Playgroud)
然而,同一篇文章的评论指出这种语法将在 C23 中删除:
附带说明一下,这是自 1989 年以来已过时的 C。不应使用空括号 () 无原型样式。它最终将在即将到来的 C23 中被删除
我对函数指针转换做了一个有趣的测试:
typedef bool (*BFUNC)(int n);
typedef int (*IFUNC)(int n);
typedef double (*DFUNC)(int n);
void vfunc(int n)
{
n++;
}
int _tmain(int argc, _TCHAR* argv[])
{
BFUNC f = (BFUNC)vfunc;
IFUNC f2 = (IFUNC)vfunc;
DFUNC f3 = (DFUNC)vfunc;
bool bRet = f(0);
int nRet = f2(0);
double dRet = f3(0);
printf("bRet=%d, nRet=%d\n", bRet, nRet); // bRet=1, nRet=1
return 0;
}
Run Code Online (Sandbox Code Playgroud)
第一件有趣的事情是这段代码编译并运行良好。第二个有趣的事情是我实际上得到了返回值,目前似乎是1。(我用的是很老的VS2010,不知道有没有关系)
我想知道发生了什么事?
我做了一些更多的实验,似乎只要我使用这种 C 风格的显式转换,那么我就可以很自由地将一个函数指针类型转换为另一个函数指针类型,我想知道这是否有实际意义?其基本原理是什么?
我已经被更高级的,经验丰富,受过良好教育的程序员比我告知,使用的函数指针在ç应该避免.我已经看到一些代码包含函数指针作为不重用该代码的理由,即使唯一的替代方案是完全重新实现.经过进一步讨论,我无法确定为什么会这样.我很乐意在适当的地方使用函数指针,就像它们允许你做的有趣和强大的东西一样,但我是否因使用它们而谨慎对待风?
我看到函数指针的优缺点如下:
优点:
缺点:
我认为Con#1通常可以通过精心挑选的符号名称和良好的评论来合理地减轻.而Con#2通常不是什么大问题.我错过了什么 - 是否有其他理由避免像瘟疫一样的功能指针?
这个问题看起来有点讨论 - 但我正在寻找很好的理由,为什么我不应该使用函数指针,而不是意见
int function_a () {
int ret_a = call_a;
int ret_b = call_b;
}
Run Code Online (Sandbox Code Playgroud)
call_a和call_b的定义是这样的:
int call_a() {
// Some 10 lines
call_c();
}
int call_b() {
// Same 10 lines
call_d();
}
Run Code Online (Sandbox Code Playgroud)
函数call_a和call_b之间的区别仅在于它们调用不同的函数.我开始知道函数指针是这种情况下的最佳方法.创建一个函数(只有call_a,而不是call_a和call_b),并将函数指针传递给call_c和call_d.我们怎样才能实现它?
希望我很清楚,让你明白.
我有一个使用函数指针的小程序.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct _myst
{
int a;
char b[10];
}myst;
void cbfunc(myst *mt)
{
fprintf(stdout,"called %d %s. \n",mt->a,mt->b);
}
int main()
{
/* func pointer */
void (*callback)(void *);
myst m;
m.a=10;
strcpy(m.b,"123");
/* point to callback function */
callback = (void*)cbfunc;
/* perform callback and pass in the param */
callback(&m);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
函数指针decleration
void (*callback)(void*);
Run Code Online (Sandbox Code Playgroud)
声明一个callback带有泛型指针并返回void 的函数指针.
在分配cbfunc时callback
callback = cbfunc;
Run Code Online (Sandbox Code Playgroud)
我收到了警告
warning: assignment from incompatible …Run Code Online (Sandbox Code Playgroud) 我有两个相同程序的进程,可能在两台不同的机器上运行.我希望进程P2通过套接字从进程P1接收函数指针.
有可能吗?这是一个好习惯吗?
编辑:更有趣的是发送函数的代码,但我对此持怀疑态度.可能吗?
这是我第一次在Stack Overflow上问一个问题,所以请随意告诉我,如果我做错了什么或不够具体.我现在用C语言编写微控制器大约4个.几天前,我参加了一个电子竞赛.许多问题之一是C代码行究竟是什么
int *(*(x[3])())[5];
Run Code Online (Sandbox Code Playgroud)
确实.这就是我记得的路线.一个支架可能在另一个位置,但我认为这就是这条线.
我的猜测是x是一个功能指针数组,我们采用第四个元素并取消引用它.然后在不移交参数的情况下执行该功能.returnvalue似乎是指向一个数组的指针,我们为了获取第一个元素的地址而将其解引用一次.然后我们选择该数组的第6个元素.我不知道int的用途是什么......
非常感谢你回答我的问题并度过了愉快的一天.
首先,让我澄清这个问题并不能清楚地解释我的怀疑.设置上下文清晰.我在C/C++中专门针对函数指针问这个问题.
我知道早期绑定和后期绑定之间的区别以及它是如何工作的.我想要了解的是以下一个使用C/C++中的函数指针的示例:
在许多教科书中,已经提到:
后期绑定的优点是它比早期绑定更灵活,因为关于调用哪个函数的决定不需要在运行时进行.
另外,它提到:
使用后期绑定,程序必须读取指针中保存的地址,然后跳转到该地址.这涉及一个额外的步骤,使其稍慢.
#include <iostream>
using namespace std;
int Add(int nX, int nY)
{
return nX + nY;
}
int Subtract(int nX, int nY)
{
return nX - nY;
}
int Multiply(int nX, int nY)
{
return nX * nY;
}
int main()
{
int nX;
cout << "Enter a number: ";
cin >> nX;
int nY;
cout << "Enter another number: ";
cin >> nY;
int nOperation;
do
{
cout << "Enter an operation …Run Code Online (Sandbox Code Playgroud) 假设我有以下功能界面:
void giveme(void (*p)());
Run Code Online (Sandbox Code Playgroud)
该函数只接受指向函数的指针,该函数没有返回类型和参数.
我想知道是否存在一种方式(不改变界面)传递类方法作为该函数的参数.
我将尝试用一个例子更好地解释.我有一节课,比如:
class Foo {
public:
template<typename T>
void bar();
};
Run Code Online (Sandbox Code Playgroud)
我想传递bar<T>(该类的可寻址实例)作为函数的参数giveme.
我想用方法绑定方法,并获取函数目标.
就像是:
int main(int argc, char *argv[]) {
Foo foo;
std::function<void()> f = std::bind(&Foo::bar<int>, &foo);
giveme(f.target<void()>());
return 0;
}
Run Code Online (Sandbox Code Playgroud)
它编译,但显然不起作用,因为,从这里:
TargetType应匹配目标类型,以便typeid(TargetType)==target_type().否则,该函数始终返回空指针.
那么,如果存在,有什么方法可以实现它?
我正在练习 C++ 中的函数指针。我编写了以下代码。我已经声明了一个整数向量并向其添加了值。之后,我通过引用将向量的值传递给函数。我将值添加到向量的每个值中。之后,当我显示原始向量的内容时,这些值不会改变。以下是代码。
void printValues (int val) {
cout << val << " ";
}
void ForEach (vector<int> values, void (* func )(int), int inc) {
for (int value : values) {
value = value + inc;
func (value);
}
}
int main()
{
vector<int> v1;
cout << "Please enter the values in vector";
for (int i = 0; i < 5; i++) {
int val = 0;
cin >> val;
v1.push_back(val);
}
cout << "value stored in vector :" …Run Code Online (Sandbox Code Playgroud)