核心要点速览

  • 数据类型分类:基本类型、复合(派生)类型、自定义类型
  • 核心复合类型:指针、引用、数组、结构体、联合体、枚举
  • 变量关键特性:存储类别(auto/static/extern 等)、初始化要求、作用域与生命周期
  • 常量核心:const(只读)、constexpr(编译期常量)
  • 类型转换:隐式转换(编译器自动)、显式转换(四种强制转换)

一、数据类型

1.1 基本类型

基本类型是 C++ 内置的基础数据类型,具有固定内存大小(部分受平台影响)和明确取值范围。

类型典型大小(32/64 位系统)含义 / 范围面试考点
bool1 字节布尔值:true(1)/false(0)sizeof(bool)恒为 1;不可用 0 / 非 0 代替(语法允许但不规范)
char1 字节ASCII 码:-128~127 或 0~255区分signed char(带符号)和unsigned char(无符号);默认符号性由编译器决定
short2 字节短整数:-32768~32767short int等价;用于节省内存
int4 字节(通用)整数:-2³¹~2³¹-1平台无关性(主流编译器统一 4 字节);计数、返回值首选类型
long4 字节(32 位)/8 字节(64 位)长整数:随平台变化避免依赖其大小,优先用固定宽度类型(如int64_t
long long8 字节超长整数:-2⁶³~2⁶³-1C++11 标准,跨平台 8 字节,适合大整数
float4 字节单精度浮点:有效数字 6-7 位精度低;避免直接比较(存在误差)
double8 字节双精度浮点:有效数字 15-17 位默认浮点类型(如3.14是 double);科学计算首选
void无大小无类型(表示 “空”)用于无返回值函数、void*指针(可指向任意类型)
关键补充
  • 跨平台一致性保证:使用 C++11 固定宽度类型(定义于<cstdint>),如int32_t(32 位带符号)、uint64_t(64 位无符号)。
  • sizeof计算规则:sizeof(char)恒为 1;sizeof(int)通常 4 字节;sizeof(void)编译报错;sizeof(bool)始终为 1。

1.2 复合类型(派生类型)

基于基本类型或自定义类型扩展,核心用于组合、关联或间接访问数据。

指针
  • 存储目标变量的内存地址,大小仅与系统位数相关(32 位 4 字节,64 位 8 字节,与指向类型无关)。
  • 核心特性:
    1. 未初始化指针为野指针(指向随机地址,操作易崩溃),需避免。
    2. nullptr(C++11):空指针常量,替代NULLNULL本质是 0,易引发歧义)。
    3. 指针运算:仅对数组指针有效(p++步长为指向类型的大小)。
    4. 数组名本质:指向数组首元素的常量指针(不可修改指向)。
引用
  • 变量的 “别名”,语法:类型& 引用名 = 变量名,必须初始化且绑定后不可更改。
