zoukankan      html  css  js  c++  java
  • 数组和指针的暧昧

    数组名不是对象,数组才是对象,指针也是一种对象,因此,数组名并没有内存空间,它是一个右值。想看具体的代码么?把下面的代码汇编一下,就可以看见其区别了:

    char   a[10];
    char   *p;
    p=a;
    a[2]=10;
    p[2]=20;

    编译器编译后的汇编代码是这样的:

    _main proc near
    push bp
    mov bp,sp
    sub sp,10
    push si
    lea si,word   ptr   [bp-10]     ;这个就是p=a,p被保存在某个地方,这里p被优化为保存在寄存器
    mov byte   ptr   [bp-8],10       ;这个是a[2]=10,a是直接堆栈操作,因为它是一个地址,没有存储空间
    mov byte   ptr   [si+2],20       ;这个是p[2]=20,p是个变量,它被保存在寄存器si里面,因此进行操作时,要先取si的值,然后+2,再进行间接寻址
    xor ax,ax
    jmp short   @1

    如果数组名是一个变量的话,那就必定得先把bp-10保存在某个地方,例如di,就会产生下面的指令:lea   di,   word   ptr[bp-10],事实是,编译器并没有这样做,而是直接堆栈操作。


    char   *a[2];
    那么a的值和&a的值是不是应该一样?
    -----------------------------------
    关于对数组名取地址的问题,由于数组名是右值,本来&a是不合法的,早期不少编译器就是指定&a是非法的,但后来C89/C99认为数组符合对象的语义,对一个对象取地址是合理的,因此,从维护对象的完整性出发,也允许&a,只不过,&a的意义,并非对一个数组名取地址,而是对一个数组对象取地址,也正因为如此,a才跟&a所代表的地址值一样,同时sizeof(a)应该跟sizeof(&a)一样,因为sizeof(&a)代表取一个数组对象的长度。

    //---------------------------------------

    int a[5];    a代表数组首元素的地址,&a代表了数组的首地址.地址一样.类型不一样.

    举一个变相的例子:数组名同时也是该数组的首元素的地址,也就是说, flizny是一个数组,下面的式子是正确的:

    flizny == &flizny[0]  //数组名是该数组的首元素地址

    flizny 和 &flizny[0] 都代表首元素的内存地址.

    dates + 2==&date[2]                  /*相同的地址*/

    *(dates + 2==dates[2]       /*相同的值*/

    定义 ar[n] 时,意思是*(ar+n),即 "寻址到内存中的ar,然后移动n个单位,再取出数值".

  • 相关阅读:
    17-vue-cli脚手架安装和webpack-simple模板项目生成
    15-其它
    14-表单输入绑定
    k8s组件通信或者创建pod生命周期
    升级CentOS 7.4内核版本--升级到最新
    Linux
    Statefulset的拓扑状态
    nginx浏览器开启密码验证
    为什么我们需要Pod?(容器设计模式sidecar)
    mysql内存优化
  • 原文地址:https://www.cnblogs.com/lvpblog/p/2523393.html
Copyright © 2011-2022 走看看