关于是否一个函数内声明的局部变量能被另一个函数访问的

q672856032 2011-03-24 07:57:42
我在一本书里面看到以上说明他给出的代码是

他是gcc的
int main()
{
a();
b();

}
void a()
{
int arr[10];
int i;
for(i=0;i<10;i++)
{
arr[i]=i;

}
}
void b()
{
int arr[10];
int i;
for(i=0;i<10;i++)
{

printf("%d",arr[i]);//能够打印出 123456789
}

}

可是我通过vc++6.0却不能得到以上结果。

#include <stdio.h>
void a();
void b();
void main()
{
a();
b();

}
void a()
{
int arr[10];
int i;
for(i=0;i<10;i++)
{
arr[i]=i;

}
}
void b()
{
int arr[10];
int i;
for(i=0;i<10;i++)
{

printf("%d",arr[i]);
}

}
...全文
1819 51 打赏 收藏 转发到动态 举报
写回复
用AI写文章
51 条回复
切换为时间正序
请发表友善的回复…
发表回复
xunyn 2012-05-02
  • 打赏
  • 举报
回复
http://blog.csdn.net/xunyn/article/details/7528290
  • 打赏
  • 举报
回复
I do not know gcc
小小的王药师 2011-03-29
  • 打赏
  • 举报
回复
b中数据使用前未初始化,内容是不确定的,在某些情况下正好是某个可以辨识的残留。
panyuzhu 2011-03-28
  • 打赏
  • 举报
回复
实际上就是一个非法的操作,如果你在两个函数中间再随便调用一个函数的话,一定不是你所说的0123456789,事实上当调用玩第一个函数之后,所有的内容都释放了的 ,只不过是两个数组刚好公用了一个位置,才会出现看似正确的结果!
soarisky08 2011-03-27
  • 打赏
  • 举报
回复
这个应该可以理解,局部变量是在该任务或进程的堆栈中按照递增或递减的方式获取空间,当a()的空间释放后b()刚好获取了这段空间,这种情况的出现依赖具体的编程器。但是我们编程是绝对不能依靠这个特性编程,写出的代码几乎没有可读性和移植性。
huacong20082009 2011-03-26
  • 打赏
  • 举报
回复
[Quote=引用 19 楼 moorsf 的回复:]

看这类问题可以加深对编译器及c语言实现的理解
但在实际的编程中当然不能如此去做,因为结果如何,是依赖于编译器的。
楼上有人说vs2010可以做到,不过我用codeblocks的G++就无法实现。
[/Quote]

我用codeblock输出两个函数的数组和i的值是一样的,并且也能输出0~9
delphiwcdj 2011-03-26
  • 打赏
  • 举报
回复
这种问题可以帮助理解编译器的行为方式,但是这种代码是不可移植的
失散糖 2011-03-26
  • 打赏
  • 举报
回复
用vc6,在release模式禁止优化下,输出0123456789,改变优化选项会得到不同的结果
Yingmg 2011-03-26
  • 打赏
  • 举报
回复
ab函数的两个数组都是在调用函数的时候才配各自的内存空间,a调用完了之后,在a里面定义的数组所占用的内存空间就要被释放掉,你怎么访问。书上会这么说,你确认不是你看错了
晓馨嫣梓 2011-03-25
  • 打赏
  • 举报
回复
a();
b();
中间加个printf("\n")刷新一下~再看看~哈哈;
好像每个程序占的空间是连续的~~每次调用函数都是在上面连续堆放,临时变量的空间是可以重复利用的~~把赋值函数里面的数组声明为静态变量也不会出现楼主所说的情况~~

这个帖子有意思
驴被脑袋踢了 2011-03-25
  • 打赏
  • 举报
回复
应该是编译器的巧合吧,VS结果是
-858993460-858993460-858993460-858993460-858993460-858993460-858993460-858993460
-858993460-858993460请按任意键继续. . .
jbz001 2011-03-25
  • 打赏
  • 举报
