C++ 基础入门笔记:变量、分支、循环与数组

📄 约 3,726 字 · ⏱ 大约 10 分钟

C++ 基础入门笔记:变量、分支、循环与数组

这里收录 C++ 语言基础相关的笔记。C++ 是一门既贴近硬件、又支持高级抽象的编程语言。它既能像 C 一样直接操作内存、写出极快的代码,又能用类、模板、标准库写出结构清晰的程序。操作系统底层、游戏引擎、高频交易系统、算法竞赛(比如 NOIP、ICPC)大量使用 C++。对初学者来说,先打牢语法基础,再刷算法题,是最稳的路线。

学习建议:先打牢语法基础,再刷算法题。每学一个知识点,立刻写几行小程序验证,比只看不写记得牢得多。

一、准备开发环境

写 C++ 需要先有个能把代码编译成可执行程序的环境。常见选择有三类:

  1. 本地编译器 + 编辑器:Windows 上装 MinGW-w64(提供 g++ 命令),再配一个编辑器如 VS Code;或者直接用 Dev-C++、Code::Blocks 这种“编译器 + 编辑器”打包好的集成环境,装完就能写。
  2. 现代 IDE:CLion(JetBrains 出品,智能提示强,学生可免费)、Visual Studio(Windows 上功能最全,体积大但最省心)。
  3. 在线编译器:不想装环境时,可以用各大 OJ(在线评测)系统自带的编辑框,或者浏览器里的在线 C++ 编译器,写一段点一下“运行”就能看结果,适合随手试小例子。

不管用哪种,核心都是同一件事:把你写的 .cpp 源文件交给编译器,编译器把它翻译成机器能直接执行的程序。命令行里常用的编译命令是 g++ main.cpp -o main,意思是把 main.cpp 编译成名为 main 的可执行文件,然后 ./main 运行它。

二、第一个程序

#include <iostream>
using namespace std;

int main() {
    cout << "Hello, World!" << endl;
    return 0;
}

逐行看:

  • #include <iostream> 引入标准输入输出库,cout、cin 都来自这里。#include 是预处理指令,编译前会把对应库的内容“粘贴”进来。
  • using namespace std; 让我们可以直接写 cout 而不是 std::cout,初学阶段图省事可以写上;大型项目里更推荐写 std::cout 避免名字冲突。
  • int main() 是程序入口,每个 C++ 程序都必须有且只有一个 main 函数,操作系统从这里开始执行。
  • cout << "Hello, World!" << endl; 把字符串输出到屏幕,<< 是输出运算符,endl 表示换行并刷新输出。
  • return 0; 告诉系统程序正常结束(返回 0 代表成功,非 0 一般代表出错)。

编译运行后,屏幕上会打印出 Hello, World!。如果编译报错,先检查引号、分号是不是中文的,这是新手最容易踩的坑。

三、变量与数据类型

变量就是一块用来存数据的内存,给它起个名字,后面就能反复用。C++ 是强类型语言,声明变量时必须指定类型,编译器据此知道要分配多少内存、怎么解释里面的比特。

