C++语言学习坚持百日基本功-基本数据类型-7
C++ 是一种静态类型语言,变量在使用前必须声明其数据类型。数据类型决定了变量存储的内容、占用的内存大小以及可执行的操作。C++ 的数据类型体系可分为**基本数据类型**和**复合数据类型**两大类,其中基本数据类型是构成更复杂数据结构的基础。
### 一、基本数据类型的分类
C++ 基本数据类型分为三大类:
1. **整数类型**:用于存储整数(正数、负数、零),包括 `bool`、`char`、`short`、`int`、`long`、`long long`。
2. **浮点类型**:用于存储小数(含科学计数法表示的数),包括 `float`、`double`、`long double`。
3. **空类型**:`void`,表示“无类型”,用于函数返回值或指针声明。
此外,C++11 新增了**固定大小整数类型**(如 `int8_t`、`uint32_t`),解决了传统整数类型大小依赖平台的问题。
### 二、整数类型详解
整数类型的核心区别在于**内存占用**和**表示范围**,且分为**有符号**(可表示负数)和**无符号**(仅表示非负数)两类(`bool` 和 `char` 除外)。
#### 1. 布尔类型(`bool`)
- **用途**:表示逻辑值(真/假)。
- **内存大小**:标准未规定,通常为 1 字节(8 位)。
- **取值范围**:仅两个值——`true`(逻辑真,编译器通常视为 1)和 `false`(逻辑假,编译器通常视为 0)。
- **特点**:
- 可参与算术运算(`true + 1` 结果为 2)。
- 赋值时非 0 会自动转为 `true`(`bool b = 10;` 等价于 `b = true`)。
**代码示例**:
```cpp
#include <iostream>
using namespace std;
int main() {
bool isPass = true;
bool isFail = false;
cout << "true 的值:" << isPass << endl; // 输出 1
cout << "false 的值:" << isFail << endl; // 输出 0
cout << "true + 5 = " << (isPass + 5) << endl; // 输出 6
cout << "10 是否为 true?" << (bool)10 << endl; // 输出 1(非 0 转为 true)
return 0;
}
```
#### 2. 字符类型(`char`)
- **用途**:存储单个字符(如 'a'、'1')或小整数(依赖 ASCII 编码)。
- **内存大小**:标准规定为 1 字节(8 位),是唯一大小固定的整数类型。
- **分类**:
- `char`:默认有符号或无符号,依赖编译器(通常为有符号)。
- `signed char`:有符号,范围为 -128 ~ 127。
- `unsigned char`:无符号,范围为 0 ~ 255。
- **特点**:
- 字符用单引号括起(`char c = 'A'`),本质存储 ASCII 码('A' 对应 65)。
- 可直接参与整数运算(`'A' + 32` 结果为 97,对应小写 'a')。
**代码示例**:
```cpp
#include <iostream>
using namespace std;
int main() {
char c1 = 'A'; // 字符赋值
char c2 = 66; // ASCII 码赋值(66 对应 'B')
unsigned char c3 = 200; // 无符号字符(范围 0~255)
cout << "c1:" << c1 << ",ASCII 码:" << (int)c1 << endl; // 输出 A,65
cout << "c2:" << c2 << ",ASCII 码:" << (int)c2 << endl; // 输出 B,66
cout << "c1 + 32 = " << (char)(c1 + 32) << endl; // 输出 a(小写转换)
cout << "c3 的值:" << (int)c3 << endl; // 输出 200(无符号)
// 有符号字符溢出示例(-128 - 1 = 127,循环溢出)
signed char c4 = -128;
cout << "c4 - 1 = " << (int)(c4 - 1) << endl; // 输出 127
return 0;
}
```
#### 3. 短整型(`short`/`short int`)
- **用途**:存储较小范围的整数,节省内存。
- **内存大小**:至少 2 字节(16 位),通常为 2 字节。
- **分类**:
- `short`:默认有符号(等价于 `signed short`),范围为 -32768 ~ 32767。
- `unsigned short`:无符号,范围为 0 ~ 65535。
**代码示例**:
```cpp
#include <iostream>
using namespace std;
int main() {
short x = 32767; // 有符号短整型最大值
unsigned short y = 65535; // 无符号短整型最大值
cout << "short 最大值:" << x << endl;
cout << "unsigned short 最大值:" << y << endl;
// 溢出示例
x += 1;
cout << "x + 1 = " << x << endl; // 输出 -32768(循环溢出)
return 0;
}
```
#### 4. 整型(`int`)
- **用途**:最常用的整数类型,兼顾范围和性能。
- **内存大小**:至少 2 字节,通常为 4 字节(32 位)。
- **分类**:
- `int`:默认有符号(等价于 `signed int`),范围为 -2147483648 ~ 2147483647。
- `unsigned int`:无符号,范围为 0 ~ 4294967295。
- **特点**:
- 编译器通常将 `int` 作为整数运算的默认类型(如 `10 + 20` 默认为 `int` 运算)。
**代码示例**:
```cpp
#include <iostream>
using namespace std;
int main() {
int a = 2147483647; // 有符号 int 最大值
unsigned int b = 4294967295; // 无符号 int 最大值
cout << "int 最大值:" << a << endl;
cout << "unsigned int 最大值:" << b << endl;
// 溢出示例
a += 1;
cout << "a + 1 = " << a << endl; // 输出 -2147483648(溢出)
return 0;
}
```
#### 5. 长整型(`long`/`long int`)
- **用途**:存储比 `int` 更大范围的整数。
- **内存大小**:至少 4 字节,32 位系统通常为 4 字节,64 位系统通常为 8 字节。
- **分类**:
- `long`:默认有符号(等价于 `signed long`),32 位系统范围与 `int` 一致,64 位系统为 -9223372036854775808 ~ 9223372036854775807。
- `unsigned long`:无符号,64 位系统范围为 0 ~ 18446744073709551615。
**代码示例**:
```cpp
#include <iostream>
using namespace std;
int main() {
long l = 9223372036854775807; // 64 位系统下的 long 最大值
unsigned long ul = 18446744073709551615; // 无符号 long 最大值
cout << "long 最大值:" << l << endl;
cout << "unsigned long 最大值:" << ul << endl;
return 0;
}
```
#### 6. 长长整型(`long long`/`long long int`)
- **用途**:C++11 新增,用于存储超大范围的整数(如天文数字、大计数器)。
- **内存大小**:至少 8 字节(64 位)。
- **分类**:
- `long long`:默认有符号(等价于 `signed long long`),范围为 -9223372036854775808 ~ 9223372036854775807。
- `unsigned long long`:无符号,范围为 0 ~ 18446744073709551615。
- **特点**:
- 是 C++ 中表示范围最大的整数类型(标准规定)。
**代码示例**:
```cpp
#include <iostream>
using namespace std;
int main() {
long long ll = 9223372036854775807; // 有符号 long long 最大值
unsigned long long ull = 18446744073709551615; // 无符号最大值
cout << "long long 最大值:" << ll << endl;
cout << "unsigned long long 最大值:" << ull << endl;
// 溢出示例
ll += 1;
cout << "ll + 1 = " << ll << endl; // 输出 -9223372036854775808(溢出)
return 0;
}
```
#### 7. C++11 固定大小整数类型
传统整数类型(如 `int`、`long`)的大小依赖平台,导致代码可移植性差。C++11 从 `<cstdint>` 头文件引入**固定大小整数类型**,确保在任何平台上大小一致:
| 类型 | 大小(字节) | 有符号/无符号 | 范围 |
|--------------|--------------|---------------|--------------------------|
| `int8_t` | 1 | 有符号 | -128 ~ 127 |
| `uint8_t` | 1 | 无符号 | 0 ~ 255 |
| `int16_t` | 2 | 有符号 | -32768 ~ 32767 |
| `uint16_t` | 2 | 无符号 | 0 ~ 65535 |
| `int32_t` | 4 | 有符号 | -2147483648 ~ 2147483647 |
| `uint32_t` | 4 | 无符号 | 0 ~ 4294967295 |
| `int64_t` | 8 | 有符号 | -9e18 ~ 9e18 |
| `uint64_t` | 8 | 无符号 | 0 ~ 1.8e19 |
**代码示例**:
```cpp
#include <iostream>
#include <cstdint> // 包含固定大小整数类型
using namespace std;
int main() {
int32_t x = 2147483647; // 32 位有符号整数
uint64_t y = 18446744073709551615; // 64 位无符号整数
cout << "int32_t 最大值:" << x << endl;
cout << "uint64_t 最大值:" << y << endl;
return 0;
}
```
### 三、浮点类型详解
浮点类型用于存储小数或科学计数法表示的数,核心区别在于**精度**和**表示范围**。
#### 1. 单精度浮点型(`float`)
- **用途**:存储精度要求不高的小数(如普通测量数据)。
- **内存大小**:通常为 4 字节(32 位)。
- **精度**:约 6~7 位有效数字(十进制)。
- **表示范围**:约 ±3.4e38(科学计数法)。
- **特点**:
- 用 `f` 或 `F` 后缀标识(`float f = 3.14f;`,否则默认为 `double`)。
- 存在精度误差(如 `0.1 + 0.2` 结果不等于 `0.3`)。
**代码示例**:
```cpp
#include <iostream>
#include <iomanip> // 用于设置输出精度
using namespace std;
int main() {
float f1 = 3.14f; // 单精度浮点型(必须加 f 后缀)
float f2 = 1.23456789f; // 超过 7 位有效数字,会丢失精度
cout << "f1 = " << f1 << endl;
cout << "f2(默认精度) = " << f2 << endl;
cout << "f2(10 位精度) = " << fixed << setprecision(10) << f2 << endl; // 输出 1.2345678806(精度丢失)
// 精度误差示例
float a = 0.1f;
float b = 0.2f;
cout << "0.1f + 0.2f = " << (a + b) << endl; // 输出 0.3000000119(不等于 0.3)
return 0;
}
```
#### 2. 双精度浮点型(`double`)
- **用途**:最常用的浮点类型,精度高于 `float`(如科学计算、工程数据)。
- **内存大小**:通常为 8 字节(64 位)。
- **精度**:约 15~16 位有效数字(十进制)。
- **表示范围**:约 ±1.7e308。
- **特点**:
- 是浮点常量的默认类型(`3.14` 默认为 `double`)。
- 精度误差比 `float` 小,但仍存在(如 `0.1 + 0.2` 仍不等于 `0.3`)。
**代码示例**:
```cpp
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
double d1 = 3.14; // 双精度浮点型(默认)
double d2 = 1.234567890123456789; // 超过 16 位有效数字,丢失精度
cout << "d1 = " << d1 << endl;
cout << "d2(15 位精度) = " << fixed << setprecision(15) << d2 << endl; // 输出 1.234567890123457(最后一位四舍五入)
// 精度误差示例
double a = 0.1;
double b = 0.2;
cout << "0.1 + 0.2 = " << (a + b) << endl; // 输出 0.30000000000000004(接近 0.3,但不等)
return 0;
}
```
#### 3. 长双精度浮点型(`long double`)
- **用途**:存储精度要求极高的小数(如高精度科学计算、金融数据)。
- **内存大小**:通常为 8 字节或 10 字节(部分平台为 16 字节)。
- **精度**:约 18~19 位有效数字(十进制)。
- **表示范围**:约 ±1.1e4932。
- **特点**:
- 用 `L` 后缀标识(`long double ld = 3.14L;`)。
- 精度最高,但内存占用和运算开销也最大。
**代码示例**:
```cpp
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
long double ld1 = 3.14159265358979323846L; // 长双精度浮点型(加 L 后缀)
cout << "ld1(20 位精度) = " << fixed << setprecision(20) << ld1 << endl; // 输出 3.14159265358979323851(精度最高)
return 0;
}
```
#### 4. 浮点类型的精度误差问题
浮点类型采用二进制存储小数,而十进制小数(如 0.1)无法用有限位二进制精确表示,导致精度误差。解决方法:
- 避免直接比较浮点数是否相等,应判断差值是否小于一个极小值(如 `1e-9`)。
- 对精度要求极高的场景(如金融计算),使用 `decimal` 类型(C++17 新增,需包含 `<decimal>` 头文件)或第三方库(如 `GMP`)。
**代码示例(浮点数比较)**:
```cpp
#include <iostream>
#include <cmath> // 包含 fabs() 函数
using namespace std;
int main() {
double a = 0.1;
double b = 0.2;
double c = 0.3;
// 错误比较:直接用 ==
if (a + b == c) {
cout << "0.1 + 0.2 == 0.3" << endl;
} else {
cout << "0.1 + 0.2 != 0.3" << endl; // 会执行此分支
}
// 正确比较:判断差值小于 1e-9
if (fabs(a + b - c) < 1e-9) {
cout << "0.1 + 0.2 近似等于 0.3" << endl; // 会执行此分支
}
return 0;
}
```
### 四、空类型(`void`)
`void` 表示“无类型”,主要用于以下场景:
#### 1. 函数返回值
表示函数不返回任何值(必须显式声明)。
```cpp
#include <iostream>
using namespace std;
void printHello() {
cout << "Hello, C++!" << endl;
}
int main() {
printHello(); // 调用无返回值函数
return 0;
}
```
#### 2. 函数参数
表示函数不接受任何参数(C++ 中可省略,但显式写 `void` 更清晰)。
```cpp
#include <iostream>
using namespace std;
void func(void) { // 等价于 void func()
cout << "无参数函数" << endl;
}
int main() {
func();
return 0;
}
```
#### 3. 指针类型(`void*`)
表示“通用指针”,可指向任何类型的数据,但无法直接解引用(需强制类型转换)。
```cpp
#include <iostream>
using namespace std;
int main() {
int x = 10;
double y = 3.14;
void* p = &x; // void* 指向 int 类型
cout << "x 的值:" << *(int*)p << endl; // 强制转换为 int* 后解引用(输出 10)
p = &y; // void* 指向 double 类型
cout << "y 的值:" << *(double*)p << endl; // 强制转换为 double* 后解引用(输出 3.14)
return 0;
}
```
### 五、基本数据类型的选择原则
1. **优先使用 `int`**:对于整数,`int` 是默认选择,兼顾性能和范围。
2. **节省内存用小类型**:如存储 ASCII 字符用 `char`,存储小范围整数用 `short`。
3. **超大整数用 `long long`**:如存储超过 `int` 范围的数(如超过 2e9)。
4. **可移植性用固定大小类型**:如跨平台项目用 `int32_t`、`uint64_t` 替代 `int`、`long`。
5. **小数优先用 `double`**:`double` 精度足够,且是默认浮点类型,性能与 `float` 接近。
6. **高精度小数用 `long double`**:如科学计算、金融数据等对精度要求极高的场景。
7. **逻辑值用 `bool`**:表示真/假时,`bool` 比 `int` 更清晰(可读性更好)。
### 六、总结
C++ 基本数据类型是构建程序的基础,其核心特性可概括为:
- **整数类型**:按大小分为 `char`、`short`、`int`、`long`、`long long`,支持有符号/无符号,需注意溢出问题。
- **浮点类型**:按精度分为 `float`、`double`、`long double`,存在精度误差,避免直接比较。
- **空类型**:`void` 用于无返回值函数、无参数函数和通用指针。
在实际开发中,应根据数据的范围、精度需求和平台特性选择合适的类型,以兼顾性能、内存和可移植性。
更多推荐



所有评论(0)