此程序打印6
.
如果我取消注释//printf("yes");
行,那么它会打印8
,但不会打印yes
。
如果我删除第一个i++;
并将该行留空,它会打印7
.
如果我删除第二个i++;
它会打印5
.
错误是什么?
int main () {
int i = 3;
if (!i)
i++;
i++;
if (i == 3)
//printf("yes");
i += 2;
i += 2;
printf("%d", i);
return 0;
}
该程序打印6,由于误导性缩进,很难获得。
它目前相当于:
int main ( ) {
int i = 3;
if (!i)
{
i++;
}
i++; // this is executed whatever the previous if
if (i==3)
//printf("yes");
{
i+=2; // could be executed because printf was commented, but isn't because of the value of i
}
i+=2; // executed whatever the previous if
printf("%d", i);
return 0;
}
第二个条件:如果你把printf
注释掉,你将执行最后一个i+=2;
,否则你将执行两个i += 2
语句。
因此执行 2 个加法:一个加 1,一个加 2。
3 + 1 + 2 = 6
请注意,gcc -Wall
在这些情况下创造了奇迹(更准确地说是-Wmisleading-indentation
(。在您的代码上:
test.c: In function 'main':
test.c:6:1: warning: this 'if' clause does not guard... [-Wmisleading-indentatio
n]
if (!i)
^~
test.c:8:5: note: ...this statement, but the latter is misleadingly indented as
if it is guarded by the 'if'
i++;
^
test.c:10:1: warning: this 'if' clause does not guard... [-Wmisleading-indentati
on]
if (i==3)
^~
test.c:13:5: note: ...this statement, but the latter is misleadingly indented as
if it is guarded by the 'if'
i+=2;
^
结论:始终使用大括号保护您的病情,即使只有一个指令。这可以保护您免受以下影响:
- 之后添加的代码(可能由其他人添加(,目的是将其添加到条件中,但失败。
- 定义 2 条或更多指令且不遵循
do {} while(0)
模式的宏:只有宏中的第一条指令受if
我相信您的困惑是因为 C 允许您在if
语句中省去大括号,但只有紧随其后的语句才算作在if
块内。
if (!i)
i++;
i++;
这和这个是一样的。
if (!i) {
i++;
}
i++;
如果你来自Ruby或Python,缩进是语法,这可能会非常令人困惑。
虽然关闭牙套可能很方便,但这也是引入错误的好方法。切勿使用此功能。
因为 'if' 语句后面没有大括号,所以只有紧跟在它们后面的行是有条件的。 缩进没有任何作用!
选项 1 答案 = 6:
int main ( )
{
int i = 3; //i==3
if (!i) i++; // !3 = False Never Executed
i++; // i==4
if (i==3) i+=2; // i!=3, Never Executed
i+=2; // i==6
printf("%d", i);
return 0;
}
选项 1 答案 = 8:
int main ( )
{
int i = 3; //i==3
if (!i) i++; // !3 = False Never Executed
i++; // i==4
if (i==3) printf("yes"); // i!=3 Never Executed
i+=2; // i==6
i+=2; // i==8
printf("%d", i);
return 0;
}