zoukankan      html  css  js  c++  java
  • 数组形参

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

  • 相关阅读:
    「字符串算法」第4章 字典树课堂过关
    「字符串算法」第3章 KMP 算法课堂过关
    「字符串算法」第2章 Hash 和 Hash 表课堂过关
    「基础算法」第5章 广度搜索课堂过关
    「基础算法」第3章 二分算法课堂过关
    「基础算法」第1章 递推算法强化训练
    「基础算法」第1章 递推算法课堂过关
    YbtOJ:冲刺 NOIP2020 模拟赛 Day10
    【模板】轻重链剖分
    LINUX-磁盘空间
  • 原文地址:https://www.cnblogs.com/hustcat/p/1730096.html
Copyright © 2011-2022 走看看