将`unsigned char`放入`char`中

时间:2014-05-05 09:53:22

标签: c++ casting

我想通过班次将unsigned char存储到char。由于两种数据类型具有相同的长度(我的机器上有1个字节),我希望以下代码可以工作:

#include <iostream>
#include <cstring>
#include <cstdio>

using namespace std;

int main () {

        printf ("%d\n", sizeof(char));
        printf ("%d\n", sizeof(unsigned char));

        unsigned char test = 49;
        char testchar = (char) (test - 127);
        printf ("%x\n", testchar);

        return 0;
}

但事实并非如此。特别是,我得到了以下输出:

1
1
ffffffb2

表明char已经转换为int。有没有人有解释,希望是解决方案?

5 个答案:

答案 0 :(得分:5)

printf是一个可变参数函数,因此它的参数受默认促销规则的约束。对于这种情况,您的char被提升为int,并在该过程中进行符号扩展。 具有二进制模式0xffffffb2的4字节的2的补码是-78。使用%hhx说明符将其打印为char。

另见Which integral promotions do take place when printing a char?

答案 1 :(得分:5)

%x是4字节int的说明符。要打印一个字节char,请使用%hhx

printf根据传递给它的格式说明符对其参数进行类型转换。这就是testchar类型被提升为int的原因。

答案 2 :(得分:2)

会发生什么!!!!

1)unsigned char test = 49; //十六进制值31被分配

2)char testchar = (char) (test - 127); // 49-127 = -78 ie; 0xb2 {作为unsigned),将其转换为signed char结果F填充b2之前将其指示为否定

3)printf ("%x\n", testchar); //由于%x是4字节int的说明符(因为 @ Do You You Worry Child 表示)ffffffb2 ,获得4字节输出

所以请按照 @不要担心孩子

答案 3 :(得分:1)

%x仅用于打印unsigned int,但您提供char

使用负值为%x的{​​{1}}会导致未定义的行为。

除此之外: char的C标准规范并不是特别清楚;有些人认为传递除printf以外的任何内容都会导致未定义的行为。其他人(包括我自己)认为传递非unsigned int的参数是可以的,但在默认参数促销之后,类型unsigned int具有非负值。该标准确保非负int具有与具有相同值的int相同的表示。

其他一些答案提示unsigned int,但这并不比%hhx好。标准(在合理的解释上)指定%x仅与%hhx参数一起使用,unsigned char仅与%hhd参数一起使用。实际上没有普通signed char的修饰符。

无论你看哪一种方式,都无法使用char以明确定义的方式将负值转换为正值表示。您必须自己转换参数,然后使用匹配的格式说明符。在这种情况下:

printf

是一种选择。 IMO printf ("%hhx\n", (unsigned char)testchar); 可以在这里使用,但如上所述,有些人不同意。

NB。在%x及其后面的行中使用了错误的格式说明符。 printf ("%d\n", sizeof(char));的说明符为size_t。所以你可以使用%zu,或者将参数转换为%zu,甚至更好:

int

答案 4 :(得分:0)

  

我希望以下代码能够正常运行:

不会。

忽略其他人如何打印字符所引发的问题,标准中无法保证您的代码能够正常工作。为什么呢?

因为char不必签名charsigned还是unsigned是否依赖于实现。一些实现使char签名,其他实现使其无符号。

因此,无法保证(char) (test - 127)会产生可由char表示的值。

C ++(14)允许在unsigned charchar之间进行无损转换。 stadnard说(3.9.1 / 1):

  

对于0到255(包括0和255)范围内的unsigned char类型的每个值i,存在类型char的值j,使得从i到{{的整数转换(4.7)的结果1}}是j,从j到char的积分转换结果是i。