C - 在函数中使用未声明的标识符。 CS50
C - use of undeclared identifier in a function. 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 - 我正在尝试返工的解决方案规范。
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);
这是范围的问题。在 C 中,范围由 {
和 }
定义。变量在其声明范围的末尾不再存在。 (好吧,静态变量没有,但它们变得不可访问。除非你有指向它们的指针。)
您需要做的是将声明移到循环之外。
不过,我确实想强调,在使用范围内声明变量是一种非常好的做法。它显着降低了错误的风险。如果变量仅在循环内使用,则在循环内声明它。这与除非必要否则不应使用全局变量的原因基本相同。
当 result
超出范围时,您可以执行 return 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");
}
}
这是关于 do/while
语句的那些不方便甚至 "unnatural" 的事情之一:你在循环体中声明的所有内容对于 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);
此解决方案的代价是
-
result
范围的不必要扩展超出了循环
- 不再可能在声明时有意义地初始化变量
对于我们中的许多人来说,这太不愉快了,我们更愿意切换到 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)
作为一种 "idiomatic" 方式来表达从中间退出的循环。出于该目的,其他人可能更喜欢 for (;;)
或 while(1)
,从而完全避免 do/while
语句。
我正在重写我的 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 - 我正在尝试返工的解决方案规范。
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);
这是范围的问题。在 C 中,范围由 {
和 }
定义。变量在其声明范围的末尾不再存在。 (好吧,静态变量没有,但它们变得不可访问。除非你有指向它们的指针。)
您需要做的是将声明移到循环之外。
不过,我确实想强调,在使用范围内声明变量是一种非常好的做法。它显着降低了错误的风险。如果变量仅在循环内使用,则在循环内声明它。这与除非必要否则不应使用全局变量的原因基本相同。
当 result
超出范围时,您可以执行 return 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");
}
}
这是关于 do/while
语句的那些不方便甚至 "unnatural" 的事情之一:你在循环体中声明的所有内容对于 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);
此解决方案的代价是
-
result
范围的不必要扩展超出了循环 - 不再可能在声明时有意义地初始化变量
对于我们中的许多人来说,这太不愉快了,我们更愿意切换到 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)
作为一种 "idiomatic" 方式来表达从中间退出的循环。出于该目的,其他人可能更喜欢 for (;;)
或 while(1)
,从而完全避免 do/while
语句。