为什么我不能在 for 循环的初始语句中声明多个变量?
Why can't I declare more than one variable in a for loop's initial statement?
当 a 与一个变量一起使用时,我们将其声明为 0,因为 i=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]);
}
}
不确定我是否理解这个问题(虽然我喜欢它)。您的两个代码片段都有效,不是吗?请注意,我们不知道 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
的工作原理和
- 变量 declaration/initialization 是如何工作的。
你可以这样想for
:
for(AAA; BBB; CCC) DDD;
与
相同
{ // Important!
AAA;
while(BBB) {
{
DDD;
}
CCC;
}
} // Important!
// Important!
大括号很重要,因为 for 引入了一个新的作用域,即 i
和 n
将无法访问 outside/after for
循环.
另一件事是declaration/initialization。所以
int i = 0, n = strlen(s);
是两个变量的初始化:i
、n
。我不是 100% 确定正确的词汇和规则(你可以参考标准),但我的想法是声明看起来像:
TYPE VAR1, VAR2, ..., VARn
其中 VARx
是声明的变量名,或者 "assignment" 在这种情况下它是一个初始化。
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
}
但是,如果可以使令人困惑的 coma/semicolon 保持一致,并且由于分号是 必须的 让我们尝试使所有内容都成为分号,我试过这个:
for ({int i = 0; int n = strlen(s); }; i < n; i++) {
// what ever
}
这没有编译,但它也没有意义,因为如果这会有 "worked"(在某种意义上我认为我可以但实际上不能),i
和n
将在小块中声明,并且在其他任何地方都无法访问,即在 i < n
中将无法访问。因此,为了使它们易于访问,我们可以尝试这样做:
int i, n;
for ({i = 0; n = strlen(s); }; i < n; i++) {
printf("%c\n", s[i]);
}
现在,如果上述 for
-while
等价性 100% 正确,那么这应该有效,但显然 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
但是正如你所看到的,它已经非常丑陋了......所以是的,你需要使用 ,
来分隔 declarations/initializations 和 ;
来终止它.
来自C标准ISO/IEC 9899:TC3 / ISO/IEC 9899/C11,语法for
语句的描述,§(6.8.5) 迭代语句,有 2 种不同的形式:
for ( expression_opt ; expression_opt ; expression_opt ) statement
for (declaration expression_opt ; expression_opt ) statement
请注意,在第一种形式中,我们在第一个位置有一个表达式,尽管它作为所有 3 个字段都是可选的,并且语句形式的所有 3 个部分都由 ;
分号分隔,用作一个分隔符。
在第二种形式中,我们可以看到括号中的第一个元素是声明而不是表达式,我们还可以注意到没有分号分隔它。这是因为 声明本身总是以分号结束 .
段落(6.7)声明描述了声明的语法:
declaration-specifiers init-declarator-list_opt ;
如您所见,declaration
总是以分号结尾。
声明当然可以采用多个声明的形式,如您的初始化:
for (int i = 0, n = strlen(s); i < n; i++)
{
printf("%c\n", s[i]);
}
所以 您使用的是第二种形式,其中分号分隔声明(不是 for
的第一部分)。
使用多个分号只是语法错误。
当 a 与一个变量一起使用时,我们将其声明为 0,因为 i=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]);
}
}
不确定我是否理解这个问题(虽然我喜欢它)。您的两个代码片段都有效,不是吗?请注意,我们不知道 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
的工作原理和
- 变量 declaration/initialization 是如何工作的。
你可以这样想for
:
for(AAA; BBB; CCC) DDD;
与
{ // Important!
AAA;
while(BBB) {
{
DDD;
}
CCC;
}
} // Important!
// Important!
大括号很重要,因为 for 引入了一个新的作用域,即 i
和 n
将无法访问 outside/after for
循环.
另一件事是declaration/initialization。所以
int i = 0, n = strlen(s);
是两个变量的初始化:i
、n
。我不是 100% 确定正确的词汇和规则(你可以参考标准),但我的想法是声明看起来像:
TYPE VAR1, VAR2, ..., VARn
其中 VARx
是声明的变量名,或者 "assignment" 在这种情况下它是一个初始化。
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
}
但是,如果可以使令人困惑的 coma/semicolon 保持一致,并且由于分号是 必须的 让我们尝试使所有内容都成为分号,我试过这个:
for ({int i = 0; int n = strlen(s); }; i < n; i++) {
// what ever
}
这没有编译,但它也没有意义,因为如果这会有 "worked"(在某种意义上我认为我可以但实际上不能),i
和n
将在小块中声明,并且在其他任何地方都无法访问,即在 i < n
中将无法访问。因此,为了使它们易于访问,我们可以尝试这样做:
int i, n;
for ({i = 0; n = strlen(s); }; i < n; i++) {
printf("%c\n", s[i]);
}
现在,如果上述 for
-while
等价性 100% 正确,那么这应该有效,但显然 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
但是正如你所看到的,它已经非常丑陋了......所以是的,你需要使用 ,
来分隔 declarations/initializations 和 ;
来终止它.
来自C标准ISO/IEC 9899:TC3 / ISO/IEC 9899/C11,语法for
语句的描述,§(6.8.5) 迭代语句,有 2 种不同的形式:
for ( expression_opt ; expression_opt ; expression_opt ) statement
for (declaration expression_opt ; expression_opt ) statement
请注意,在第一种形式中,我们在第一个位置有一个表达式,尽管它作为所有 3 个字段都是可选的,并且语句形式的所有 3 个部分都由 ;
分号分隔,用作一个分隔符。
在第二种形式中,我们可以看到括号中的第一个元素是声明而不是表达式,我们还可以注意到没有分号分隔它。这是因为 声明本身总是以分号结束 .
段落(6.7)声明描述了声明的语法:
declaration-specifiers init-declarator-list_opt ;
如您所见,declaration
总是以分号结尾。
声明当然可以采用多个声明的形式,如您的初始化:
for (int i = 0, n = strlen(s); i < n; i++)
{
printf("%c\n", s[i]);
}
所以 您使用的是第二种形式,其中分号分隔声明(不是 for
的第一部分)。
使用多个分号只是语法错误。