【发布时间】:2008-10-09 18:22:52
【问题描述】:
我想确保一组函数在某些 C 代码中具有相同的签名。理想情况下,我将能够定义一个描述函数的返回值和参数的新类型,然后使用这种新类型声明我的一组函数。
另外,有没有办法为此函数 typedef 指定参数的默认值?
【问题讨论】:
标签: c
我想确保一组函数在某些 C 代码中具有相同的签名。理想情况下,我将能够定义一个描述函数的返回值和参数的新类型,然后使用这种新类型声明我的一组函数。
另外,有没有办法为此函数 typedef 指定参数的默认值?
【问题讨论】:
标签: c
/* define a typedef for function_t - functions that return void */
/* and take an int and char parameter */
typedef void function_t( int param1, char param2);
/* declare some functions that use that signature */
function_t foo;
function_t bar;
现在,当您定义函数时,如果它们不使用与 typedef 中相同的签名,则会出现错误。
void foo( int x, char c)
{
/* do some stuff */
return;
}
/* this will result in a compiler error */
int bar( int x, char c)
{
/* do some stuff */
return 1;
}
至于您的新问题(2008 年 10 月 20 日添加):“另外,有没有办法为此函数 typedef 的参数指定默认值?”
不,没有办法将默认参数添加到 typedef。当然不是在 C 中,它根本不支持默认参数。即使在 C++ 中你也不能这样做,因为参数的默认值不是类型的一部分。实际上,从基类覆盖虚拟方法的类可以为默认参数指定不同的值(甚至完全删除默认值)——但是,这通常不应该这样做,因为它只会引起混淆(http://www.gotw.ca/gotw/005.htm)。
如果您使用的是 C++,则可以使用以下其中一种(或组合)获得您想要的行为:
但是,如果不知道您想要完成的具体目标的更多细节,就很难提出建议。而且我认为结果很可能很糟糕。
【讨论】:
这类似于函数指针的工作方式:
// Declaration of function with int arg returning int
typedef int (*CALLBACK)(int);
//Definition
int myFunc(int arg)
{
return 0;
}
// Function pointer usage
CALLBACK pFunc = myFunc;
【讨论】:
我认为你不能直接这样做,但你可以声明一个函数指针类型,然后将所有函数收集到一个数组中。编译器会让你知道哪些不匹配。
typedef void (*MethodSig)(int, int);
static MethodSig x[] = { fnA, fnB, ... };
或者使用宏来声明函数签名
#define MyFunc(X) void X(int a, int b)
这样他们就都一样了。
【讨论】:
您不能真正阻止任何人使函数具有任何签名。但是你可以控制你会调用什么。所以我认为这就是你想要的。
让调用任意函数的函数将指向函数的指针作为参数。既然你提到了 typedef,你可以在程序的前面定义一个 typedef,像这样:
假设您只需要签名“unsigned short id_for_allowed_functions (int x, char* y)”的函数:
typedef unsigned short (*id_for_allowed_functions)(int, char*);
然后,你的调用函数:
void calling_function (id_for_allowed_function x) { (*x)(3, "bla"); }
并为其提供函数 foo:
unsigned short foo(int x, char* y) { /* ... */ }
calling_function(&foo);
【讨论】:
这是一个创建映射到简单字符串的函数列表的示例。
首先是 typedef:
typedef GenList *(*DBLISTLOADER)(Database *pDB, char *quellCD, char *profilName);
typedef ObjDescription *(*DBCOLUMNLOADER)();
typedef struct dbinfo
{
char *dbName;
DBLISTLOADER dbListLoader;
DBCOLUMNLOADER dbColumnLoader;
char *options;
} DBINFO;
然后是映射表:
DBINFO dbInfoList[] =
{
{ "SRCDOC", loadSRCDOC, colSRCDOC, "q" },
{ "PRF_CD", loadPRF_CD, colPRF_CD, "" },
{ "MEDIA", loadMEDIA, colMEDIA, "" },
{ NULL, NULL, NULL }
};
现在从该表中查找一个函数并调用它:
while (dbInfoList[i].dbName != NULL)
{
if (strcmp(dbInfoList[i].dbName, szDatabase) == 0)
{
return (dbInfoList[i].dbListLoader)(pDB, quellCD, profilName);
}
i++;
}
对不起,如果它有点“原始”。直接从我们的代码粘贴;-)
【讨论】: