0

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

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);

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

4

4 回答 4

2

您需要将转换为unsigned.

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

应该输出:

-1
255
于 2012-09-24T21:49:31.477 回答
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); 
于 2012-09-24T21:53:26.287 回答
0

当你定义一个变量的类型时,你实际上是在告诉编译器它应该如何解释内存中的位。因此,将 char 转换为 unsigned 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 字节整数之前,我们将其转换为无符号字符。这是为了强制编译器首先将这些位解释为无符号位,然后对剩余的 3 个字节进行零扩展(而不是符号扩展)。

希望这会有所帮助=)

于 2012-09-24T22:03:10.343 回答
0

在 char 的 8 位值中,-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 。

于 2012-09-24T22:04:54.183 回答