【问题标题】:What to do in C when there is no valid value to return?当没有有效值要返回时,在 C 中该怎么办?
【发布时间】:2017-02-12 12:21:59
【问题描述】:

我有一个由多个参数和唯一 ID 定义的元素数组,我创建了一个函数,该函数返回与某个唯一 ID 关联的元素,问题是如果输入了无效 ID(不是由数组存储),我的函数没有返回有效值。

我的问题是,如果函数不一定返回某些内容,我的代码将无法编译,有没有办法告诉编译器在这里可以这样做?

谢谢。

【问题讨论】:

  • 发布你的一些代码。
  • 代码示例会有所帮助...

标签: c function declaration


【解决方案1】:

有几种方法可以做到这一点。

最简单的方法是返回一个不在有效值范围内的值。

另一种方法是再声明一个参数,该参数是指向用作错误的变量的指针。或者返回错误值并将有效值作为参数声明为引用。

例如

int /* error */ f( T *valid_value );

另一种方法是返回一个包含两个值的结构,其中一个是报告失败或成功的布尔值。

【讨论】:

    【解决方案2】:

    您必须定义一个无效值,这样的值只是不属于一组有效值的值。

    例如:

    如果有效值为[0, inf),那么-1 是一个很好的无效值

    【讨论】:

    • 我对这种方法有点失望。因为它牺牲了大量的值来获得一个无效的值。我经常尝试使0 无效值,以及所有其他无符号整数(一定大小)的范围。
    • @StoryTeller 这种方法只有在有效值集确实有限且定义明确的情况下才有效。当然,还有其他方法,但这种方法很简单,因此很优雅。虽然,它肯定不会一直有效。此外,我相信它被用于许多重要的应用程序中,例如用于字符串终止的'\0' 和用于指针的NULL 是最广泛使用和标准化的。我可以继续,EOF ...但你明白了。
    【解决方案3】:

    我会返回一个指向元素的指针,而不是元素本身。比如这个。

    struct Element* find(struct Element* elements, int count, int id)
    {
       for(int i = 0; i < count; i++)
       {
          if(elements[i].id == id)
             return elements + i; //pointer to i'th element
       }
       return NULL; //if it makes it here return NULL since no element was found.
    } 
    

    然后你可以做这样的事情。

    struct Element* e = find(elements, m, 1234);
    if(e) //check and see if it is not null
    {
       //handle found case
    }
    else
    {
       //handle not found case
    }
    

    【讨论】:

    • 你的方法有问题,可以把NULL传给free(),但是不能把这个函数的返回值传给free()。这与我建议的几乎相同,但NULL 有它自己的用例。也许,一个具有无效成员和int element_is_valid(Element *) 函数的元素就可以了。此外,将* 附加到类型是一个坏主意,让我想把我的眼睛扯掉!
    • 我不相信“无法释放返回值”是一个有效的投诉。
    【解决方案4】:

    .....有没有办法告诉编译器在这里可以这样做?

    不,没有办法做到这一点。

    函数必须始终返回相同类型的值(即您在声明中给出的类型)或从不返回任何值(即声明为void foo(...))。

    在某些情况下您不能返回值,而在其他情况下则返回“无”。同样,在某些情况下不能返回整数,而在其他情况下不能返回结构。返回值在所有情况下都必须相同。

    一般的解决方法是引入一种方法来告诉调用者该函数未能找到请求的元素。如其他答案中所述,有多种方法可以做到这一点。选择哪种解决方案取决于您的代码和需求。

    我通常更喜欢该函数返回一个int,其中值零表示“失败”,非零表示“成功”。然后,我将使用指针“返回”该元素。喜欢这个伪代码:

    int foo(struct MyStruct *p, .....)
    {
         if (found.....)
         {
              *p = the_found_element;
              return 1;
         }
         return 0; 
     }
    
    
     struct MyStruct ms;
     if (foo(&ms, ....))
     {
         // okay - carry on using ms
         ...
     }
     else
     {
         // failure - don't use ms as it is invalid
         ... 
      }
    

    【讨论】:

      猜你喜欢
      • 2017-12-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-08-17
      • 2011-03-18
      相关资源
      最近更新 更多