回复
其实是这样的,第一个函数申请了变量,执行完后释放。
但是对应的地址仍然保存了那个值。
当第二个函数再次申请同样的变量,并且没赋值,则有可能默认值和上一个函数的相同。
这本书讲得都是歪门邪道,又不说明原因,纯属误人子弟。
我是苦力 2011-03-25
  • 打赏
  • 举报
回复
[Quote=引用 29 楼 meteor_code 的回复:]
都用大脑想想好不?
一旦多线程,同一个函数同时运行多个,你得到的是哪个啊????????
至于输出一样,这太明显了,几乎完全相同的函数变量,栈地址恰巧重合了啊
[/Quote]
首先LZ的这个例子不能商业使用(指一般商用,特殊功能不算),只能在讲解栈的时候拿来做一个特例说明栈这个东西在函数调用的时候内存是怎么分配。而且在不同的编译器或者不同的优化参数下可能会出来不一样的结果。
至于多线程,这个例子不会由于多线程而有不同的结果,这个是栈特性决定的,同一个线程的栈只能是同一个,除非你在测试的时候让A()在一个线程,B()在例外一个线程。
liutengfeigo 2011-03-25
  • 打赏
  • 举报
回复
[Quote=引用 27 楼 zhao4zhong1 的回复:]

VC调试时按Alt+8,TC或BC用TD调试,打开汇编窗口看每句C对应的汇编并单步执行一遍不就啥都明白了吗。
(Linux或Unix下应该也可以在用GDB调试时,看每句C对应的汇编。)
[/Quote]
就是这个.自己去看汇编代码就明白了.
luxihua 2011-03-25
  • 打赏
  • 举报
回复
[Quote=引用 29 楼 meteor_code 的回复:]

都用大脑想想好不?
一旦多线程,同一个函数同时运行多个,你得到的是哪个啊????????
至于输出一样,这太明显了,几乎完全相同的函数变量,栈地址恰巧重合了啊
[/Quote]
是这个意思。
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 q672856032 的回复:]
其实也不是什么书,是斯坦福的网络课堂。那个教授的意思大概就是这个意思。不过我也觉得不可思议!!!!!
[/Quote]

主要看那门课是什么,我想一个教授应该不会这样教你编程,否则估计他该下课了。。。。

如果是在深入讲解C编译时的地址分配等,那这个教授的课真值得好好学下。
因为这部分内容会牵涉汇编,编译原理,系统可移植性等内容,值得我们好好学习和思考,国内的大学都不太会讲这部分内容,一般工作几年或是对C语言学习的特别深入的人才能理解这部分内容。

我们编程肯定不会这样写,但是在调试或是分析错误时说不定真会遇到这类问题。
wansbest 2011-03-25
  • 打赏
  • 举报
回复
这个很正常啊!第一个函数调用结束,那个数组没了,但事实上那块内存上的值还在,然后紧接着调用第二个函数,定义一个相同大小的数组,编译器申请内存的时候,还是会从那块内存里申请,所以很可能会出现这种情况!!不过总的来说,这种情况发生了,但你不能认为就可以在一个函数里面调用另一个函数中的局部变量,这是跟本不可能的事!比如你把你的那个例子改下,在第二个函数第一数组之前再定义一个变量那结果可能不是这样了。真要实现函数之间值的传递,要不就用static变量,要么在函数里直接操作全局变量!!
Meteor_Code 2011-03-25
  • 打赏
  • 举报
回复
都用大脑想想好不?
一旦多线程,同一个函数同时运行多个,你得到的是哪个啊????????
至于输出一样,这太明显了,几乎完全相同的函数变量,栈地址恰巧重合了啊
wizard_tiger 2011-03-25
  • 打赏
  • 举报
回复
在CodeBlocks中试了一下,不能出现上述结果。
赵4老师 2011-03-25
  • 打赏
  • 举报
回复
VC调试时按Alt+8,TC或BC用TD调试,打开汇编窗口看每句C对应的汇编并单步执行一遍不就啥都明白了吗。
(Linux或Unix下应该也可以在用GDB调试时,看每句C对应的汇编。)
加载更多回复(28)

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