hackerrank编译器出错

时间:2016-06-07 12:47:46

标签: c

我已经在hackerrank问题上写了这个函数。

int lonelyInteger (int a[], int n) {
    int i, b[99] = {0};
    for (i = 0; i < n; i ++) {
        b[a[i]] ++;
    }
    for (i = 0; i < 100; i ++) {
        if (b[i] == 1) {
            return i;
        }
    }
}

但是我收到了这个编译错误。

solution.c: In function 'lonelyInteger':
solution.c:13:1: error: control reaches end of non-void function [-Werror=return-type]
 }
 ^

我使用了逻辑,因此它必须在i = 0到i = 99之间返回。但是它的编译器给出了错误。所以我的问题是有必要在最后使用return语句(或者是一个好的做法)?

PS - 我在最后写了一个随机的return语句,它运行正常。

PPS - 如果您正在考虑b [i]是否永远不等于1,那么事实并非如此。根据问题,对于某些i = {0,1,2 ......,98},它必须等于1。

3 个答案:

答案 0 :(得分:1)

编译器无法知道您的return语句将执行。 您可以添加包含某种错误代码的默认返回值,或者断言;如果你确定该函数应该在

之前返回

答案 1 :(得分:1)

未在所有程序控制路径上定义显式return

您的编译器警告您:未从非void函数返回值的行为是 undefined 且编译器不够聪明(或者它不可能要知道程序控制将一直运行到函数的末尾。

代替冗余的return,您可以使用assert语句。一个好的编译器应该不显示警告。

答案 2 :(得分:1)

您声明b有99个元素,这意味着它们的编号从0到 98 ,而不是99;你的第二个循环冒险跑掉该阵列的边缘。您需要声明b包含100个元素从0到99循环。

避免使用魔法数字;为数组大小和循环计数器使用符号常量:

#define RANGE_MAX 100
...
int b[RANGE_MAX] = {0};

您可以按如下方式重构循环;

for ( i = 0; i < RANGE_MAX && b[i] != 1; i++ )
  ; // empty loop body

return i;

这会将return语句移到循环体之外,从而避免错误。

您应该添加一个检查,每个a[i]的范围是0到99,如下所示:

for ( i = 0; i < n; i++ )
{
  assert( a[i] >= 0 && a[i] < RANGE_MAX );
  b[a[i]]++;
}

问题是,越界数组访问不能保证崩溃,或以任何其他可预测的方式运行;您的代码可能会彻底崩溃,可能会导致输出错误,可能会导致状态错误导致其在执行后期崩溃,或者可能会在没有问题的情况下运行完成。断言将允许您的代码在任何a[i]超出范围的情况下以一致,明确定义的方式运行。