2016-06-07 59 views
-8

我在hackerrank问题上写过这个函数。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] 
} 
^ 

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

PS - 我在最后写了一个随机返回语句,它工作正常。

PPS - 如果你在考虑如果b [i]从不等于1,那就不是真的。根据问题,对于某些i = {0,1,2 ...,98},它必须等于1。

+0

事后编辑仍在研究中,但不在现场。无论如何,你的代码有其他未定义的行为。获取笔和纸并手工处理您的循环(或在调试器中单步执行)。然后观看'b'的索引以及您分配了多少元素。 – Olaf

+0

为什么我的问题被低估?我有问题吗? –

+0

https://www.hackerrank.com/challenges/lonely-integer –

回答

1

明确的return未在所有程序控制路径上定义。

你的编译器警告你这一点:不光是来自非void函数返回值的行为是不确定和编译器是不够聪明(或者它不可能为它知道)程序控制将永远跑到你的功能的最后。

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

+0

你能告诉我如何使用assert吗?我的意思是语法。 –

+1

请参见http://www.tutorialspoint.com/c_standard_library/c_macro_assert.htm – Bathsheba

+0

一个常量'true'断言应该导致消除条件并且仅仅离开'abort'调用。根据标准(7.22.4.1),该函数必须是'_Noreturn'。 – Olaf

1

编译器没有办法知道你的return语句会执行。 你也许可以添加一个包含某种错误代码或断言的默认返回值;如果您确定函数应在返回之前返回

1

您声明b拥有99个元素,这意味着它们从0索引到而非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]超出范围的情况下,断言将允许您的代码以一致的,明确定义的方式运行。

+0

抱歉给您带来不便。看到我的新价值 –