C++ 发展简史与核心语法入门

🚀 C++ 发展简史与核心语法入门

✅ 零基础也能看懂

✅ 从"为什么要有 C++"讲起,到命名空间、输入输出、缺省参数、函数重载、引用、内联函数、nullptr

✅ 所有代码可运行,附详细注释和对比说明

✅ 帮你避开初学者常见"坑点"


第一章:C++ 是怎么来的?

起源:为了解决 C 的"痛"

  • 时间:1979 年
  • 人物:Bjarne Stroustrup(本贾尼·斯特劳斯特卢普),贝尔实验室研究员
  • 背景:他在开发操作系统和仿真软件时,发现C 语言虽然快,但缺乏抽象能力:
    • 代码冗长、难维护
    • 无法表达"对象"概念(比如一个"学生"包含姓名、成绩等)
    • 复用性差

💡 他想:"能不能在 C 的基础上,加上面向对象的能力?"

诞生:C with Classes → C++

  • 1983 年 :Stroustrup 在 C 语言基础上加入 类(class)、封装、继承 等特性,命名为 "C with Classes"

  • 同年正式更名为C++

    ++ 是 C 中的自增运算符,寓意 "C 的进化版"

标准化之路

时间 事件
1989 年 ANSI/ISO 成立联合委员会,启动 C++ 标准化
1994 年 提出第一个标准草案
1990s 中期 STL(标准模板库) 被提议纳入标准(由 Alexander Stepanov 等人在惠普开发) → 极大增强泛型编程能力,但也推迟了标准发布时间
1998 年 C++98 正式发布!第一个国际标准

📌 后续重要标准:

  • C++03(小修)
  • C++11(现代 C++ 起点,革命性更新)
  • C++14 / C++17 / C++20 / C++23(持续进化)

官方文档推荐

链接 特点 适用场景
https://legacy.cplusplus.comeference/ 非官方,只更新到 C++11,但按头文件组织,简洁易读 初学者查基础用法
https://zh.cppreference.com/w/cpp 官方中文版,覆盖最新标准(C++26) 深度学习、查新特性
https://en.cppreference.com/w/ 官方英文版,最权威、最全 英文好者首选

✅ 建议:初学用 cplusplus.com,进阶用 cppreference


第二章:你的第一个 C++ 程序

兼容 C 的写法(不推荐长期使用)

c 复制代码
// test.cpp
#include <stdio.h>
int main() {
    printf("Hello World\n");
    return 0;
}

🔧 编译方式:

  • Windows (VS):.cpp 后缀自动调用 C++ 编译器
  • Linux:用 g++ test.cpp(不是 gcc!)

真正的 C++ 写法

c++ 复制代码
#include <iostream>      // C++ 输入输出流头文件
using namespace std;     // 使用 std 命名空间(后面详解)

int main() {
    cout << "Hello World" << endl;  // 输出 + 换行 + 刷新缓冲区
    return 0;
}

🌟 关键点:

  • cout:标准输出对象(console output)
  • <<:流插入运算符(不是位移!)
  • endl:换行并刷新缓冲区(比 \n 更"彻底")

第三章:命名空间(namespace)------ 解决名字冲突

问题:C 语言中的"名字灾难"

c 复制代码
#include <stdlib.h>
int rand = 10;  // ❌ 冲突!stdlib.h 中已有 rand() 函数
int main() {
    printf("%d\n", rand); // 编译报错:重定义
}

💥 C 语言所有标识符都在全局作用域,极易冲突!


解决方案:命名空间

c++ 复制代码
#include <iostream>
#include <cstdlib>

namespace mylib {
    int rand = 10;
    int add(int a, int b) { return a + b; }
    struct Node { int val; Node* next; };
}

int main() {
    std::cout << std::rand() << std::endl;   // C 库的 rand()
    std::cout << mylib::rand << std::endl;   // 我们的 rand
    return 0;
}

mylib::randstd::rand() 互不干扰!


命名空间使用方式(三种)

方式 示例 适用场景
1. 显式指定 mylib::add(1,2) 项目推荐,清晰无歧义
2. 展开单个成员 using mylib::add; add(1,2); 常用函数,避免重复写前缀
3. 展开整个命名空间 using namespace mylib; ❌ 项目中禁用!易引发冲突 ✅ 小练习可用

⚠️ 重要规则

  • 命名空间可嵌套
  • 多文件中同名 namespace 会自动合并
  • C++ 标准库所有内容都在 std 命名空间中

第四章:C++ 输入 & 输出(IO 流)

基本用法

c++ 复制代码
#include <iostream>
using namespace std;

int main() {
    int a; double b; char c;
    
    cin >> a >> b >> c;          // 自动识别类型!
    cout << a << " " << b << " " << c << endl;
    
    // 混用 C 风格(不推荐)
    scanf("%d", &a);
    printf("%d\n", a);
}

