转换指针地址偏移量各不相同

时间:2013-10-22 10:04:35

标签: c endianness

我写了一段代码来确定我的系统的字节顺序。但输出让我感到困惑。

...
    int a = 0x12345678;
    uint8_t c0, c1, c2, c3;

    c0 = *( (uint8_t *)&a   );
    c1 = *( (uint8_t *)&a+1 );
    c2 = *( (uint8_t *)&a+2 );
    c3 = *( (uint8_t *)&a+3 );

    /* Print addresses of all the variables. */
...

输出:

&a : 0xbf9b23f8  
&c0: 0xbf9b23fc   // &c0 - &a = 4, Why &a != &c0 ? 
&c1: 0xbf9b23fd    
&c2: 0xbf9b23fe    
&c3: 0xbf9b23ff

如果我评论一些陈述,偏移量会有所不同。

...
    int a = 0x12345678;
    uint8_t c0;

    c0 = *( (uint8_t *)&a   );
...

输出:

&a : 0xbf893788
&c0: 0xbf89378f    // &c0 - &a = 7 ??

3 个答案:

答案 0 :(得分:1)

我可以建议一种更简单的方法吗?

int a=0x01234567;
unsigned char *c;
c = (unsigned char*)(&a);
for(int i=0; i<4; i++) {
  printf("byte %d = %02x\n", i, c[i]);
}

但要回答您的基本问题 - 当您将变量c0设置为等于a的第一个字节的值时,这并不意味着它们共享相同的地址......

始终保持代码尽可能简单,但不能简单。

答案 1 :(得分:0)

刚刚修改了源代码中的一些内容,

#include <stdio.h>
#include <stdint.h>  // for uint8_t
#include <stdlib.h>

int main(void)
{
    int a = 0x12345678;
    uint8_t *c0, *c1, *c2, *c3; // Changed to pointers

    c0 = (uint8_t *)&a;      //address is stored
    c1 = (uint8_t *)&a+1;
    c2 = (uint8_t *)&a+2;
    c3 = (uint8_t *)&a+3;

    printf("&a : %p\n", (void *)&a );
    printf("&c0: %p\n", (void *)c0);
    printf("&c1: %p\n", (void *)c1);
    printf("&c2: %p\n", (void *)c2);
    printf("&c3: %p\n", (void *)c3);
    exit(0);
}

输出:

&a : 0022FF34
&c0: 0022FF34
&c1: 0022FF35
&c2: 0022FF36
&c3: 0022FF37

答案 2 :(得分:0)

您正在打印变量的地址。为什么期望地址改变?它包含从另一个变量的部分地址复制的数据,但是c0到c3的地址与您使用它们的算法之间没有关系(打印a每字节字节的地址)

  

&amp; c0 - &amp; a = 4,Why&amp; a!=&amp; c0?

因为它们是不同的变量。

  

如果我评论一些陈述,偏移量会有所不同。

编译器可以随意在堆栈上分配对象。您无法预先知道变量将在堆栈中分配的方式或位置。编译器很可能会尝试在堆栈框架中正确对齐变量。