C 取消引用的联合成员字节不相同

C 取消引用的联合成员字节不相同,c,memory,unions,C,Memory,Unions,从learnc的教程中,我正在试验一些关于指针和联合的非常基本的东西。在下面的代码中,我创建了一个struct操作符,它具有一个匿名的联合,由浮点、双精度和整数组成。由于double是最大的一个,有八个字节,我希望看到我的int有八个字节,确实如此。但是,它们与double的字节不同 typedef enum { INTEGER = 0, FLOAT = 1, DOUBLE = 2, } operator_type; typedef struct operator {

从learnc的教程中,我正在试验一些关于指针和联合的非常基本的东西。在下面的代码中,我创建了一个
struct操作符
,它具有一个匿名的
联合
,由
浮点
双精度
整数组成。由于
double
是最大的一个,有八个字节,我希望看到我的
int
有八个字节,确实如此。但是,它们与double的字节不同

typedef enum {
    INTEGER = 0,
    FLOAT = 1,
    DOUBLE = 2,
} operator_type;

typedef struct operator {
    operator_type type;

    union {
        int intNum;
        double doubleNum;
        float floatNum;
    };
} operator_t;

int main() {

    operator_t op;
    op.type = FLOAT;
    op.floatNum = 3.14f;

    printf("op.intNum = %i\nop.doubleNum = %f\nop.floatNum = %f\n", op.intNum, op.doubleNum, op.floatNum);

    printf("op.intNum [%i, %i, %i, %i, %i, %i, %i, %i, %i]",
           &(op.intNum) + 0,
           &(op.intNum) + 1,
           &(op.intNum) + 2,
           &(op.intNum) + 3,
           &(op.intNum) + 4,
           &(op.intNum) + 5,
           &(op.intNum) + 6,
           &(op.intNum) + 7,
           &(op.intNum) + 8
           );

    printf("op.doubleNum [%i, %i, %i, %i, %i, %i, %i, %i, %i]",
           &(op.doubleNum) + 0,
           &(op.doubleNum) + 1,
           &(op.doubleNum) + 2,
           &(op.doubleNum) + 3,
           &(op.doubleNum) + 4,
           &(op.doubleNum) + 5,
           &(op.doubleNum) + 6,
           &(op.doubleNum) + 7,
           &(op.doubleNum) + 8
    );

    return 0;
}
我得到输出:

op.intNum [-13304, -13300, -13296, -13292, -13288, -13284, -13280, -13276, -13272]
op.doubleNum [-13304, -13296, -13288, -13280, -13272, -13264, -13256, -13248, -13240]
不应该
&(op.intNum)=&(op.doubleNum)==&(op.floatNum)

不应该
&(op.intNum)
=
&(op.doubleNum)
=
&(op.floatNum)

是的,他们应该,他们是

要打印地址,请使用
%p
作为格式说明符,并将其强制转换为
void*
。阅读更多

编辑:

&(op.intNum)+1
是紧跟在
op.intNum
末尾的地址

也就是说,如果op.intNum位于地址A,并且op.intNum的大小为4,那么您编写的表达式的值为A+4


这是指针算术定义的结果

在您的情况下,您不解除对union的引用,对于解除引用,您需要将op声明为指针

供参考:

在代码中打印

  • int成员的地址,并且sizeof(int)在您的体系结构中是4,所以增加1,您的地址将是address+sizeof(int)

  • 双成员地址和sizeof(double)在8中,在这种情况下,每次递增后,您的地址将是地址+8


希望这会有所帮助。

您正在打印什么?该联合存储的八个字节中每个字节的int表示形式?您是否试图打印这些字节的地址或值?对不起,是的,地址不是值。要打印指针,您应该使用格式说明符
“%p”
,并强制转换为
(void*)
,但是这些都是指向
int
,所以你也不会得到预期的结果。。。实际上,将它们转换为
(void*)
是使它们具有相同输出的原因,因为
%i
,所以输出格式可能毫无意义,但我仍然感兴趣的是,
(void*)
转换是必要的。@tacos_tacos_tacos_tacos关于这一点,请参阅例如@tacos_tacos_tacos_tacos_tacos我发布了一份Bob的副本。指针可以有不同的表示形式,因此需要将它们转换为通用的形式。。