zoukankan      html  css  js  c++  java
  • 转载 转载 转载 数组a[],a,&a之间的区别

             通俗理解:内存就是公寓房间,指针就是房间的门牌号,数组就是连续的公寓房间,数组名就是这组连续房间的起始地址,也就是第一个房间的地址。

    例如int a[5]   a是数组名,也就是第一个房间号

                                &a就是整个数组的门牌号,值和第一个门牌号相等,但是物理意义不一样。

    下面是转载自别处

    #include<stdio.h>

    int main()

    {

    int a[5];

    printf("%d ",a);   //指向第一个数组元素的首地址            1245036

    printf("%d ",&a);        //指向整个数组的地址                 1245036

    printf("%d ",a + 1);            //a[1]元素的地址                               1245040

    printf("%d ",&a + 1);         //整个数组的字节长度4*5=20           1245056

    printf("%d ",&a[0] + 1);  //下一个元素的地址,下一个门牌号  1245040

    printf("%d ",sizeof(a));

    printf("%d ",sizeof(&a));

     

    return 0;

    }

     

    运行结果:

     

    分析:

        由运行结果可知,数组名a和&a得内存地址相同。我们由数组和指针的关系知道,a代表这个数字,它相当于一个指针,指向第一个元素(&a[0]),即指向数组的首地址。数组中的其他元素可以通过a的位移得到,此时的进阶是以数组中单个的元素类型为单位的。所以有a+1为1245040,即数组中a[1]的地址是1245040(在首地址1245036基础上加int的字节数4得到的)。

        然而,&a代表的不是取a这个变量的地址,而是取数组元素的地址。虽然&a和a得内存地址相同,但它们的意义不相同,它是代表整个数组的,它的进阶单位是整个数组的字节长度(这里是4*5=20),所以&a+1得内存地址为1245056。

     

       其实,a的类型是int[5]   数组

            &a的类型是int(*)[5]  指针——指向int[5]数组的指针

            &a[0]的类型是int*    指针——指向int类型的指针

    另外,当用sizeof时,由于它是个关键词,而不是个函数,所以数组不自动转换为指针,得到的结果是数组的长度*数组中元素类型所占的字节数,本例中sizeof(a)和sizeof(&a)都是20.

     

    ps:如果是(int)a +1,则结果是1245037(即1245036+1)

    另一篇博客:

    C语言规定,数组名代表数组的首地址,也就是第0号元素的地址。所以a==&a[0]

    但对数组名取地址时却要注意了,在理解“对数组名取地址”这一表达式的含义时一定要记住:数组名是“数组”这种变量的变量名

    这样,&a就好理解了,它取的是“数组”这种变量的地址

    &a+1自然也就要跨过整个数组,所有元素长度总和,这么长的一个长度。例如:inta[10],那么&a+1就要跨过10个int的长度

     

    详细分析——

    1 int array[100];

    2

    3 memset(array,  0, sizeof(array));

    4 memset(&array, 0, sizeof(array));

    第3行和第4行有什么不同吗?其实从效果上来说是一样的,但是这里要注意 array 和 &array 的类型是不同的。

    array 相当于 &array[0],它们都是整型指针。而 &array 是一个指向 int[100] 的指针,这是一个数组指针,类型是 int(*)[100],当用数组指针变量来接收它的值时,你会发现它与整型指针array、&array[0]的巨大不同。

    以下代码可以看出这个不同:

    #include <stdio.h>

    int main()

    {

    int array[100] = {0, 1, 2};

    typedef int (*ARRAY)[100];

    int*p1 = array;//数组名代表第0号元素的地址(准确的说应该是代表第0号元素的指针):&array[0],第0号元素是一个整型变量

    ARRAYp2 = &array;

    int*p3 = &array;//实际上赋值符自动向下兼容,将&array转换为了一个整型变量指针:&array[0]

    //或者可能是像空指针可以接收所有类型的指针值一样,各类型的指针都可以接收自己类型的数组指针,并完成兼容性转换,例如int型指针可以接收int数组的数组指针,并转换为int型指针;char型指针可以接收char数组的数组指针,并转换为char型指针。

     

    printf("p1 = 0x%08d ",  p1);

    printf("p2 = 0x%08d ",  p2);

    printf("p3 = 0x%08d ",  p3);

    printf("int=%dbyte ",sizeof(int));

    printf("p1+1=0x%08d ",p1+1);

    printf("p2+1=0x%08d ",p2+1);

    printf("p3+1=0x%08d ",p3+1);

     

    printf("p1[2] = %d ", p1[2]);

    printf("p2[2] = %d ", p2[2]);

    printf("p3[2] = %d ", p3[2]);

    printf("(*p2)[2] = %d ", (*p2)[2]);

    //printf("(*p1)[2] = %d ", (*p1)[2]);//这样编译错误

    //printf("(*p3)[2] = %d ", (*p3)[2]);//这样编译错误

     

    getchar();

    return 0;

    }

    运行结果可能是:

     

     从上面的分析以及程序可以发现:

    指针与地址其实还是有差异的,指针的属性中包含有地址这个概念,而且对于不同的指针,其地址概念却都是相同的,都是用一个数表示内存条上的某个位置。

    但指针的属性中还有大小、距离的概念:

    大小——不同类型的指针,其指向的变量所占据的内存大小不同,即从内存条上的起始位置(即地址)开始,所占据的字节数不同。例如int占4个byte,char占1个byte

    距离——不同类型的指针移动一个单位,其在内存条上移动的字节数不同。例如int型指针+1则移动4个byte,char型指针+1则移动1个byte,数组型指针+1则移动许多许多个byte

  • 相关阅读:
    在HTML中使用JavaScript
    网站发布流程
    React组件
    React渲染和事件处理
    Java IO(三)
    Java IO(二)
    Java IO(一)
    Java常用类库
    Java集合框架(四)
    Java集合框架(三)
  • 原文地址:https://www.cnblogs.com/zhouweibaba/p/10127914.html
Copyright © 2011-2022 走看看