在 C99 中哪里可以合法地声明变量?

发布于 2024-08-23 09:27:08 字数 795 浏览 5 评论 0原文

当我第一次接触 CI 时,他们告诉我要始终在函数顶部声明变量。现在我已经掌握了这门语言,我将重点放在编码风格上,特别是限制变量的范围。我已经了解了限制范围的好处,并且遇到了一个有趣的例子。显然,C99 允许你这样做...

for (int i = 0; i < 10; i++)
{
   puts("hello");
}

我原以为变量范围受到最内层周围大括号{ }的限制,但在上面的示例中int i 的范围似乎受到 for 循环的花括号的限制,即使它是在花括号之外声明的。

我尝试使用 fgets() 扩展上面的示例来执行我​​认为类似的操作,但这两个都给了我一个语法错误。

fgets(char fpath[80], 80, stdin); *参见注释**

fgets(char* fpath = malloc(80), 80, stdin);

所以,在 C99 中声明变量到底在哪里是合法的? for 循环示例是该规则的例外吗?这是否也适用于 whiledo while 循环?

*注意**:我什至不确定这在语法上是否正确,即使我可以在那里声明 char 数组,因为 fgets() 正在寻找指针to char 而不是指向 char 数组 80 的指针。这就是我尝试 malloc() 版本的原因。

When I was first introduced to C I was told to always declare my variables at the top of the function. Now that I have a strong grasp of the language I am focusing my efforts on coding style, particularly limiting the scope of my variables. I have read about the benefits to limiting the scope and I came across an interesting example. Apparently, C99 allows you to do this...

for (int i = 0; i < 10; i++)
{
   puts("hello");
}

I had thought that a variables scope was limited by the inner-most surrounding curly braces { }, but in the above example int i appears to be limited in scope by the curly braces of the for-loop even though it is declared outside of them.

I tried to extend the above example with fgets() to do what I thought was something similar but both of these gave me a syntax error.

fgets(char fpath[80], 80, stdin); *See Note**

fgets(char* fpath = malloc(80), 80, stdin);

So, just where exactly is it legal to declare variables in C99? Was the for-loop example an exception to the rule? Does this apply to while and do while loops as well?

*Note**: I'm not even sure this would be syntactically correct even if I could declare the char array there since fgets() is looking for pointer to char not pointer to array 80 of char. This is why I tried the malloc() version.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

花期渐远 2024-08-30 09:27:08

在 C99 中,您可以在需要的地方声明变量,就像 C++ 允许您这样做一样。

void somefunc(char *arg)
{
    char *ptr = "xyz";
    if (strcmp(arg, ptr) == 0)
    {
        int abc = 0;    /* Always could declare variables at a block start */

        somefunc(arg, &ptr, &abc);

        int def = another_func(abc, arg);   /* New in C99 */
        ...other code using def, presumably...
    }
}
  • 您可以在“for”循环的控制部分声明变量:

     for (int x = 0; x < 10; x++) /* C99 中的新功能 */
    
  • 您不能在“while”循环或“if”语句的控制部分声明变量。

  • 不能在函数调用中声明变量。

  • 显然,您可以(并且始终可以)在任何循环或“if”语句之后在块中声明变量。

C99标准说:

6.8.5.3 for 语句

声明

for ( clause-1 ; expression-2 ; expression-3 ) statement

的行为如下:表达式 expression-2 是控制表达式,即
在每次执行循环体之前进行评估。表达式表达式3是
每次执行循环体后计算为 void 表达式。如果子句 1 是
声明,它声明的任何变量的范围是声明的其余部分,并且
整个循环,包括其他两个表达式;按执行顺序到达
在第一次计算控制表达式之前。如果子句 1 是一个表达式,则它是
在第一次计算控制表达式之前,将其计算为 void 表达式。

In C99, you can declare your variables where you need them, just like C++ allows you to do that.

void somefunc(char *arg)
{
    char *ptr = "xyz";
    if (strcmp(arg, ptr) == 0)
    {
        int abc = 0;    /* Always could declare variables at a block start */

        somefunc(arg, &ptr, &abc);

        int def = another_func(abc, arg);   /* New in C99 */
        ...other code using def, presumably...
    }
}
  • You can declare a variable in the control part of a 'for' loop:

      for (int x = 0; x < 10; x++)    /* New in C99 */
    
  • You cannot declare a variable in the control part of a 'while' loop or an 'if' statement.

  • You cannot declare a variable in a function call.

  • Obviously, you can (and always could) declare variables in the block after any loop or an 'if' statement.

The C99 standard says:

6.8.5.3 The for statement

The statement

for ( clause-1 ; expression-2 ; expression-3 ) statement

behaves as follows: The expression expression-2 is the controlling expression that is
evaluated before each execution of the loop body. The expression expression-3 is
evaluated as a void expression after each execution of the loop body. If clause-1 is a
declaration, the scope of any variables it declares is the remainder of the declaration and
the entire loop, including the other two expressions; it is reached in the order of execution
before the first evaluation of the controlling expression. If clause-1 is an expression, it is
evaluated as a void expression before the first evaluation of the controlling expression.

护你周全 2024-08-30 09:27:08

我要注意的第一件事是,您不应该混淆

for (int i = 0; i < 10; i++) {
    puts("hello");
}

fgets(char* fpath = malloc(80), 80, stdin);

第一个是控制结构,而第二个是函数调用。控制结构以与函数调用非常不同的方式评估其 parens() 内的文本。

第二件事是......我不明白你想说什么:

如果您尝试在 for 循环体中使用 i,编译器会立即给出错误。

您为 for 循环列出的代码是 C 中非常常见的结构,并且变量“i”确实应该在 for 循环体内可用。即,以下内容应该有效:

int n = 0;
for (int i = 0; i < 10; i++) {
    n += i;
}

我是否误读了您所说的内容?

The first thing I'd note is that you shouldn't confuse

for (int i = 0; i < 10; i++) {
    puts("hello");
}

and

fgets(char* fpath = malloc(80), 80, stdin);

The first is a control structure while the second is a function call. The control structure evaluates the text inside it's parens() in a very different way from how a function call does.

The second thing is... I don't understand what you're trying to say by:

the compiler will promptly give you an error if you try to use i inside the for-loop body.

The code you listed for the for loop is a very common structure in C and the variable "i" should, indeed, be available inside the for loop body. Ie, the following should work:

int n = 0;
for (int i = 0; i < 10; i++) {
    n += i;
}

Am I misreading what you're saying?

初雪 2024-08-30 09:27:08

关于 for/fgets 混淆的底线是,虽然“封闭大括号控制范围”在大多数情况下是 C 中的正确规则,但还有另一条关于C99 中的作用域(借自 C++)表示在控制结构的序言中声明的变量(即 forwhileif)位于结构体的范围内(并且不在结构体之外的范围内)。

The bottom line with respect to your for/fgets confusion is that while "enclosing braces control scope" is the correct rule in C most of the time, there is another rule regarding scope in C99 (borrowed from C++) that says that a variable declared in the prologue of a control structure (i.e. for, while, if) is in scope in the body of the structure (and is not in scope outside the body).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文