数组和指针

来源:互联网 发布:php 局域网访问慢 编辑:程序博客网 时间:2024/06/18 06:23

数组和指针

  指针和数组有什么区别?

  C程序(array.c):

#include <stdio.h>int main(){    int date[3] = {2012,11,11};    int *p = date;    int a = date[1];    int b = p[1];    printf("a:%d b:%d\n", a, b);    printf("date:%p\np   :%p\n", date, p);    return 0;}

  汇编及注释:

    .file    "array.c"    .section    .rodata.LC0:    .string "a:%d b:%d\n".LC1:    .string "date:%p\np   :%p\n"    .text.globl main    .type   main, @functionmain:    pushl   %ebp            #-帧指针切换    movl    %esp, %ebp      #/    andl    $-16, %esp      #-栈对齐到16字节    subl    $48, %esp       #-开拓局部变量空间    movl    $2012, 24(%esp) #\    movl    $11, 28(%esp)   #-date数组初始化    movl    $11, 32(%esp)   #/    leal    24(%esp), %eax  #\    movl    %eax, 44(%esp)  #-初始化指针p    movl    28(%esp), %eax  #\    movl    %eax, 40(%esp)  #-初始化a    movl    44(%esp), %eax  #\    addl    $4, %eax        #-\    movl    (%eax), %eax    #-初始化b    movl    %eax, 36(%esp)  #/
    movl    $.LC0, %eax    movl    36(%esp), %edx    movl    %edx, 8(%esp)    movl    40(%esp), %edx    movl    %edx, 4(%esp)    movl    %eax, (%esp)    call    printf      #第一次调用 printf 函数
    movl    $.LC1, %eax    movl    44(%esp), %edx    movl    %edx, 8(%esp)    leal    24(%esp), %edx    movl    %edx, 4(%esp)    movl    %eax, (%esp)    call    printf      #第二次调用 printf 函数
    movl    $0, %eax    #return 0    leave    ret    .size   main, .-main    .ident  "GCC: (GNU) 4.5.1 20100924 (Red Hat 4.5.1-4)"    .section    .note.GNU-stack,"",@progbits

  大家对 lea 指令可能比较陌生,它跟 mov 指令很像,不过 lea 指令传递的是内存的地址,而 mov 指令传递的的是内存的值,例如:

leal 24(%esp), %eax     # 将 24+esp 的结果给 eaxmovl 24(%esp), %eax     # 将 2012 给 eax

总结

  首先,我们看到 main 也是一个函数,它编译后的汇编代码跟函数调用中分析过的 Double 函数有一样的结构。

  其次,指针是有存储空间的(32位机是4个字节的大小),其中存储的是一个内存地址;而数组只有数组中的元素有存储空间,而 C 代码中经常用到的数组首地址(用数组名来代替)可以说是没有存储空间的。假设将数组首地址赋值给一个指针,数组首地址的存在形式是:

  • 如果是全局数组,它将是 mov 指令中的一个立即数(常量)
  • 如果是局部数组,它将是 lea 指令中由 esp 或 ebp + 常量计算的结果

  所以数组的首地址是一条机器指令的操作数,不在局部变量空间中,也不在全局变量空间中,而是被固化在代码中。因此,数组首地址不能被更改。

  printf 函数的调用跟别的函数一样:先传参数,然后 call printf,打印指针都可以使用 %p 格式描述符。程序的运行结果如下:

[lqy@localhost temp]$ gcc -o array array.c[lqy@localhost temp]$ ./arraya:11 b:11date:0xbf9c3b68p   :0xbf9c3b68[lqy@localhost temp]$ 

  date 和 p 的值都是 date 数组的首地址。

原创粉丝点击