为什么char长度为1个字节即8位时占7位?

Why does char occupy 7 bits when the length is 1 byte ie 8 bits?

我看到下面的程序只占用 7 位内存来存储字符,但一般来说,我研究过的所有地方都说 char 占用 1 个字节的内存,即 8 位。

单个字符需要8位还是7位?

如果需要8位,那么另一位会存储什么?

#include <iostream>
using namespace std;

int main()
{
    char ch = 'a';
    int val = ch;
    
    while (val > 0)
    {
        (val % 2)? cout<<1<<" " : cout<<0<<" ";
        val /= 2;
    }
    return 0;
}

输出:

1 0 0 0 0 1 1 

下面的代码显示了字符之间的内存间隙,即7位:

9e9 <-> 9f0 <->......<-> a13

#include <iostream>
using namespace std;

int main()
{
    char arr[] = {'k','r','i','s','h','n','a'};
    for(int i=0;i<7;i++)
        cout<<&arr+i<<endl;
   
    return 0;
}

输出:

0x7fff999019e9
0x7fff999019f0
0x7fff999019f7
0x7fff999019fe
0x7fff99901a05
0x7fff99901a0c
0x7fff99901a13

您的第一个代码示例不打印前导零位,因为 ASCII 字符的高位都设置为零,如果使用 ASCII 字符,您最多只能打印七位。扩展 ASCII 字符或 utf-8 将高位用于基本 ASCII 字符集之外的字符。

你的第二个例子实际上是打印每个字符是七个 字节 长,这显然是不正确的。如果您将正在使用的数组的大小更改为不超过七个字符,您会看到不同的结果。

&arr + i 等同于 (&arr) + i,因为 &arr 是指向 char[7] 的指针,其大小为 7,+i 添加 7 * i 字节到指针。 (&arr) + 1 指向数组末尾后一个字节,如果您尝试打印这些指针指向的值,您将得到垃圾或崩溃:**(&arr + i).

您的代码应该是 static_cast<void*>(&arr[i]),然后您会看到每次迭代时指针都上升 1。强制转换为 void* 是阻止标准库尝试将指针打印为空终止字符串所必需的。

与为char分配的space无关。您只需将 char 的 ASCII 表示转换为二进制。

ASCII 是一个 7 位字符集。在 C 中通常由 8 位字符表示。如果设置了 8 位字节中的最高位,则它不是 ASCII 字符。第八位用于奇偶校验。使用不同编码在计算机之间传递信息。

ASCII是American Standard Code for Information Interchange的缩写,强调American。字符集不能表示阿拉伯字母(例如带有变音符号的东西)或拉丁字母。

“扩展”ASCII 集并使用那些通过使用所有 8 位变得可用的额外 128 个值,这导致了问题。最终,Unicode 出现了,它可以表示每个 Unicode 字符。但是 8 位成为 char.

的标准