• C语言深度剖析自测题8解析


    #include <stdio.h>

    int  main(void) {
        int  a[5] = {1, 2, 3, 4, 5};

        int* ptr1 = (int*)(&a + 1);

        int* ptr2 = (int*)((int)a + 1);

        printf("%x, %x ", ptr1[-1], *ptr2);

    }

     这个题目主要是考了两个知识点一个是指针的知识,第二个是大端机和小端机的知识

    首先需要明确x86是小端机,所以它的数值在各个字节中的顺序是从小到大的

    比如对于int型的数值其在内存中的编码就是 1 0 0 0

    在解释清楚这一点后,正式的解析下这道题目

    int* ptr1 = (int*)(&a + 1);

    &a 对数组名进行取地址,数组名所代表的是一个有5个int元素的数组,所以&a代表的就是一个代表有五个元素的数组的指针

    所以这里的(&a + 1)实际上就是取得了a[4]也就是数字5后面的地址,这样又将其转换为一个int*指针,此时的ptr1就是一个指向

    a[5]后地址的int型指针,ptr1[-1]其实就等价于*(ptr1-1)这样的运算,所以ptr1-1得到的就是a[4]的地址所以得出的第一个值就是a[4]的值

    也就是5.

    接下来再对第二个指针进行分析,(int)将一个指针值转换为了int值,(int)a+1就是a的地址值加上1,a是int*类型的所以a+1的话其值实际上

    了4,而现在将a转换为int型的所以这样就相当于给其值加上1,这个的作用效果和(char*)a + 1是相同的.然后这里又将该值转换为一个int*类型

    的指针,所以当使用*ptr2的时候就会取四个字节,并读取出其中的值.

    因为是小端机所以1在4个字节中的分布是0x01 0x00 0x00 0x00, 2在4个字节中的分布是 0x02 0x00 0x00 0x00

    此时ptr2指向的是a中的第二个字节所在的地址,所以当取4个字节时实际取到的是 0x00 0x00 0x00 0x02这样当将其解释出真是的值实际是

    0x02 0x00 0x00 0x00 这里的输出使用的是%x所以输出的是十六进制的数字,所以输出了2000000.

  • 相关阅读:
    基础
    基础
    基础
    基础
    基础
    基础
    基础
    基础
    Gym102361A Angle Beats(直角三角形 计算几何)题解
    Petrozavodsk Summer Training Camp 2016H(多标记线段树)题解
  • 原文地址:https://www.cnblogs.com/coder-zhang/p/3733910.html
Copyright © 2020-2023  润新知