给定8位整数'c8',必须将位模式复制为32位整数'c32',以使'c32'由重复4次的'c8'组成。例如,

if c8 =     1000 1110,
then c32 =  1000 1110 1000 1110 1000 1110 1000 1110

我已经考虑过这一点,并在C语言中提出了两种方法。但是,我经验不足,因此我不确定最终代码中应该使用哪种方法(如果有)。

最少的例子:
uint8_t c8 = 0b10001110;  // for this example

// method 1
uint32_t c32 = ((c8 << 8 | c8) << 16) | (c8 << 8 | c8);

// method 2
uint16_t c16 = c8 << 8 | c8;
uint32_t _c32 = c16 << 16 | c16;

两种方法都能按预期工作,但是我想知道从专家的角度来看哪一种方法“更好” :-)。

在第一种方法中,我要计算多个班次,而在第二种方法中,我要创建一个额外的变量。我对低级的东西(以及这种低级的东西的表现)没有经验,如果有人可以指出正确的方向,或者找到更好的方法,我将不胜感激。

谢谢。

最佳答案

最好是使用memset。一个好的编译器将其视为intrinsic并以可能的最佳方式对其进行优化。我用GCC 6.3.0,-O3测试了以下程序

#include <stdio.h>
#include <inttypes.h>
#include <string.h>

int main(void) {
    uint32_t target;
    uint8_t byte;

    // if we don't do this, GCC could just *fold the value as a constant*
    scanf("%c", &byte);
    memset(&target, byte, sizeof(target));
    printf("%08" PRIX32 "\n", target);
}

生成的机器代码实际上最终在我的平台上执行的操作类似于:
#include <stdio.h>
#include <inttypes.h>
#include <string.h>

int main(void) {
    uint32_t target;
    uint8_t byte;
    scanf("%c", &byte);

    target = 0x01010101UL * byte;
    printf("%08" PRIX32 "\n", target);
}

08-15 21:54