容易被忽略但常出问题的基础语法点:bool 与 boolalpha、sizeof 的指针陷阱、auto 的 const 剥离、nullptr 与 static。

1. bool 类型与 boolalpha

核心规则

场景结果说明
bool b = true输出 1默认输出数字
bool b = false输出 0默认输出数字
bool b = -8输出 1非零即为 true
bool b = 0输出 0零即为 false

boolalpha 操纵符

使用 std::boolalpha 可以让 cout 输出 true/false 而不是 1/0。

#include <iostream>
using namespace std;

int main() {
    bool isTrue = true;

    // 默认输出(数字)
    cout << "默认: " << isTrue << endl;      // 输出: 1

    // 使用 boolalpha(文字)
    cout << boolalpha;
    cout << "boolalpha: " << isTrue << endl; // 输出: true

    // 非零值也为 true
    bool b = -8;
    cout << "-8 转 bool: " << b << endl;     // 输出: true

    return 0;
}

常见陷阱

// 陷阱1:非零即为 true
bool b1 = 42;       // true
bool b2 = -1;       // true
bool b3 = 0.001;    // true
bool b4 = nullptr;  // false (C++11)

// 陷阱2:bool 与整数混合运算
int a = true + true;  // a = 2(true 被提升为 1)
int b = true * 10;    // b = 10

2. sizeof 运算符

基本用法

#include <iostream>
using namespace std;

int main() {
    cout << "char:      " << sizeof(char) << endl;      // 1
    cout << "short:     " << sizeof(short) << endl;     // 2
    cout << "int:       " << sizeof(int) << endl;       // 4
    cout << "long:      " << sizeof(long) << endl;      // 4 或 8
    cout << "long long: " << sizeof(long long) << endl; // 8
    cout << "float:     " << sizeof(float) << endl;     // 4
    cout << "double:    " << sizeof(double) << endl;    // 8

    // 数组
    int arr[10];
    cout << "int[10]:   " << sizeof(arr) << endl;       // 40

    // 指针
    int* p;
    cout << "int*:      " << sizeof(p) << endl;         // 4 或 8

    return 0;
}

动态数组的 sizeof 陷阱

int* arr = new int[10];
cout << sizeof(arr) << endl;  // 输出 4 或 8(指针大小,不是数组大小!)

// 正确获取动态数组大小:需要额外传参或用 vector

3. auto 关键字(C++11)

基本用法

auto x = 42;           // int
auto y = 3.14;         // double
auto z = "hello";      // const char*
auto flag = true;      // bool

// 推荐用于复杂类型
#include <vector>
#include <map>

std::vector<int> v = {1, 2, 3};
auto it = v.begin();   // std::vector<int>::iterator

std::map<std::string, int> m;
auto pair = std::make_pair("key", 1);

注意事项

// auto 会忽略顶层 const
const int a = 10;
auto b = a;        // b 是 int,不是 const int
const auto c = a;  // c 是 const int

// 引用形式的 auto 才保留底层 const
const int& ref = a;
auto ref2 = ref;   // ref2 是 int 拷贝——普通 auto 剥离引用,连同底层 const 一起丢
auto& ref3 = ref;  // ref3 是 const int&——auto& 保留底层 const(不能改 *ref3)

4. nullptr(C++11)

与 NULL 的区别

// NULL 在 C++ 中可能是 0 或 (void*)0
void func(int);
void func(char*);

func(NULL);    // 编译错误!歧义
func(nullptr); // OK,调用 func(char*)

最佳实践

// 初始化指针
int* p = nullptr;

// 判断指针
if (p != nullptr) {
    // 使用 p
}

// 函数参数
void foo(int* ptr) {
    if (ptr == nullptr) {
        return;
    }
}

5. const 与 constexpr(简记)

特性constconstexpr
初始化时机运行时编译时
可用于函数返回值是是
编译期常量否是
const int x = 10;        // OK
constexpr int y = 20;    // OK,编译期常量

// constexpr 函数
constexpr int square(int n) {
    return n * n;
}
constexpr int val = square(5);  // 编译期计算

const 与 constexpr 的完整对比、constexpr 函数、if constexpr、C++20 的 consteval/constinit,见另一篇《C++ namespace、const 与 constexpr 知识点总结》。

6. static 关键字

静态局部变量

void counter() {
    static int count = 0;  // 只初始化一次
    count++;
    cout << "调用次数: " << count << endl;
}

// 多次调用
counter(); // 调用次数: 1
counter(); // 调用次数: 2
counter(); // 调用次数: 3

静态全局变量/函数

// file1.cpp
static int internal_only = 42;  // 只在本文件可见

// file2.cpp
// 无法访问 internal_only

总结

知识点关键记忆
bool非零即 true,用 boolalpha 输出文字
sizeof指针大小 ≠ 数组大小
auto值推导剥离顶层 const;引用形式(auto&)才保留底层 const
nullptr类型安全的空指针,替代 NULL
constexpr编译期常量,用于优化
static静态变量生命周期 = 程序生命周期

自测清单

  • 理解 bool 的隐式转换规则
  • 能正确使用 boolalpha
  • 理解 sizeof 对指针和数组的区别
  • 能正确使用 auto 和 nullptr
  • 区分 const 和 constexpr 的使用场景