对比项指针引用
定义可空(nullptr不可空(必须绑定变量)
指向修改可重新指向其他变量绑定后不可更改
初始化可延迟初始化(风险高)必须定义时初始化
内存占用占内存(存储地址)不占额外内存(编译器优化)
核心用途动态内存管理、多级间接访问函数参数 / 返回值(避免拷贝)、简化代码
结构体(Struct)
  • 组合多个不同类型数据(成员)为一个整体,成员按顺序占用独立内存。
  • 核心特性:结构体大小 = 成员大小之和 + 内存对齐填充字节。
  • 用途:存储关联数据(如个人信息:姓名、年龄、身高)。
联合体(Union)
  • 所有成员共享同一块内存,同一时间仅能有效使用一个成员。
对比项结构体(Struct)联合体(Union)
内存分配成员独立占用内存,总大小 = 成员和 + 填充成员共享内存,总大小 = 最大成员大小(+ 对齐填充)
成员关系成员并存(可同时访问)成员互斥(同一时间仅能用一个)
核心用途组合关联数据节省内存、实现类型转换
枚举(Enum)
  • 自定义整数类型,用于组合含义相关的命名常量。
  • 分类:
    1. 传统枚举:enum E {A, B=5, C};,成员作用域全局(易冲突),可隐式转 int。
    2. 强类型枚举(C++11 推荐):enum class E {A, B};,作用域受限(需E::A访问),不可隐式转 int(更安全)。
  • 赋值规则:未手动赋值时,首个常量为 0,后续依次 + 1;中间赋值后,后续常量基于该值递增。

1.3 自定义类型

  • 由用户通过class(类)、struct(结构体)、enum(枚举)等关键字定义的类型。
  • 核心作用:封装数据与行为,提升代码可读性和复用性。

二、变量

2.1 变量的定义与初始化

  • 定义:编译器为变量分配内存空间。
  • 初始化:定义时赋予初始值(避免 “垃圾值”,提升代码安全性)。
  • 常见初始化方式:
    int a = 10;    // 拷贝初始化
    int b(20);     // 直接初始化(适合构造函数场景)
    int c{30};     // 列表初始化(C++11,禁止窄化转换,如int{3.14}编译报错)
    int d = {40};  // 拷贝列表初始化
    

2.2 存储类别(关键字修饰)

存储类别决定变量的生命周期、作用域和存储位置。

关键字核心特性与用途
auto(C++11)编译器自动推导类型;不能用于函数参数(模板除外)、数组类型;推导引用需显式加&
static局部静态变量:生命周期为程序全程,首次调用初始化;全局静态变量:仅当前.cpp 可见(避免命名冲突);类静态成员:属于类,所有对象共享
extern声明变量 / 函数在其他文件定义(跨文件共享);仅声明不分配内存,带初始化则变为定义
register提示编译器存于寄存器(C++17 后弃用,现代编译器优化足够)
mutable仅用于类非静态成员;允许 const 成员函数修改该变量(突破 const 限制)
volatile禁止编译器优化;变量值可能被外部因素修改(如硬件、多线程),每次访问直接读内存

2.3 常见问题解答

  • 局部变量屏蔽全局变量时如何访问全局变量?用::(全局作用域解析符),如::global_var
  • 全局变量与局部static变量的初始化顺序?全局变量在main前初始化,局部static变量首次进入函数时初始化(C++11 后线程安全);销毁顺序与初始化相反。
  • 未初始化的局部变量和全局变量区别?局部非static变量是 “垃圾值”;全局变量和static变量会零初始化(数值为 0,指针为nullptr)。

2.4 常量

常量是初始化后不可修改的变量,核心分为constconstexpr

const(只读常量)
  • 修饰变量:初始化后不可修改,作用域与变量一致。
  • 修饰指针(三大场景):
    const int* p;    // 常量指针:指向的内容不可改(*p不可改),p可改指向
    int* const p;    // 指针常量:p的指向不可改,*p可改
    const int* const p;  // 指向常量的指针常量:内容和指向均不可改
    
constexpr(编译期常量,C++11)
  • 要求表达式在编译期可计算,比const更严格(const可运行期初始化)。
  • 用途:定义数组大小、模板参数等依赖编译期常量的场景。

2.5 类型转换

隐式转换(自动转换)
  • 遵循 “安全优先” 原则,优先 “小范围→大范围”(类型提升),避免溢出。
  • 转换顺序:boolcharshortintlonglong longfloatdoublelong double
  • 注意:explicit关键字可禁止类的隐式类型转换。
显式转换(四种强制转换)
转换方式核心用途风险程度
static_cast基本类型转换(int→double)、父类 / 子类指针转换(无动态检查)中等(父类→子类可能越界)
dynamic_cast多态类型转换(仅用于含虚函数的类),运行期检查有效性低(失败返回nullptr/ 抛异常)
const_cast移除指针 / 引用的const属性高(修改原const变量会导致未定义行为)
reinterpret_cast底层二进制重解释(如int*→char*极高(依赖平台,无移植性)
问答
  • 何时用dynamic_cast?多态场景下,需将父类指针安全转为子类指针(需父类有虚函数,运行期校验合法性)。
  • 为何避免reinterpret_cast?直接操作二进制,忽略类型安全,结果依赖平台,移植性极差。
Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