c/c++ 数组名是指针吗?使用汇编分析

结论在前:数组名是纯地址值,不是指针。


反汇编的方法分析:

void fun(int *a,int *b){}

int main()
{
  int a[]={1};
  int bb=1;
  int *b=&bb;

  fun(a,b);
  fun(a,&bb);
}

使用g++ -g temp.cpp编译出二进制,并使用objdump -S a.out进行反汇编,以下为截取的部分汇编代码:

  int a[]={1};
    1177:       c7 45 f4 01 00 00 00    movl   $0x1,-0xc(%rbp)
  int bb=1;
    117e:       c7 45 e4 01 00 00 00    movl   $0x1,-0x1c(%rbp)
  int *b=&bb;
    1185:       48 8d 45 e4             lea    -0x1c(%rbp),%rax
    1189:       48 89 45 e8             mov    %rax,-0x18(%rbp)

  fun(a,b);
    118d:       48 8b 55 e8             mov    -0x18(%rbp),%rdx
    1191:       48 8d 45 f4             lea    -0xc(%rbp),%rax
    1195:       48 89 d6                mov    %rdx,%rsi
    1198:       48 89 c7                mov    %rax,%rdi
    119b:       e8 a9 ff ff ff          callq  1149 <_Z3funPiS_>
  fun(a,&bb);
    11a0:       48 8d 55 e4             lea    -0x1c(%rbp),%rdx
    11a4:       48 8d 45 f4             lea    -0xc(%rbp),%rax
    11a8:       48 89 d6                mov    %rdx,%rsi
    11ab:       48 89 c7                mov    %rax,%rdi
    11ae:       e8 96 ff ff ff          callq  1149 <_Z3funPiS_>

可以看到

  1. 数组起始地址为0xc
  2. int变量的地址为0x1c
  3. 指向int变量的指针的地址为0x18

lea代表将纯地址送给寄存器
mov代表将地址上的内容送给寄存器

观察fun(a,b);fun(a,&bb);,其中前者是一个mov指令和一个lea指令,后者是两个lea指令。而&bb是右值纯地址值,这说明数组名和&bb一样是纯地址值。


不从汇编角度分析,从逻辑角度分析:

数组名不占用堆栈空间,指针占用堆栈空间(全局指针占用data段空间)。


大多数场景下,由于两者的数值相等,很多人容易混着用,但是容易出bug。参见《C专家编程》里对数组名和指针的讨论,主要是使用export时,混用数组名和指针会出现bug。
函数名也是和数组名一样,属于纯地址值,并非是指针,不占用堆栈空间。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

朴人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值