取消引用的联合成员字节不相同
Dereferenced union member bytes are not the same
根据 learnc 的教程,我正在试验一些关于指针和联合的非常基本的东西。在下面的代码中,我创建了一个 struct operator
和一个由 float
、double
和 int
组成的匿名 union
。由于 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)
吗?
Shouldn't &(op.intNum)
== &(op.doubleNum)
== &(op.floatNum)
?
是的,他们应该,他们确实是。
为了打印地址,使用 %p
作为格式说明符,并将其转换为 void*
。在 How to print variable addresses in C?
中阅读更多内容
编辑:Why do I have to cast my memory address to (void *)?
&(op.intNum) + 1
是op.intNum
结束后的地址。
即如果op.intNum在地址A,sizeofop.intNum为4,那么你写的表达式的值为A+4。
这是指针算法定义方式的结果。
在您的情况下,您没有取消引用联合,为了取消引用,您需要将 op 声明为指针。
仅供参考:
在您的代码中打印
int 成员的地址,而 sizeof(int) 在你的架构中是 4,所以增加 1,你的地址将是 address + sizeof(int)
double 成员的地址和 sizeof(double) 在 8 中,在这种情况下,每次递增后,您的地址将是地址 + 8
希望这会有所帮助。
根据 learnc 的教程,我正在试验一些关于指针和联合的非常基本的东西。在下面的代码中,我创建了一个 struct operator
和一个由 float
、double
和 int
组成的匿名 union
。由于 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)
吗?
Shouldn't
&(op.intNum)
==&(op.doubleNum)
==&(op.floatNum)
?
是的,他们应该,他们确实是。
为了打印地址,使用 %p
作为格式说明符,并将其转换为 void*
。在 How to print variable addresses in C?
编辑:Why do I have to cast my memory address to (void *)?
&(op.intNum) + 1
是op.intNum
结束后的地址。
即如果op.intNum在地址A,sizeofop.intNum为4,那么你写的表达式的值为A+4。
这是指针算法定义方式的结果。
在您的情况下,您没有取消引用联合,为了取消引用,您需要将 op 声明为指针。
仅供参考:
在您的代码中打印
int 成员的地址,而 sizeof(int) 在你的架构中是 4,所以增加 1,你的地址将是 address + sizeof(int)
double 成员的地址和 sizeof(double) 在 8 中,在这种情况下,每次递增后,您的地址将是地址 + 8
希望这会有所帮助。