c - 无符号类型转换并分配给不同字节大小的变量

标签 c casting unsigned signed

有符号整数被分配给无符号整数。使用不同字节大小的无符号整数时,行为看起来有点奇怪。

代码1:

    #include <stdio.h>
    typedef unsigned long   uint32;
    typedef unsigned short  uint16;
    typedef signed short    sint16;

    sint16 rawTCU = -100;

    int main()
    {
        uint32 _tmpSig = 0;
        _tmpSig = (uint32)rawTCU;
        printf("_tmpSig = %d",_tmpSig );
        return 0;
    }

代码2:

    #include <stdio.h>
    typedef unsigned long   uint32;
    typedef unsigned short  uint16;
    typedef signed short    sint16;

    sint16 rawTCU = -100;

    int main()
    {
        uint16 _tmpSig = 0;
        _tmpSig = (uint16)rawTCU;
        printf("_tmpSig = %d",_tmpSig );
        return 0;
    }

代码 1 打印

    _tmpSig = -100

代码 2 打印

    _tmpSig = 65436

我不明白它的行为有何不同,为什么不同的类型会导致不同的值输出。为什么当使用 uint16 进行赋值时它会创建一个不同的值(等于 65536 - 100 = 65436)。这是如何得到优化的,但在使用 uint32 期间却没有得到优化。请提供您的建议,它是如何运作的。谢谢!

最佳答案

当有符号整数类型的负对象被分配(或转换)为具有更大大小的无符号整数类型时,符号位将被传播。

在这个表达式中

_tmpSig = (uint32)rawTCU;

rawTCU 负值的符号位传播到所有 32 位。

在这个表达式中

_tmpSig = (uint16)rawTCU;

有 16 位截断。转换的结果被视为无符号值。所以这两种传播都不会发生。

注意这个调用

printf("_tmpSig = %d",_tmpSig );

有未定义的行为。你必须写

printf("_tmpSig = %lu",_tmpSig );
                  ^^^

关于c - 无符号类型转换并分配给不同字节大小的变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58026788/

相关文章:

c - 在代码中间定义变量可能会产生编译错误

c - 为什么通过强制转换来动态分配结构不起作用?

java - 我们可以在Java中制作无符号字节吗

c - 将带符号的正整数输入为无符号整数(反之亦然)

c++将 union 转换为其成员类型之一

c - C 如何处理符号扩展?

c - 如何用assert实现C宏

c - 应用程序未链接到 CUDA

C 变量传输返回错误

java - Double to Int 无损精度