转换为unsigned char无效

时间:2012-09-24 21:46:02

标签: c types

我有一个非常恼人的问题。这是我正在使用的缓冲结构

typedef struct BufferDescriptor {
   char * ca_head ;    /* pointer to the beginning of character array (character buffer) */
   int capacity ;      /* current dynamic memory size (in bytes) allocated to character buffer */       
   char inc_factor;    /* character array increment factor */
   int addc_offset ;    /* the offset (in char elements) to the app-character location */
   int mark_offset ;   /* the offset (in chars elements) to the mark location */
   char r_flag;        /* reallocation flag */
   char mode;          /* operational mode indicator*/

} Buffer ;

我无法对上述代码进行任何更改。 inc_factor应该能够取0到255之间的值。

因此,在创建缓冲区的函数中,我执行以下操作以确保inc_factor不是负数:

Buffer* b_create(int init_capacity, char inc_factor,char o_mode){
    Buffer* buffer = (Buffer*)malloc(sizeof(Buffer));
    buffer->ca_head=(char*)malloc(sizeof(char)*init_capacity);

    buffer->inc_factor=(unsigned char)(inc_factor);

但是以下行给出了一个负数:

printf("inc factor = %d",buffer->inc_factor);

我在这里做错了什么? Plz帮助。

4 个答案:

答案 0 :(得分:2)

您需要在使用值的任何地方投射unsigned

char value = 255;
printf("%d\n", value);
printf("%d\n", (unsigned char) value);

应输出:

-1
255

答案 1 :(得分:2)

您正在将signed变量格式化为signed值,因此如果变量超过127,它会输出负值。这就是存储unsigned时会发生的情况将值转换为signed变量 - 它包含在负数中。如果您无法更改变量类型本身,则必须更改其格式(将signed值类型转换为unsigned类型,然后分配给signed变量无意义):

printf("inc factor = %u", (unsigned char) buffer->inc_factor); 

或者:

printf("inc factor = %d", (unsigned char) buffer->inc_factor); 

答案 2 :(得分:0)

当你定义一个变量的类型时,你实际上是告诉编译器应该如何解释内存中的位。因此,将char转换为unsigned char不会更改内存中的位,但实际上会影响数据对其使用的操作的影响。

在你的情况下,你施放它,但存储回一个签名的字符。当编译器读取数据时(记住,没有位被修改),它被解释为signed char,因为它是BufferDescriptor.inc_factor的类型。

最简单的解决方案是在使用它时进行投射:

printf("inc factor = %d",(unsigned char)buffer->inc_factor);

但这里存在严重而危险的错误。编译器会在键入解释时将参数推送到堆栈(在本例中为单字节无符号字符)。问题是printf函数从堆栈中删除参数,因为它们键入你告诉它解释(在这种情况下,%d通常表示4字节整数)。如您所见,缺少3个字节。 printf将强制读取这三个字节,因此它实际上会从内存中获取无效数据。

要解决此问题,请将其作为4字节整数推送到堆栈:

printf("inc factor = %d",(int)((unsigned char)buffer->inc_factor));

请注意,在将它转换为4字节整数之前,我们将其转换为unsigned char。这是为了强制编译器首先将这些位解释为无符号,然后对剩余的3个字节进行零扩展(而不是符号扩展)。

希望这有助于=)

答案 3 :(得分:0)

在8位char值中,-1 = 1111 1111(二进制),255 = 1111 1111(二进制)。所以它的表示方式完全取决于你如何施展它。

如果你没有施放printf(" inc factor =%d",buffer-> inc_factor);您将打印-1,因为%d正在尝试打印带符号的小数。如果您将打印值转换为:

printf("inc factor = %d", (unsigned char) buffer->inc_factor);

你将打印255.你应该将一个局部变量存储为:

unsigned char unsigned_char_inc_factor = (unsigned char) buffer->inc_factor;

之后才使用unsigned_char_inc_factor。