数组形参

《C专家编程》一书中的216页有一个很有意思的示例。它形象的展示了数组形参在函数内部是如何作为指针来使用的。

为了简单,稍微简化了一下:

ExpandedBlockStart.gif 代码
#include  < stdio.h >

int     ga[ 10 ];

void  array_fun( int  a[])
{
    a[
0 =   1 ;
    printf(
" &a = %#x\n " & a);
    printf(
" &a[0] = %#x\n " & a[ 0 ]);
}


int  main()
{
    printf(
" &ga = %#x\n " & ga);
    printf(
" &ga[0] = %#x\n " & ga[ 0 ]);
    array_fun(ga);
    
    
return   0 ;
}

 

输出结果如下:

&ga = 0x4394b0
&ga[0] = 0x4394b0
&a = 0x12ff30
&a[0] = 0x4394b0

 

为了更好的理解数组形参,下面给出汇编代码(VC 6.0下):

ExpandedBlockStart.gif 代码
7 :        a[ 0 ] =  1 ;
00402878     mov          eax,dword ptr [ebp+ 8 ]
0040287B     mov          dword ptr [eax], 1
8 :        printf( " &a = %#x\n " , &a) ;
00402881     lea          ecx,[ebp+ 8 ]   #实参在栈中的位置(实参本身的内存地址)-->ecx
00402884     push         ecx
00402885     push         offset string  " &a = %#x\n "  ( 00432038 )
0040288A     call         printf ( 00404910 )
0040288F     add          esp, 8
9 :        printf( " &a[0] = %#x\n " , &a[ 0 ]) ;
00402892     mov          edx,dword ptr [ebp+ 8 ]  #实参的内容(数组的地址) -->edx,(注意实参本身的地址(通过lea指令获取)与数组地址的差别)
00402895     push         edx
00402896     push         offset string  " &a[0] = %#x\n "  ( 00432028 )
0040289B     call         printf ( 00404910 )
004028A0     add          esp, 8

结论:

对数组形参本身取地址,即 &a,则相当于LEA R, [ebp+8]   (R表示寄存器),本质上相当于求参数本身的地址;

而对数组形参的元素取地址,即 &a[n],则相当于MOV R,[ebp+8+n*scale],尽管,这是C的语法,但是不能不看到LEA与MOV的精妙与区别所在。

指针(*),则相当于寄存器间接寻址的MOV;取址(&),则相当于寄存器间接寻址的LEA,如是而已——闲着没事,乱谈一番。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值