在将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]);
}
}
答案 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
的工作方式以及
-变量声明/初始化的工作方式。
您可以这样考虑for
:
for(AAA; BBB; CCC) DDD;
与
{ // Important!
AAA;
while(BBB) {
{
DDD;
}
CCC;
}
} // Important!
// Important!
花括号很重要,因为for引入了一个新的作用域,即i
和n
在for
循环的外部/之后将无法访问。
另一件事是声明/初始化。所以
int i = 0, n = strlen(s);
是两个变量的初始化:i
,n
。我不确定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]);
}
的第一部分)。
使用多个分号只是一个语法错误。