13

我写了一些 C++ 代码来在控制台上显示 ASCII 字符,这是我在我正在阅读的一本书中找到的。代码如下所示:

#include <iostream>

using namespace std;

int main()  
{  
    for (unsigned char i = 32; i<128; i++)  
       cout << i;  
    int response;  
    cin >> response;  
    return 0;  
}

当我拿走unsigned关键字并signed改用时,结果变得无限,PC 会发出哔哔声,直到我关闭可执行文件。但是当我使用int i变量时,我不需要取消对变量的签名。这是为什么?

4

6 回答 6

26

unsigned只是意味着这个数字不会变成负数。是的,数字,因为 achar真的只是一个 8 位整数。

因此,当 时unsigned,每个位都在非负范围内使用,从 0 到 255。当您省略并使用signed(默认)字符时,范围将从 -128 到 127,因此它总是更少超过 128 并进入无限循环。

您听到的哔哔声是由于“打印”了值 7 的字符。


int另一方面,即使签名从 -2.147... 一直到 +21.47 亿,它也会正常迭代,直到达到 128 并停止。

于 2013-07-05T00:17:24.957 回答
8

有符号char类型的范围从-128+127

因此,i<128永远不能为假,因此您的循环将永远不会终止。

相反,127 + 1作为一个有符号字符将环绕到-128(因为它会设置符号位),然后它将第二次继续循环。

第二次迭代将包括每个字符,包括\a(bell),打印时会发出哔哔声。

于 2013-07-05T00:16:25.437 回答
5

无符号意味着变量将只包含正值,这意味着它们可以包含更大的正数。unsigned char 的范围通常是 0 到 255,signed char 的范围是 -128 到 +127。这可能因不同的硬件而异(但不会在您可能遇到的大多数硬件上)。

当变量从最大值递增时,它会溢出。变量会发生什么取决于它是否是无符号的。无符号类型保证为 0,而有符号类型的行为未定义。在我见过的大多数系统上,变量会环绕到最小值(在本例中为 -128),但您不能依赖这种行为。

这意味着变量永远不会达到 128,因此循环将永远继续。

如果您转到此页面并查看基本数据类型,您可以看到所有基本类型的有符号与无符号的典型范围:http ://www.cplusplus.com/doc/tutorial/variables/

于 2013-07-05T00:21:43.480 回答
3

类型signed charunsigned char是不同的整数类型。顾名思义,一种是有符号类型(即,可以表示负值),另一种是无符号类型(即,. 只能表示非负值)。

char没有signed或前缀的 typeunsigned是另一种不同的类型。它具有与 signed char or 相同的表示和范围unsigned char;哪一个是实现定义的。(微妙的一点:尽管其中两种具有相同的特征,但它们仍然是三种不同的类型。)

对于典型的实现,所有这三种类型都是 8 位,并且有符号类型使用二进制补码表示,signed char范围为 -128 .. +127 和unsigned char范围 0 .. +255。

在您的实现中,似乎char已签署 plain (这很常见)。所以 ifi是 type char, theni < 128总是正确的,你有一个无限循环并且增加一个charsigned char对象超过其最大值实际上具有未定义的行为,但通常它会从最大值环绕到最小值,这就是您所看到的。(当正在打印的字符是\007ASCIIBEL字符时,可能会产生哔声;或者,您发送的控制字符会弄乱您的终端。)

将其设置为 0 到 255iunsigned char范围,当它达到 128 时循环停止。(将无符号类型的值递增超过其最大值是明确定义的,但无论如何您都不要这样做。)

int始终是有符号类型,语言要求其范围至少为 -32767 .. +32767。如今,它通常是 32 位,范围为 -2147483648 .. +2147483647。但即使有最低要求的范围,它对于你的循环来说也足够大了。

于 2013-07-05T01:17:54.337 回答
3

signed char范围是 -128 到 +127,所以它总是小于 128

当你这样做

signed i=127;
i++;

i通常是-128(但你不能指望这种行为)

unsigned char范围是从 0 到 255

并非所有ASCII字符都是可打印的!打印它们是无稽之谈。

于 2013-07-05T00:17:05.407 回答
1

有符号字符(至少在典型情况下)只能表示从 -128 到 +127 的值。由于它永远不会有值 128,因此您的循环将永远运行。

正式地,当它的值为 127 并且您递增时,结果是未定义的行为。实际上,在几乎任何典型的机器上(任何使用 2 的补码的机器),当它的值是 127 并且你递增时,它会回绕到 -128,回升到 127,回绕到 -128 并经历整个循环再次。

使用无符号字符,您将获得从 0 到(至少)255 的值,因此当您达到 127 并递增时,该值变为 128,按预期结束循环。

同样,int要求 an 的范围至少为 -32767 到 +32767。因此,当它的值为 127 并且您递增时,结果将是 128,正如您通常所期望的那样。

于 2013-07-05T00:16:50.303 回答