你能在C中进行重载并且具有相同的函数名吗?

Jus*_*ode 1 c overloading

在Java中,当方法具有相同名称时,我们可以进行重载。我在谷歌上搜索,它说 C 不支持重载,所以我想知道是否有一种方法可以做类似于 C 中的重载的事情。

例如:

int max(int num1, int num2);
double max(double num1, num2);

int main(){
  printf(...);
  printf(...);
}

int max(int num1, int num2){
  ...
}

double max(double num1, double num2){
  ...
}
Run Code Online (Sandbox Code Playgroud)

ric*_*ici 8

您找到的参考是正确的:C 本身不支持重载。

它所拥有的(假设我们谈论的是实际的 C 而不是历史版本)是一个通用选择器,它允许您编写自己的宏来进行动态调度。

C99 引入了tgmath.h标头,它允许重载某些数学函数,以便与不同宽度的浮点参数一起使用,在某些情况下还可以使用复杂的参数。然而,C99 中没有引入允许将该功能推广到其他功能的设施。C11 中引入的通用选择器就是这样的工具。

选择器的形式为_Generic(select-expression, type-associations),其中type-associations由逗号分隔的形式对列表组成type : expression。选择器将被替换为与 的类型对应的表达式select-expression。其中 s 之一type可以是关键字default;其他的必须是唯一的完整类型(即列表中的两种类型不能兼容)[注1]。需要注意的是,关联列表中的所有表达式都必须无错误地编译,而不仅仅是最终选择的表达式。通常,表达式是函数指针,而不是函数调用。

一个例子可能会让这一点更清楚。假设我们有两个函数(它们具有不同的名称,因此这不是名称重载):

int max_int(int a, int b) { return a > b ? a : b; }
double max_dbl(double a, double b) { return a > b ? a : b; }
Run Code Online (Sandbox Code Playgroud)

现在,我们可以定义宏 MAX:

#define MAX(a, b) _Generic((a)+(b),          \
                    int : max_int,           \
                    double : max_dbl)(a, b)
Run Code Online (Sandbox Code Playgroud)

在这里,我使用a+bas 选择器表达式而不是a,因为 的类型a+b是通常算术转换产生的类型。如果我刚刚使用a, thenMAX(3, 5.7)会产生意外的结果,因为通用选择器将被选择max_int并被5.7默默地截断为 5。使用 时a+b,选择器的类型将为double,导致调用max_dbl,其中两个值都是转换为双倍。

我可以不用(a)+(b)在宏中使用,因为_Generic它不会计算选择器表达式(如sizeof)。因此,不存在对具有副作用的参数进行双重评估的危险。


笔记:

  1. 泛型关联的类型不能是 VLA(可变长度数组),即使编译器实现了它们。但任何其他完整类型都可以,即使是指向不完整类型的指针。