指定十六进制值为字符

问题描述:

uint8_t a = 0x1234; 

a == 34?这是因为0x34是第一个字节吗?指定十六进制值为字符

如果是这样,我怎么进行检查,以确保我分配到a值不超过uint8_t大小?

+1

应该有一个合适的编译器,警告,否?或者这是一个关于'int x = 0x1234; uint8_t = x;'? (但不,34!= 0x34。) – 2011-11-23 03:28:03

+0

嗯我只是偶然发现了这样的行为,虽然没有编译器警告。当我试图运行它变量a实际上取值为0x34,因此我的假设在后 – edelweiss

+0

陈述因此,你的问题是避免在uint8_t溢出? uint8_t只是一个由8个字节组成的无符号整数(通常是一个无符号字符)。 uint8_t的范围为0-255(含),因此在分配值之前,您是否可以不检查rhs是否在该范围内?例如 'int foo = 0x1234; uint8_t bar = 0; 如果(FOO> = 0 && FOO

jslagle @ AR-E642-45QS3R1:〜$猫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; 
} 

[email protected]:~ $ gcc -o test test.c 
test.c: In function ‘main’: 
test.c:5:3: warning: large integer implicitly truncated to unsigned type [-Woverflow] 

[email protected]:~ $ ./test 
52 34 

它确实那样做。如果你这样做,GCC会给你一个警告。

+0

+1现在,哪里有一个C标准要说的内容的参考;-) – 2011-11-23 03:34:59

+0

C标准使这种未定义的行为。 – Joshua

+0

嗯,我使用visual studio 2010.但从未给出任何警告。 – edelweiss

在这种情况下,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的商。

+0

其余值可以用模函数(简称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

+0

@LittleFunnyMan:我知道你说了什么。我使用十进制来明确地指出当分配一个大于数据类型容量的数字时真正发生的事情。 – yasouser

+0

我只是想说,在你的回答中,听起来像计算机正在积极计算投入价值。算术铸造0x1234更可能导致0xFF(如果未签名)。 – LittleFunnyMan