将十六进制值赋给字符变量

3
uint8_t a = 0x1234;

会吗,这是因为0x34是第一个字节。

如果是这样,如何执行检查以确保我分配给a的值不超过uint8_t的大小?


1
应该有一个合适的编译器,警告,不是吗?还是这是关于像 int x = 0x1234; uint8_t = x; 这样的问题?(但是不,34 != 0x34。) - user166390
我刚刚偶然发现了这种行为,尽管没有编译器警告。当我尝试运行它时,变量a实际上取值为0x34,因此我在帖子中所述的假设成立。 - kkh
所以你的问题是如何避免 uint8_t 溢出?uint8_t 只是由 8 个字节组成的无符号整数(通常是无符号字符)。uint8_t 的范围是 0-255,因此在赋值之前,您不能检查 rhs 是否在该范围内吗?例如:int foo = 0x1234; uint8_t bar = 0; if (foo >= 0 && foo <= 0xFF) bar = foo;如果我完全误解了您的问题,请见谅 :) - Chris Parton
1
@ChrisParton:8字节 -> 8位。 - Dietrich Epp
糟糕,我的错!感谢您指出。很遗憾,现在已经太晚了,我无法编辑我的帖子。 - Chris Parton
2个回答

3

jslagle@AR-E642-45QS3R1:~ $ cat test.c

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

int main (int argc, char **argv) {
  uint8_t a = 0x1234;

  printf("%d %x\n",a,a);
  return 0;
}

jslagle@AR-E642-45QS3R1:~ $ gcc -o test test.c
test.c: In function ‘main’:
test.c:5:3: warning: large integer implicitly truncated to unsigned type [-Woverflow]

jslagle@AR-E642-45QS3R1:~ $ ./test
52 34

确实会出现这种情况。如果您这样做,GCC会给您一个警告。


+1 现在,C标准有什么参考资料吗?;-) - user166390
C标准将此定义为未定义行为。 - Joshua
1
@Joshua:这不是未定义行为。无符号类型是模数的,分配超出范围的值保证按照标准完全相同的方式运作(但范围可能不同)。 - Dietrich Epp
@Dietrich Epp:我的 ANSI C 书籍列出了溢出是未定义的。我承认大多数代码都是写成假定模块化的,但这并不保证一定是这样的情况。 - Joshua
@Joshua:仅对于像int这样的有符号类型是未定义的。 如果您的书陈述无符号溢出是未定义的,则该书是错误的。 - Dietrich Epp
显示剩余2条评论

0
在这种情况下,a会取值34吗?因为[34]是第一个字节吗?
不完全是这样。如果您以十六进制格式查看数字,它可能看起来是这样的。但是,如果您以十进制数查看该数字,则0x1234 = 4660(以十进制表示)。与@user1061077上面给出的示例程序一样,存储的值为52,即4660%256,即将数字除以256时的余数。为什么是256?因为在8位内存中,您只能存储从0到255(总共256个数字)的值。当您分配大于256的值时,数字将滚动并最终存储余数。因此,当您尝试存储256而不是4660时,结果值将为0。因此,对于更大的数字,滚动发生的次数将恰好是除法的商:number-to-be-stored / total-number-of-numbers。在您的情况下,它是4660/256的商。

一个值的余数可以通过模函数(简称mod)来计算。例如,4660 mod 256 = 52 = 0x34。要计算2的幂(2、4、8、16、32、64等)的模数,可以使用位掩码并调用算术与运算符。因此,不必调用4660 mod 256,也可以调用2660&256。当从uint32_t转换为uint8_t时,这是隐式完成的。从8到32的所有位都被清零,因此0x34是0x1234的第一个字节的说法是更或多或少正确的(取决于如何定义字节顺序)。 - LittleFunnyMan
@LittleFunnyMan:我知道你所解释的。我使用十进制来明确突出当您分配大于数据类型容量的数字时实际发生的情况。 - yasouser
我只是想说,在你的回答中,听起来像是计算机正在积极地计算以转换值。如果进行算术转换0x1234,则更有可能得到0xFF(如果无符号)。 - LittleFunnyMan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接