Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C编程中,为什么字符a=-1不同于无符号字符b=-1_C - Fatal编程技术网

在C编程中,为什么字符a=-1不同于无符号字符b=-1

在C编程中,为什么字符a=-1不同于无符号字符b=-1,c,C,我在下面写了一个小程序 #include <stdio.h> main(){ char a=-1; unsigned char b=-1; printf("%d %d\n",a,b); printf("%x %x\n",a,b); if(a==b) printf("equal\n"); else printf("not equal\n"); } 因为char只有一个字节,-1以2的补码形式表示,所以我认为0xff将同时存储在a和b中,

我在下面写了一个小程序

#include <stdio.h>
main(){
    char a=-1;
    unsigned char b=-1;
    printf("%d %d\n",a,b);
    printf("%x %x\n",a,b);
    if(a==b) printf("equal\n");
    else printf("not equal\n");
}

因为char只有一个字节,-1以2的补码形式表示,所以我认为0xff将同时存储在a和b中,因此两者应该相等。有人能告诉我为什么它们不同,为什么a的十六进制代表是0xFFFFFF&而不是0xff。我得到了一个相关链接,但我无法得到答案。任何帮助都将不胜感激。谢谢。

字符
类型有点反常,因为它与
有符号字符
无符号字符
不同(与其他整数类型不同-
int
等,除非明确声明
无符号
,否则都是隐式签名的)。
char
是否实际签名取决于实现,有些编译器甚至允许您通过命令行开关指定签名


底线:永远不要假设
char
是有符号的或无符号的-如果您确实需要有符号或无符号的8位数量,那么显式地使用
signed char
unsigned char
,或者更好,使用
int8\u t
uint8\u t
来自
char
类型有点反常,因为它与
有符号字符
无符号字符
(与其他整数类型不同,
short
int
long
等,除非明确声明
unsigned
,否则这些整数类型都是隐式签名的。)字符是否实际签名取决于实现,一些编译器甚至允许您通过命令行开关指定签名


底线:永远不要假设
char
是有符号的或无符号的-如果您实际需要有符号或无符号的8位数量,那么明确地使用
signed char
unsigned char
,或者更好地使用
int8_t
uint8_t
,它们是相同的。或者更确切地说,它们的基本属性是相同的表示形式相同(假设编译器使用两个补码形式)

另一方面,它们表示的值是-1和255

当您打印它们时,它们会扩展到数据类型
int
无符号字符
是零扩展,而有符号字符是符号扩展,这就解释了您看到的差异

比较这两个值时会出现相同的扩展。
a==b
不比较底层表示,而是将这两个值扩展到
int
,因此将255与-1进行比较,后者不相等


请注意,普通的
字符可以是有符号的,也可以是无符号的。在您的环境中,它显然是有符号的。

它们是相同的。或者更确切地说,它们的基本表示形式是相同的(假设您的编译器使用两个补码形式)

另一方面,它们表示的值是-1和255

当您打印它们时,它们会扩展到数据类型
int
无符号字符
是零扩展,而有符号字符是符号扩展,这就解释了您看到的差异

比较这两个值时会出现相同的扩展。
a==b
不比较底层表示,而是将这两个值扩展到
int
,因此将255与-1进行比较,后者不相等


请注意,普通的
char
可以是有符号的,也可以是无符号的。在您的环境中,它显然是有符号的。

a
signed int
是有符号的,a
unsigned int
是无符号的。如果您只使用
int
,它意味着
signed int
。对于
short
long
long。但是
char
不是这样。
signed char
是有符号的,
unsigned char
是无符号的,但是
char
可以是有符号的,也可以是无符号的。数据类型char应该包含一个“字符”,因此它的名称是有符号的,所以它不是“真的”一种整数类型,用于保存要在计算中使用的整数。当然,字符实际上是某种类型的整数,但其类型取决于实现(C标准不强制任何特定类型)。因此,如果要将字符类型用于整数值(也用于计算),始终显式使用
signed char
unsigned char
,并且仅在您真正处理字符时使用
char
,或者如果char是有符号或无符号的,则对代码完全没有影响时使用

比较失败,因为您的实现将
char
定义为事实上的
signed char
,因此您在最后的
if
语句中将
signed char
unsigned char
进行比较。每当您比较两个不同类型的整数时,编译器都会将两个值转换为同一类型在实际执行比较之前。在您的例子中,这意味着C编译器实际执行以下操作:

if((int)a==(int)b) printf("equal\n");
    else printf("not equal\n");
}
现在,这两个值不匹配的原因应该很明显了。
(int)a
的值为
-1
,而
(int)b
的值为
255
,这两个值不相等

根据类型提升的规则,
char
(在您的案例中是有符号的)被提升为
int
无符号char
也被提升为
int
。ISO C 2011标准规定:

如果int可以表示原始类型的所有值(受限 根据宽度(对于位字段),将值转换为int; 否则,它将转换为无符号整数 整数促销。)所有其他类型均不受整数的影响 晋升

整数值包括符号。如前所述 之前,是否为“普通”字符
if((int)a==(int)b) printf("equal\n");
    else printf("not equal\n");
}