C支持重载吗?

我只想知道C是否支持过载? 因为我们使用不同参数的printf这样的系统函数。 帮帮我

不,C不支持任何forms的重载(除非您已经指望内置的操作符已经被重载 ,是一种超载的forms)。

printf使用一个名为varargs的特性来工作。 你打电话看起来可能会超载:

 printf("%d", 12); // int overload? printf("%s", "hi"); // char* overload? 

其实不是。 只有一个printf函数,但编译器使用一个特殊的调用约定来调用它,其中提供的任何参数都按顺序放在堆栈上[*]。 printf(或vprintf)检查格式string,并使用它来找出如何读取这些参数。 这就是为什么printf不是types安全的原因:

 char *format = "%d"; printf(format, "hi"); // undefined behaviour, no diagnostic required. 

标准实际上并没有它们是通过堆栈传递的,或者根本没有提到堆栈,但这是自然的实现。

C不支持重载。 (很明显,即使这样做,他们也不会使用printf:你需要一个printf来处理每种可能的types组合!)

printf使用可变参数 。

不,C不支持重载,但支持variables函数 。 printf是variables函数的一个例子。

这一切都取决于你如何定义“支持”。

显然,C语言在核心语言中提供了重载操作符 ,因为C中的大多数操作符都有重载的function:可以使用二进制+ intlong和指针types。

但同时C不允许你创build自己的重载函数,C标准库也不得不求助于不同types的函数(比如absfabslabs等)。

换句话说,C有一定程度的重载编码成为核心语言,但标准库和用户都不允许自己重载。

不,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); 

不是直接的,这不是printf工作方式,但是如果types的大小不同,可以使用macros创build相当于重载的函数。 C99标准的tgmath.h中的types通用math函数可以以这种方式实现。

C标准没有规定运营商超载。 由于许多构build系统无法容纳具有相同名称的多个function,所以添加它的build议已被拒绝。 而C ++可以通过例如拥有解决这个问题

 void foo(int); int foo(char*); long foo(char *, char **); 

编译为名为v__foo_i,i__foo_pc和l__foo_pc_ppc的函数[编译器使用不同的命名约定,尽pipeC ++标准禁止在标识符中使用内部双下划线,以便编译器可以在不冲突的情况下给出类似上述的名称]。 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 ++之间寻找一个embedded式编译器来支持上述的非标准扩展,但是我对这些细节并不积极。 无论如何,即使一些C编译器确实支持不具有外部链接的函数的重载,C14也不支持它,也不知道(不幸的是)(不幸的是)有任何积极的努力将这种特性添加到未来的C标准中。

尽pipe如此,GCC可以通过使用macros来支持一种重载的forms,这种forms的重载不会直接被运算符重载的语言所支持。 GCC包含一个内在的特征,它将确定一个expression式是否可以作为一个编译时常量进行评估。 使用这种内在的,可以写一个macros,它可以根据参数不同的方式(包括通过调用函数)评估expression式。 在某些情况下,如果给定编译时常量参数,则公式将作为编译时常量进行计算,但如果给定可变参数则会产生可怕的混乱。 作为一个简单的例子,假设我们希望位反转一个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)) ) 

和一个expression式,如uint32_t x=word_swap(0x12345678); 会简单地加载0x87654321。 另一方面,如果该值不是一个常数,结果将是可怕的:一个expression式,如uint32_t y=word_swap(x); 可能会产生许多指令; 调用具有部分展开循环的函数将几乎一样快,但更紧凑。 另一方面,使用循环会阻止将结果视为编译时常量。

使用GCC,可以定义一个macros,如果给定一个常量,它将使用常量产生macros,或者在给定variables时调用函数:

 #define wswap(x) \ (__builtin_constant_p((x)) ? word_swap((x)) : word_swap_func((x)) 

这种做法不能做任何基于types的重载可以做的事情,但是可以做很多事情,重载不了。

C不支持重载。 但是我们可以通过编程我们自己的库来实现这个function,从而可以提供超载支持。

没有c不支持函数重载。 但是如果你使用g ++(一个c ++编译器),你可以把它编译/工作。