char类型为啥只能存储0-255
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了char类型为啥只能存储0-255相关的知识,希望对你有一定的参考价值。
因为char类型的数据长度是一个字节,也就是8个二进制位00000000-11111111,表示范围只能表示0-255
就像用两位10进制的数最大能表示到99一样,再加1就得用3位10进制数了。
同样char只有8位,表示再大点的就要9位或更多了。追问
帅哥,char的数据长度是两个字节,是16bit
参考技术A 要存储更多的内容,改双精度小数型,或长整数型追问哥们,你没听懂我的意思
追答本质上两种类型都占一个字节。
作为字符使用时,都是存储字符的ASCII码。比如:
unsigned char uc='a';
char c='a';
printf("%d %d",uc,c);
结果为: a a
作为整数使用时,两种类型的取值范围就不同了。unsigned char 可取0至255,而char可取-128至+127。比如:
unsigned char uc=255;
char c=255;
printf("%d %d",uc,c);
结果为: 255 -1
原因是没有用unsigned修饰的char类型系统将其存储的一个字节值(8位2进制)看作为一个有符号数来处理,最高位为0时,表示正数,为1时表示负数,表示负数时的值为余下7位二进制每一位取反后整体+1。
比如上例中:char c=255; 表面看来超过了char的范围,但系统并不是这样处理的。
系统将十进制数255转为二进制数11111111进行存储。在计算或打印时,发现最高位为1,是负数,余下7位1111111取反后为0000000,加1后为0000001,转为十进制数等于1,最后系统当作-1看待。所以此时按整数打印c时,输出为-1。
总的来说,系统最终存储的都是二进制数11111111,只是在参与运算或显示的时候,unsigned char和char才会有所区别。
在 C++11 标准中,为啥要依赖 char 类型的实现?
【中文标题】在 C++11 标准中,为啥要依赖 char 类型的实现?【英文标题】:In the C++11 standard, why leave the char type implementation dependent?在 C++11 标准中,为什么要依赖 char 类型的实现? 【发布时间】:2019-09-12 01:27:34 【问题描述】:背景
几个 C++ 源材料和堆栈溢出问题讨论了 char
的实现依赖性质。也就是说,C++ 中的char
可以定义为unsigned char
或signed char
,但根据ARM Linux FAQ,此实现depends entirely on the compiler:
上面的代码实际上是错误的,因为它假定类型“char”等价于“signed char”。 C 标准确实说“char”可以是“signed char”或“unsigned char”,这取决于编译器的实现或所遵循的平台。
这为歧义问题和不良做法打开了大门,包括mistaking the signage of a char 用作 8 位数字。 Rationale for C 提供了为什么会出现这种情况的一些原因,但没有解决留下歧义可能性的问题:
指定了三种类型的 char:signed、plain 和 unsigned。一个普通的 char 可以表示为有符号或无符号,这取决于实现,如在先前的实践中一样。引入有符号字符类型是为了在那些将普通字符实现为无符号的系统上提供单字节有符号整数类型。出于对称的原因,关键字signed 被允许作为其他整数类型的类型名称的一部分。
如果只保留unsigned char
和signed char
的类型作为8 位单元的两种数据类型,那么关闭甚至可能产生歧义的可能性似乎是有利的。这促使我提出这个问题......
问题
考虑到歧义的可能性,为什么要依赖 char
数据类型实现?
【问题讨论】:
char 类型在 C++ 中是一团糟。它们有 3 个完全不同的用途:字符串中的字符、字节和整数,在类型系统中无法消除它们之间的歧义。尝试cout
std::int8_t
...是的...
一些处理器更喜欢有符号字符,而另一些处理器更喜欢无符号字符。例如,POWER 可以从内存中加载一个零扩展的 8 位值,但不是符号扩展。但是 SuperH-3 可以从内存中加载一个带有符号扩展但不能为零扩展的 8 位值。 C++ 派生自 C,C 保留了语言实现定义的许多细节,以便可以定制每个实现以使其最有效地适应其目标环境。
@RaymondChen 这应该是一个答案
@RaymondChen 根据 bolov 的建议,我已将您的评论作为社区 wiki 答案。
请记住,普通 char
与 signed char
或 unsigned char
具有相同的表示形式,但它们仍然是三种不同且不兼容的类型。
【参考方案1】:
一些处理器更喜欢有符号字符,而另一些处理器更喜欢无符号字符。例如,POWER 可以从内存中加载一个零扩展的 8 位值,但不是符号扩展。但是 SuperH-3 可以从内存中加载一个带有符号扩展但不能为零扩展的 8 位值。 C++ 派生自 C,C 保留了语言实现定义的许多细节,以便可以定制每个实现,使其最适合其目标环境。
【讨论】:
重要的是,当您使用char
作为实际字符数据时,符号无关紧要(您的怪异 ASCII 超集的字形可以像使用正值一样容易地用负值引用)。所以在这种情况下,简单的char
使用更有效的类型就可以了。只有当您将它用于数学时,实现定义的签名才是一个问题。在这种情况下,您应该明确指定签名,或者只使用像 uint8_t
/int8_t
这样的 stdint 类型来明确您依赖于数字行为,而不仅仅是存储字符。以上是关于char类型为啥只能存储0-255的主要内容,如果未能解决你的问题,请参考以下文章