C/C++ 入门:基础语法

学完 HelloWorld 之后,下一步把变量、类型、运算符、输入输出、分支和循环这条主线连起来。

📚 基本概念速读

名称 定义 省流
变量 有名字、可读写的一块数据 会变的值
常量 初始化后不应该再修改的值 固定的值
类型 规定数据怎么存、能做什么操作 数据的形状
表达式 由变量、常量、运算符组成,能算出一个值 一段计算
语句 程序执行的基本单位,通常以分号结尾 一步动作
作用域 名字能被访问的代码范围 名字的有效范围
控制流 程序语句的执行顺序 程序怎么走

🧩 基础语法总览

C++ 基础语法可以按“数据从哪里来、怎么计算、程序怎么走”来理解。



flowchart LR
    A[变量与常量] --> B[基本类型]
    B --> C[运算符]
    C --> D[输入输出]
    D --> E[分支结构]
    E --> F[循环结构]

最小心智模型:

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
using namespace std;

int main()
{
int score = 90;

if (score >= 60) {
cout << "pass" << endl;
}

return 0;
}

这里已经同时出现了变量、类型、初始化、关系运算、分支、输出和返回码。

🧱 变量与常量

变量定义

变量定义的一般形式:

1
类型 变量名 = 初始值;

示例:

1
2
3
4
int age = 18;
double height = 1.75;
char grade = 'A';
bool passed = true;

int age = 18; 的意思是:创建一个名为 age 的整型变量,并把初始值设为 18

初始化

初始化就是变量创建时给它一个确定的值。初学阶段建议:变量定义时尽量立刻初始化

1
2
3
int a = 10;      // 推荐:有明确初始值
int b{}; // 推荐:值初始化,int 会变成 0
int c; // 不推荐:局部变量未初始化,值不确定

int a = 10;int b{}; 都是在初始化,但含义不完全一样。

写法 名称 含义 结果
int a = 10; 复制初始化 用右边的 10 初始化 a a 的值是 10
int b{}; 列表初始化/值初始化 没写具体值,用该类型的默认零值初始化 b 的值是 0
int c; 默认初始化 对局部基础类型来说,不会自动清零 c 的值不确定

int a = 10; 适合你已经知道变量应该是什么值的情况:

1
2
int score = 90;
int count = 5;

int b{}; 适合你暂时还没有具体值,但希望它处于一个安全的初始状态:

1
2
3
4
int sum{};      // 0
double avg{}; // 0.0
bool ok{}; // false
char ch{}; // '\0'

这种 {} 写法还有一个好处:它能阻止一些可能丢失信息的窄化转换。

1
2
int x = 3.14;   // 允许,但 x 会变成 3
// int y{3.14}; // 错误:列表初始化会阻止这种窄化转换

所以初学阶段可以先记住:

场景 推荐写法
有明确初始值 int a = 10;
只是想先清零 int b{};
局部基础类型 不要写 int c; 后直接使用

未初始化局部变量是 C/C++ 初学里非常常见的坑。

作用域

作用域决定一个名字在哪里可见。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
using namespace std;

int main()
{
int outer = 1;

{
int inner = 2;
cout << outer << endl; // 可以访问
cout << inner << endl; // 可以访问
}

cout << outer << endl; // 可以访问
// cout << inner << endl; // 错误:inner 已经离开作用域

return 0;
}

花括号 {} 会形成一个新的块作用域。

const

const 表示这个变量初始化后不应该再被修改。

1
2
const double PI = 3.1415926;
const int MAX_SCORE = 100;

如果后面写:

1
// PI = 3.14;  // 错误:const 变量不能被重新赋值

编译器会报错。初学阶段可以把 const 理解成“给不会变的值加一层保护”。

🔢 基本类型

整型

整型用来表示整数。

1
2
int count = 10;
long long bigNumber = 10000000000LL;

10000000000LL 末尾的 LL 是整数后缀,表示这个整数字面量的类型是 long long。如果不写后缀,编译器会根据数值大小和规则推导类型;写上 LL 可以明确告诉编译器“这是一个长整型整数”。

常用选择:

类型 说明 常见用途
int 常用整数类型 普通计数、下标、分数
long long 更大范围整数 大数计数、算法题
unsigned int 非负整数 位运算、底层接口较常见

注意:unsigned 不是“更大的 int”这么简单,它不表示负数,混用有时会产生反直觉结果。

浮点型

浮点型用来表示小数。

1
2
float x = 1.5f;
double y = 3.1415926;

日常优先用 doublefloat 占用空间更小,但精度更低,常见于图形、深度学习、嵌入式等场景。

字面量后缀

代码里的 101.5'A' 这种直接写出来的值叫 字面量。有些字面量可以加后缀,用来明确它的类型。

常见整数后缀:

后缀 含义 示例
L long 100L
LL long long 10000000000LL
U unsigned 10U
ULL unsigned long long 100ULL

常见浮点后缀:

后缀 含义 示例
fF float 1.5f
无后缀 double 1.5
lL long double 1.5L

所以:

1
2
3
float a = 1.5f;     // 1.5f 是 float
double b = 1.5; // 1.5 默认是 double
long long c = 10LL; // 10LL 是 long long

