• 数组形参


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

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

    代码
    #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下):

    代码
    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,如是而已——闲着没事,乱谈一番。

  • 相关阅读:
    类变量、绑定方法、静态方法和类方法
    面向对象练习及补充
    2、error:file /usr/bin/ ** mysql-client-5.6.39-1.el7.x86_64
    15、Linux 磁盘映射DM
    14、echo “$JAVA_HOME/bin” >>/etc/profile 转义
    typora文件导出word
    1、Rocketmq centos7下安装及使用
    13、hostname及hostnamectl区别
    1、MySql集群
    Hadoop安装
  • 原文地址:https://www.cnblogs.com/hustcat/p/1730096.html
Copyright © 2020-2023  润新知