gpt4 book ai didi

c - uint16_t 和 uint32_t 之间的区别

转载 作者:太空宇宙 更新时间:2023-11-04 01:44:12 24 4
gpt4 key购买 nike

在我的代码中,uint16_t 和 uint32_t 之间没有区别。为什么?

我在带有 ARMv7(32 位)的 RasPi 上使用 Raspbian。

root@zentrale:/src# uname -a
Linux zentrale 4.19.42-v7+ #1219 SMP Tue May 14 21:20:58 BST 2019 armv7l GNU/Linux

这是代码:

void main()
{

uint16_t wert1;
uint32_t wert2;

int i;

wert1=2;
wert2=2;
for (i=0; i<33;i++)
{
printf("i: %2d\tLShifted wert1: %10u\t",i,wert1 << i);
printf("RShifted wert1: %10u\t",wert1 >> i);
printf("LShifted wert2: %10u\t",wert2 << i);
printf("RShifted wert2: %10u\n",wert2 >> i);
}
exit(0);
}

这是剥离后的输出:

i:  0   LShifted wert1:          2      RShifted wert1:          2      LShifted wert2:          2      RShifted wert2:          2
i: 1 LShifted wert1: 4 RShifted wert1: 1 LShifted wert2: 4 RShifted wert2: 1
[...]
i: 14 LShifted wert1: 32768 RShifted wert1: 0 LShifted wert2: 32768 RShifted wert2: 0
i: 15 LShifted wert1: 65536 RShifted wert1: 0 LShifted wert2: 65536 RShifted wert2: 0
i: 16 LShifted wert1: 131072 RShifted wert1: 0 LShifted wert2: 131072 RShifted wert2: 0
[...]

我本以为 16 位的 wert1 会随着 i=15 值变为零,正如名称所示,它是 16 位长。

相反,这两个变量没有区别。

我在 Raspian 中找到了 uint16_t 的最大值的一些引用(参见 https://raspberry-projects.com/pi/programming-in-c/memory/variables )

那为什么没有区别呢?

非常感谢!

最佳答案

Both operands of << will undergo integer promotions ,即 C11 6.3.11p2 :

2 The following may be used in an expression wherever an int or unsigned int may be used:

  • An object or expression with an integer type (other than int or unsigned int) whose integer conversion rank is less than or equal to the rank of int and unsigned int.
  • A bit-field of type _Bool, int, signed int, or unsigned int.

If an int can represent all values of the original type (as restricted by the width, for a bit-field), the value is converted to an int; otherwise, it is converted to an unsigned int.

int在您的平台上是 32 位宽,uint16_t 的所有值由 int 表示. uint32_t转换为 unsigned int !

现在他们两个的行为似乎相同因为 GCC 保证了其中的大部分! GCC 支持的所有体系结构上的所有带符号算术都使用 2 的补码;和 additionally GCC does not consider the behaviour << on signed numbers as undefined in the cases where the sign bit is changed .

但是,仍然未定义(即使在 GCC 中)如果移位宽度大于或等于操作数的宽度(在本例中为 32 位)会发生什么,所以 << 32<< 33将有未定义的行为。

除此之外,一般来说,C 标准规定,如果将带符号的正整数左移以便符号位发生变化,则行为是未定义的!当您移动 uint16_t 时会发生这种情况留下这么多位,它将改变 int 的移位位.因此,

(uint16_t)0xFFFF << 16

在 32 位平台上有未定义的行为,因为最高位被移动到 int 的符号位。 , 而

(uint32_t)0xFFFF << 16

不会,因为后者会使用无符号算术。一如既往,编译器可以定义超出标准要求的行为。

关于c - uint16_t 和 uint32_t 之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56881772/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com