初学阶段不用背全,只要记住两个常见规则:

写法 什么时候用
LL 整数很大,或者明确要 long long
f 明确要 float,避免默认按 double 处理

字符

char 表示单个字符,字符字面量使用单引号

1
char ch = 'A';

注意区分:

1
2
char a = 'A';      // 字符
// char b = "A"; // 错误:"A" 是字符串字面量

布尔

bool 只有两个值:truefalse

1
2
bool isReady = true;
bool isEmpty = false;

它常用于条件判断:

1
2
3
if (isReady) {
cout << "ready" << endl;
}

类型转换

类型转换就是把一种类型的值变成另一种类型的值。入门阶段先掌握三件事:隐式转换显式转换窄化转换

隐式转换

隐式转换是编译器自动帮你转。

1
2
int a = 10;
double b = a; // 隐式转换:int -> double

int 转成 double 通常安全,因为整数 10 可以自然表示成小数 10.0

常见隐式转换:

例子 含义
int -> double 整数转小数
char -> int 字符按编码值转整数
bool -> int false0true1

显式转换

显式转换是你主动告诉编译器“我知道这里要转类型”。

1
2
double x = 3.8;
int y = static_cast<int>(x); // 显式转换:结果是 3

static_cast<int>(x) 会把 double 转成 int。小数部分会被直接截掉,不是四舍五入。

1
2
3
4
5
double x = 3.8;
double y = -3.8;

cout << static_cast<int>(x) << endl; // 3
cout << static_cast<int>(y) << endl; // -3

初学阶段优先用 static_cast<目标类型>(值),不要急着用 C 风格强转:

1
2
int a = static_cast<int>(3.8); // 推荐:意图更明确
int b = (int)3.8; // 不推荐作为初学主写法

窄化转换

窄化转换指“目标类型装不下原来的信息”,比如小数转整数、大范围整数转小范围整数。

1
2
int a = 3.14;       // a 变成 3,小数部分丢失
// int b{3.14}; // 错误:列表初始化会阻止窄化转换

这和前面讲的 int b{}; 属于同一类 {} 初始化规则:列表初始化更严格,能帮你挡住一些容易出错的转换。

整数除法

整数除法是类型转换里最常见的坑:

1
2
cout << 5 / 2 << endl;        // 输出 2
cout << 5.0 / 2 << endl; // 输出 2.5

如果两个操作数都是整数,/ 会先执行整数除法,结果已经是 2。就算你把结果赋给 double,也不会变回 2.5

1
2
3
double a = 5 / 2;    // 2.0
double b = 5.0 / 2; // 2.5
double c = static_cast<double>(5) / 2; // 2.5

判断规则很简单:

表达式 结果
5 / 2 整数除法,结果 2
5.0 / 2 浮点除法,结果 2.5
static_cast<double>(5) / 2 先把一个操作数转成 double,结果 2.5

🧮 运算符

算术运算符

运算符 作用 示例
+ 加法 a + b
- 减法 a - b
* 乘法 a * b
/ 除法 a / b
% 取余 a % b

示例:

1
2
3
4
5
6
int a = 7;
int b = 3;

cout << a + b << endl; // 10
cout << a / b << endl; // 2
cout << a % b << endl; // 1

% 只能用于整数,不能直接用于浮点数。

关系运算符

关系运算符的结果是 bool

运算符 作用
== 等于
!= 不等于
> 大于
< 小于
>= 大于等于
<= 小于等于
1
2
int score = 85;
cout << (score >= 60) << endl; // true 通常输出为 1

逻辑运算符

运算符 作用 示例
&& a > 0 && a < 10
|| a == 0 || a == 1
! !ok
1
2
3
4
5
6
int age = 20;
bool hasTicket = true;

if (age >= 18 && hasTicket) {
cout << "enter" << endl;
}

赋值运算符

赋值是把右边的值写入左边变量。

1
2
3
4
int x = 10;
x = 20;
x += 5; // 等价于 x = x + 5
x *= 2; // 等价于 x = x * 2

常见复合赋值:

运算符 等价写法
+= x = x + value
-= x = x - value
*= x = x * value
/= x = x / value
%= x = x % value

自增自减

1
2
3
4
5
int i = 0;
i++; // i 变成 1
+i; // i 变成 2
i--; // i 变成 1
--i; // i 变成 0

单独作为一条语句时,i++++i 效果一样。放在复杂表达式里时有区别,初学阶段不建议写这种代码:

1
2
3
int i = 0;
cout << i++ << endl; // 先使用 i,再自增
cout << ++i << endl; // 先自增,再使用 i

🖥️ 输入输出

cout

cout 用于向标准输出写内容。

1
2
3
4
5
6
7
8
9
#include <iostream>
using namespace std;

int main()
{
int age = 18;
cout << "age = " << age << endl;
return 0;
}
简单补充缓冲区的概念

cout 输出内容时,通常不是每写一个字符就立刻交给屏幕,而是先放进一块临时区域,这块临时区域就叫缓冲区

这样做的原因是:直接和设备交互比较慢,先把内容攒起来,再一次性输出,效率更高。

