当前位置: 代码迷 >> C语言 >> [求助] 为什么死循环,不能肯定答案的请不要发表相关的答案
  详细解决方案

[求助] 为什么死循环,不能肯定答案的请不要发表相关的答案

热度:212   发布时间:2005-03-12 15:14:00.0
[求助] 为什么死循环,不能肯定答案的请不要发表相关的答案
#include <stdio.h> long *p; void loop(){ long i; for (i=0; i<10; i++) { (*p)--; printf("%ld ", i); } } void addr(){ long k; k = -1; p = &k; } void main (){ addr() ; loop() ; } /* 谁要是告诉我程序怎么修改, 我拿钉子钉他 呵呵,偶主要想知道,为什么死循环, 以及 堆和栈方面的知识,以及一些编译原理, HOHO */
搜索更多相关的解决方案: long  void  include  知识  

----------------解决方案--------------------------------------------------------

#include <stdio.h>

long *p; void loop(){ long i; printf("I ---->>%p \n", &i); getch(); for (i=0; i<10; i++) { (*p)--; printf("%ld ", i); } }

void addr(){ long k; k = -1; p = &k; printf("K ---->>%p \n", &k); }

void main (){ addr() ; loop() ; }


----------------解决方案--------------------------------------------------------
void  addr(){
       static long  k;
        k = -1;
        p = &amp;k;
        printf("K  ----&gt;&gt;%p  \n", &amp;k);
}
当在主函数中调用LOOP时,P指向的变量已被释放。因此*P可能是一个不可知的数。加上STATIC就好了。
----------------解决方案--------------------------------------------------------
3楼找钉啊
----------------解决方案--------------------------------------------------------
呵呵

[此贴子已经被作者于2005-3-12 18:33:26编辑过]



----------------解决方案--------------------------------------------------------

首先我们要了解变量的生存周期问题。

好,我们看看你的这两个函数:

void loop() { long i; for(i=0;i<10;i++) { (*p)--; printf("%ld ", i); } }

void addr() { long k; k=-1; p=&k; }

请注意你的i和k,他们都是局部变量,而且只在他们的函数里面有效。什么意思呢?就是说,如果函数loop()结束,那么变量i也随着被释放。同理addr()中的k也是一样的。

然后我们再来看看你的 void main() { addr(); loop(); }

这里,你先调用了addr()函数,定义了变量k,并且让全局指针p指向了k的地址。然而当addr()函数结束后,k随即被释放,然后执行loop()函数,定义了变量i。

这里,最致命的错误出现了。因为addr()中的k被释放,所以编译器把loop()中的i放在里k原来的地址之上。也就是说,i取代了k的位置。但是你要记得,全局指针始终都在指向原来k的地址,也就是现在i的地址!

于是在这一句 for(i=0;i<10;i++) { (*p)--; printf("%ld ", i); } 其实我们可以等价于 for(i=0;i<10;i++) { i--; printf("%ld ", i); }

很明显,这是一个无限循环,因为i永远不可能到达1更加别说到10了。

为了验证我前面所说的k地址被i取代的问题,我编写了下面这个小程序 void funa() { int a; printf("%d\n",&a); }

void funb(){ int b; printf("%d\n",&b); }

void main(){ funa(); funb(); getch(); }

你会发现,输出的两个地址都是一样的,这说明了b放到了a原来的地址之上。


----------------解决方案--------------------------------------------------------
至于栈和堆,你先看明白这我写的东西再说
----------------解决方案--------------------------------------------------------
http://www.programfan.com/club/showbbs.asp?id=65325 这里的解释也对吧?
----------------解决方案--------------------------------------------------------
恩恩~
那里的帖子:
"1楼的解释完全正确"
----------------解决方案--------------------------------------------------------
这个就是c程序的强大哦
不过我不是很赞成那个解释的,主要是不赞成在堆中分配的变量。
实际上程序在调用函数的时候会修改register ss sp的内容让他指向
新的地址,就是那个函数的堆栈,实际上对于函数的变量他们的
内存的分配是在栈中而不是堆中,而对于栈他们会共用的,
所以上面说得不完全正确!!
这个是我要说明的,希望批评指正!!!
----------------解决方案--------------------------------------------------------
  相关解决方案