对于所有系统,是否存在通用的"隔离单字节"位掩码,而不管CHAR_BIT如何?

Gov*_*mar 2 c byte

如果CHAR_BIT == 8在目标系统上(大多数情况下),屏蔽单个字节非常容易:

unsigned char lsb = foo & 0xFF;
Run Code Online (Sandbox Code Playgroud)

但是,有一些系统和C实现,其中CHAR_BIT既不是8也不是其倍数.由于C标准仅规定了值的最小范围char,因此无法保证屏蔽0xFF将为您隔离整个字节.

我一直在寻找有关通用"字节掩码"的信息,但到目前为止还没有找到任何东西.

总有O(n)解决方案:

unsigned char mask = 1;
size_t i;
for (i = 0; i < CHAR_BIT; i++)
{
    mask |= (mask << i);
}
Run Code Online (Sandbox Code Playgroud)

但是,我想知道在某个地方是否有任何O(1)宏或代码行可以实现这一点,考虑到这个任务在许多系统级编程场景中的重要性.

Eri*_*hil 7

unsigned char从整数值中提取一个最简单的方法就是将其强制转换为unsigned char:

(unsigned char) SomeInteger
Run Code Online (Sandbox Code Playgroud)

根据C 2018 6.3.1.3 2,结果是SomeInteger模数的余数UCHAR_MAX+1.(这是一个非负余数;它总是被调整为大于或等于零且小于UCHAR_MAX+1.)

分配给a unsigned char具有相同的效果,因为赋值执行转换(并且初始化也起作用):

unsigned char x;
…
x = SomeInteger;
Run Code Online (Sandbox Code Playgroud)

如果你想要一个显式位掩码,UCHAR_MAX就是这样一个掩码.这是因为无符号整数在C中是纯二进制,并且无符号整数的最大值设置了所有值位.(无符号整数一般也可能有填充位,但unsigned char可能没有.)

在非常古老或深奥的系统中可能会出现一个区别:如果有符号整数用符号和一个补码表示而不是今天无处不在的二进制补码,那么unsigned char从负值中提取一个的结果将根据您是否使用而有所不同转换方法或位掩码方法.

  • @P__J__:C标准"仅"要求`UCHAR_MAX`至少为255.在5.2.4.2.1中,它要求`UCHAR_MAX`为`unsigned char`类型的对象的最大值.由于`unsigned char`是具有所有值位且没有填充位的纯二进制,所以最大值都设置了所有位,因此`UCHAR_MAX`必须设置所有位. (2认同)