为什么以下不将两个字符解释为16位组?
char c[2];
c[0] = 2;
c[1]= 2;
short a = short(c[0]);
我想两个人一起读取数据全部16位?什么是最快(延迟)的方式?
答案 0 :(得分:2)
你必须写入实际的短片。你可以这样做:
short a;
unsigned char * p = reinterpret_cast<unsigned char *>(&a);
p[0] = 2;
p[1] = 2;
答案 1 :(得分:2)
获取机器本机字节顺序的最便携方式是:
char c[] = { whatever, from whatever source };
short s;
memcpy(&s, c + offset, sizeof (short));
大多数优化编译器会将其转换为等效的
short s = *(short*)(c + offset); // C-style cast, equivalent to C++ reinterpret_cast
(这只是一个典型的16位内存访问,非常快)
由于编译器知道别名的重要区别,不会违反任何语言规则。编译器还将做必要的事情来处理那些重要的架构上的对齐。
特定字节排序的可移植代码更简单:
short s = (c[offset + 1] << 8) | (uint8_t)c[offset]; // little-endian
short s = (c[offset] << 8) | (uint8_t)c[offset + 1]; // big-endian
当指定的字节顺序与机器匹配时,优化器将再次(非常高的可能性)生成单个16位访问指令。
答案 2 :(得分:1)
您正在使用第一个char
,即2
,然后您将该单个值转换为short
。已经太晚了:到演员阵容发生时,你的代码完全忘记了其他char
。你只将其中一人送进演员阵容。
你必须使用指针来假装编译器你有一个16位宽的单个对象,你可以用reinterpret_cast
来做。
答案 3 :(得分:1)
使用联盟!这样,在您将数据读入字符后,您可以立即将数据视为已经短暂的数据。
根据您的需要,您甚至可能不需要复制短片,只需使用“短片”:)
union
{
char c[2];
short s;
}
c[0] = 2;
c[1] = 2;
short a = s;
在你的另一个问题中,你首先询问为什么这是一个问题。
当您访问c [0]时,您正在访问一个字符。您希望计算机“知道”您也想要周围的数据。 c [0]的访问明确表示您只想访问该单个字符中的数据。
答案 4 :(得分:0)
因为你只是将c [0]的值赋给a。你的最后一行与:
相同short a = c[0];
执行所需操作的一种方法是使用按位运算复制c [0]和c [1]:
short a = (short)(c[0] + (c[1] << 8));
请注意,我将结果转换为(short),因为gcc将按位结果转换为int。