字符到无符号字符
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 汇编代码