• 数组的首地址,数组名取地址,地址的强制转换为int


    来源:http://blog.csdn.net/normal_cai/article/details/8252603

    #include <stdio.h> 

    int main() { int a[5]={7,8,9,10,11}; int *ptr1=(int *)(&a+1);
    int *ptr2=(int *)((int)a+1);

    printf("%d ",&a); printf("%d ",(int)a); printf("%d,%d ",ptr1,ptr2); printf("%d,%x ",ptr1[-1],*ptr2);

    return 0; }

    输出结果:

    1245036 1245036 1245056,1245037 11,8000000 Press any key to continue 结果怎么会是这样的呢???特别是&a,(int)a的值都是1245036 那么分别加以后怎么结果不是一样的???还有就是*ptr2的值(十六进制)是:80000这个值不是随机数呢??(我开始认为是的,但实际不是的),让我们来一起分析一下:

    首先我们要知道a[5]={7,8,9,10,11};的意思:在内存中开辟一个数组大小是: sizeof(int)*5=4*5=20个字节(一个整形占4个字节),那么数组名a的值就是这片内存单元的首地址

    我们看到printf("%d ",&a);printf("%d ",(int)a);输出的结果:1245036 1245036,我们可以知道&a是上面内存单元的首地址,(int)a是把首地址转换成int的数据。

    int *ptr1=(int *)(&a+1); 其中&a+1,不是简简单单的加一,而是加上数组的大小(表示指针移到数组内存单元的最后的下一个单元地址)为什么???那是因为系统在内存中(具体的说应该是栈中)为数组分配一个连续大小为20字节的大小,并把首地址赋值给数组名a,那么&a+1就是表示这个内存的下一个地址,这个加一不是我们平时说的整数1,而是数组的大小即1245036+20=1245056,那么指针变量ptr1就是指向此内存单元,那么*ptr表示地址为1245056单元的内容,而ptr1[-1]等价于*(ptr1-1),ptr1-1即先把指针后移一个,不是指向数组的最后一个元素吗??,那么*(ptr1-1)不就是数组最后的值吗???即11,十六进制是b

    而int *ptr2=(int *)((int)a+1); 就是在1245036+1=1245037,这又是为什么???原因很简单那是因为:(int)a表示的把数组地址即内存单元的编号转换成整数,那么此时的(int)a+1加一相当于加一个整数!!

    注意1245037在于数组第一个和第二个元素地址中间(可以数组数组的第一元素和第二个元素的地址分别是:1245036 1245040),那么*ptr2的值就是第一个元素的二进制和第二个元素的二进制的组合:那我们看看数组第一元素和第二个元素的二进制是:

    7的二进制:0000 0000 0000 0000 0000 0000 0000 0111

    8的二进制:0000 0000 0000 0000 0000 0000 0000 1000

    那么*ptr2的值就是从7的二进制的第二个字节开始数四个字节(即取7的后三个字节和8的第一个字节):

    0000 0000 0000 0000 0000 0111 0000 0000

    注意在内存是先放低字节,然后是高字节,那么计算的时候的到过来即:0000 0000 0111 0000 0000 0000 0000 0000 0000

    那么对应的十六进制是:0080000,即80000

  • 相关阅读:
    Spark Streaming(一)
    ACID
    SparkSQL
    scala样例类
    centos7 防火墙有关命令
    HBase优化
    scp
    HBase与Hive
    HBase与MapReduce交互
    Hadoop安全模式
  • 原文地址:https://www.cnblogs.com/mangci/p/3321051.html
Copyright © 2020-2023  润新知