我有一个值,我知道它小于16(不超过4个比特)在一个int
中。我想将其按位或到一个char
中。我可以这样做吗:
c |= i;
这是否取决于字节顺序(endianness)?如果是问题,那么这样做是否可行:
c |= (char)i;
解决它?
在进行算术运算时,字节序并不重要,只有在以某种其他方式处理值(大于1个char
)时才重要,例如使用char指针遍历保存较大值的缓冲区。
在您的情况下,没有必要进行强制类型转换,自动算术提升会确保一切正常。代码如下:
char c = 0;
int i =3;
c |= i;
等同于
c = c | i;
int
类型,然后再转换回存储类型。c
是char
,而i
是int
。 - James Kanzemodf
函数中,我必须从double中提取指数)。这通常不是问题。 - James Kanzec |= i;
相当于 c = static_cast<char>( static_cast<int>( c ) | i );
。至少在概念上,编译器会将 char
转换为 int
进行 |
操作,然后将结果转换回 char
。(当然,在可以对 char
进行硬件或操作的机器上(大多数机器都不能这么做),编译器很可能会意识到所有这些类型转换对结果没有影响,并放弃它们。) - James Kanze这与字节序无关。 c |= i;
将直接起作用。
char
与 LSB 进行了 OR
操作。但是现在我写这篇文章时,我不确定为什么我曾经会这样想。 - Baruchchar
将与 LSB 进行或运算。无论该字节在 int
的内存布局中的位置如何。 - James Kanzec = c | (0x0f & i);
这也作为提醒,指出源中哪些位是要提取的目标位。c = c | (0x0f & i);
吗? - pmgc = c | (0x0fu & i);
,因为它将强制 C 的隐式类型提升规则确保结果为无符号数(然后截断为 char)。 - Lundinu
将把字面量0x0f转换为unsigned int
类型。这将进而将操作0x0fu & i
的结果转换为无符号整数。这将进而将c | (0x0fu & i)
的结果转换为无符号整数。如果您不知道C中隐式类型提升的工作原理,那么永远不要考虑对有符号整数类型进行位运算。您将会产生大量非常微妙的错误。 - Lundinc
和 i
应该是 unsigned char
和 unsigned int
。但由于他明确表示只使用了四个低位,所以这没关系。 - James Kanze你最好使用 c |= (char)(i);
c |= i;
之前加上一个断言:assert((i&〜0x0F)== 0);
。但那是另外一个问题。) - James Kanzesizeof(c | (char)some_int)
,它将是一个整数的大小。如果你想要一个类型转换来提醒自己某些事情,你应该写成 c = (char)(c | i);
,这至少是有意义的。 - Lundin
char
上进行位运算,情况就更加如此,因为char
可以是有符号或无符号的,它是实现定义行为。 - Lundin