类型 含义 大致范围 / 说明
int 整数 约 -21 亿 ~ 21 亿,够日常用
long long 长整数 约 ±9×10¹⁸,数很大时用它
double 双精度小数 带小数点的数,如 3.14
float 单精度小数 精度比 double 低,占空间小
char 单个字符 一个字母或符号,如 'A'
bool 布尔 只有 true / false
string 字符串 一串字符,如 "你好"(需 #include <string>)

声明并初始化:

int age = 17;
double pi = 3.14159;
char ch = 'X';
bool isOpen = true;
string name = "小明";

变量命名规则:只能由字母、数字、下划线组成,不能以数字开头,不能用关键字(如 int、if、while)。建议见名知意,比如用 studentCount 而不是 a1——好的命名能让一个月后的你依然看懂代码。

类型转换:不同类型混算时,C++ 会做隐式转换(如 int 和 double 相加,int 会先变成 double)。也可以用显式转换:double x = (double)a / b;,强制先把 a 转成 double,避免整数相除丢小数。

字符串常用操作:string s = "abc"; s.size() 求长度,s + "d" 拼接,s.substr(0,2) 取子串,s.find("b") 查找位置。处理文本时 string 比 C 风格的 char 数组方便太多。

四、常量 const

有些值在程序里不该被改,用 const 修饰,改了编译器会报错,能减少很多低级 bug:

const double PI = 3.14159;
PI = 3.14;   // 编译错误:常量是只读的

习惯上常量名全大写,一眼就能看出它是只读的。凡是“算出来就不会变”的东西,比如圆周率、数组最大长度,都建议加 const。

五、运算符

  • 算术:+ - * / %(% 是取模,即求余数,只对整数有意义,如 7 % 3 得 1;负数取模结果在不同语言里规则不同,C++ 里 -7 % 3 得 -1)。
  • 关系:> < >= <= == !=,结果是 bool。注意判断相等是两个等号 ==,一个等号 = 是赋值,写成 if (a = 5) 是常见错误(它会把 5 赋给 a 再判断真假)。
  • 逻辑:&&(与)、||(或)、!(非)。逻辑运算有“短路”特性:a && b 若 a 为假就不再算 b;a || b 若 a 为真就不再算 b,这能在 b 可能出错时保护程序。
  • 赋值:=,以及复合赋值 += -= *= /=,如 x += 3 等价于 x = x + 3。
  • 自增自减:i++ 先用后加,++i 先加后用,单独写时效果一样;但在复杂表达式里顺序不同结果不同,建议单独成行避免混淆。
  • 三元:条件 ? 真值 : 假值,如 int m = a > b ? a : b; 取两者较大值,相当于精简版的 if-else。

运算符有优先级,不确定时多用括号,既清晰又不容易错。

六、输入 cin

用 cin 从键盘读入:

int x;
cout << "请输入一个整数:";
cin >> x;
cout << "你输入的是 " << x << endl;

>> 是输入运算符,可以连着读多个:cin >> a >> b >> c;。读字符串时 cin >> s 遇到空格就停,想读一整行用 getline(cin, s)。

七、条件判断

int score;
cin >> score;
if (score >= 90) {
    cout << "优秀";
} else if (score >= 60) {
    cout << "及格";
} else {
    cout << "不及格";
}

注意 else if 会按顺序判断,一旦满足就跳过后面。多分支还可以用 switch,适合对一个变量的多个固定值分别处理:

int day = 1;
switch (day) {
    case 1: cout << "周一"; break;
    case 2: cout << "周二"; break;
    default: cout << "其他";
}

别忘了每个 case 末尾的 break,否则会“穿透”执行到下一个分支——有时候故意利用穿透,但新手最好每个都写 break。

八、循环

for 循环——已知次数时用:

for (int i = 1; i <= 10; i++) {
    cout << i << " ";
}

while 循环——条件满足就一直做:

int i = 1;
while (i <= 10) {
    cout << i << " ";
    i++;
}

do-while——至少执行一次,再判断:

int x;
do {
    cin >> x;
} while (x < 0);   // 直到输入非负数才停

嵌套循环常用于遍历二维结构,也常用来打印规律图形,比如九九乘法表:

for (int i = 1; i <= 9; i++) {
    for (int j = 1; j <= i; j++)
        cout << j << "*" << i << "=" << i*j << " ";
    cout << endl;
}

break 立刻跳出当前循环,continue 跳过本次剩余、进入下一轮。

九、数组

数组是一组同类型元素的连续存放:

int a[5] = {10, 20, 30, 40, 50};
cout << a[0];   // 10,下标从 0 开始
for (int i = 0; i < 5; i++) cout << a[i] << " ";

二维数组像表格:

int g[3][4];           // 3 行 4 列
g[0][0] = 1;

遍历二维:for (int i=0;i<3;i++) for (int j=0;j<4;j++) ...。

数组常见算法:逆序(首尾交换)、找最值、冒泡排序(相邻两两比较交换)。字符串在 C++ 里既可以用 string,也可以用 char 数组(以 \0 结尾),初学先用 string 更省心。

数组大小用常量定义更安全:const int N = 1000; int a[N];。注意数组下标越界不会报错,但会读到乱七八糟的内存,是隐蔽 bug 来源。

十、函数

把一段功能封装成函数,避免重复:

int add(int x, int y) {
    return x + y;
}
int main() {
    cout << add(3, 5);   // 8
}
  • 函数先声明/定义再被调用(或把定义写在 main 之前)。大型项目常把声明放头文件、定义放 .cpp。
  • 参数默认是传值:函数里改的是副本,不影响外面。想要改外面的值,要传指针或引用(见指针篇)。
  • 默认参数:void f(int x, int y = 10) 调用 f(3) 时 y 取 10。
  • 函数重载:同名函数参数类型/个数不同可以共存,如 add(int,int) 和 add(double,double)。
  • 递归:函数自己调用自己,适合分治问题,如阶乘 n! = n * (n-1)!、斐波那契。但递归要有明确的终止条件,否则会无限调用直到栈溢出。

十一、作用域与生命周期

  • 作用域:变量在哪段代码里可见。在 {} 里定义的变量,只在这个块里有效,出了块就访问不到。
  • 局部变量:函数内定义,函数结束就销毁。
  • 全局变量:函数外定义,整个程序都能用,但过多全局变量会让程序难以维护,尽量克制。

理解作用域能帮你避免“为什么这个变量读不到”的困惑。

十二、头文件与预处理

#include 把库或别的文件内容包含进来。自己写多个文件时,通常 .h 里放声明、.cpp 里放定义,用 #include "my.h" 引入。标准库用尖括号 <>,自己写的用引号 ""。预处理阶段还会做宏替换(#define),但现代 C++ 更推荐用 const 和 inline 代替宏。

十三、常见错误与调试

  1. 中文标点:把 ; 写成 ;、引号用了中文,编译直接报错。
  2. 少分号:每条语句末尾要有 ;,但 if/for 后面的圆括号后不用分号。
  3. 数组越界:下标超出范围,结果不可预测,是隐蔽 bug 来源。
  4. 除零:整数除以 0 会运行时崩溃;cin 读入时没判断也可能导致后续计算异常。
  5. 变量未初始化就使用:里面是随机垃圾值,每次运行结果可能都不一样。
  6. == 写成 =:把赋值当成判断,逻辑 silently 出错。

调试技巧:在关键位置用 cout 打印变量值,看程序跑到哪、值对不对;学会看编译器报错的第几行,那通常就是你写错的地方附近;复杂逻辑可以画个表,把每一步的变量值填进去,顺着推。

十四、练习建议

  1. 写一个程序读入两个整数,输出它们的和、差、积、商(注意商可能为小数)。
  2. 判断一个年份是不是闰年(能被 4 整除但不能被 100 整除,或能被 400 整除)。
  3. 用循环打印 1 到 100 里所有能被 3 整除的数。
  4. 读入 10 个数,找出最大值和最小值。
  5. 写一个函数 isPrime(n) 判断 n 是不是质数(只需检查到 √n)。
  6. 用双层循环打印一个 5 行 5 列的星号方阵。
  7. 写程序把输入的字符串逆序输出。
  8. 用递归实现斐波那契第 n 项,并想想当 n 很大时为什么会很慢(提示:重复计算)。

每道题先自己想思路,再写代码,跑不通就打印中间变量,比直接看答案收获大得多。

十五、补充:几个实用的小算法雏形

学会了基础语法,就可以写一些“小算法”练手,顺便体会“把问题拆小”的思路。

最大公约数(GCD):用辗转相除法,不断用较大的数对较小的数取余,直到余数为 0,最后的除数就是最大公约数。比如求 12 和 18:18 % 12 = 6,12 % 6 = 0,所以最大公约数是 6。

判断素数:只需检查 2 到 √n 之间有没有能整除 n 的数,不用傻傻试到 n-1,这样速度快很多,n 很大时差距明显。

交换两个数:除了用临时变量,还可以用异或技巧(不借助第三变量,但可读性差,实际项目里还是用临时变量更清楚)。理解它有助于搞懂位运算。

输入加速(竞赛常用):当数据量很大时,cin 默认为了兼容 C 的 scanf 会慢一些,可以在程序开头加 ios::sync_with_stdio(false); cin.tie(0); 让输入快很多,这几乎是所有算法题模板的第一行。注意开启后就不要混用 cin 和 scanf 了。

这些小例子都在训练同一种能力:把模糊的“怎么做”转换成精确的“每一步做什么”。算法题本质上就是这种能力的进阶版,语法熟了,再去刷题就不会被基础卡住。

补充:推荐的学习路径

建议顺序是:先把本篇基础全部亲手敲一遍 → 再学指针篇把地址概念吃透 → 然后刷数组和字符串的基础题练手感 → 最后才上动态规划。每学完一篇,合上文档,自己能默写出核心语法和一段能跑的示例,才算真懂,而不是“看的时候以为会了”。遇到报错不要慌,编译器报错信息虽然啰嗦,却是最好的老师,逐行看它说第几行有问题,比盲目修改快得多。基础阶段宁可慢一点、把每一个点敲熟,也别贪多求快,后面学算法时语法才不会拖后腿。

小结

C++ 基础看起来琐碎,但其实就几块:变量与类型、运算符、输入输出、条件与循环、数组、函数,再加上作用域和头文件的概念。把它们一个个写熟,后面学指针、学算法都会顺很多。记住一句话:看懂不等于会写,会写不等于写对——多动手编译运行,让编译器帮你查错,是入门最快的路。基础扎得牢,上算法题才不至于被语法拖后腿。

📰 每日速递 更多 →