比较有符号和无符号字符
Comparison signed and unsigned char
这似乎很奇怪。我发现了误解。我使用带有字符的 gcc 作为签名字符。我一直认为在比较表达式(和其他表达式)中,如有必要,有符号值会转换为无符号值。
int a = -4;
unsigned int b = a;
std::cout << (b == a) << std::endl; // writes 1, Ok
但问题是
char a = -4;
unsigned char b = a;
std::cout << (b == a) << std::endl; // writes 0
如果它不仅仅是按位的,那么比较运算符的魔力是什么?
根据C++标准
6 如果两个操作数都是算术或枚举类型,则通常 对两个操作数执行算术转换;每个 如果指定的关系为真,则运算符应生成 true,并且 如果它是假的,则为假。
所以在这个表达中
b == a
的示例
char a = -4;
unsigned char b = -a;
std::cout << (b == a) << std::endl; // writes 0
这两个操作数都转换为类型 int
。作为结果,有符号字符传播其有符号位,两个值变得不相等。
为了演示效果,请尝试运行此简单示例
{
char a = -4;
unsigned char b = -a;
std::cout << std::hex << "a = " << ( int )a << "'tb = " << ( int )b << std::endl;
if ( b > a ) std::cout << "b is greater than a, that is b is positive and a is negativen";
}
输出为
a = fffffffc' 'b = 4
b is greater than a, that is b is positive and a is negative
编辑:直到现在我才看到变量的定义必须看起来像
char a = -4;
unsigned char b = a;
这是定义中的减号,b ahould 不存在。
由于(unsigned) int
至少为 16 位宽,因此让我们将其用于教学目的:
在第一种情况下:a = 0xfffc
和 b = (unsigned int) (a) = 0xfffc
按照算术转换规则,比较的评估公式为:
((unsigned int) b == (unsigned int) a)
或(0xfffc == 0xfffc)
,这是(1)
在第两种情况下:a = 0xfc
,b = (unsigned char) ((int) a)
或:
b = (unsigned char) (0xfffc) = 0xfc
,即符号扩展到(int)
并截断
由于 和 int
可以表示signed char
和unsigned char
类型的范围,因此比较的评估公式为:(零扩展与符号扩展)
((int) b == (int) a)
或(0x00fc == 0xfffc)
,即(0)
。
注意:在这些情况下,C 和 C++ 整数转换规则的行为方式相同。当然,我假设char
类型是 8 位,这是典型的,但只是所需的最小值。
它们都输出0
因为无符号值可以转换为有符号值,而不是viceversa(如您所说)。
- 从矢量<无符号字符>转换为字符* 包括垃圾数据
- C++中无符号字符溢出
- 使用无符号字符数组有效存储内存
- 在 std::无符号字符的向量处存储 int 的十六进制表示形式
- 如何在保持其值的同时将 c++ 无符号字符变量转换为 char 变量
- 从 std::vector<无符号字符>切片中提取 int?
- 将无符号字符的向量存储在数组中会给我 std::bad_alloc
- 使用 fopen 打开 .pak 文件并使该文件应用于 const 无符号字符* (C++)
- 库特无符号字符
- 寻找一种更好的方法来表示无符号字符数组
- C++ 无符号字符 *{varName};-> C#
- 如何返回/复制unique_ptr<无符号字符[]>的值?
- 将浮点数转换为无符号字符数组并打印出来
- 在函数中返回无符号字符数组,但不返回指针
- 如何在 C/C++ 中将无符号字符*转换为无符号字符数组?
- 如何返回实际值(在我的例子中是无符号字符数组)而不是来自 C++ 函数的指针?
- 如何将带有十六进制值的 std::string 转换为 std::vector<无符号字符>
- 无符号字符打印其 ASCII 值
- 字符数组到无符号字符 *
- 是否可以在 c++ 中将两位数保存在无符号字符中