文章目录
- 参考
- 描述
- 数据类型
- 整形
- 有符号
- 无符号
- 规则
- sizeof 运算符
- 进制
- cout 的自动转换(进制)
- 后缀
- 验证
- 溢出
- 主动权
- 溢出
- 布尔型
- 变量
- 判断结果
- 字符型
- ASCII
- 细节
- 范围
参考
项目 | 描述 |
---|---|
菜鸟教程 | 数据类型 |
搜索引擎 | |
C++ Primer Plus (第六版)中文版 | 史蒂芬·普拉达 / 张海龙,袁国忠 译 |
黑马程序员 | C++ |
描述
项目 | 描述 |
---|---|
操作系统 | Windows 10 专业版 |
编辑器 | VScode |
g++ | 8.1.0 |
数据类型
使用编程语言进行编程时,需要用到各种变量来存储各种信息。变量保留的是它所存储的值的内存位置。这意味着,当您创建一个变量时,就会在内存中保留一些空间。
您可能需要存储各种数据类型(比如字符型、宽字符型、整型、浮点型、双浮点型、布尔型等)的信息,操作系统会根据变量的数据类型,来分配内存和决定在保留内存中存储什么。
上述内容引用自 菜鸟教程
整形
有符号
有符号整型能够存储负数。
项目 | 大小 | 范围 | 数量级 |
---|---|---|---|
short、signed short、short int 、signed short int | 两个字节 | -32,728 ~ 32,727 | 万 |
int、signed | 四个字节 | -2,147,483,648 ~ 2,147,483,647 | 十亿 |
long、signed long、long int、signed long int | Windows 占用四个字节;Linux 的 32 位 系统占用四个字节,64 位 系统占用八个字节 | -2,147,483,648 ~ 2,147,483,647 | 十亿 |
long long、signed long long、long long int、singned long long int | 八个字节 | -9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807 | 百亿亿 |
注:
- 有符号整型中的各个类型均存在别名,你可以使用某一种类型的所有名称中的其中一种来表示该类型。
- 有符号整型需要使用一个位(最小的存储单位,在二进制系统中仅能存储一个一或一个零)来表示存储的数值的类型为负数还是非负数。因此,在占用相同内存的情况下,使用有符号数据类型所能表示的最大数值(绝对值)要比无符号数据类型所能表示的最大数值(绝对值)要小。
- 有符号整型可以存储负数,但这也导致了能够存储的正数的数值范围的减小。所以,请权衡数据类型的内存占用量及该类型所能够表示的整数范围来选择合适的数据类型。
无符号
无符号整型仅能存储正数及零。
项目 | 大小 | 范围 | 数量级 |
---|---|---|---|
unsigned short、unsigned short int | 两个字节 | 0 ~ 65,535 | 十万 |
unsigned、unsigned int | 四个字节 | 0 ~ 4,294,967,295 | 十亿 |
unsigned long、unsigned long int | Windows 占用四个字节;Linux 的 32 位 系统占用四个字节,64 位 系统占用八个字节 | 0 ~ 4,294,967,295 | 十亿 |
unsigned long long、unsigned long long int | 八个字节 | 0 ~ 18,446,744,073,709,551,615 | 千亿亿 |
规则
在不同的 C++ 实现中,不同的数据类型所占用的内存空间是不同的,这可能会导致混乱。C++ 提供了一种灵活的标准(借鉴于 C 语言),该标准确保了不同数据类型所占用的最小内存空间:
- short 数据类型所占据的内存空间至少为 两个字节。
- int 至少与 short 数据类型所占据的内存空间相同。
- long 数据类型所占据的内存空间至少为 四个字节,且至少与 int 数据类型所占据的内存空间相同。
- long long 数据类型至少为 八个字节,且至少与 long 数据类型所占据的内存空间相同。
sizeof 运算符
使用 sizeof 运算符你可以获取当前 C++ 实现下,某个数据类型或变量所占用的内存空间(以字节为单位)。
举个栗子
// 导入 C++ 标准库 iostream 以实现输入输出功能
#include <iostream>
// 使用标准命名空间
using namespace std;
int main(){
// 定义变量
short short_num;
int int_num;
// 将变量或数据类型所占用的内存空间进行打印
cout << "short\t" << sizeof(short_num)<< endl;
cout << "int\t" << sizeof int_num << endl;
cout << "long\t" << sizeof(long) << endl;
cout << "long long\t" << sizeof(long long) << endl;
// 禁止执行窗口自动关闭以观察程序的输出结果
system("pause");
}
执行结果
short 2
int 4
long 4
long long 8
请按任意键继续. . .
注:
使用 sizeof 运算符检测当前 C++ 实现下某个变量所占用的内存空间时,可以使用 sizeof 的函数形式或关键字形式。而使用 sizeof 运算符检测当前 C++ 实现下某个数据类型所占用的内存空间时,仅能使用 sizeof 的函数形式,否则你将观察到错误信息。
进制
C++ 允许你使用三种方式来表示整数。具体如下:
- 若数值之前存在 0 ,则该整数将被视为八进制数值。
- 若数值之前存在 0X 或 0x,则该整数将被视为十六进制数值。
- 除上述情况外的其他整数都将被视为十进制数值。
举个栗子
#include <iostream>
using namespace std;
int main() {
// 八进制数值
cout << 036 << endl;
// 十进制数值
cout << 36 << endl;
// 十六进制数值
cout << 0X36 << endl;
system("pause");
}
执行结果
30
36
54
请按任意键继续. . .
注:
- 在八进制数值中,数值的每一位仅允许是 0 ~ 7 范围中的数值。例如 0982 就是一个错误的八进制数值。
- 在十六进制数值中,数值的每一位仅允许是 0 ~ 9 及 a ~ f 或 A ~ F 范围中的数值。例如,0X89D 就是一个错误的十六进制数值。
- 在十进制中,数值的每一位仅允许是 0 ~ 9 范围中的数值。例如,10a 就是一个错误的十进制数值。
cout 的自动转换(进制)
在上一个示例中,我们虽使用了其他进制(非十进制)的数值,但在使用 cout 关键字将其输出到执行窗口中后,观察到的内容却为其他进制转换为十进制后的结果。
如果你希望 cout 将数值转换指定进制的数值后在执行窗口中输出,那么你可以使用 hex、dec 及 oct 关键字用以将数值分别转换为十六进制、十进制及八进制数值后在执行窗口中输出。
举个栗子
#include <iostream>
using namespace std;
int main() {
cout << oct;
cout << "八进制数值\t" << 36 << endl;
cout << dec;
cout << "十进制数值\t" << 36 << endl;
cout << hex;
cout << "十六进制数值\t" << 36 << endl;
system("pause");
}
执行效果
八进制数值 44
十进制数值 36
十六进制数值 24
请按任意键继续. . .
注:
- 使用 cout << oct; 等语句时并不会真的输出什么内容,该类语句可以将后续语句中的 cout 语句中的数值转换为指定的进制后在执行窗口中显示 。
举个栗子
#include <iostream>
using namespace std;
int main() {
cout << dec;
cout << "十进制数值\t" << 36 << endl;
cout << oct;
cout << "八进制数值\t" << 36 << endl;
cout << "八进制数值\t" << 36 << endl;
system("pause");
}
执行效果
十进制数值 36
八进制数值 44
八进制数值 44
请按任意键继续. . .
- 你也可以将 oct 等关键字添加到需要发生进制转换的 cout 语句中,但这样做也任将影响到后续的 cout 语句。
举个栗子
#include <iostream>
using namespace std;
int main() {
cout << hex;
cout << "十进制数值\t" << 36 << endl;
cout << oct << "八进制数值\t" << 36 << endl;
cout << "八进制数值\t" << 36 << endl;
system("pause");
}
执行效果
十进制数值 24
八进制数值 44
八进制数值 44
请按任意键继续. . .
后缀
验证
在计算机科学中,字面量 是用于表达源代码中一个固定值的表示法。几乎所有计算机编程语言都具有对基本值的字面量表示,诸如:整数、浮点数以及字符串;而有很多也对布尔类型和字符类型的值也支持字面量表示;还有一些甚至对枚举类型的元素以及像数组、记录和对象等复合类型的值也支持字面量表示法。
上述内容引用自 百度百科
在 C++ 中,并不是只有变量有其数据类型,字面量也是有其数据类型的。整型字面量使用的默认数据类型为 int,我们可以通过如下代码进行验证。
#include <iostream>
using namespace std;
int main(){
cout << sizeof 12 << endl;
system("pause");
}
执行结果
4
请按任意键继续. . .
溢出
在字面量数值的大小超出了 int 所能表示的范围时,C++ 将从其它整型数据类型中选择尽可能小且合适的数据类型作为该整型字面量的数据类型。但十进制和非十进制数值的字面量可选择的数据类型存在不同,非十进制数值字面量可以选择无符号整型相关的数据类型,而十进制数值字面量仅能使用有符号整型相关的数据类型。
举个栗子
#include <iostream>
using namespace std;
int main() {
// 2200000000(即 22 亿)
// 超出了 int 所能表示的数值范围
cout << sizeof 2200000000 << endl;
// 十六进制数值 83215600 转换为十进制
// 数值为 2200000000
cout << sizeof 0X83215600 << endl;
system("pause");
}
执行结果
8
4
请按任意键继续. . .
分析
-
由于 2200000000(即 22 亿) 超出了 int 及 long 所能支持的最大数值且该数值为十进制数值,所以使用 long long 作为该整型字面量的数据类型。
-
由于 0X83215600(即 22 亿) 超出了 int 及 long 所能支持的最大数值且该数值为十六进制数值,所以使用 unsigned int 作为该整型字面量的数据类型。
主动权
除了让 C++ 为整型字面量分配合适的数据类型外,我们也可以通过在字面量中添加后缀来指定该字面量使用的数据类型。C++ 支持的整型数据类型的后缀有:
项目 | 后缀 |
---|---|
long | l、L |
unsigned long | ul(u 及 l 的顺序可以发生变换且两者的大小写形式不被限制) |
long long | ll、LL |
unsigned long long | ull、Ull、uLL、ULL |
注:
在使用后缀规定字面量的数据类型时,请检查数值是否在该数据类型所支持的范围内,否者 C++ 将抛出错误。
举个栗子
#include <iostream>
using namespace std;
int main() {
cout << sizeof 22Ul<< endl;
cout << sizeof 22LL << endl;
system("pause");
}
执行结果
4
8
请按任意键继续. . .
溢出
在某一数据类型的变量存储的值的大小超出了该数据类型所支持的范围时,变量值将跳转到范围的另一端并在次基础上继续计算。
举个栗子
#include <iostream>
using namespace std;
int main() {
// 无符号 short 数据类型所支持的最大值
short span_max = 32767;
// 无符号 short 数据类型所支持的最小值
short span_min = -32768;
span_max += 7;
span_min -= 10;
cout << span_max << endl;
cout << span_min << endl;
system("pause");
}
执行结果
-32762
32758
请按任意键继续. . .
布尔型
ANSI/ISO C++ 标准开始支持 布尔类型。布尔 这个名称来源于英国数学家 George Boole ,是他开发了逻辑率的数学表示法。在计算中,布尔变量的值可以是 true 或 false ,分别代表了 真 与 假。
拓展
- 在 C99 之前,C语言 的标准没有提供布尔类型,但是这不意味着 C90 不能表示布尔值的概念。C 中的所有布尔运算 (&&, ||) 以及条件声明 (if, while) 都以非零值代表真,零值代表假。
- 在 C++ 支持布尔类型前,C++ 同 C 一般,将 0 解释为 false,将 非 0 值 解释为 true。但在 C++ 支持布尔类型后,你也仍可以使用 0 来代替 false 或是使用 非 0 值 来代替 true 在条件语句发挥作用。
变量
在 C++ 中,关键字 true 及 false 分别可以看作是存储了 1 及 0 的变量。
举个栗子
#include <iostream>
using namespace std;
int main() {
cout << true << endl;
cout << false << endl;
system("pause");
}
执行结果
1
0
请按任意键继续. . .
判断结果
布尔类型通常作为判断一个表达式是否正确的结果,若表达式正确则布尔运算的结果为 true ,若表达式错误则布尔运算的结果为 false。
举个栗子
#include <iostream>
using namespace std;
int main() {
bool result = 3 < 1;
// 括号用于提升表达式的优先级,
// 防止 > 号被 cout 关键字误解。
cout << (3 > 1) << endl;
cout << result << endl;
system("pause");
}
执行结果
1
0
请按任意键继续. . .
字符型
在 C++ 中,字符型变量用于存储数值及 ASCII 码。你可以使用 char 关键字声明一个字符型变量,使用 char 关键字创建的变量将占用一个字节的内存空间。
注:
- 字符需要使用单引号包裹,若使用双引号,C++ 将抛出错误。
- 字符型变量仅能包含单个字符,但转移字符除外,因为转义字符需要使用两个字符来表示一个转义字符。例如:\n、\t。
ASCII
细节
在 C++ 中,使用 char 类型的变量存储某一字符时,存储的不是字符本身而是该字符对应的编码值。我们可以通过如下代码对此进行验证:
#include <iostream>
using namespace std;
int main() {
char letter = 'a';
letter = letter + 1;
cout << letter << endl;
system("pause");
}
执行效果
b
请按任意键继续. . .
分析
在使用关键字 char 创建字符型变量 letter 后,我们对 letter 自身进行了加一的操作。在将 letter 输出到执行窗口后,我们观察到的是 b 而不是 a。
这是由于我们将 a 对应的 ASCII 码存入了变量 letter 中,我们对其进行加一操作,导致存储的 ASCII 码发生了变化,最终打印出了其他字符。
注:
-
cin 与 cout 在面对字符串类型数据时将进行特殊的处理,具体如下:
- cin 将输入的字符转换为其对应的 ASCII 码值。
- cout 将 char 变量中保存的 ASCII 码转换为其对应的字符并将其输出到执行窗口中。
-
除了传递字符给 char 变量外,你还可以直接将需要保存的字符对应的 ASCII 码传递给该变量。例如:
#include <iostream>
using namespace std;
int main() {
char letter = 65;
cout << letter << endl;
system("pause");
}
执行结果
A
请按任意键继续. . .
范围
char 在默认情况下是否为有符号数据类型由 C++ 实现来决定,这样编译器的开发人员将能够最大限度地将这种类型与硬件属性匹配起来。你可以使用 signed char 或 unsigned char 来显式指定 char 为哪一种类型。
如果将 char 用作数值类型,则 unsigned char 与 signed char 之间的差异将变得非常重要。unsigned char 类型所支持的范围为 0 ~ 255 ,而 signed char 类型所支持的范围为 -128 ~ 127
举个栗子
#include <iostream>
using namespace std;
int main() {
unsigned char letter = 130;
cout << letter << endl;
cout << "--------------------" << endl;
cout << (int)letter << endl;
system("pause");
}
执行效果
--------------------
130
请按任意键继续. . .
注:
-
cout 语句仅能将存储的数值为 0 ~ 127 的 char 变量转化为该数值对应的字符。
-
(int) 语句可以将其他类型的数据转换为 int 类型的数据。
-
请尽可能使用 unsigned char 或 signed char 来显式指定 char 的类型,否则你无法判断运行程序后是否会出现如下状况:
#include <iostream>
using namespace std;
int main() {
char letter = 130;
cout << letter << endl;
cout << "--------------------" << endl;
cout << (int)letter << endl;
system("pause");
}
执行结果
--------------------
-126
请按任意键继续. . .