为什么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.
的标准
我看到下面的程序只占用 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.
的标准