由于从 -128 到 -1 的字符与从 +128 到 +255 的字符相同,那么使用 unsigned char 有什么意义呢?
Since characters from -128 to -1 are same as from +128 to +255, then what is the point of using unsigned char?
#include <stdio.h>
#include <conio.h>
int main()
{
char a=-128;
while(a<=-1)
{
printf("%c\n",a);
a++;
}
getch();
return 0;
}
上面代码的输出与下面代码的输出相同
#include <stdio.h>
#include <conio.h>
int main()
{
unsigned char a=+128;
while(a<=+254)
{
printf("%c\n",a);
a++;
}
getch();
return 0;
}
那为什么要用unsigned char
和signed char
呢?
因为unsigned char
用于C89
中的一个字节整数。
请注意 C89
中存在三种不同的 char
相关类型:char
、signed char
、unsigned char
。
对于字符类型,使用char
。
unsigned char
和 signed char
用于一字节整数,如 short
用于两字节整数。您不应该真正使用 signed char
或 unsigned char
作为字符。您也不应依赖这些值的顺序。
K & R,章节和诗歌,p. 43 和 44:
There is one subtle point about the conversion of characters to
integers. The language does not specify whether variables of type char
are signed or unsigned quantities. When a char is converted to an int,
can it ever produce a negative integer? The answer varies from machine
to machine, reflecting differences in architecture. On some machines,
a char whose leftmost bit is 1 will be converted to a negative integer
("sign extension"). On others, a char is promoted to an int by adding
zeros at the left end, and thus is always positive. [...] Arbitrary
bit patterns stored in character variables may appear to be negative
on some machines, yet positive on others. For portability, specify
signed or unsigned if non-character data is to be stored in char
variables.
数字的位表示是计算机存储的内容,但如果没有人(或某物)强加某种模式,它就没有任何意义。
unsigned char
和 signed char
模式之间的区别在于我们如何解释设置位。在一种情况下,我们决定零是最小的数字,我们可以添加位直到我们得到 0xFF
或二进制 11111111
。在另一种情况下,我们决定 0x80
是最小的数字,我们可以添加位直到我们到达 0x7F
。
我们之所以用这种有趣的方式来表示有符号数(后一种模式)是因为它将零 0x00
大致放在序列的中间,并且因为 0xFF
(这是 - 1,就在零之前)加上0x01
(也就是1,就在零之后)加在一起进位,直到所有位都进位,留下0x00(-1 + 1 = 0)
。同样地 -5 + 5 = 0
通过相同的机制。
为了好玩,有很多表示不同事物的位模式。例如 0x2a
可能是我们所说的 "number" 或者它可能是 *
字符。这取决于我们选择强加给位模式的上下文。
打印字符 - 没有区别:
函数 printf()
使用 "%c"
并接受 int
参数并将其转换为 unsigned char
并且 然后 打印它.
char a;
printf("%c\n",a); // a is converted to int, then passed to printf()
unsigned char ua;
printf("%c\n",ua); // ua is converted to int, then passed to printf()
带打印值(数字)- 系统使用 char
时的差异 已签名 :
char a = -1;
printf("%d\n",a); // --> -1
unsigned char ua = -1;
printf("%d\n",ua); // --> 255 (Assume 8-bit unsigned char)
注意:稀有机器的 int
大小与 char
相同,其他问题适用。
因此,如果代码使用 a
作为数字而不是字符,则打印差异很大。
创建不同的类型是为了告诉编译器如何"understand"一个或多个字节的位表示。例如,假设我有一个包含 0xFF
的字节。如果解释为signed char
,则为-1;如果它被解释为 unsigned char
,则为 255。
在你的例子中,a
,无论是有符号还是无符号,都被整数提升为 int
,并传递给 printf()
,后者随后将其隐式转换为 unsigned char
在将其打印为字符之前。
但是让我们考虑另一种情况:
#include <stdio.h>
#include <string.h>
int main(void)
{
char a = -1;
unsigned char b;
memmove(&b, &a, 1);
printf("%d %u", a, b);
}
实际写成printf("%d %u", a, a);
其实是可以接受的。 memmove()
用于避免未定义的行为。
它在我的机器上的输出是:
-1 4294967295
还有,想想这个可笑的问题:
Suppose sizeof (int) == 4
, since arrays of characters (unsigned
char[]){UCHAR_MIN, UCHAR_MIN, UCHAR_MIN, UCHAR_MIN}
to (unsigned
char[]){UCHAR_MAX, UCHAR_MAX, UCHAR_MAX, UCHAR_MAX}
are same as
unsigned int
s from UINT_MIN
to UINT_MAX
, then what is the point
of using unsigned int
?
#include <stdio.h>
#include <conio.h>
int main()
{
char a=-128;
while(a<=-1)
{
printf("%c\n",a);
a++;
}
getch();
return 0;
}
上面代码的输出与下面代码的输出相同
#include <stdio.h>
#include <conio.h>
int main()
{
unsigned char a=+128;
while(a<=+254)
{
printf("%c\n",a);
a++;
}
getch();
return 0;
}
那为什么要用unsigned char
和signed char
呢?
因为unsigned char
用于C89
中的一个字节整数。
请注意 C89
中存在三种不同的 char
相关类型:char
、signed char
、unsigned char
。
对于字符类型,使用char
。
unsigned char
和 signed char
用于一字节整数,如 short
用于两字节整数。您不应该真正使用 signed char
或 unsigned char
作为字符。您也不应依赖这些值的顺序。
K & R,章节和诗歌,p. 43 和 44:
There is one subtle point about the conversion of characters to integers. The language does not specify whether variables of type char are signed or unsigned quantities. When a char is converted to an int, can it ever produce a negative integer? The answer varies from machine to machine, reflecting differences in architecture. On some machines, a char whose leftmost bit is 1 will be converted to a negative integer ("sign extension"). On others, a char is promoted to an int by adding zeros at the left end, and thus is always positive. [...] Arbitrary bit patterns stored in character variables may appear to be negative on some machines, yet positive on others. For portability, specify signed or unsigned if non-character data is to be stored in char variables.
数字的位表示是计算机存储的内容,但如果没有人(或某物)强加某种模式,它就没有任何意义。
unsigned char
和 signed char
模式之间的区别在于我们如何解释设置位。在一种情况下,我们决定零是最小的数字,我们可以添加位直到我们得到 0xFF
或二进制 11111111
。在另一种情况下,我们决定 0x80
是最小的数字,我们可以添加位直到我们到达 0x7F
。
我们之所以用这种有趣的方式来表示有符号数(后一种模式)是因为它将零 0x00
大致放在序列的中间,并且因为 0xFF
(这是 - 1,就在零之前)加上0x01
(也就是1,就在零之后)加在一起进位,直到所有位都进位,留下0x00(-1 + 1 = 0)
。同样地 -5 + 5 = 0
通过相同的机制。
为了好玩,有很多表示不同事物的位模式。例如 0x2a
可能是我们所说的 "number" 或者它可能是 *
字符。这取决于我们选择强加给位模式的上下文。
打印字符 - 没有区别:
函数 printf()
使用 "%c"
并接受 int
参数并将其转换为 unsigned char
并且 然后 打印它.
char a;
printf("%c\n",a); // a is converted to int, then passed to printf()
unsigned char ua;
printf("%c\n",ua); // ua is converted to int, then passed to printf()
带打印值(数字)- 系统使用 char
时的差异 已签名 :
char a = -1;
printf("%d\n",a); // --> -1
unsigned char ua = -1;
printf("%d\n",ua); // --> 255 (Assume 8-bit unsigned char)
注意:稀有机器的 int
大小与 char
相同,其他问题适用。
因此,如果代码使用 a
作为数字而不是字符,则打印差异很大。
创建不同的类型是为了告诉编译器如何"understand"一个或多个字节的位表示。例如,假设我有一个包含 0xFF
的字节。如果解释为signed char
,则为-1;如果它被解释为 unsigned char
,则为 255。
在你的例子中,a
,无论是有符号还是无符号,都被整数提升为 int
,并传递给 printf()
,后者随后将其隐式转换为 unsigned char
在将其打印为字符之前。
但是让我们考虑另一种情况:
#include <stdio.h>
#include <string.h>
int main(void)
{
char a = -1;
unsigned char b;
memmove(&b, &a, 1);
printf("%d %u", a, b);
}
实际写成printf("%d %u", a, a);
其实是可以接受的。 memmove()
用于避免未定义的行为。
它在我的机器上的输出是:
-1 4294967295
还有,想想这个可笑的问题:
Suppose
sizeof (int) == 4
, since arrays of characters(unsigned char[]){UCHAR_MIN, UCHAR_MIN, UCHAR_MIN, UCHAR_MIN}
to(unsigned char[]){UCHAR_MAX, UCHAR_MAX, UCHAR_MAX, UCHAR_MAX}
are same asunsigned int
s fromUINT_MIN
toUINT_MAX
, then what is the point of usingunsigned int
?