如何让函数指针能指向任意函数?如何保存可变参数?

灼眼的超哥 2012-01-15 12:03:17
如题,先看下面的示例代码:

#include<stdio.h>
int max(int x,int y) /* 声明一个函数 */
{
return(x > y ? x : y);
}
  void main()
  {
  int (*ptr)(int, int);/* 声明一个函数指针 */
  int a,b,c;
  ptr = max;/* 将func函数的首地址赋给指针f */
  scanf("%d%d",&a,&b);
  c=(*ptr)(a,b);
  printf("a=%d,b=%d,max=%d",a,b,c);
}


请问,如何让任何函数都能赋值给同一个函数指针?
也就是说,让这个函数指针能像printf函数那样,支持任意数量,多种类型的参数。

还有,如何保存这N个参数,等需要用函数指针时,将保存的参数作为调用函数指针指向的函数所传递的参数?

比如要实现这样的代码:

int a(int n, char *s)
{
//省略代码
}

int b(char *in, char *out, int n)
{
//省略代码
}


int main()
{
char str[100], ss[200];
int n, m;
int (*ptr_a)(XXXXXX), (*ptr_b)(XXXXXX);/* 如何声明这两个函数指针? */

/* save_func函数支持不定参数,并且能保存这些参
* 数,等调用run_func函数时,就会调用函数指针
* 指向的函数,并将保存的这些参数传给这个函数
*/
save_func( ptr_a, a, n, str);
save_func( ptr_b, b, str, ss, m);

run_func(ptr_a);
run_func(ptr_b);
}

run_func函数和save_func函数该如何写?
...全文
1064 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
iamnobody 2012-01-16
  • 打赏
  • 举报
回复
Qt我刚刚学了几天。connect的信号和槽都是通过一个宏来生成的。具体原理我还没研究。但是应该用到了C 的编译期多态,个人觉得c语言是无法模仿的编译期多态的。
你说按键问题,每个合法键盘输入都对应一个键盘消息。你应该考虑模仿windows的回调函数(参数固定)。而不是Qt
孤独小剑 2012-01-16
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 lile1234_show 的回复:]
C/C++ code


/*LZ所说的,实在没想好.. 下面是用共同体写的,算是一个思路吧,
当将某个函数赋值给共同体中的一个函数指针成员后,就可以通过共同体中
其他与函数参数相同的函数名调用*/
#include <iostream>
using namespace std;
void Show()
{
cout<<"Show()"<<end……
[/Quote]++
灼眼的超哥 2012-01-16
  • 打赏
  • 举报
回复
先结帖了。
灼眼的超哥 2012-01-16
  • 打赏
  • 举报
回复
现在找到的可行方法就是:
先保存该自定义函数的函数指针,并且,自定义函数的参数只能是个void*类型的变量,想要传多个参数,那就必须先写个结构体,转换成void型,再由自定义的函数将这个void型变量转换回来。
等事件触发后,调用函数指针所指向的函数,并传递参数。

灼眼的超哥 2012-01-16
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 mingliang1212 的回复:]

Qt我刚刚学了几天。connect的信号和槽都是通过一个宏来生成的。具体原理我还没研究。但是应该用到了C 的编译期多态,个人觉得c语言是无法模仿的编译期多态的。
你说按键问题,每个合法键盘输入都对应一个键盘消息。你应该考虑模仿windows的回调函数(参数固定)。而不是Qt
[/Quote]
我说的是程序的图形界面上的按钮,不是键盘上的按键。
现在虽然可以得到鼠标单击时游标所处的坐标,并能判断被点击的是哪个窗口部件,但是,不知道如何让这个部件被点击后调用自定义的函数,不只是这些,鼠标游标移动至这个窗口部件上后,该调用什么函数,比如:改变鼠标游标的样式,改变该部件的图形内容等,如果我没有将某个函数与该事件关联,默认忽略处理。
quwei197874 2012-01-15
  • 打赏
  • 举报
回复
用void指针
jaaaver 2012-01-15
  • 打赏
  • 举报
回复
可能有其他巧妙的方法
但想像你说的这么智能,c语言真心办不到
jaaaver 2012-01-15
  • 打赏
  • 举报
回复
三个字:办不到
灼眼的超哥 2012-01-15
  • 打赏
  • 举报
回复
热都去哪里了。。。
AnYidan 2012-01-15
  • 打赏
  • 举报
回复
lz 为何有如此需要

目前c 标准中没有,说明 :
1。 太难,办不到
2。有别的解决办法,没必要
灼眼的超哥 2012-01-15
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 mingliang1212 的回复:]

可以,但是没有意义。怎么知道该传什么类型的结构体。如果你知道该传什么类型的结构体,那么说明你也可以明确地知道应该调用哪个类型函数。这样直接调用不就行了,为啥多此一举用指针?函数指针一般是为运行时多态或者代码重用,没需求应该避免。
[/Quote]
Qt中,信号与槽的关联可以用connect函数,我想实现的功能,也就是类似这个函数的功能。
灼眼的超哥 2012-01-15
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 mingliang1212 的回复:]

