变量与基本类型
更新时间:2026-08-27。本文是
languages/cpp/主题入门层第 3 篇。C++ 的变量类型和 C 长得像,但多了bool的真身、auto推导、以及用{}初始化防止窄化的新玩法。本篇讲清类型清单、初始化方式对比、以及auto什么时候该用。
本文要回答的问题
- C++ 有哪些基本类型?和 C 相比多了什么、改了啥?
int a = 0;、int a(0);、int a{0};三种初始化有什么区别?auto是什么?无脑用auto会踩什么坑?
一、基本类型清单
| 类型 | 含义 | 典型大小(64 位 Linux) | C 对照 |
|---|---|---|---|
bool | 布尔 | 1 字节(true/false) | C99 _Bool(少见) |
char | 字符 | 1 字节 | 同 |
int | 整数 | 4 字节 | 同 |
long | 长整数 | 8 字节 | 同 |
float | 单精度浮点 | 4 字节 | 同 |
double | 双精度浮点 | 8 字节 | 同 |
unsigned | 无符号变体 | 同对应类型 | 同 |
两个关键点:
bool在 C++ 是原生类型,true/false是关键字;C 里要么用_Bool要么用int0/1 糊弄。C++ 里bool参与条件判断、函数返回、重载都能精确匹配,这是 C 没有的。- 类型大小随平台变(
int在 32 位是 4 字节、long在 Windows 是 4 字节)。要固定宽度用<cstdint>:int32_t、int64_t、uint64_t——这也是工程里的最佳实践。
cpp
#include <iostream>
#include <cstdint>
int main() {
bool ok = true;
int32_t n = 42; // 固定 4 字节
uint64_t big = 123456789ULL; // 固定 8 字节无符号
std::cout << ok << " " << n << " " << big << std::endl;
return 0;
}二、三种初始化方式
C++ 里声明变量有三种写法:
cpp
int a = 10; // 拷贝初始化(C 风格)
int b(10); // 直接初始化
int c{10}; // 列表初始化(C++11 起)| 写法 | 特点 | 典型坑 |
|---|---|---|
int a = 10; | 经典,随手写 | 丢失精度时静默(见下) |
int b(10); | 函数式,类类型常用 | 和函数声明可能混淆(最麻烦的解析) |
int c{10}; | 推荐,禁止窄化 | 隐式丢精度会被编译拒绝 |
列表初始化 {} 的最大价值是拒绝"窄化":
cpp
int x = 3.14; // 编译通过,x == 3(静默丢精度,危险)
int y{3.14}; // 编译错误:double 转 int 是窄化,被拒绝
double d{1.0 / 3}; // OK:double ← int 是加宽,允许{} 把"数据放得下吗"的检查交给编译器——放不下直接报错,而不是悄悄截断。入门阶段建议统一用 {} 初始化,C++ 社区称其为"统一初始化",类和数组也都能用。
三、auto:让编译器替你写类型
C++11 引入 auto,变量类型由初始化表达式推导:
cpp
auto i = 42; // int
auto d = 3.14; // double
auto s = std::string("hi"); // std::string什么时候用 auto 真香:
- 类型名超长时:
std::map<std::string, std::vector<int>>::iterator手写要命,auto it = ...一行搞定; - 类型随表达式变化:
auto result = obj.calc();不用管calc()返回什么; - lambda / 模板场景:类型无法手写(lambda 的类型只有编译器知道)。
什么时候别用 auto:
- 想要隐式转换时:
auto x = n / 2;如果n是int,x就是int(整除截断)——想得double必须显式double(n) / 2; - 可读性反而变差时:
auto x = 42;看不出意图,不如直接int x = 42;; - 引用和指针的坑:
auto会剥掉引用和 const,const auto&才能保留——这个细节在引用入门和高手层展开。
四、变量初始化别留"未初始化"
C 的一个经典坑:局部变量不初始化,值是"垃圾"。C++ 里写 int x; 同样有这问题。规则:能用 {} 就给初值,不要留裸声明。
cpp
int x{}; // 零初始化:x == 0
std::string s; // 默认构造:空串(类类型自动初始化)对于类类型(std::string、std::vector),声明即初始化(调用默认构造函数),不会出现垃圾值——这比 C 的裸数组、裸 int 安全得多。这也呼应了 C++ 的核心理念:类型自己负责自己的初始状态。
五、与本站主线衔接
- 各类型的内存占用、对齐与缓存行为,见 L3 内存子系统;
int32_t等固定宽度类型在二进制协议、序列化中的意义,见 L5 ELF 与 ABI;- C 的变量与类型对照,见 C 语言变量与常量与 基本数据类型。
一句话总结
C++ 类型在 C 的基础上多了原生 bool、推荐固定宽度 int32_t 等;初始化用 {} 列表初始化(拒绝窄化),auto 让编译器推导类型——超长类型、表达式结果、lambda 场景真香,但隐式转换、可读性、引用 const 场景要小心;核心心法:声明即给初值,类型自己负责初始状态。
上一篇:命名空间与 using 下一篇:const 与 constexpr 入门