是否可以在C函数中使用变量输入

时间:2014-10-21 05:09:27

标签: c function int double

我正在编写一个简单的函数来计算两个输入之间的差异。只是为了方便。在个人头文件中引用的东西。

我想输入:

两个整数:输出一个整数

两个双打:输出一个双倍

我尝试在线搜索某种全局输入声明,但找不到它。

我不希望有两个功能,只需一个简单的功能。

示例代码标头: int diff(int a,int b); 双差异(双a,双b);

感谢您的帮助!

3 个答案:

答案 0 :(得分:6)

不,这称为重载,它不是C的功能。您最好创建不同的函数来处理此问题。

可以使用各种C语言(你可以用足够的C语言来做任何),但是生成的代码可能会如此难看不可维护: - )

例如,C11引入了通用选择,带有_Generic主表达式,这允许您根据输入参数类型调用不同的函数。它确实比这更多,但根据你的问题,这是你感兴趣的方面。

例如,我们假设您定义了两个函数:

int     diffi (int    a, int    b) { return a - b; }
double  diffd (double a, double b) { return a - b; }

通常情况下,必须根据输入类型决定调用哪个。 C11通用选择功能允许您执行此操作:

#define diff(a,b)        \
    _Generic((a),        \
        double:  diffd,  \
        int:     diffi,  \
        default: diffX   \
    )(a,b)

这基本上是在源代码中找到宏diff(x,y)时的作用:

  • 确定表达式(a)的类型,而不进行评估;
  • 向源流中注入与该类型匹配的令牌(如果未找到匹配项,则为默认值);
  • 在源流中注入最后的(a,b)文本。

因此,如果您的源文件包含以下行:

x = diff (1,   2);
y = diff (1.0, 2);

这将被翻译成:

x = diffi (1  , 2);
y = diffd (1.0, 2);

为您提供有效的超载。

现在这是一个中等容易的案例,因为它只依赖于第一个参数类型 - 如果你试图这样做,你会看到一个洞:

z = diff (1, 2.0);

因为第一个参数的类型是int,所以你得到:

z = diffi (1, 2.0);

这不是你真正想做的事情。这是复杂性的来源,因为你必须涵盖四个的可能性:{int/int, int/double, double/int, double/double}并且它根据参数的数量和可能的类型得到更多复杂每个论点。

然而,您的完整案例可以通过明智地使用默认值和嵌套通用选择来完成,例如:

#define diff(a,b)              \
    _Generic((a),              \
        double:  diffd,        \
        default: _Generic((b), \
            double:  diffd,    \
            default: diffi     \
        )                      \
    )(a,b)

这可以理解为:

  • 如果a的类型为double,请使用diffd;
  • 否则,如果b的类型为double,请使用diffd;
  • 否则,请使用diffi
  • 也不要忘记注入论点。

以下完整程序(使用clang 3.0编译)显示了此功能的实际应用:

#include <stdio.h>

int diffi (int a, int b) {
    printf ("diffi %d %d", a, b);
    return a - b;
}
double diffd (double a, double b) {
    printf ("diffd %f %f", a, b);
    return a - b;
}

#define diff(a,b)              \
    _Generic((a),              \
        double:  diffd,        \
        default: _Generic((b), \
            double:  diffd,    \
            default: diffi     \
        )                      \
    )(a,b)

int main (void) {
    int i; double d;
    i = diff (1  , 2  ); printf (" --> %d\n", i);
    d = diff (1.0, 2  ); printf (" --> %f\n", d);
    d = diff (1  , 2.0); printf (" --> %f\n", d);
    d = diff (1.0, 2.0); printf (" --> %f\n", d);
    return 0;
}

该程序的输出是:

diffi 1 2 --> -1
diffd 1.000000 2.000000 --> -1.000000
diffd 1.000000 2.000000 --> -1.000000
diffd 1.000000 2.000000 --> -1.000000

显示正在为四种可能性调用正确的函数。


事实上,正如rici在评论中指出的那样,您可以依赖C的促销规则,其中添加doubleint(按任意顺序)在添加两个double变量时int为您提供int

#define diff(a,b) _Generic((a+b), double:diffd, default:diffi)(a,b)

答案 1 :(得分:3)

C中没有

Function overloading。 一些可能的解决方法

  1. 对ex:diff_i和diff_d使用两个具有不同名称的函数 (推荐)
  2. 使用varargs(不推荐)这会使代码难以维持。
  3. 使用_Generic

答案 2 :(得分:2)

IEEE754双精度具有超过32位的精度,因此只需编写双版本并让自动转换处理其余部分。

当然,如果您使用的系统中sizeof(int)>4char的位数超过8位,最好为每种类型编写变体,并采用某种匈牙利语命名方式 - 对他们来说。然后你可以写,也许:

int diffi(int, int);
double diffd(double, double);
ssize_t diffz(size_t, size_t);

等。本质上,这是手动 名称修改,这是C ++编译器用于为对象文件的导出表生成不同符号名称的相同技术。