我想确保一组函数在某些C代码中具有相同的签名。理想情况下,我可以定义一个描述函数返回值和参数的新类型,然后使用这个新类型声明我的函数集。
另外,有没有办法为这个函数typedef的参数指定默认值?
答案 0 :(得分:13)
/* 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;
}
至于你的新问题(08年10月20日添加):“另外,有没有办法为这个函数typedef的参数指定默认值?”
不,没有办法将默认参数添加到typedef中。当然不在C中,根本不支持默认参数。即使在C ++中也不能这样做,因为参数的默认值不是该类型的一部分。实际上,从基类重写虚方法的类可以为默认参数指定不同的值(或者甚至完全删除默认值) - 但是,这通常不应该做,因为它只会导致混淆(http://www.gotw.ca/gotw/005.htm)。
如果您正在使用C ++,您可以使用以下某个(或其组合)获得所需的行为:
但是如果不了解更多关于你要完成什么的具体细节,就很难提出建议。而且我认为结果可能很糟糕。
答案 1 :(得分:0)
这类似于函数指针的工作方式:
// 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;
答案 2 :(得分:0)
我认为你不能直接这样做,但你可以声明一个函数指针类型,然后将所有函数收集到一个数组中。编译器会告诉您哪些不匹配。
typedef void (*MethodSig)(int, int);
static MethodSig x[] = { fnA, fnB, ... };
或者使用宏来声明函数签名
#define MyFunc(X) void X(int a, int b)
这样他们都会一样。
答案 3 :(得分:0)
你不能真正阻止任何人使某个功能有任何签名。但你可以控制你会打电话的内容。所以我认为这就是你想要的。
让调用任意函数的函数将指向函数的指针作为参数。由于您提到了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);
答案 4 :(得分:0)
这是一个创建映射到简单字符串的函数列表的示例。
首先是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++;
}
很抱歉,如果它有点'原始'。直接粘贴我们的代码; - )