C-在函数中使用未声明的标识符。 CS50

时间:2018-08-05 22:13:11

标签: c function validation cs50

我正在重写CS50信用解决方案以使用功能。 定义readCardNumber()时偶然发现错误。

long long readCardNumber()
{
    do
    {
        long long result = get_long_long("Enter card number to verify: \n");
        if (result < 0)
        {
            printf("Retry: \n");
        }
    }
    while (result < 0);

    return result;
}

我正在使用CS50.h https://reference.cs50.net/cs50/get_long_long来获取号码。由于以下原因,我无法编译此解决方案:

error: use of undeclared identifier 'result'

有经验的人可以在这里解释什么问题吗?我确实在代码的开头声明了函数,并在函数中声明并初始化了结果。 验证该号码的更好方法是什么?

https://docs.cs50.net/2018/x/psets/1/credit/credit.html-我正在尝试重做的解决方案规范。

4 个答案:

答案 0 :(得分:7)

result变量在do...while块内声明。在包含while的条件的代码块外部不可见。

您需要将变量定义移出循环:

long long result;
do
{
    result = get_long_long("Enter card number to verify: \n");
    if (result < 0)
    {
        printf("Retry: \n");
    }
}
while (result < 0);

答案 1 :(得分:1)

这是范围的问题。在C语言中,范围由{}定义。变量在其声明的范围的末尾不再存在。 (好吧,静态变量不是,但是它们不可访问。除非您有指向它们的指针。)

您需要做的是将声明移到循环外。

但是,我确实要强调,在变量使用范围内声明变量是一种很好的做法。它大大降低了错误的风险。如果变量仅在循环内使用,则在循环内声明它。基本上与您除非有必要就不使用全局变量的原因相同。

答案 2 :(得分:1)

如果return result;超出范围,则执行result。但是您的代码包含冗余:您测试result < 0两次。我建议更改结构以避免这种情况,并具有解决原始问题的额外副作用:

long long readCardNumber(void)
{
    for (;;)
    {
        long long result = get_long_long("Enter card number to verify: \n");
        if (result >= 0)
             return result;

        printf("Retry: \n");
    }
}

答案 3 :(得分:1)

这是关于do/while语句的不便甚至是“不自然”的事情之一:您在循环体内声明的所有内容对于该语句的while部分中的条件将是不可见的。这些标识符的范围在}部分之前的while处结束。

这通常迫使用户在循环之前声明变量(一个或多个)

long long result;
do
{
  result = get_long_long("Enter card number to verify: \n");
  if (result < 0)
    printf("Retry: \n");
}
while (result < 0);

该解决方案要付出的代价

  1. result范围的不必要扩展,超出了周期
  2. 在声明时不再可能有意义地初始化变量

对于我们中的许多人来说,这太令人不愉快了,我们更愿意使用do/while(1)切换到break的方法来终止周期

do
{
  long long result = get_long_long("Enter card number to verify: \n");
  if (result >= 0)
    break;

  printf("Retry: \n");
}
while (1);

这显然也不完美。自己选择,哪种方法更适合您。

在后一种情况下,do/while(1)充当“惯用”方式来表示从中间退出的循环。为此,其他人可能更喜欢for (;;)while(1),从而完全避免了do/while的声明。