可以,但是没有意义。怎么知道该传什么类型的结构体。如果你知道该传什么类型的结构体,那么说明你也可以明确地知道应该调用哪个类型函数。这样直接调用不就行了,为啥多此一举用指针?函数指针一般是为运行时多态或者代码重用,没需求应该避免。
[/Quote]
比如:
我想实现在按钮按下后调用我定义的函数,按钮不止一个,每个按钮按下后调用的函数也不一样,这些函数的参数也不一样。
iamnobody 2012-01-15
  • 打赏
  • 举报
回复
可以,但是没有意义。怎么知道该传什么类型的结构体。如果你知道该传什么类型的结构体,那么说明你也可以明确地知道应该调用哪个类型函数。这样直接调用不就行了,为啥多此一举用指针?函数指针一般是为运行时多态或者代码重用,没需求应该避免。
灼眼的超哥 2012-01-15
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 lusedeya6 的回复:]

用结构体的话转换也需要参数的类型,不知道参数怎么转,联合可能还管用,但是有意义吗
引用 9 楼 liuchao35758600 的回复:
引用 7 楼 mingliang1212 的回复:

参数都不确定怎么知道该用什么?根本不存在这种需求。可以把函数都通过一个相同参数的函数封装起来再调用。

看来,只有像pthread_create()函数那样,传给子线程的参数必须是一个void*……
[/Quote]
转换成void*不就可以了吗?
例如:

typedef struct
{
int a;
char b;
}test;

int func(void *in)
{
test *t;
t = (*test)in;
t->a = 1;
t->b = 'a';
}
int main()
{
test a;
func((void)a);
}
lusedeya6 2012-01-15
  • 打赏
  • 举报
回复
用结构体的话转换也需要参数的类型,不知道参数怎么转,联合可能还管用,但是有意义吗
[Quote=引用 9 楼 liuchao35758600 的回复:]
引用 7 楼 mingliang1212 的回复:

参数都不确定怎么知道该用什么?根本不存在这种需求。可以把函数都通过一个相同参数的函数封装起来再调用。

看来,只有像pthread_create()函数那样,传给子线程的参数必须是一个void*类型的变量。
要想让子线程调用的函数能接受多个,多种类型的参数,就必须预先写个结构体,转换成void型传进去,之后,由子线程中的函数转换回来,……
[/Quote]
灼眼的超哥 2012-01-15
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 mingliang1212 的回复:]

参数都不确定怎么知道该用什么?根本不存在这种需求。可以把函数都通过一个相同参数的函数封装起来再调用。
[/Quote]
看来,只有像pthread_create()函数那样,传给子线程的参数必须是一个void*类型的变量。
要想让子线程调用的函数能接受多个,多种类型的参数,就必须预先写个结构体,转换成void型传进去,之后,由子线程中的函数转换回来,再使用。
si_sky 2012-01-15
  • 打赏
  • 举报
回复
我也不会!
iamnobody 2012-01-15
  • 打赏
  • 举报
回复
参数都不确定怎么知道该用什么?根本不存在这种需求。可以把函数都通过一个相同参数的函数封装起来再调用。
lee_鹿游原 2012-01-15
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 lile1234_show 的回复:]

C/C++ code

/*LZ所说的,实在没想好.. 下面是用共同体写的,算是一个思路吧,
当将某个函数赋值给共同体中的一个函数指针成员后,就可以通过共同体中
其他与函数参数相同的函数名调用*/
#include <iostream>
using namespace std;
void Show()
{
cout<<"Show()"<<endl;
}

voi……
[/Quote]

int main(int argc, char* argv[]); 改成 int main(); //避免编译器不同
lee_鹿游原 2012-01-15
  • 打赏
  • 举报
回复

/*LZ所说的,实在没想好.. 下面是用共同体写的,算是一个思路吧,
当将某个函数赋值给共同体中的一个函数指针成员后,就可以通过共同体中
其他与函数参数相同的函数名调用*/
#include <iostream>
using namespace std;
void Show()
{
cout<<"Show()"<<endl;
}

void Add(int a, int b)
{
cout<<"a + b = "<<a + b<<endl;
}

void PrintStr(char* ch)
{
cout<<ch<<endl;
}

typedef void (*PShow)(void);
typedef void (*PAdd)(int a, int b);
typedef void (*PPrintStr)(char *ch);

union FunPtr
{
PShow fun1;
PAdd fun2;
PPrintStr fun3;
};

int main(int argc, char* argv[])
{
int a = 3;
int b = 4;
char* str = "Hello World!";

FunPtr fun;

fun.fun1 = (PShow)Show;
fun.fun1();

fun.fun1 = (PShow)Add;
fun.fun2(a, b);

fun.fun1 = (PShow)PrintStr;
fun.fun3(str);
system("pause");
return 0;
}

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