我只想知道C是否支持加载? 由于我们使用printf等系统函数,其参数不同。 帮我出来C支持重载吗?
C支持重载吗?
回答
不,C不支持任何形式的超载(除非你是内置运营商重载已经是事实,是的超载一种形式)。
printf
使用称为varargs的功能工作。你让一个呼叫看起来像它可能过载:
printf("%d", 12); // int overload?
printf("%s", "hi"); // char* overload?
其实事实并非如此。只有一个printf函数,但编译器使用特殊的调用约定来调用它,其中提供的任何参数都按顺序放置在堆栈上[*]。 printf(或vprintf)检查格式字符串并使用它来计算出如何读取这些参数。这就是为什么printf的是不是类型安全:
char *format = "%d";
printf(format, "hi"); // undefined behaviour, no diagnostic required.
[*]标准实际上并不说他们在栈中传递,或提栈可言,但是这是自然的实现。
我不能为所有编译器说话,但是一旦函数返回,与我一起工作的那个调用者就会调整它所推送的参数的堆栈。对于我来说,这对于可变参数函数来说似乎是一个好主意 - 比使函数从堆栈中弹出它们更安全。 – tomlogic 2010-02-28 17:42:14
你说得对,实际上cdecl的调用约定就是这样的(调用者负责堆栈清理);我删除了评论以避免混淆其他读者。真正的问题在于scanf,如果提供的格式字符串不正确,可能会将数据写入内存中的随机位置(从堆栈中取出)。 – 2010-02-28 17:47:31
C1X将支持通过类型通用表达式和宏 – Spudd86 2011-07-22 22:30:11
不,C不支持重载,但支持Variadic functions。 printf是变量函数的一个例子。
C不支持重载。 (显然,即使它确实如此,它们也不会将它用于printf:对于每种可能的组合类型,您都需要printf!)
printf使用varargs。
不,C不支持重载。如果你想实现类似于C++的重载,你将不得不手动地调整你的函数名称,使用某种一致的约定。例如:
int myModule_myFunction_add();
int myModule_myFunction_add_int(int);
int myModule_myFunction_add_char_int(char, int);
int myModule_myFunction_add_pMyStruct_int(MyStruct*, int);
这一切都取决于您如何定义“支持”。
显然,C语言提供重载运算核心语言中,因为使用C大多数运营商都重载功能:您可以使用二进制+
与int
,long
与指针类型。
然而,在同一时间C不允许你创建你自己的重载函数和C标准库也有诉诸不同名称的功能与不同类型(如abs
,fabs
,labs
等使用)。
换句话说,C有一定程度的重载编码为核心语言,但标准库和用户都不允许自己重载。
没有c不支持函数重载。 但是如果你使用g ++(一个C++编译器),你可以把它编译/工作。
-1,如果你正在编写C你应该使用C编译器。 – 2010-02-28 18:51:08
借调。如果您使用C++编译器来编译代码,那么您正在撰写的是C++代码,而不是C代码。特别是如果您使用C++中不在C中的功能,例如功能重载! – 2010-02-28 21:40:37
认真-2哈哈 – chinmaya 2010-03-01 02:14:20
不是直接的,这不是printf
的工作方式,但如果类型大小不同,则可以使用宏创建等效的重载函数。 C99标准的tgmath.h中的类型通用数学函数可以用这种方式实现。
C标准没有规定操作符重载;由于许多构建系统无法容纳具有相同名称的多个功能,所以添加它的建议已被拒绝。虽然C++可以通过例如有
void foo(int);
int foo(char*);
long foo(char *, char **);
编译成一个名为类似v__foo_i,i__foo_pc和l__foo_pc_ppc [编译器使用不同的命名规则的功能,虽然C++标准禁止在标识符利用内部双下划线的,以使编译器给东西的名字像上面没有冲突]。 C标准的作者不希望任何编译器改变命名约定以允许重载,所以他们不提供它。
编译器将允许重载静态和内联函数而不会产生命名问题;这将在实际中是一样允许外部联性功能超载为有用的,因为人们可以具有一个头文件:
void foo_zz1(int);
int foo_zz2(char*);
long foo_zz3(char *, char **);
inline void foo(int x) { foo_zz1(x); }
inline int foo(char* st) { foo_zz2(st); }
long foo(char *p1, char **p2) { foo_zz3(p1,p2); }
我记得在看为C和C++之间的混合的嵌入式编译器,其支持上述的作为一个非标准的延伸,但我对细节并不积极。无论如何,即使一些C编译器支持重载没有外部链接的函数的重载,C14也不支持它,但我不知道(不幸的是)(不幸)有任何积极的努力将这种特性添加到未来的C标准中。
尽管如此,GCC可以通过使用宏来支持一种重载形式,这种形式的重载不会直接在具有运算符重载的语言中被支持。 GCC包含一个内在的特征,它将确定一个表达式是否可以作为编译时常量进行评估。使用这个内在的,可以写一个宏,它可以根据参数以不同的方式(包括通过调用函数)来评估表达式。在某些情况下,如果给定编译时常量参数,公式将作为编译时常量进行计算,但在给定可变参数时会产生可怕的混乱情况。作为一个简单的例子,假设有人希望位反转一个32位的值。如果该值是恒定的,一个能做到这一点通过:
#define nyb_swap(x) \
((((x) & 1)<<3) | (((x) & 2)<<1) | (((x) & 4)>>1) | ((((x) & 8)>>3))
#define byte_swap(x) \
((nyb_swap(x)<<4) | nyb_swap((x) >> 4))
#define word_swap(x) \
((byte_swap(x)<<24) | (byte_swap((x) >> 8)<<16) | \
(byte_swap((x) >> 16)<<8) | (byte_swap((x) >> 24)))
而像uint32_t x=word_swap(0x12345678);
表达只会加载x
与0×87654321。另一方面,如果该值不是一个常数,结果将是可怕的:像uint32_t y=word_swap(x);
这样的表达式可能会产生许多指令;使用部分展开的循环调用函数几乎同样快,但更紧凑。另一方面,使用循环会阻止将结果视为编译时常量。
使用GCC,可以定义一个宏,这将既可以使用固定收益宏,如果在恒定的,或者给一个变量时调用一个函数:
#define wswap(x) \
(__builtin_constant_p((x)) ? word_swap((x)) : word_swap_func((x))
这种方法不能做的一切类型基于重载可以做,但它可以做很多事情,重载不能。
- 1. EL支持重载方法吗?
- 2. printf支持函数重载在C中?
- 3. C#支持程序吗?
- 4. GNU Global支持objective-c吗?
- 5. Objective-C支持traits/mixins吗?
- 6. Java 8支持多重继承吗?
- 7. psexec支持输入重定向吗?
- 8. 是否dwscript支持运算符重载
- 9. Delphi支持哪些操作符重载?
- 10. Java是否支持运算符重载?
- 11. Windows 8桌面支持C++/cli吗?
- 12. Visual C++支持循环不切换吗?
- 13. C支持可选的空参数吗?
- 14. 微软会继续支持C++/CLI吗?
- 15. VS2008有一些C++ 0x的支持吗?
- 16. 你支付Subversion支持吗?
- 17. 除C++外,哪些编程语言支持运算符重载?
- 18. 为什么客观C不支持重载
- 19. GWT支持Javapaces吗?
- 20. Android支持SNMP吗?
- 21. Robotium支持OpenGL吗?
- 22. Wix3.5支持VS2010吗?
- 23. GWT支持Deque吗?
- 24. emfield支持iTunes吗?
- 25. PlayBook支持GWT吗?
- 26. SlimBox2支持PNG吗?
- 27. OpenVswitch支持BFD吗?
- 28. Lucene支持Unicode吗?
- 29. Chrome支持“addEventListener”吗?
- 30. CockroachDB支持JSON吗?
Duplicate:http://stackoverflow.com/questions/479207/function-overloading-in-c – 2010-03-20 10:25:30
请参阅Leushenko 2014年答案使用C11 _泛型类型选择器在愚蠢http://stackoverflow.com/questions/479207/function -overloading-在-C。 – 2015-04-16 07:52:21