很抱歉尝试以另一种方式询问此question。
typedef struct
{
char duo_word[8];
} duo_word;
duo_word duo_word_inst = { .duo_word = { 'º', '\b', '\x1', '\0', 'À', '\xe', '2', 'a' } };
printf(" %i ", duo_word_inst); // gives 67770 but how?
如何将67770值提取到例如一个int变量?
答案 0 :(得分:3)
%i
的{{1}}格式说明符需要printf
作为参数。但是,您传递的是int
。使用错误的duo_word
格式说明符调用undefined behavior。在这种情况下,你很幸运"它碰巧打印出你想要的东西,但你不能依赖这种行为。
假设struct中的前4个字节表示小端格式的32位整数,则可以拉出各个字节并将它们设置为整数,如下所示:
printf
答案 1 :(得分:1)
这是未定义的行为,所以任何事情都可能发生。
可能发生的事情是duo_word_inst
只会粘贴在堆栈上
而%i
只会导致printf
从该堆栈值中分割sizeof(int)
。
您可以通过简单地使用memcpy
手动并以定义的方式完成所有操作:
#include <stdio.h>
#include <string.h>
typedef struct
{
char duo_word[8];
} duo_word;
int main()
{
duo_word duo_word_inst = { .duo_word = { 'º', '\b', '\x1', '\0', 'À', '\xe', '2', 'a' } };
int x;
memcpy(&x, &duo_word_inst, sizeof(x));
printf(" %i ", x); //prints 67770 too
#if UNDEFINED_BEHAVIOR
printf(" %i ", duo_word_inst); // gives 67770 but how?
#endif
return 0;
}
(更好的方法是在dbush的答案中使用bitops粘贴值,从而避免实现定义的行为。)
答案 2 :(得分:0)
对于与您认为正在解决的问题不同的问题,您的代码可能是错误的解决方案。
首先,数组char [8]
不能用于可靠地存储整数值。这是因为char
类型具有实现定义的签名。这意味着编译器可以随心所欲地将其实现为有符号或无符号。在这个内部,你将角色存储在基本角色之外,所以不知道你的代码会做什么。
如果您希望存储原始数据,则必须使用uint8_t
中的stdint.h
。
然后正如其他人所指出的那样,你不能使用%i
打印结构,也不能打印字符数组。如果你很幸运,你会得到某种看似确定的行为,但正式地说这是完全未定义的行为。在你的情况下,它可能将字节视为一个4字节的小端数,'º', '\b', '\x1', '\0'
给出了十六进制00 01 08 BA,而这又是dec 67770.该程序可能会崩溃或打印垃圾,因为你依赖未定义的行为。它今天可以工作,明天也会崩溃。
为了确定性地,便携且可靠地获得值67770,您可以执行以下操作:
#include <stdint.h>
#include <stdio.h>
#include <inttypes.h>
typedef union
{
uint8_t bytes [8];
uint32_t ints [2];
} duo_word;
int main (void)
{
duo_word dw = { .bytes = { 0xBA, 0x08, 0x01, 0x00 } };
printf("%"PRIu32, dw.ints[0]);
}
这使用&#34;类型惩罚&#34;通过一个联合,这在C中是可以的(但不是在C ++中)。这仍然假设您正在使用一个小端CPU。对于真正的可移植代码,您必须改为使用位移。