✅ 优势:

  • 无需格式符 (告别 %d %lf
  • 支持自定义类型(后续讲运算符重载)

提高 IO 效率(竞赛必备)

c++ 复制代码
ios_base::sync_with_stdio(false);  // 解绑 C/C++ IO
cin.tie(nullptr);                  // 解除 cin 与 cout 绑定
cout.tie(nullptr);

⏱️ 可提速 3~5 倍!适用于大量输入输出场景


第五章:缺省参数(Default Arguments)

什么是缺省参数?

函数调用时,未传实参则使用默认值

c++ 复制代码
void print(int a = 0, int b = 10) {
    cout << a << ", " << b << endl;
}

int main() {
    print();        // 输出: 0, 10
    print(5);       // 输出: 5, 10
    print(1, 2);    // 输出: 1, 2
}

规则(必须遵守!)

规则 说明
半缺省必须靠右 f(int a, int b=1, int c=2)f(int a=1, int b, int c=2)
声明给,定义不给 .h 文件中写默认值,.cpp 中不写
调用从左到右 不能跳过中间参数

📦 实战示例:栈初始化带默认容量

c++ 复制代码
// Stack.h
void STInit(ST* ps, int n = 4);  // 默认容量为4

// test.cpp
ST s;
STInit(&s);        // 用默认值
STInit(&s, 1000);  // 自定义

第六章:函数重载(Overloading)

什么是重载?

同一作用域内,函数名相同,但参数不同(类型/个数/顺序)。

c++ 复制代码
int add(int a, int b) { return a + b; }
double add(double a, double b) { return a + b; }
void add(int a, char b) {}
void add(char b, int a) {}  // 参数顺序不同也算重载!

返回值不同不算重载!


注意:缺省参数可能引发歧义

c++ 复制代码
void f();
void f(int a = 10);

f(); // ❌ 二义性!编译器不知道调哪个

⚠️ 设计时要避免这种情况!


第七章:引用(Reference)------ 别名机制

引用是什么?

引用 = 已存在变量的别名,不占额外内存!

c++ 复制代码
int a = 10;
int& b = a;  // b 是 a 的别名
b = 20;      // 等价于 a = 20
cout << a;   // 输出 20

🔍 查看地址:

c++ 复制代码
cout << &a << " " << &b; // 地址完全相同!

引用三大特性

  1. 必须初始化
    int& r; ❌ 编译错误

  2. 一个变量可有多个引用
    int& r1 = a; int& r2 = a;

  3. 一经绑定,不可更改

    c++ 复制代码
    int a = 10, b = 20;
    int& r = a;
    r = b;  // ❌ 不是让 r 引用 b!而是 a = b;

引用 vs 指针

特性 引用 指针
内存 不占空间 占 4/8 字节
初始化 必须 建议但非必须
可变性 绑定后不可变 可随时指向新对象
使用 直接用 r *p 解引用
安全性 不会空引用 易出现空指针/野指针

引用更适合做函数参数和返回值


引用实战:简化数据结构代码

c++ 复制代码
// 传统 C 风格(需二级指针)
void ListPushBack(ListNode** phead, int x);

// C++ 引用风格(更简洁)
void ListPushBack(ListNode*& phead, int x) {
    // 直接修改 phead 指向
}

const 引用(非常重要!)

c++ 复制代码
const int a = 10;
// int& r = a;        ❌ 权限放大(非常量引用常量)
const int& r = a;     ✅

int b = 20;
const int& rb = b;    ✅ 权限缩小(安全)

// 临时对象必须用 const 引用
const int& tmp = 10 + 20;  ✅
// int& tmp = 10 + 20;     ❌

💡 临时对象具有常性,只能被 const 引用绑定


第八章:内联函数(inline)------ 替代宏函数

为什么需要 inline?

C 语言用宏实现"函数":

c++ 复制代码
#define ADD(a, b) ((a) + (b))  // 写错一个括号就出 bug!

❌ 宏不进行类型检查,难以调试


inline 函数

c++ 复制代码
inline int add(int a, int b) {
    return a + b;
}

✅ 优势:

  • 类型安全

  • 可调试

  • 编译器自动展开(避免函数调用开销)
    ⚠️ 注意:

  • 仅建议用于短小、频繁调用的函数

  • 不要声明和定义分离(否则链接错误!)


第九章:nullptr ------ 安全的空指针

NULL 的问题

c++ 复制代码
void f(int x) { cout << "int\n"; }
void f(int* p) { cout << "pointer\n"; }

f(NULL);  // 输出 "int"!因为 NULL = 0

😱 本想调用指针版本,结果调用了整型版本!


nullptr 的解决方案

c++ 复制代码
f(nullptr);  // ✅ 明确调用指针版本

nullptr指针专属字面量,不会被当作整数!


🎯 总结:C++ 核心语法速查表

特性 关键点
命名空间 namespace 隔离名字,std 是标准库
IO 流 cin/cout 自动识别类型,endl 刷新缓冲区
缺省参数 靠右连续,声明给默认值
函数重载 参数不同即可,返回值不算
引用 别名,必须初始化,不可变,安全高效
inline 替代宏,短小函数用,勿分离声明定义
nullptr 安全空指针,告别 NULL 二义性

💡 给初学者的建议

  1. 先掌握 namespacecout/cin,写出规范 C++ 程序;
  2. 引用代替指针传参,代码更简洁安全;
  3. 遇到函数参数多?考虑缺省参数
  4. 需要同名函数?用重载
  5. 永远用 nullptr,不用 NULL

这份笔记助你从 C 到 C++ 平稳过渡,打好现代 C++ 编程基础!

加油,未来的 C++ 工程师!🔥

相关推荐
Liangwei Lin37 分钟前
洛谷 P1443 马的遍历
数据结构·算法
老鱼说AI39 分钟前
算法基础教学第二步:数组(超级详细原理级别讲解)
数据结构·神经网络·算法·链表
m5655bj41 分钟前
通过 C# 将 RTF 文档转换为图片
开发语言·c#
小白程序员成长日记1 小时前
2025.12.01 力扣每日一题
算法·leetcode·职场和发展
爱装代码的小瓶子1 小时前
【cpp知识铺子】map和set的前身-二叉搜索树
c++·算法
5***g2981 小时前
Windows安装Rust环境(详细教程)
开发语言·windows·rust
XL's妃妃1 小时前
Java 基准测试工具 JMH 详细介绍
java·开发语言·测试工具
free-elcmacom1 小时前
MATLAB信号分析:眼图生成与高速系统评估
开发语言·matlab·信号处理