• C语言中对数组名取地址


    在C/C++中,数组名相当于一个指针,指向数组的首地址。这里“相当于”不代表等于,数组名和指针还是有很多区别的,这个在《C陷阱与缺陷》里有详尽的讲述。而这里要说的是对于数组名取地址的这么一个操作。

    如果声明有如下数组:

    int arr[5];

    那么,&arr这个操作得到了什么值呢?

    如果简单的认为arr就是一个指向数组首地址的指针的话,那么很自然会想到&arr得到的是一个指向存放arr这个指针的指针,也就是一个二级指针,然而事实却并不是这样。

    观察以下代码:

    int arr[5];
    printf("%p
    %p
    ", arr, &arr);
    
    int *pointer = new int[5];
    printf("%p
    %p
    ", pointer, &pointer);

    在我的电脑上运行的结果如下:

    0024FC08
    0024FC08
    0042B158
    0024FBFC

    我们可以看到,这里pointer这个指针确实如我们所想指向了不同的地址,但是,arr这个数组名的表现却和指针不同,arr和&arr指向的地址是一样的。

    这里便体现除了数组名和指针的一个不同之处:对数组名进行&操作,并不是取其地址,而是得到了指向整个数组的指针。也就是说,arr与&arr指向的是同一个地址,但是他们的类型不一样。arr相当于&arr[0],类型是int *,而&arr是指向整个数组的指针,类型是int (*)[5]。

    而这样的区别显然也会在对指针或者数组名的加减操作中体现出来,看如下代码:

    int arr[5] = { 1, 2, 3, 4, 5 };
    printf("%d
    ", *arr);
    printf("%d
    ", *(arr + 1));
    printf("%d
    ", *((int*)(&arr + 1)));
    printf("%d
    ", *((int*)(&arr + 1) - 1));

    输出为:

    1
    2
    -858993460
    5

    前两个输出是很好理解的,对指针的加一操作会使指针按照指针的类型移动相应的位置。

    第三行输出中,首先得到了指向整个数组的指针,对其进行加一操作,指针就指向了整个数组后面的地址,也就是5后面的地址,那么此时将其转化为int*类型再输出,就得到了该未初始化过的值。

    第四行输出中,过程为,指针指向5后面的地址,转为int*类型,此时的减一操作使指针移动一个int类型大小的地址空间,那么便指向了5。

    这种特性推广到二维至多维指针的情况下都是类似的。

  • 相关阅读:
    Java中String类两种实例化的区别(转)
    Linux内核如何装载和启动一个可执行程序(转)
    CentOS 7 下安装jdk1.8(转)
    MySQL中死锁(转)
    CTF取证方法大汇总,建议收藏!
    实战经验|大神战队都在i春秋教你打CTF
    CTF丨从零开始搭建WEB Docker靶场
    业务逻辑漏洞探索之敏感信息泄露
    实战经验丨业务逻辑漏洞探索之活动类漏洞
    漏洞经验分享丨Java审计之XXE(下)
  • 原文地址:https://www.cnblogs.com/TX980502/p/6671127.html
Copyright © 2020-2023  润新知