c中有符号和无符号字符之间的区别

Difference between in signed and unsigned char in c

C 中有符号和无符号 char 有什么区别?当我尝试在没有 unsigned 的情况下 运行 以下代码时,它进入了一个无限循环,因为有符号字符的范围最大为 127 (为什么默认情况下它是有符号的?)。但是当我添加 unsigned (其范围最大为 255)时,它工作正常。什么原因?

#include <stdio.h>

int main() {
    unsigned char x;
    x = 0;
    while (x <= 225) {
         printf("%c=%d\n", x, x);
         x = x + 1;
    }
    return 0;
}

C语言没有专门的"character type"。 char 是整数类型,(在这方面)与 int、short 和其他整数类型相同。

  • 都是整型
  • 它们的大小相同(一个 btye)。

如果您使用数字作为字符

  • Signed char,它至少为您提供 -127 到 127 的范围。 (-128 至 127 很常见)
  • 无符号字符,它至少为您提供 0 到 255 的范围。

来自 3.9.1 基本类型

Plain char, signed char, and unsigned char are three distinct types. A char, a signed char, and an unsigned char occupy the same amount of storage and have the same alignment requirements (3.11); that is, they have the same object representation.

有符号字符范围是 -128 到 127。无符号字符范围是 0 到 255。 如果 x 变量定义为无符号字符,您的 while 循环将按预期工作。

如果你用signed char定义变量,那么变量'x'位于-128到127之间。它总是小于255。

同声明

x=x+1;

发生了一些事情。

首先将计算表达式 x + 1。这将导致 usual arithmetic conversion of the value in x so it becomes promoted to an int。 (提升的)值将增加 1,然后将结果分配回 x。问题从这里开始。

因为 x + 1 的结果是 int,所以需要将其转换回 (signed) char。这是通过 integer conversion 完成的,并且在从较大的有符号类型(如 int)转换为较小的有符号类型(如 signed char)时,当值不能适合较小的类型时(就像尝试将 128 存储在 signed char 中)行为是 实现定义的 .

实际发生的情况是该值变为负值(值从0x7f增加到0x80,即-128 two's complement(最常见的负数编码))。这进一步导致 x 小于 225 forever 和你的无限循环。

  • char 大小为一个字节,这意味着要编码的 256 个可能值。
  • signed表示该值可以是负值或正值,在C标准中声明为signed chard的变量范围从-127127
  • unsigned 仅表示正值,这导致声明为 unsigned char 的变量范围从 0255

为了更好地理解这一点,让我们检查这个例子 unsigned char x =-1,问题是 x 的值是多少?答案是 x 在机器中不是 -1,因为编译器会将 x 视为 char 类型的正值,因此 x 将是 255 ,如果我们有 unsigned char x = -2 那么 x 将变为 254 等等.这个例子说明了理解编译器如何在后台解释事物以及我们在代码执行期间得到什么结果的重要性。

unsigned char的简单意思是:在进行算术运算时,使用最高有效位而不是将其作为+/-符号的位标志。

例如,如果您使用 char 作为数字,则意义重大:

typedef char BYTE1; typedef unsigned char BYTE2;

BYTE1一个; BYTE2 b; 对于变量 a,只有 7 位可用,其范围为(-127 到 127)=(+/-)2^7 -1。对于变量 b,所有 8 位都可用,范围是 0 到 255 (2^8 -1)。

如果您使用 char 作为字符,"unsigned" 将被编译器完全忽略,就像从您的程序中删除注释一样。

Char是C语言中用于存储字母、标点符号等字符的数据类型。但是,它仍然是一个整数类型。这是由于 char 类型在技术上存储整数而不是字符的原因。它使用数字代码,该数字代码使用整数表示字符 将 char 值转换为 int 值由 C 自动完成。但是,它仍然取决于决定结果是否为负的机器。大写A相当于整数值65.