定义空索引的最佳实践

时间:2013-09-14 00:37:33

标签: c++ c

我经常要编写将索引返回到数组的方法,这样就有可能找不到索引。我使用了三种基本方法:

  1. 将“空索引”值定义为负数(即,如果是 函数返回-1表示没有有效的索引返回
  2. 将“空索引”值定义为索引类型的最大值 (即如果索引是int,函数返回INT_MAX。)
  3. 传入一个指向返回的布尔值的指针 value是一个有效的索引(即传入指向布尔值的指针) 如果返回值是数组中的实际索引,则设置为true, 否则返回值为false)
  4. 我已经看到了所有这些方法的使用(尽管第三种选择似乎要少得多)。关于哪一项更可取(或者有第四种选择),是否有任何共识?

7 个答案:

答案 0 :(得分:3)

如有疑问:复制STL。例如std :: string :: npos,std :: vector :: end()等等。我想这将是你列表中的选项2。

像STL容器一样工作的容器也可以重用STL算法。

答案 1 :(得分:2)

#4。返回最近的较低索引的负数,即插入点。首先添加1,这样您就不必担心-0了。因此,任何否定结果都是'找不到',如果您在下一次操作中需要它,可以从中获取插入点。

答案 2 :(得分:1)

由于数组的索引通常是非负整数,因此返回负整数(例如,-1)以指示无效索引是可接受的方法。 / p>

答案 3 :(得分:1)

另一种在某些情况下有用的技术是使用1 .. N作为索引,并使NULL索引为0,因此您可以从第0个元素中提取某种默认值,或者累积到第0个元素中。在你的调用者中,你实际上不必检查你是否得到了NULL索引。

答案 4 :(得分:1)

没有人记得errno吗?我认为这是一个合理的解决方案。如果函数返回某个值,例如0(因为我们讨论的是数组索引)和errno == ERANGE,则返回一个无效的索引:

idx =foo.bar(baz);
if (!idx && errno == ERANGE) {
    // problem
}

可以说,您甚至不需要设置值,因为无论如何都需要检查errno

这样,您就可以充分利用该阵列。另一种方法是这种方法的变体,它已经是布尔值方法的变体:使用类本地错误变量,类似于设置badbit,failbit和/或eofbit的I / O错误。如果你没有使用课程,那么我会说errno /布尔方法是最好的。

答案 5 :(得分:1)

在大多数情况下,我会说#4:

  • 返回一个状态代码,指示操作是成功还是失败,并通过引用返回索引(使用引用或指针,具体取决于您的C版本)。

#4优于#3的优点是:

  1. 当您需要函数返回多个值时,只需为需要返回的值添加更多参考参数。

  2. 如果您的C函数始终在程序中的任何位置返回状态代码,那么您始终知道返回代码是状态。

  3. 它不会占用函数返回的返回索引(或其他数据类型)的值空间,并避免幻数常量。 (例如,如果您以摄氏度返回温度值,则0和-1都有效,正如任何正数一样。您可能会返回-274为无效,但这有点迟钝。)

  4. 返回代码可以提供失败或成功的原因,而不仅仅是布尔成功或失败,而且非常简单。

  5. OTOH,如果你的程序非常小,并且你不介意一些神奇的常数,那么#1或#2在道德上是相同的,并且可以比#3或#4更少输入。与#1相比,#2有一些优势:

    1. 如其他答案中所述,有符号的int返回值只能表示unsigned int可以表示的数字的一半。

    2. 如果要与sizeof(array),std :: vector :: string(size_t)进行比较,它可以避免有符号和无符号比较问题。大多数情况下,问题是编译器警告被忽略(导致人们通常忽略它们时不会发出警告)或某人用演员表修复它,希望在分析之后确保演员表真的有效。

    3. 我个人使用过#1,#2和#4,并发现#4最佳。我倾向于默认为#4,特别是在代码中,故障是常见的并且需要处理。如果代码较小并且您正在调用许多返回一个并且不会失败的例程(例如,图像处理例程),则1或2通常效果最佳。

答案 6 :(得分:0)

最好的“空索引”是与空模型匹配的索引。这是一个根本不存在的索引。

要将其关闭,通常会抛出异常。