【问题标题】:Returning void from a double function?从双重函数返回 void?
【发布时间】:2013-04-30 09:35:36
【问题描述】:

我有一个双精度函数,通常返回变量的新值,但有时我不想更改变量,我想通过返回一个特殊值来表示这一点,例如 void。这可能吗?

例如:

double GetNewValue(int feature) {
    switch( feature ) {
        case TYPE1:
            return void; // or maybe use return; here?
        case TYPE2:
            return 2.343;
        default:
            return featureDefaultValue;
    }
}

PS:我知道我可以使用 NaN,但我已经将它用作具有其他含义的有效值(目前还没有可用的数字)。

/编辑:谢谢大家的回答,这3个答案都适用于我的问题,并且都同样有效。我现在正在努力选择我要使用哪一个(我会接受哪个,但我希望我能全部接受!)。

【问题讨论】:

  • 您可以使用NaNvoid 没有意义,因为它类似于类型,而不是值。
  • 但是我该如何检查呢?是否可以影响变量并检查返回值是否为none?
  • 顺便说一句。有许多不同的 NaN。原则上,您可以使用不同的 NaN 来表示不同的含义,但这可能是个坏主意。
  • 关于你的后记,“我知道我可以使用 NaN,但我已经将它用作具有另一种含义的有效值(还没有可用的数字”,你知道有 几个 NaN?您只需要使用与用于“尚无可用编号”的那个不同的一个。Google“NaN 有效负载”以获取详细信息。
  • @CodesInChaos 我认为如果您打算进行涉及其中几个的计算,那么使用不同的 NaN 只是一个坏主意。然后,您可能会得到任何原始 NaN 作为结果(AFAIK 每个 IEEE 754 操作都被定义为返回它作为参数接收的一个 NaN,如果它的某些参数是 NaN)。使用几个 NaN 作为占位符很好。

标签: c function return void


【解决方案1】:

在这种情况下,您需要从一个函数中返回两件东西,而不是一件。这样做的一种常见方法是获取一个指向返回值的指针,并返回一个是/否标志来指示实际 double 的有效性:

int GetNewValue(double *res, int feature) {
    switch( feature ) {
    case TYPE1:
        return 0; // no change to res
    case TYPE2:
        *res = 2.343;
        return 1;
    default:
        *res = featureDefaultValue;
        return 1;
}

现在不要这样做

double res = GetNewValue(myFeature);

您的函数的用户需要这样做:

double res;
if (GetNewValue(&res, myFeature)) {
    // use res here - it's valid
} else {
    // do not use res here - it's not been set
}

【讨论】:

  • 我接受这个答案,因为在我的情况下,我已经分离了 GetNewValue() 函数和 SetNewValue() 函数(后者仅在 GetNewValue() 返回时修改值),所以它更干净使用这种方法。我唯一的遗憾是其他用户必须始终添加适当的返回语句(我想最大限度地减少复杂性),但这是此实现的一个小缺点,并且比在我的情况下使用指针更干净。
【解决方案2】:

一种方法是将结果变量作为指针传递:

void AssignNewValue(int feature, double* result)
{
    switch( feature ) {
    case TYPE1:
        return;
    case TYPE2:
        *result = 2.343;
        break;
    default:
        *result = featureDefaultValue;
        break;
    }
}

像这样使用:

double featureValue = 42.0;

/* ... */

AssignNewValue(feature, &featureValue);

【讨论】:

  • 这与只返回一个 double 有何不同?
  • 我认为我没有把它作为“读者练习”......但是如果调用者通过TYPE1,那么featureValue 的值将被保留。因此,这与仅返回双精度值不同。
  • 是的,它确实保留了 *result 的旧值。但如果没有结果代码,它根本不会告诉调用者发生了什么。
  • 确实没有显式信号,但对于我的应用程序,我只需要一个隐式信号。这实际上是一个非常好的答案。不知道选哪一个!
  • @bobobobo:我对调用代码做出了其他答案没有做出的假设。
【解决方案3】:

听起来您想要一个“可选”返回参数。您似乎(并且正确地)不想使用 0.0 作为“无价值”结果,因为这意味着 0.0 不能用于实际值。

您有时看到的 2 个很好的解决方案是使用“结果代码”,或使用 指针 作为返回结果。 (指针更复杂)。我先从#1开始:

1。结果代码

// definitions for result codes
#define FAIL 0
#define OK 1

int GetNewValue(int feature, double *result) {
    switch( feature ) {
        case TYPE1:
            *result = 0.0 ;
            return FAIL ; // caller of the function should recognize
                          // the call "failed"
        case TYPE2:
            *result = 200.0 ;
            return OK ;
        default:
            *result = 47.0 ;
            return OK;
    }
}

// use:
double feature ;
int result = GetNewValue( 5, &feature ) ;
if( result == OK )
{
    // do something with "feature"
}

2。使用指针

double* GetNewValue(int feature) {
    switch( feature ) {
        case TYPE1:
            return NULL ; // NO POINTER means FAIL
        case TYPE2:
            return new double(200) ;
        default:
            return new double( 47 ) ;
    }
}

// use:
double* result = GetNewValue( 5 ) ;
if( result != NULL )
{
    // result had a value, so you can use it
}

带指针的问题是你需要记住deleteresult

delete result ; // when done with pointer that was created
                // with `new`, you must `delete` it after
                // otherwise you'll get a memory leak

【讨论】:

  • 非常好的答案,尤其是使用指针的第二种方法,除了值之外,它不需要返回另一个值,但由于我当前项目的指导方针,我不能使用指针。但我会把这个方法保存在我的书中,谢谢!
猜你喜欢
  • 2016-08-28
  • 2015-01-24
  • 2015-01-12
  • 2023-01-28
  • 2012-02-18
  • 1970-01-01
  • 1970-01-01
  • 2011-03-26
  • 1970-01-01
相关资源
最近更新 更多