C++ 数据类型
类型(type)告诉编译器"这个变量占几个字节、能存什么样的数据、能做哪些运算"。C++ 是静态强类型语言——每个变量必须有明确类型,且不会自动做不安全的转换。这一章我们系统过一遍 C++ 的基本数据类型。
一、整型:int、long、short
整型用来存整数。C++ 根据占字节数和是否有符号,提供了一组类型:
#include <iostream>
using namespace std;
int main() {
short s = 32767; // 2 字节,-32768~32767
int i = 2147483647; // 4 字节,-21 亿~21 亿
long l = 9999999999L; // 至少 4 字节
long long ll = 999999999999LL; // 8 字节(C++11)
unsigned int u = 4000000000U; // 无符号 int,4 字节全正数
cout << s << " " << i << endl;
cout << l << " " << ll << endl;
cout << u << endl;
return 0;
}整型的取值范围(64 位系统典型值):
- short:2 字节,-32768 ~ 32767
- int:4 字节,-21 亿 ~ 21 亿(最常用)
- long:Windows 4 字节,macOS/Linux 8 字节
- long long:8 字节,-9.2×10^18 ~ 9.2×10^18(C++11 引入)
- unsigned 前缀:无符号,只存非负数,最大值翻倍
整型溢出是常见 bug,溢出后值会"绕一圈":
#include <iostream>
using namespace std;
int main() {
short a = 32767;
a = a + 1; // 上溢:正数变负数!
cout << a << endl; // -32768(未定义行为,但通常如此)
unsigned int b = 0;
b = b - 1; // 下溢:0 变最大正数
cout << b << endl; // 4294967295
return 0;
}二、浮点型:float、double
浮点型用来存小数。C++ 提供三种:
#include <iostream>
#include <iomanip> // 用于控制输出精度
using namespace std;
int main() {
float f = 3.14f; // 4 字节,6~7 位有效数字
double d = 3.141592653589793; // 8 字节,15~17 位有效数字
long double ld = 3.14L; // 通常 16 字节
// 默认 cout 只显示 6 位有效数字
cout << d << endl; // 3.14159
// 设置显示 15 位
cout << setprecision(15) << d << endl; // 3.14159265358979
// 浮点数有精度误差
cout << 0.1 + 0.2 << endl; // 0.300000000000000(近似 0.3)
return 0;
}- float:4 字节,6~7 位有效数字。字面量加
f后缀。 - double:8 字节,15~17 位有效数字。默认浮点类型,推荐默认用。
- long double:通常 16 字节,更高精度。字面量加
L后缀。
浮点数精度陷阱:由于二进制无法精确表示某些小数,0.1 + 0.2 != 0.3!这是个老问题,几乎所有语言都有。比较浮点数要用 abs(a - b) < 1e-9 这样的"容差比较"。
三、字符型:char
char 存单个字符,占 1 字节。本质是个小整数:
#include <iostream>
using namespace std;
int main() {
char c = 'A'; // 字符字面量用单引号
char newLine = '\n'; // 换行符
char tab = '\t'; // 制表符
char nullChar = '\0'; // 空字符
cout << c << endl; // A
cout << (int)c << endl; // 65(char 本质是 1 字节整数)
// 常见转义字符
cout << "Line1\nLine2" << endl; // 换行
cout << "a\tb" << endl; // 制表
cout << "Say \"hi\"!" << endl; // 输出双引号: Say "hi"!
cout << "Path: C:\\dir" << endl; // 输出反斜杠: Path: C:\dir
// wchar_t:宽字符(用于中文/Emoji 等多字节字符)
wchar_t wc = L'中';
return 0;
}几个要点:
- 字符字面量用单引号:
'A'。字符串用双引号"A"。区别:字符占 1 字节,字符串还多一个结尾空字符(共 2 字节)。 - char 本质是整数:可以参与算术运算,
'A' + 1等于'B'。 - 转义字符:以反斜杠开头的特殊字符,如换行、制表、反斜杠、双引号、空字符等。
- wchar_t:宽字符,用于多字节字符(中文、Emoji)。日常编程用得少,中文一般用 UTF-8 编码 + string。
四、布尔型:bool
bool 只存两种值:true(真)或 false(假),占 1 字节:
#include <iostream>
using namespace std;
int main() {
bool b1 = true; // 真
bool b2 = false; // 假
// bool 本质是 1 字节整数:true=1, false=0
cout << b1 << endl; // 1
cout << b2 << endl; // 0
// 任何非零值转 bool 都是 true
int x = 42;
if (x) {
cout << "x 非零" << endl; // 会打印
}
cout << boolalpha; // 让 cout 把 bool 显示为 true/false
cout << b1 << endl; // true
return 0;
}bool 主要用于条件判断。不要写 if (b == true),直接写 if (b) 更简洁。同理,if (!b) 比 if (b == false) 好。
五、枚举:enum
枚举用于定义一组命名的整数常量,让代码更有意义:
#include <iostream>
using namespace std;
// 1. 传统 enum(老式,不推荐)
enum Color { RED, GREEN, BLUE }; // 默认 0, 1, 2
// 2. enum class(C++11,强类型枚举,推荐)
enum class Direction { Up, Down, Left, Right };
int main() {
Color c = RED;
cout << c << endl; // 0(隐式转 int)
Direction d = Direction::Up;
// cout << d << endl; // 编译错误:enum class 不能隐式转 int
cout << static_cast<int>(d) << endl; // 0,需显式转换
// enum class 的优势:不会污染外层命名空间
// Color 和 Direction 都有同名成员也不会冲突
return 0;
}- 传统 enum(老式):成员可以直接转 int,且会污染外层命名空间。不推荐。
- enum class(C++11):也叫强类型枚举。成员必须用
Direction::Up访问,不会转 int 也不会冲突。强烈推荐。
六、字符串:string
C++ 处理字符串有两套:
#include <iostream>
#include <string>
using namespace std;
int main() {
// 1. C 风格字符串:char 数组(不推荐,容易溢出)
char cstr[] = "Hello";
// 2. C++ string 类(强烈推荐)
string s1 = "Hello";
string s2 = "World";
// 拼接:+
string s3 = s1 + ", " + s2 + "!";
cout << s3 << endl; // Hello, World!
// 长度:.length() 或 .size()
cout << s3.length() << endl; // 13
// 取字符:[index]
cout << s3[0] << endl; // H
// 子串:.substr(起始, 长度)
cout << s3.substr(0, 5) << endl; // Hello
// 查找:.find(),返回下标,找不到返回 string::npos
if (s3.find("World") != string::npos) {
cout << "found!" << endl;
}
return 0;
}- C 风格字符串:char 数组
char s[] = "hi"。老旧、危险(容易溢出),不要用。 - C++ string 类:封装好的字符串类,自动管理内存。强烈推荐。
string 常用方法:length()(长度)、[i](取字符)、substr(start, len)(子串)、find(s)(查找)、+(拼接)、==(比较)。
七、用 sizeof 查字节数
不确定某个类型占多大?用 sizeof 一查便知:
#include <iostream>
using namespace std;
int main() {
// sizeof 返回类型或变量占的字节数
cout << "char: " << sizeof(char) << endl; // 1
cout << "short: " << sizeof(short) << endl; // 2
cout << "int: " << sizeof(int) << endl; // 4
cout << "long: " << sizeof(long) << endl; // 8(macOS/Linux 64 位)
cout << "long long: " << sizeof(long long) << endl;// 8
cout << "float: " << sizeof(float) << endl; // 4
cout << "double: " << sizeof(double) << endl; // 8
cout << "bool: " << sizeof(bool) << endl; // 1
cout << "指针: " << sizeof(int*) << endl; // 8(64 位系统)
return 0;
}注意:C++ 标准只规定了相对大小关系(如 sizeof(short) <= sizeof(int) <= sizeof(long)),具体字节数在不同平台可能不同。
八、类型转换
C++ 类型转换有四种写法:
#include <iostream>
using namespace std;
int main() {
// 1. 隐式转换(编译器自动)
int i = 42;
double d = i; // int -> double,无损
cout << d << endl; // 42
// 2. 显式转换(C 风格,不推荐)
double pi = 3.14;
int truncated = (int)pi;
cout << truncated << endl; // 3
// 3. static_cast(推荐,C++ 风格)
int rounded = static_cast<int>(pi + 0.5);
cout << rounded << endl; // 3
// 4. 字符串转数字(C++11)
string s = "42";
int n = stoi(s); // string to int
double dd = stod("3.14"); // string to double
cout << n << " " << dd << endl;
// 5. 数字转字符串
string s42 = to_string(42);
cout << s42 << endl; // "42"
return 0;
}- 隐式转换:编译器自动做"安全"转换(如 int → double)。
- C 风格
(int)x:不推荐,危险(不检查类型)。 - static_cast:C++ 推荐,显式、可被搜索、可读性高。
- stoi/stod/to_string:字符串与数字互转(C++11)。
小结
这一章你认识了 C++ 的基本数据类型:整型(int/long)、浮点(double)、字符(char)、布尔(bool)、枚举(enum class)、字符串(string)。知道了 sizeof 查大小、static_cast 做类型转换。下一篇我们看运算符——怎么操作这些数据。
← 上一篇 C++ 变量
下一篇 C++ 运算符 →