我可以在 do-while 语句的主体中声明 C 中的变量吗?

Can I declare variables in C in the body of do-while statement?

我刚刚开始我的编码之旅,我一直在使用 cs50 的 IDE。每次我在 do 函数的主体中声明一个整数时,当我尝试在 while 函数的主体中使用相同的整数时,我会收到使用未声明标识符的错误,这是不允许的吗?如果是,为什么会这样?

这里是代码供参考-

do{

   int n = get_int("Height: ");

  }

while(n < 1 || n > 8);

是的,你可以。您可以在任何代码块中定义它们,包括复杂语句。

请记住,这些变量的范围是它们在其中声明的块,因此在您的情况下是 do ... while() 循环。

从 C99 开始,您可以在任何作用域中声明自动变量,包括像您显示的那样的嵌套块作用域。

但是, 声明的变量存在于该范围内。在右大括号处...它消失了。

因此,您在 while 语句中收到 未声明的标识符 错误的原因是标识符在 } 之前停止存在 [= =11=].

供参考:

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 中,您必须在块作用域(通常是顶级函数作用域)的开头声明变量,在 { 开头之后但在任何其他语句之前。这不再是事实,但您可能仍会看到旧代码的旧样式。

do-while 语句的主体(子语句)构成一个块作用域。在此块范围内声明的所有内容的生命周期都受到块边界的限制(如果没有存储说明符 static)。但无论如何,这样的声明在块外是不可见的。所以在这个do while loop

中声明的变量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 An iteration statement is a block whose scope is a strict subset of the scope of its enclosing block. The loop body is also a block whose scope is a strict subset of the scope of the iteration statement.

注意:这个答案显示了一个模糊的结构。

如果您使用的是 GCC,请查看 this library。 你可以这样写:

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 !!!!
}

我以前遇到过这段代码。当函数超过 70 或 80 行(页面长度)时很难找到。
作为处理继承代码时对自己的个人提醒,我通常会快速扫描以查找未初始化的自动装置,这些在过去很常见,然后移动它们或给它们起更好的名字。