• c语言基础知识点(一)C语言中的指针运算和数组名的特性


     

    1. #include
    2. int main()
    3. {
    4. int a[5]={1,2,3,4,5};
    5. int *p=a; printf("p = %p\n",p);
    6. int *ptr = (int *)(&a+1);
    7. printf("ptr=%p\n",ptr);
    8. printf("%d %d\n",*(a+1),*(ptr-1));
    9. printf("sizeof(ptr-1) = %d\n",sizeof(ptr-1));
    10. printf("sizeof(*ptr-1) = %d\n",sizeof(*ptr-1));
    11. }

    结果:

    bfdf6cbdc2d5456eb3dedbfba91b2950.png

    分析

    • p = 0061FF04:这是数组 a 的首地址,即数组名即为数组首元素的地址。
    • ptr = 0061FF18;(&a+1) 会将 &a 的地址加上整个数组 a 所占的字节数(即 sizeof(a)),指向的是数组 a 的末地址加上整个数组大小之后的位置,而不是直接增加整个数组 a 的大小。这是因为数组 a 的类型是已知的,编译器可以根据类型确定数组所占的字节数。

      在代码中,(int *)(&a+1) 的作用是将数组 a 的地址增加了一个数组大小的偏移量,并将其强制转换为 int* 类型的指针。这样得到的指针 ptr 指向了数组 a 之后的内存位置。

      具体来说,&a 取得数组 a 的地址,它等价于 &a[0],即数组首元素的地址。由于 a 是一个具有 5 个元素的整型数组,而每个整型元素占据 4 个字节的空间(取决于系统平台),所以 (&a + 1) 得到的地址值向后增加了 sizeof(int) * 5 个字节的偏移量。

      例如,假设数组 a 的首地址是 0x7ffd9aee3e40,那么根据 sizeof(int) * 5 的偏移量计算,可以得到 (&a + 1) 的地址为 0x7ffd9aee3e40 + sizeof(int) * 5 = 0x7ffd9aee3e40 + 20 = 0x7ffd9aee3e54。而 ptr 被强制转换为 int* 类型后,就指向了这个地址。

    • *(a+1):这是数组 a 的第二个元素的值,即 2
    • *(ptr-1):这是 ptr 的前一个位置的值,即数组 a 的最后一个元素的值,即 5
    • sizeof(ptr-1):这是 ptr-1 表达式的大小,由于 ptr-1 是一个指针类型,所以大小为 4 字节(32位系统)。
    • 在32位系统中,整数类型通常占用4个字节的空间,所以 sizeof(*ptr-1) 的结果为 4

    383d279aadc442869ec6689c5fe63b9d.png

     二级指针,&arr代表整个数组,加一跳过数组。一级解引用获得指向尾后元素的指针(这里我的理解是指向整个数组首地址指针退化为指向数组首元素地址的指针),减一(也就是往前偏移一个数组元素地址的大小)再解引用得到5。

     

     

    c899add0108e4d6bafdae13a96285d3b.png

     b514b0e7121f483fa37b29e814ac780a.jpeg

     

     

     

     

     

     

     

     

     

     

     

     

  • 相关阅读:
    [python][学习]循环与嵌套---打印乘法口诀
    微信小程序自定义图片上传组件
    关于EMC的这些经典问题,你必须知道
    数据结构与算法-(7)---栈的应用-(3)表达式转换
    ATPCS:ARM-Thumb程序调用的基本规则
    24年计算机等级考试22个常见问题解答❗
    随机森林计算指标重要性—从决策树到随机森林Python实现
    【Java后端】美团提前批一面和二面面经!
    零时科技 || Earing Farm攻击事件分析
    山东大学软件学院项目实训-创新实训-网络安全靶场实验平台(十一)
  • 原文地址:https://blog.csdn.net/qq_51519091/article/details/132868011