我正在编写一个简单的函数来计算两个输入之间的差异。只是为了方便。在个人头文件中引用的东西。
我想输入:
两个整数:输出一个整数
两个双打:输出一个双倍
我尝试在线搜索某种全局输入声明,但找不到它。
我不希望有两个功能,只需一个简单的功能。
示例代码标头: int diff(int a,int b); 双差异(双a,双b);
感谢您的帮助!
答案 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的促销规则,其中添加double
和int
(按任意顺序)在添加两个double
变量时int
为您提供int
:
#define diff(a,b) _Generic((a+b), double:diffd, default:diffi)(a,b)
答案 1 :(得分:3)
Function overloading。 一些可能的解决方法
答案 2 :(得分:2)
IEEE754双精度具有超过32位的精度,因此只需编写双版本并让自动转换处理其余部分。
当然,如果您使用的系统中sizeof(int)>4
或char
的位数超过8位,最好为每种类型编写变体,并采用某种匈牙利语命名方式 - 对他们来说。然后你可以写,也许:
int diffi(int, int);
double diffd(double, double);
ssize_t diffz(size_t, size_t);
等。本质上,这是手动 名称修改,这是C ++编译器用于为对象文件的导出表生成不同符号名称的相同技术。