为什么在for循环的初始语句中不能声明多个变量?

时间:2019-12-29 11:25:51

标签: c cs50

在将a与一个变量一起使用时,像这里的i = 0一样,将其声明为0

但是当我们使用两个变量,就像我添加n = strlen以使代码更有效时,则未声明i = 0,而是使用逗号并声明了n = strlen(s)。为什么我们不能使用'i = 0;'就像之前的代码一样?

编辑:cs50.h是哈佛制造的沙箱cs50的一部分。

#include <stdio.h>
#include <string.h>

int main(void)
{
    string s = get_string("Input:  ");
    printf("Output: ");
    for (int i = 0; i < strlen(s); i++)
    {
        printf("%c\n", s[i]);
    }
}
#include <cs50.h>
#include <stdio.h>
#include <string.h>

int main(void)
{
    string s = get_string("Input: ");
    printf("Output:\n");
    for (int i = 0, n = strlen(s); i < n; i++)
    {
        printf("%c\n", s[i]);
    }
}

2 个答案:

答案 0 :(得分:3)

不确定我是否理解这个问题(尽管我喜欢)。您的两个代码段都起作用,不是吗?请注意,我们不知道cs50.h中包含什么,但是我尝试对其进行编译,并且它可以工作(编译和运行)。

#include <stdio.h>
#include <string.h>

int main(void) {
  char *s = "Hello world!";
  printf("Output:\n");
  for (int i = 0, n = strlen(s); i < n; i++) {
    printf("%c\n", s[i]);
  }
}

这里可能有两件事相关; -for的工作方式以及 -变量声明/初始化的工作方式。

您可以这样考虑forfor(AAA; BBB; CCC) DDD;

相同
{ // Important!
  AAA;
  while(BBB) {
    {
      DDD;
    }
    CCC;
  }
} // Important!

// Important!花括号很重要,因为for引入了一个新的作用域,即infor循环的外部/之后将无法访问。

另一件事是声明/初始化。所以

int i = 0, n = strlen(s);

是两个变量的初始化:in。我不确定100%正确的词汇和规则(您可以参考标准),但是想法是声明看起来像: TYPE VAR1, VAR2, ..., VARn VARx是声明的变量名,或者是“赋值”,在这种情况下,它是初始化。

UPDATE / PART2: 通常我将如何执行此操作:

const int len = strlen(s);
// Good practice to declare const what every you know wont change
for(int i = 0; i < len; i++) {
  // whatever
}

但是,如果可以使令人困惑的昏迷/分号保持一致,并且既然分号是必须的,那么让我们尝试将所有内容都设为分号,我已经尝试过了:

for ({int i = 0; int n = strlen(s); }; i < n; i++) {
  // what ever
}

这没有编译,但是也没有意义,因为如果可以的话,i和{{1} }将在小块中声明,并且在其他任何地方都无法访问,即在n中将无法访问。因此,要使它们可访问,我们可以尝试以下方法:

i < n

现在,如果上述int i, n; for ({i = 0; n = strlen(s); }; i < n; i++) { printf("%c\n", s[i]); } -for的对等度为100%是正确的,则此方法本来应该有效,但是显然while不必是单个语句(通常声明),并且不能是一个块,即AAA。确切的编译器错误:

{...}

但是您可以看到它已经非常丑陋了……所以,是的,您需要使用cc hola.c -o hola hola.c: In function ‘main’: hola.c:8:8: error: expected expression before ‘{’ token 8 | for ({ | ^ make: *** [<builtin>: hola] Error 1 来分隔声明/初始化,并使用,来终止它。

答案 1 :(得分:3)

根据C标准 ISO / IEC 9899:TC3 / ISO / IEC 9899 / C11 SELECT x.InventoryTransTempID ,x.InventoryTransID FROM ( SELECT * FROM InventoryTransTemp UNION ALL SELECT * FROM InventoryTrans ) x 语句的语法描述§ (6.8.5)迭代语句,有2种不同的形式:

  

for

     

for ( expression_opt ; expression_opt ; expression_opt ) statement

请注意,在第一种形式中,我们在第一个位置有一个表达式,尽管它是可选的,因为所有3个字段,并且语句形式的所有3个部分都用for (declaration expression_opt ; expression_opt ) statement分号分隔,用作定界符

在第二种形式中,我们可以看到括号中的第一个元素是声明而不是表达式,并且我们还注意到,没有用分号定界。这是因为声明本身总是以分号终止。

段落(6.7)声明描述了声明的语法:

  

;

如您所见,declaration-specifiers init-declarator-list_opt ;总是以分号结尾。

一个声明当然可以采用多个声明的形式,如您的:

declaration

所以您使用的是第二种形式,其中用分号分隔了声明(不是for (int i = 0, n = strlen(s); i < n; i++) { printf("%c\n", s[i]); } 的第一部分)

使用多个分号只是一个语法错误。