人较笨且记性不好,故记录在此.折叠代码打不开请F5.本博中很多是转载收录其他网友的文章(原文地址请见博文末尾),所有权为原作者所有!!!
此博客已不再更新和维护,欢迎关注我的github新博客

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: :: 管理 ::
 1 #include <stdio.h>
2
3 int&foo(int a)
4 {
5 static int t;
6 t = a;
7 return t;
8 }
9
10 void main(void)
11 {
12 if (foo(1) == foo(2))
13 {
14 printf("right!\n");
15 }
16 return;
17 }

  最后结果为:right!

  下面为执行过程中的汇编代码:

16:       if (foo(1) == foo(2))
00401078 push 1
0040107A call @ILT
+10(Test::Test) (0040100f)
0040107F add esp,
4
00401082 mov esi,eax
00401084 push 2
00401086 call @ILT+10(Test::Test) (0040100f)
0040108B add esp,
4
0040108E mov ecx,dword ptr [esi]
00401090 cmp ecx,dword ptr [eax]
00401092 jne main+41h (004010a1)
17: {
18: printf("right!\n");
00401094 push offset string"right!\n" (00420f74)
00401099 call printf (0040bac0)
0040109E add esp,
4
19: }
20: return;
21: }
004010A1 pop edi
004010A2 pop esi
004010A3 pop ebx
004010A4 add esp,40h
004010A7 cmp ebp,esp
004010A9 call __chkesp (
00401230)
004010AE mov esp,ebp
004010B0 pop ebp
004010B1 ret

  是不是能看出什麽?
  首先执行"foo(1)" 的时候,由于是引用型,所以返回 t的地址到“eax”中,然后再将“exa”中的值赋给“esi”,这样“exa”和“esi”的值就相等了,都是指向 t的地址。然后执行“foo(2)”,再次返回 t的地址【注意①】到“exa”中,最后在比较“exa”和“esi”储存的地址所指向的值,由于存储的地址相同,所以指向的值也就相同了,当然语句"if( foo(1) == foo(2))"成立。

注意:

  ①这里第二次返回 t的地址到底变化没有,我不敢确定。我和朋友讨论认为,由于执行“foo(1)”和“foo(2)”的间隔比较短,考虑编译器的优化,执行"foo(2)"的时候并没有再次申请内存地址空间,故两次返回 t的地址一样。这里我在vc6.0和vs2005环境下均测试了,两者结果一样。【若有不对,请指教!!!
  另一种解释:foo返回的是一个全局变量的引用。因为函数中 t变量是静态的,在数据块中的位置有点关。

 附上一篇文章:http://www.cnblogs.com/fanzi2009/archive/2011/08/03/2126256.html

posted on 2011-08-31 21:48  子坞  阅读(283)  评论(0编辑  收藏  举报