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

Posted

技术标签:

【中文标题】c中的有符号字符和无符号字符之间的区别【英文标题】:Difference between in signed and unsigned char in c 【发布时间】:2017-07-21 06:18:20 【问题描述】:

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

【问题讨论】:

嗯?您刚刚解释了主要区别(signed char 为 127,unsigned 为 255),但随后您问有什么区别。 如果普通的char 被签名或未签名是实现定义。 IE。两个不同的编译器可能有不同的。 @M.M 是唯一的区别吗?除此以外,它们在各个方面都相同吗? 更重要的是,在我使用 gcc 的 Windows 10 笔记本电脑上,它们会生成不同的汇编语言指令。也许一个更快/更小。 区别在上一个问题中已经解释过了。我们要再次提供完全相同的答案吗? 【参考方案1】:

C 语言中没有专用的“字符类型”。 char 是整数类型,与 int、short 和其他整数类型(在这方面)相同。

它们都是整数类型。 它们的大小相同(一个字节)。

如果你使用数字作为字符

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

从 3.9.1 基本类型开始

Plain char、signed char 和 unsigned char 是三种不同的类型。一种 char、signed char 和 unsigned char 占用相同数量的 存储并具有相同的对齐要求(3.11);也就是说,他们 具有相同的对象表示。

【讨论】:

charunsigned charsigned char 被称为 字符类型。 (这些也是整数类型)【参考方案2】:

附言

x=x+1;

发生了一些事情。

首先将评估表达式x + 1。这将导致usual arithmetic conversion 中的值在x 中,因此它变为promoted to an int。 (提升的)值将增加1,然后将结果分配回x。问题就从这里开始了。

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

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

【讨论】:

【参考方案3】:

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

如果您使用有符号字符定义变量,则变量“x”位于 -128 到 127 之间。它始终小于 255。

【讨论】:

这些是最小范围,可能更大。但是,signed char 的最小范围是 [-127, 127]。【参考方案4】: char 的大小为 1 个字节,这意味着 256 个可能的编码值。 signed 表示该值可以是 negatif 或 positif,在 C 标准中,声明为 signed chard 的变量范围从 -127127 unsigned 仅表示正值,这导致声明为unsigned char 的变量范围从0255

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

【讨论】:

char 根据定义具有一个字节的大小,但一个字节不必是 8 位。您声明的范围是标准保证的最小范围。 @DavidBowling:实际上,char 类型的最小范围是 255 个值,而不是 256。事实上,CHAR_MIN 在非 2 的补码系统上可以是 -127。我们都知道这一点(正如您对另一个答案的评论),但这远远超出了一些受访者的技能水平。 @chqrlie--“256 个可能的编码值”;当我第一次看到它时,这实际上从我身边溜走了。你当然是对的。我很欣赏这个注释:)【参考方案5】:

无符号字符只是意味着:在执行算术运算时,使用最高有效位而不是将其视为 +/- 符号的位标志。

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

typedef 字符 BYTE1; typedef unsigned char BYTE2;

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

如果您使用 char 作为字符,编译器会完全忽略“无符号”,就像从程序中删除 cmets 一样。

【讨论】:

【参考方案6】:

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

【讨论】:

以上是关于c中的有符号字符和无符号字符之间的区别的主要内容,如果未能解决你的问题,请参考以下文章

有符号/无符号字符之间的区别[重复]

为啥在有符号和无符号表示之间转换一个数字?

Arduino 在 uint32_t 和无符号字符之间转换

SWIG C/python 和无符号字符指针

C语言里怎样理解长整型 短整型 和无符号型变量和常量?

C中溢出后有符号和无符号的不一致相等