由于-128到-1的字符与从+128到+255的字符相同,那么使用unsigned char有什么意义呢?

时间:2016-03-22 06:12:56

标签: c char 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 charsigned char

5 个答案:

答案 0 :(得分:3)

K&amp; R,章和节,p。 43和44:

  

关于字符转换有一个微妙的观点   整数。该语言未指定char类型的变量   是签名或未签名的数量。当char转换为int时,   能产生负整数吗?答案因机器而异   加工,反映建筑的差异。在某些机器上,   最左边的位为1的char将转换为负整数   (“符号扩展”)。在其他情况下,通过添加将char提升为int   在左端是零,因此总是积极的。 [...]任意   存储在字符变量中的位模式可能看起来是负面的   在一些机器上,但在其他机器上是积极的为了便于携带,请指定   如果要将非字符数据存储在char中,则为signed或unsigned   变量

答案 1 :(得分:2)

因为unsigned char用于C89中的一个字节整数。

请注意char中有三种不同的C89相关类型:charsigned charunsigned char

对于字符类型,使用char

unsigned charsigned char用于一个字节整数,如short用于两个字节的整数。您不应该将signed charunsigned char用于字符。你也不应该依赖这些价值观的顺序。

答案 2 :(得分:2)

数字的位表示是计算机存储的内容,但如果没有某人(或其他东西)在其上施加模式,它并不意味着什么。

unsigned charsigned char模式之间的差异是我们如何解释设置位。在一种情况下,我们确定零是最小的数字,我们可以添加位,直到我们到达0xFF或二进制11111111。在另一种情况下,我们确定0x80是最小的数字,我们可以添加位,直到我们到达0x7F

我们有一种有趣的方式来表示有符号数字(后一种模式)是因为它将0x00大致放在序列的中间,因为0xFF(即-1,在零之前)加0x01(在零之后为1)加在一起进行,直到所有位都离开高端,留下0x00 (-1 + 1 = 0)。同样-5 + 5 = 0同样的机制。

为了好玩,有很多位模式意味着不同的东西。例如0x2a可能是我们称之为“数字”的字符,也可能是*字符。这取决于我们选择对位模式施加的上下文。

答案 3 :(得分:2)

使用打印字符 - 没有区别:

函数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作为数字而不是字符,则打印差异很大。

答案 4 :(得分:0)

创建不同的类型以告诉编译器如何理解&#34;一个或多个字节的位表示。例如,假设我有一个包含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

另外,想想这个荒谬的问题:

  

假设sizeof (int) == 4,因为字符数组(unsigned char[]){UCHAR_MIN, UCHAR_MIN, UCHAR_MIN, UCHAR_MIN}(unsigned char[]){UCHAR_MAX, UCHAR_MAX, UCHAR_MAX, UCHAR_MAX}相同   从unsigned intUINT_MIN UINT_MAX,那么重点是什么   使用unsigned int