C中的函数重载
今天,看一下open()
的手册页,我注意到这个函数”overloaded’:
int open(const char *pathname, int flags); int open(const char *pathname, int flags, mode_t mode);
我不认为这是可能的C.实现这一目标的“诀窍”是什么?
后期编辑:
所以它并没有真正超载,因为在使用varargs时 – 你只能提供相同类型的多个参数。 那么, mode_t
幕后是一个int吗?
它使用变量参数 。 这些声明只出现在手册页中,因为这两个是你应该调用open()的唯一方法。 实际的C函数将被声明为例如
int open(const char *pathname,int flags,...);
对于变量参数,参数不需要是相同的类型。 printf
就是一个明显的例子。
在open()的情况下,如果’ flags
包含O_CREAT标志,则第一个变量参数必须是mode_t,因为open()的实现期望它是mode_t(在幕后可能是unsigned int或unsigned long – 但是与varargs无关)
C确实可以用可变数量的参数编写函数,例如printf
。
话虽如此,在C中没有可靠的跨平台方式来编写一个只需要2或3个参数的函数; 一般来说,你必须做类似的事情
some_function(5, 6, 7, NULL); some_function(5, 6, 8, 2, 5, NULL);
换句话说,您必须有一个终止“sentinal”参数。 或者,您可以在某个早期参数中以某种方式包含参数的数量,例如
another_func(2, "hello", "world"); another_func(3, "goodbye", "cruel", "world");
printf
系列function采用这种方法; 第一个格式参数包含所需的额外参数的数量; 例如,对于printf("%f %f", 5.6, 7.11)
您知道必须有2个浮点参数。 但是,这在用户定义的库函数中有些不安全,因为如果你说my_printf("%s %f %f %f %s", 5.6)
那么你可能会遇到段错误或更糟。 幸运的是,大多数C编译器会在编译时检查你对printf
的调用,以避免出现这种问题。
在open
的情况下,该函数被声明为具有可变参数,并且仅在设置了O_CREAT
时才检查第三个参数。 所以这就是它如何“安全地”确定是否存在第三个参数。 我把“安全”放在引号中,因为从技术上讲,没有办法在运行时知道实际传递了多少参数。 例如,以下调用将编译时没有任何错误或警告:
open("foo.txt", 5, "not an integer", 7); // extra and invalid parameters open("bar.txt", O_CREAT); // third parameter is missing
“当O_CREAT在标志中时必须指定mode,否则将被忽略。”
extern int open (__const char *__file, int __oflag, ...)
如果__oflag
包含O_CREAT
它使用varargs
并仅加载模式变量参数。
非常简短的回答 – varargs
你可以使用变量参数列表伪造它...
int function(int x, ...);