对于一个简单地for语句,学过C的朋友可能觉得很简单,但是,看完下面这个简单地程序还能想明白的朋友(但是真的不简单)
那才是真的不错,,好了,不废话了,大家看代码吧!!!
程序1:
#include <stdio.h>
#include <conio.h>
int main(){
int i;
int a[5];
for(i = 0; i <= 5; i++)
a[i] = 0;
printf("programming formal!");
getch();
return 0;
}
运行结果如下:
由上图可知,我们的编译器什么都没有做,一直就停在这里,也可以说程序一直死在这里了,
大家可以自己分析分析:
我们来通过简单程序调试看一看啊!!
程序2:
#include <stdio.h>
#include <conio.h>
int main(){
int i;
int a[5];
for(i = 0; i <= 5; i++){
a[i] = 0;
printf(" i is : %d\n", i);
getchar();
}
printf("programming formal!");
getch();
return 0;
}
运行结果如下:
通过上面的结果,我们可以得出的结论就是,在这个for语句中i的值一直在0到4之间来回变动,并没有满足退出的条件,所以,我们的编译器表现也就是一直在这里不动,进入死循环了
但是,但是,这是为什么 啊!!
我们猜想这其实这可能跟编译器分配给变量的地址情况有关,对于当前的变量定义的类型及数组,我们可以查看他们的内存分配
如下: 程序3:
#include <stdio.h>
#include <conio.h>
int main(){
int i;
int a[5];
printf("i is ip :%p\n", &i);
printf("a[0] is ip: %p\n", &a[0]);
printf("a[1] is ip: %p\n", &a[1]);
printf("a[2] is ip: %p\n", &a[2]);
printf("a[3] is ip: %p\n", &a[3]);
printf("a[4] is ip: %p\n", &a[4]);
printf("a[5] is ip: %p\n", &a[5]);
for(i = 0; i <= 5; i++){
a[i] = 0;
printf(" i is : %d\n", i);
getchar();
}
printf("programming formal!");
getch();
return 0;
}
结果如下:
如上图,可以证明我们的说法是正确的i和a[5]的地址都是0022febc,
所以,也就是说,a[5]和i是一样的,对a[5]进行的所有操作也就是对i进行操作,所以对于a[5] = 0,的情况,也就是说,此刻i = 0,所以,这也就刚好解释了i一直是0到4的原因了
对于这里编译器对于那些变量分配内存的情况以及顺序的问题,大家有问题可以参考下面这个博客:
点击打开链接:http://blog.csdn.net/msdnwolaile/article/details/50576418
同时,上面的程序中出现了getchar,getch,如果还有人对这些东西不太懂,或者想了解更多关于(scanf,gets,getche之间的关系或细节),可以参考这个博客,哈哈,他们并不是大家想的那么简单地,
点击打开链接:http://blog.csdn.net/msdnwolaile/article/details/49922371
好了,接下来我们再看:
倘使我们给变量的顺序变一下呢??
程序4:
#include <stdio.h>
#include <conio.h>
int main(){
int a[5];
int i;
for(i = 0; i <= 5; i++)
a[i] = 0;
printf("programming formal!");
getch();
return 0;
}
运行结果:
可以很明显的看成,当前我们这个程序也是出于死循环之中,我们这样来看:
程序5:
#include <stdio.h>
#include <conio.h>
int main(){
int a[5];
int i;
for(i = 0; i <= 5; i++){
a[i] = 0;
printf("i is :%d\n", i);
getchar();
}
printf("programming formal!");
getch();
return 0;
}
同样的,我们来看结果:
跟上面一样,这一定也是有原因的,但是绝对不会跟变量的地址有关,为什么??
哈哈,因为编译器和操作系统对用户定义变量的过程和顺序有严格的规定的,
不信啊, 来,我们来看看吧!!
程序6:
#include <stdio.h>
#include <conio.h>
int main(){
int a[5];
int i;
printf("a[0] is ip: %p \n", &a[0]);
printf("a[1] is ip: %p \n", &a[1]);
printf("a[2] is ip: %p \n", &a[2]);
printf("a[3] is ip: %p \n", &a[3]);
printf("a[4] is ip: %p \n", &a[4]);
printf("a[5] is ip: %p \n\n", &a[5]);
printf("i is ip: %p\n", &i);
for(i = 0; i <= 5; i++){
a[i] = 0;
printf("i is :%d\n", i);
getchar();
}
printf("programming formal!");
getch();
return 0;
}
结果如下:
我们可以很明显的看到,a【5】的地址(0022fec0)和i的地址(0022fea8)并不一样
哈哈,看到了吧!!
但是,但是,为什么这次我们的程序不会出现循环了,而正确的运行出来我们的结果呢????
而前面的就不能呢??
这里我经过反复的检验,发现了一个东西:
程序7:
#include <stdio.h>
#include <conio.h>
int main(){
int a[5];
int i;
//printf("i is ip: %p\n", &i);
printf("a[0] is ip: %p \n", &a[0]);
printf("a[1] is ip: %p \n", &a[1]);
printf("a[2] is ip: %p \n", &a[2]);
printf("a[3] is ip: %p \n", &a[3]);
printf("a[4] is ip: %p \n", &a[4]);
printf("a[5] is ip: %p \n\n", &a[5]);
for(i = 0; i <= 5; i++){
a[i] = 0;
printf(" a[i] is :%d || a[i] is address: %p || i is :%d\n", a[i], &a[i], i);
getchar();
}
printf("programming formal!");
getch();
return 0;
}
大家看结果:
程序8:
#include <stdio.h>
#include <conio.h>
int main(){
int a[5];
int i;
printf("i is ip: %p\n", &i);
printf("a[0] is ip: %p \n", &a[0]);
printf("a[1] is ip: %p \n", &a[1]);
printf("a[2] is ip: %p \n", &a[2]);
printf("a[3] is ip: %p \n", &a[3]);
printf("a[4] is ip: %p \n", &a[4]);
printf("a[5] is ip: %p \n\n", &a[5]);
for(i = 0; i <= 5; i++){
a[i] = 0;
printf(" a[i] is :%d || a[i] is address: %p || i is :%d\n", a[i], &a[i], i);
getchar();
}
printf("programming formal!");
getch();
return 0;
}
运行结果:
我们可以看到两个程序一个正常结束了,另外一个还在死循环里,,对于程序7,由于没有探究i的地址,所以,我们程序打印出来的结果是a【0】的地址是(0022fea8)
但是对于程序8,程序里面打印了i的地址,所以我们编译器给i分配的地址是0022fea8,而a【0】的地址是(0022feac)
经过博主的测试,也就是说我们程序中如果讨论或打印了关于i的地址的问题,我们的程序就是可以跳出这个循环的,
但是好像如果不讨论的话,就会进入一个死循环里,而且这个东西还跟地址并没有关系!!
也就是说即使我们的for循环里面这样写:
也是可以得到正确的结果的!!
对于这一点,目前博主也不太清楚,欢迎大家前来讨论,谢谢!!!