长度假设返回穿过线槽时沿着计数器走的距离。但是,仅在事先打印时它才返回正确的值。如果我注释掉printf
,它将返回0。
有人对此有解释吗?
#include<stdio.h>
#include<string.h>
#define MAX 100
int length(char *s) {
int i;
for (i = 0; s[i] != '\0'; ++i)
printf("%d ", i); //<-- here
return i;
}
int main()
{
char s[MAX];
fgets(s, (char)sizeof(s), stdin);
s[strcspn(s, "\n")]='\0';
printf("Length: %d\n", length(s));
return 0;
}
答案 0 :(得分:7)
问题是,如果在printf()
函数中注释掉length()
语句,则return
语句成为循环主体的一部分,并且第一次迭代从调用返回然后您得到i
的 then 值,它只是循环0
的入口值。
for (i = 0; s[i] != '\0'; ++i)
//printf("%d ", i); //<-- here
return i; // without brace-enfoced scope, this is the loop body.
与
相同for (i = 0; s[i] != '\0'; ++i)
return i;
您需要执行以下循环以完成执行,达到退出标准,然后以return
的最新值执行i
语句。
因此,为避免此问题,您可以通过类似
的方法强制执行循环的空执行for (i = 0; s[i] != '\0'; ++i) ; // notice the ; here, ends the scope.
return i;
,甚至更好(对读者而言)
for (int i = 0; i < 10; i++)
{/*nothing here*/} //indicates empty loop body
return i;
注意:作为一种替代方法,为了增强可读性,除了使用for
循环之外,您还可以使用while
循环,就像
while (s[i] != '\0')
{
i++; //increment statement is explicit.
}
答案 1 :(得分:5)
在这样的循环中:
for (...)
statement1;
statement2;
statement1
将是循环中唯一执行的操作。当您注释掉printf
调用后,return i;
在第一次迭代时执行,立即返回零。
但是请注意,statement1
可以为空,因此,要运行没有主体的循环,请执行以下操作:
for (...)
; // yes, a hanging semicolon
// or like this:
for (...);
答案 2 :(得分:3)
如果您只是想表达那个printf
,那么您将得到:
int length(char *s) {
int i;
for (i = 0; s[i] != '\0'; ++i)
return i;
}
这等于:
int length(char *s) {
int i;
for (i = 0; s[i] != '\0'; ++i){
return i; // returns in the first iteration, without even incrementing i once
}
}
当然这不是您想要的。而是在for
循环后加上分号:
for (i = 0; s[i] != '\0'; ++i);
这样,for (i = 0; s[i] != '\0'; ++i);
不会意外影响以下语句。
您可以通过添加明确的括号来表示您的意图来预防此类事故,例如:
int length(char *s) {
int i;
for (i = 0; s[i] != '\0'; ++i) {
printf("%d ", i); //<-- here
}
return i;
}
现在,如果删除printf
行,则除了省略打印之外,它不会以任何其他方式影响程序执行。