我目前使用三种不同的函数来返回数值(一个返回一个double
,另外两个返回一个long
):
int main(void)
{
// lots of code
dRate = funcGetInterestRate();
lMonths = funcGetTerm();
lPrincipal = funcGetPrincipal();
// lots of code
return 0;
}
这三个函数代码大约有90%相同,因此我想合并为1个函数。我想将值标志传递给单个函数,如下所示:
double
long
long
在调用函数时,我只想从该函数返回1个值,但是我想返回的值可以是double
或long
。我想做这样的事情:
void funcFunction(value passed to determine either long or double)
{
// lots of code
if (foo)
return double value;
else
return long value;
}
有一种简单的方法吗?
答案 0 :(得分:10)
函数的返回类型在编译时是固定的。您无法根据传入的参数更改返回类型。
但是,由于您的主要目标是删除函数中的重复代码并将其合并,因此可以通过其他方式解决。换句话说,这是XY problem。
在这种情况下,您可以做的是将三个函数中的每个函数的通用代码提取到一个单独的函数中,然后,三个原始函数可以调用该通用函数来完成大部分工作,然后提取所需的部分并返回。
例如:
struct loan {
double rate;
long term;
long principal;
};
void calcLoan(struct loan *loan)
{
// do stuff
loan->rate = // some value
loan->term = // some value
loan->principal = // some value
}
double funcGetInterestRate()
{
struct loan loan;
calcLoan(&loan);
return loan.rate;
}
long funcGetTerm()
{
struct loan loan;
calcLoan(&loan);
return loan.term;
}
long funcGetPrincipal()
{
struct loan loan;
calcLoan(&loan);
return loan.principal;
}
答案 1 :(得分:1)
否,C不允许这样做。返回类型在函数声明中(您将其声明为void)。
稍微容易一点的是提供两个指向变量的指针,并指示在返回值中使用哪个指针:
int funcFunction(yourArgument, long *longResult, double *dblResult)
{
// lots of code
if (foo)
{
*dblResult = value;
return 1;
} else
{
*longResult = otherValue;
return 0;
}
}
(也许您甚至可以使用union
。)
但是...我不得不在内部使用value
和otherValue
作为 函数,不能使用相同的变量来保存long
或< / em> double
。同样,您可以使用union
–但是这强调了只有一个功能到断点的渴望。
答案 2 :(得分:1)
您可以考虑返回一些tagged union。 Glib GVariant类型可能是鼓舞人心的,并且由于Glib是自由软件,因此您可以研究其源代码。另请参见this answer。
因此,您将在内部声明一个带有匿名struct
的公共union
:
struct choice_st {
bool islong;
union {
long i; // valid when islong is true
double d; // valid when islong is false
}
}
,您可以返回该struct choice_st
的值。
struct choice_st res;
if (foo) {
res.islong = true;
res.i = somelong;
return res;
}
else {
res.islong = false;
res.d = somedouble;
return res;
}
您可能还决定使用C dynamic memory allocation,返回指向malloc
的全新struct choice_st
版指针,并采用约定由谁负责free
-指针。 (顺便说一句,GVariant
正在做类似的事情。)
答案 3 :(得分:0)
您可以做到这一点。显示起来比解释要容易,但是如果不清楚,我会添加一个解释:
void add_or_divide_by_xor(unsigned int a, unsigned int b, unsigned short c,
unsigned long *add, unsigned double *divide) {
unsigned int xor = a ^ b;
if (add != NULL) {
*add = xor + c;
}
if (divide != NULL) {
*divide = (double)xor / (double)c;
}
}
致电:
unsigned long add;
unsigned double divide;
add_or_divide_by_xor(5, 17, 4, &add, NULL);
add_or_divide_by_xor(17, 6, 4, NULL, ÷);
答案 4 :(得分:0)
根据您的平台,double
可能是long
的超集。您应该已经知道这是否正确(因为您知道算法的作用以及它们可能的输出值是什么);如果您不这样做,请考虑以下事项:
double
可以精确表示最多2个 53 的整数long
是32位或64位类型因此,如果您的long
值为32位,则始终可以从函数中返回double
,并在需要时将其转换为函数外的long
。
答案 5 :(得分:0)
您可以尝试这样的事情。
#include <stdio.h>
void* func1(int key){
static double interest;
static long term;
static long principle;
//your common code to modify values of interest, term and principle
//
//Let us give them some dummy values for demonstration
interest = 34.29347;
term = 5843535;
principle = 7397930;
//conditions
if(key == 1){
return &interest;
}
else if(key == 2){
return &term;
}else if(key == 3){
return &principle;
}else printf("%s\n","error!!");
}
int main()
{
printf("%f\n",*(double*)func1(1));
printf("%ld\n",*(long*)func1(2));
printf("%ld\n",*(long*)func1(3));
func1(4);
return 0;
}
输出
34.293470
5843535
7397930
错误!