可以粗略理解为:

1
2
3
4
5
6
7
程序里的 cout
|
v
输出缓冲区
|
v
控制台屏幕

endl 表示换行并刷新缓冲区。普通换行也可以用 '\n'

1
cout << "Hello\n";

所以:

写法 含义 是否主动刷新缓冲区
cout << '\n'; 只输出换行
cout << endl; 输出换行并刷新

日常大量输出时,优先用 '\n';需要立刻看到输出结果时,再用 endl

cin

cin 用于从标准输入读取内容。

1
2
3
4
5
6
7
8
9
10
#include <iostream>
using namespace std;

int main()
{
int age{};
cin >> age;
cout << "age = " << age << endl;
return 0;
}

读取多个值:

1
2
3
4
int a{};
int b{};
cin >> a >> b;
cout << a + b << endl;

cin 默认按空白字符分隔输入,空格、换行、Tab 都可以作为分隔。

格式化输出入门

格式化输出常用 <iomanip>

1
2
3
4
5
6
7
8
9
10
#include <iomanip>
#include <iostream>
using namespace std;

int main()
{
double pi = 3.1415926;
cout << fixed << setprecision(2) << pi << endl; // 3.14
return 0;
}

这行代码对新手容易难懂,因为它把“输出内容”和“设置输出格式”写在了一起。

先把它拆开看:

1
2
3
4
cout << fixed;
cout << setprecision(2);
cout << pi;
cout << endl;

cout 是一个输出流,可以理解成一条通往控制台的输出通道。

<<流插入运算符,意思是“把右边的东西送进左边的输出流”。所以:

1
cout << pi;

表示把变量 pi 的值送到 cout 里输出。

fixedsetprecision(2) 不是要显示出来的普通数据,而是格式操纵符。它们会修改 cout 后续输出数字的格式:

写法 作用
fixed 使用固定小数位形式输出
setprecision(2) 小数点后保留 2 位

所以这一整行可以读成:

先告诉 cout:接下来用固定小数位;再告诉它保留 2 位小数;然后输出 pi;最后换行并刷新。

常见工具:

工具 作用
fixed 使用定点小数形式输出
setprecision(n) 控制精度
setw(n) 设置输出宽度

🌿 分支结构

if/else

if/else 用于根据条件选择不同路径。

1
2
3
4
5
6
7
8
9
int score = 75;

if (score >= 90) {
cout << "A" << endl;
} else if (score >= 60) {
cout << "pass" << endl;
} else {
cout << "fail" << endl;
}

switch

switch 适合处理一个整数或枚举值对应多个固定分支的场景。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int day = 3;

switch (day) {
case 1:
cout << "Monday" << endl;
break;
case 2:
cout << "Tuesday" << endl;
break;
case 3:
cout << "Wednesday" << endl;
break;
default:
cout << "unknown" << endl;
break;
}

break 用来跳出 switch。如果漏写,程序会继续执行后面的 case,这叫 fallthrough。

条件表达式

条件表达式也叫三目运算符:

1
条件 ? 条件为真时的值 : 条件为假时的值

示例:

1
2
3
int score = 80;
string result = score >= 60 ? "pass" : "fail";
cout << result << endl;

适合简单选择,不适合塞进复杂逻辑。

🔁 循环结构

for

for 适合循环次数比较明确的场景。

1
2
3
for (int i = 0; i < 5; i++) {
cout << i << endl;
}

while

while 适合循环次数不固定,但继续条件明确的场景。

1
2
3
4
5
6
int n = 5;

while (n > 0) {
cout << n << endl;
n--;
}

while 是先判断,再执行。

do while

do while 是先执行一次,再判断。

1
2
3
4
5
6
int n = 0;

do {
cout << n << endl;
n++;
} while (n < 3);

即使条件一开始就是假,循环体也会至少执行一次。

break

break 用于提前结束整个循环。

1
2
3
4
5
6
for (int i = 0; i < 10; i++) {
if (i == 3) {
break;
}
cout << i << endl;
}

输出:

1
2
3
0
1
2

continue

continue 用于跳过本轮循环剩余语句,进入下一轮。

1
2
3
4
5
6
for (int i = 0; i < 5; i++) {
if (i == 2) {
continue;
}
cout << i << endl;
}

输出:

1
2
3
4
0
1
3
4

⚠️ 常见误区

误区 正解
局部变量不初始化也能安全使用 未初始化局部变量的值不确定,先初始化
5 / 2 会得到 2.5 两个整数相除得到整数,结果是 2
=== 可以混用 = 是赋值,== 是比较
cin 可以自动处理所有错误输入 输入类型不匹配时,cin 会进入失败状态
breakcontinue 一样 break 结束循环,continue 跳到下一轮
switchbreak 可写可不写 不写可能继续执行后续 case

✅ 总结

基础语法的核心不是记住每个符号,而是理解:数据用变量和类型表示,计算靠表达式和运算符,程序路径由分支和循环控制。

下一步可以继续学函数、数组、字符串和指针。它们会把“单段代码”组织成更完整的程序。

Happy Hacking! 🎉