我刚刚开始我的编码之旅,我一直在使用cs50的IDE。每次我在do函数的主体中声明一个整数时,当我尝试在while函数的主体中使用相同的整数时,我都会收到一个错误,因为我使用了未声明的indentifier,这是不允许的吗? 如果是,为什么?
下面是代码,供参考--------。
do{
int n = get_int("Height: ");
}
while(n < 1 || n > 8);
do-while语句的主体(子语句)形成一个块范围。所有在这个块作用域中声明的东西,其生命时间都受到块的限制(如果没有存储指定符static)。但是在任何情况下,这样的声明在块外都是不可见的。因此,在这个do while循环中声明的变量n
do{
int n = get_int("Height: ");
}
while(n < 1 || n > 8);
在循环的主体(子语句)之外是不存在的。
你必须在循环之前声明这个变量,比如说
int n = 0;
do{
n = get_int("Height: ");
} while(n < 1 || n > 8);
根据C标准(6.8.5 迭代语句),do-while语句的定义是这样的
do statement while ( expression ) ;
和
5 迭代语句是一个块,它的作用域是其包围块作用域的严格子集。循环体也是一个块,其作用域是迭代语句作用域的严格子集。
是的,你可以。你可以在任何代码块中定义它们,包括复杂语句。
请记住,这些变量的范围就是它们被声明的块,所以在你的例子中,do ... while()循环。
从C99开始,你可以在任何范围内声明自动变量,包括像你展示的嵌套块范围。
然而,声明的变量 只是 存在于该范围内。在收尾的支架上......它就消失了。
所以,你得到一个 未申报的标识符 误中 while
语句是,该标识符在以下时间点停止存在 }
之前 while
.
供参考。
void foo(int a) /* a will exist for the entire body of the function */
{
int b = 2 * a; /* so will b */
/* c is introduced at the start of the for statement ... */
for (int c = a; c < b; ++c)
{
int d = c; /* d is initialized and destroyed on each iteration */
} /* ... but c lasts until the end of the whole for statement,
which is here */
do
{ /* d will be initialized on every iteration */
int d = bar(); /* just like the (unrelated) d in our for loop above */
} /* and disappear at the end of each iteration */
while (d != a); /* ERROR - d doesn't exist here */
} /* a and b finally go out of scope */
在C89 - 99中,你必须在块作用域(通常是顶层函数作用域)的开头声明变量,在开场白之后 {
但在任何其他语句之前。现在已经不是这样了,但你可能还能看到老式的代码。
注意:这个答案显示了一个晦涩的结构。这个答案显示的是一个晦涩的结构。
如果你正在使用GCC,请查看 本馆.你可以写这样的东西。
do(int n){
n = get_int("Height: ");
}
while(n < 1 || n > 8);
前面给出的答案都是好的 但你可能已经注意到了一个值得注意的问题... 现在仍然有很多代码使用C89和之前的惯例, 随后被添加到现代项目中. 所以要注意以下几点。
void my_old_function(int val)
{
/* define old C89 variables, often including i,j, or k, usually unitililized. */
int i;
for (i=0; i<val; i++)
{
/* our legacy code */
}
// some modern edit in C99 or after
do {
int i = 0;
// more new code
i++;
} while(i < val); // not what you think it is !!!!
}
我以前也遇到过这样的代码 当函数超过那七八十行(页面长度)的时候,疯狂的难找。作为对自己的个人提醒,在处理继承代码时,我通常会快速扫描寻找未初始化的自动机,这在以前是很常见的,然后把它们移走或者给它们取更好的名字。