【问题标题】:How to copy two elements of a list into one bigger element?如何将列表的两个元素复制到一个更大的元素中?
【发布时间】:2020-05-25 20:46:50
【问题描述】:

这是一个例子:

我有一个 uint8_t 元素列表(这不是真正的代码 ^^):

List[0] = 0010 1001
List[1] = 0100 0111

并且有一个无符号短元素(两倍于 uint8_t 的大小)。

我希望我的短元素是这样的:0010 1001 0100 0111

我可以这样移动吗:

ShortElement = (unsigned short) UnsignedInt8List[0];

或者我必须使用二进制调整来移动它吗?

谢谢你:)

【问题讨论】:

    标签: c list casting copying


    【解决方案1】:

    不,您不能简单地转换值。由于unsigned short 始终可以表示uint8_t 中的值,因此该值将保持不变。如果你执行ShortElement = (unsigned short) UnsignedInt8List[0];ShortElement 将被赋值为0000 0000 0010 1001

    您应该使用按位运算来组合值:

    ShortElement = ((unsigned short) UnsignedInt8List[0] << 8) |
                   ((unsigned short) UnsignedInt8List[1] << 0);
    

    这比它需要的要冗长一些,但为了清楚起见,我已经包含了所有内容。它可以等效地写成:

    ShortElement = ((unsigned short) UnsignedInt8List[0] << 8) | UnsignedInt8List[1];
    

    一个注意事项是要小心你的类型。你知道uint8_t 的大小,但你不知道unsigned short 正好是 16 位长,你只知道它必须至少有 16 位长才能容纳范围 [0, 65535] .这在您展示的任何内容中都不是问题,因为至少 16 位,甚至经常建议在安全和方便的情况下使用非固定宽度类型,但请记住这一点。


    一个可能很诱人但您应该做的事情是使用指针来获取值:

    // DO NOT DO THIS, IT IS THE WRONG WAY
    ShortElement = *(unsigned short *) &UnsignedInt8List[0];
    

    不要这样做,您会在许多系统上得到错误的结果,并且可能会直接导致某些系统崩溃。这是未定义的行为。

    【讨论】:

    • 您不能只使用硬编码位算术,因为这会硬编码您所依赖的 CPU 架构,而 OP 并未指定。
    • @liberforce 他们没有指定数组中的内容是 CPU 字节顺序。他们只是指定要以指定方式组合的 8 位值。第一个字节明确显示为用作 16 位值的高 8 位。
    • 你是对的,看到 OP 尝试访问数组作为读取数据的短代码使我专注于字节顺序。我现在不允许删除我的反对票,希望将来能解决这个问题。谢谢你的解释。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-12-20
    • 1970-01-01
    • 1970-01-01
    • 2010-11-12
    • 1970-01-01
    • 1970-01-01
    • 2018-07-17
    相关资源
    最近更新 更多