【问题标题】:Boolean Functions in C "control may reach end of non-void function" errorC中的布尔函数“控件可能到达非无效函数的结尾”错误
【发布时间】:2020-10-31 13:58:22
【问题描述】:

编译代码时,我总是在布尔函数上得到“控制可能到达非空函数的结尾”,但不知道是什么原因造成的。

这是代码,谢谢

#include <stdio.h>
#include <math.h>
#include <cs50.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>

bool digit_validation (string s);

int main (int argc, string argv[])
{
    
    if((argc == 2) && (digit_validation(argv[1]) == true))
    {
        int key = atoi(argv[1]);
        printf("%i\n", key);
    }
    
    else
    {
        printf("Usage: ./caesar key\n");
    }

}

bool digit_validation (string s)
{
for (int i = 0, lenght = strlen (s); i < lenght; i++ )
{
    if(isdigit(s[i]))
    {
        return true;
        break;
    }
    
    else
    {
        return false;
    }
}
}

【问题讨论】:

  • 你的main 函数return 有什么作用吗?
  • 如果根本没有输入for,你的函数将不会返回值(长度为0)。
  • 我对你的for 语句感到特别困惑,其中有一个if,它们都退出了。如果您要在第一次迭代中确定保释,为什么还要循环?
  • s 为空字符串时,您的digit_validation 函数将不会执行return 语句。
  • PSA:这是length 而不是lenght

标签: c function boolean cs50


【解决方案1】:

编译器警告说,函数digit_validation 可能最终会从函数中“脱落”——而不返回任何值。如果调用者使用该值,就像在您的代码中发生的那样,它会导致 undefined behaviour

例如,如果你传递一个空字符串"",那么length为0,则根本不进入for循环。

digit_validation还有其他问题。

  • 如果你传递一个空指针,strlen 就会有问题。

  • 它实际上并没有验证 所有 个字符都是数字;一旦找到第一个数字,函数就返回而不检查其余数字。

它可以固定为:

bool digit_validation (string s)
{
    if (!s || !s[0]) return false;

    for (size_t i = 0; s[i]; ++i) {
        if(!isdigit((unsigned char)s[i])) return false;
    }
  
    return true;
}

几点:

  • isdigit(以及所有一般的 ctype 函数)的参数需要强制转换为 unsigned char 以避免 undefined behaviour in case of negative values

  • 鉴于s 是一个字符串,您可以避免使用strlen 来计算长度,而是使用前哨空字节(毕竟strlen 将检查相同)。

【讨论】:

  • 谢谢,这很有帮助。知道如何验证所有字符都是数字吗?
  • 更新了如何解决函数中的这些问题。
【解决方案2】:

我认为您的第二个功能有点混乱,但很容易解决:

bool digit_validation(string s) {
  size_t length = strlen(s);

  for (size_t i = 0; i < length; i++) {
    if (isdigit(s[i])) {
      return true;
    }
  }        

  return false;
}

正如其他人所观察到的,您的循环可能已被跳过,这将导致函数结束而不返回任何内容。作为一般规则,您希望构建代码以使退出点显而易见,而您的原始代码并非如此。

这还没有检测到“所有数字”,你仍然需要通过反转逻辑来解决这个问题:

bool digit_validation(string s) {
  size_t length = strlen(s);

  if (!length) {
    return false;
  }

  for (size_t i = 0; i < length; i++) {
    if (!isdigit(s[i])) {
      return false;
    }
  }        

  return true;
}

【讨论】:

  • 这是 C,不是 C++。另外,您为什么将int 用于i 而将size_t 用于length
  • @MikeCAT 我真的,真的,真的鄙视 CS50。
  • 另外for 中的, 应该是;
  • @MikeCAT 已修复。
  • 从代码的上下文来看,digit_validation 应该返回 true,但前提是 s 是一个包含一个或多个数字且只有数字的字符串。如果 s 包含数字,即使它包含非数字,此答案中的代码也会返回 true。
猜你喜欢
  • 1970-01-01
  • 2016-06-21
  • 1970-01-01
  • 2014-04-20
  • 1970-01-01
  • 1970-01-01
  • 2013-10-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多