字符到无符号字符

Posted

技术标签:

【中文标题】字符到无符号字符【英文标题】:Char to unsigned char 【发布时间】:2013-09-16 20:58:14 【问题描述】:

我有一个带有字段的缓冲区结构

    char inc_factor;

这是字符数组中要增加的字节数。问题是它必须能够保持最大 255 的值。显然,最简单的解决方案是将其更改为 unsigned char,但我无法更改提供的结构定义。功能:

    Buffer * b_create(short init_capacity, char inc_factor, char o_mode)

接受这些参数并返回一个指向缓冲区的指针。我想知道如何将数字 255 放入已签名的字符中。

【问题讨论】:

你在写b_create函数吗? 是的,我正在编写 b_create 函数。结构已经给定了,但它必须最多可以取255作为参数 我不明白,如果给出了调用代码,为什么他们试图传递一个 0 到 255 的值??我的意思是他们需要一个字符,而不是无符号字符,但他们传递的值不适合字符... "char" 倾向于表示 8 位值。 “signed char”(简称:“char”)使用最高位来表示符号,而 unsigned 则没有。它们仍然只能存储 0x00-0xff 的值。有符号与无符号前缀仅决定解释。 击败我。规范只是说它必须 x.x 。生病问它是否应该是未签名的。也许这是一个错字,因为我认为否则这是不可能的 【参考方案1】:

你可以转换类型:

unsigned char n = inc_factor;

有符号到无符号的转换定义明确,可以满足您的要求,因为所有三种 char 类型都需要具有相同的宽度。

您可能需要小心 调用 端(或者当您将 char 存储在您的结构中时)并执行类似 f(n - UCHAR_MAX) 左右的操作(同样,如果这是负面的而char 是未签名的,一切都很好)。

【讨论】:

仍然需要将 inc_factor 存储在结构中。 buff->inc_factor = n 。仍然会导致溢出。另外我没有创建调用代码......只是所有函数的实现 @JosipDorvak : 分配 inc_factor 不会 导致溢出,只是重新解释 - 位模式保持不变,并且可以在有符号或无符号字符变量之间互换传递。正如 Kerrek 所指出的,在算术表达式中必须小心,因为这涉及到 int(更大的类型)的隐式强制转换。【参考方案2】:

让我们使用术语“字节”来表示内存中的 8 位存储空间。

值为“0xff”的字节可以作为无符号字符或有符号字符访问。

BYTE byte = 0xff;
unsigned char* uc = (unsigned char*)&byte;
signed char* sc = (signed char*)&byte; // same as "char", the "signed" is a default.
printf("uc = %u, sc = %d\n", *uc, *sc);

(我选择使用指针是因为我想证明存储在内存中的底层值是相同的)。

会输出

uc = 255, sc = -1

“有符号”数字使用与无符号相同的存储空间(位数),但它们使用最高位作为标志来告诉 cpu 是否将它们视为负数。

表示“255”(11111111) 无符号的位模式与表示 -1 的位模式相同。位模式“10000000”是 128 或 -127。

因此,您可以将数字“255”存储在有符号字符中,方法是存储“-1”,然后将其转换为无符号整数。

编辑:

如果您想知道:为了计算方便,负数从“顶部”开始(即 0xff/255)。请记住,底层存储是一个字节,因此如果您取“0xff”并加 1,仅使用正常的无符号 cpu 数学运算,它会产生值“0x00”。当“i = -1”时,哪个是“i + 1”的正确值。当然,如果负数以“-1”开头且值为 0x80/128,则同样奇怪。

【讨论】:

糟糕,我以为问题被标记为 c++,用好的 ol' printf 替换了流运算符 :) 大声笑 :) 我知道这一切。只是价值必须是积极的。我每次使用它时都可以投射它:/ 很多时候遗留代码都有一个只使用“char”的 API,因为他们不太关心(编译器不那么严格),尤其是网络数据等。所以只要投它。就个人而言,我会将函数实现中的变量重命名为“inc_factor_”,并在函数的第一行声明unsigned char inc_factor = (unsigned char)inc_factor_; // there'll be no decrementing for you! @JosipDorvak :您只需要在 b_create 中进行转换,如果您将无符号字符传递给 b_create,编译器会将其隐式转换为 char(可能是有符号或无符号 - 它取决于编译器) 【参考方案3】:

你可以施放它。

 (unsigned char)inc_factor = 250;

然后你也可以用演员表读回来:

 if( (unsigned char)inc_factor == 250 ) ...

但是,这确实不是最佳实践,它会让任何必须维护代码的人感到困惑。

此外,如果您将 inc_factor 传递给需要有符号字符的函数,它也不会帮助您。

无法将该值读取为带符号字符并获得大于 128 的值。

【讨论】:

我想我可以临时做这件事。这是一项任务,因此可维护性并不是非常重要。改天我会澄清这个问题。 (unsigned char)inc_factor 不是 C 中的左值。 您必须投射作业的右轴,而不是左轴:inc_factor = (char)250;。但是强制转换指定了隐式完成的转换,因此没有必要。不过,在需要比较之前转换为 unsigned char

以上是关于字符到无符号字符的主要内容,如果未能解决你的问题,请参考以下文章

字符到无符号字符

从有符号/无符号字符到无符号/有符号整数类型转换的 IA32 汇编代码

C ++十六进制字符串到无符号整数[重复]

如何将 8 字节十六进制枚举值添加到无符号字符指针?

如何在 Rust 中将有符号整数添加到无符号整数,检查无符号溢出?

一元减号和有符号到无符号的转换