我是 C 编程新手,在理解指针方面遇到了一些困难。我尝试使用 for 循环进行实验,以更好地了解它们的工作原理。我在循环外部声明了一个变量,并尝试在循环条件内使用指向该变量的指针来查看该变量在循环执行时将如何变化。
我先执行了这个:
int main(void){
int i = 5;
for (int *m = &i; *m < 10; *m++){
printf("%d\n", *m);
}
printf("%d", i);
return EXIT_SUCCESS;
}
在这种情况下,循环提前中断,我的输出是
5
5
但是如果我执行这个
int main(void){
int i = 5;
for (int *m = &i; *m < 10; i++){
printf("%d\n", *m);
}
printf("%d", i);
return EXIT_SUCCESS;
}
我得到了预期的输出。
5
6
7
8
9
10
它们有何不同,是什么导致循环在第一个代码片段中提前中断?
如有错误,敬请谅解。我对 C 和这个网站都是新手,所以我可能犯了一些错误,但这是我从大约一个小时的使用中发现的。
正如其他人评论的那样,问题是您使用了 *m++。如果你想以类似的方式做到这一点,你可以做 *m+=1。看起来这些是同一件事,但问题本质上归结为操作顺序。
使用 *m++,编译器将其读取为 *(m++),所以发生的情况是您增加 m(地址)并设置 *m(指向的值),它现在指向与以前不同的数字,到之前的地址,m 增加之前的值。
循环只打印两个五的原因是因为内存地址很可能是一个非常大的整数,这意味着它大于 10 并且会脱离循环。如果你运行这个程序几次,最终你会得到一个负数。在这种情况下,您将得到如下输出:
5
-1663524456
5
我不确定为什么它最终不会从负数增加到 10,我不确定。如果其他人知道答案,我很想知道,但在我所有的测试中,我从未让它经历超过 2 个循环。
这是我的测试代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char * argv[])
{
int i = 5;
int *m = &i;
int n = 1;
for (int *m = &i; *m < 10; *m++){
printf("in loop %d:\n*m = %d\n", n, *m);
printf(" m = %d\n\n", m);
n++;
//printf("*m++ = %d\n\n", *m++);
}
printf("End of loop:\n*m = %d\n", *m);
printf(" m = %d\n", m);
return 0;
}
结果示例:
in loop 1:
*m = 5
m = -65445932
in loop 2:
*m = -65445932
m = -65445928
End of loop:
*m = 5
m = -65445932
这里可以看到*m开始指向i,m是起始地址。然后,在第一个循环之后,m 已移动到下一个地址(与数组一样增加 4),并且 *m 已成为 m 的先前值。然后在下一个循环之后,由于某种原因 m 返回到起始地址(这是我感到困惑并需要一些帮助的部分),它仍然指向 i 的值。再说一次,我不知道为什么这会打破循环,我相信这应该无限,因为按照这个逻辑,你将继续循环,然后转到与循环 2 相同的结果,但相反,循环在 5 < 10 is still true.
时中断