火龙信奥
  • 分享
  • 课程
  • 题库
  • 打卡
    • 代码对战
    • 快速对战
  • 题单
  • 团队
  • 荣誉墙
  • 商城
  • 登录 / 注册

第一章 C++ 程序结构与流程控制

作者: 作者的头像   huolong , 时间:2026-08-20 18:08:46 , 所有人可见, 阅读  38

第一章 C++ 程序结构与流程控制

在准备 CSP 和 GESP 的过程中,理解 C++ 的程序结构和流程控制是编写算法的基础。C++ 程序由一系列指令构成,通过合理的顺序、选择和循环结构,控制计算机高效地执行任务。

下面是我们编写的第一个 C++ 程序,用于计算两个整数的和(A+B 问题):

#include <iostream>
using namespace std;

int main() { // 程序入口
    int a, b;
    cin >> a >> b;
    cout << a + b << "\n"; 
    return 0; 
}

1.1 程序基本框架

1. 注释

注释用于提高代码的可读性,编译器会直接忽略它们。C++ 支持两种注释方式: * 单行注释 //:必须单独放置在一行,或紧跟在代码行的后面。 * 块注释 /* ... */:成对出现,可以插入到代码的任意位置,常用于注释多行代码。

2. 引用头文件

在代码开头使用 #include <头文件名> 引入标准库。 * 尖括号 < >:表示编译器只从系统标准目录中搜索该头文件(竞赛中绝大多数情况使用此方式)。 * 双引号 "":表示编译器会先从当前源文件所在的目录搜索,如果找不到,再到系统标准目录中搜索(常用于引入自己编写的头文件)。

3. 命名空间

标准 C++ 库中的所有标识符都定义在一个名为 std 的命名空间中。为了避免每次都写 std::cin 或 std::cout,我们通常在头文件引入后加上:

using namespace std;

4. main() 主函数

main() 是所有 C++ 程序的入口。在算法竞赛(如 CSP-J、NOIP、GESP 考级)中,main() 函数的返回值必须是 0(通过 return 0; 返回)。如果返回其他非零值,评测系统会判定为程序异常终止(Runtime Error),从而导致该测试点得零分。

5. 语句与语句块

  • 语句:在 C++ 中,单条语句必须以分号 ; 结束。为了代码的美观与可读性,一条语句可以换行书写,多条语句也可以写在同一行。
  • 语句块:使用大括号 { 和 } 包围的多条语句。在语法上,一个完整的语句块被视为单条复合语句。

1.2 选择结构(分支结构)

1. if 条件分支语句

if 用于判断条件是否为真。如果条件为真,则执行紧跟其后的语句或语句块;否则执行 else 分支中的代码。如果没有编写 else 且条件为假,则直接跳过该分支。

格式一:基础单分支
if (条件) {
    语句或语句块;
}
格式二:双分支
if (条件) {
    语句或语句块A;
} else {
    语句或语句块B;
}
格式三:多分支(嵌套)
if (条件1) {
    语句或语句块A;
} else if (条件2) {
    语句或语句块B;
} else {
    语句或语句块N;
}
  • 注意:else if 中间必须留有空格。它在本质上是 else 分支中嵌套了另一个 if 语句。

2. switch 开关分支语句

switch 语句根据表达式的整数值(或字符值)进行多路分支选择,结构如下:

switch (表达式) {
    case 值1: 
        代码段A; 
        break;
    case 值2: 
        代码段B; 
        break;
    default: 
        代码段N; 
        break;
}
  • break 关键字:如果某个 case 分支中省略了 break,程序会继续执行其后的所有 case 分支代码(产生“穿透”现象),直到遇到 break 或 switch 语句结束。
  • default 分支:当所有 case 都不匹配时执行 default 段,此部分可以省略。
  • 结束分号:整个 switch 大括号闭合后不需要在结尾补分号(非强制,但保持代码整洁)。
实例:闰年判定与月份天数计算

输入一个日期,判断其所在年份是否为闰年,并输出该月份的天数。 (提示:闰年的判断方法为:四年一闰,百年不闰,四百年又闰。)

int year, month, day;
bool is_leap = false;
cin >> year >> month >> day;

// 判断是否为闰年
if (year % 400 == 0) {
    is_leap = true;
} else if (year % 100 != 0 && year % 4 == 0) {
    is_leap = true;
}

if (is_leap) {
    cout << year << "是闰年。\n";
} else {
    cout << year << "不是闰年。\n";
}

// 判断所在月份的天数
switch (month) {
    case 1: case 3: case 5: case 7: case 8: case 10: case 12:
        cout << "这个月有31天。\n"; 
        break;
    case 4: case 6: case 9: case 11:
        cout << "这个月有30天。\n"; 
        break;
    case 2:
        cout << "这个月有" << (is_leap ? 29 : 28) << "天。\n"; 
        break;
}

1.3 循环结构

1. while 语句

先判断条件,若条件成立则执行循环体,重复此过程直到条件不成立为止。

while (条件) {
    循环体;
}

2. do-while 语句

先执行一次循环体,再判断条件。若条件成立则继续循环。它与 while 的主要区别在于:do-while 的循环体至少会被执行一次。

do {
    循环体;
} while (条件); // 注意:结尾的分号不可省略

3. for 语句

for 循环将循环的控制结构集中在一行,包含:初始化、循环判定条件、更新变量(状态转移)以及循环体。

for (初始条件; 继续循环的条件; 状态转移的条件) {
    循环体;
}

其等价的 while 循环形式为:

初始条件;
while (继续循环的条件) {
    循环体;
    状态转移;
}
  • for 语句括号内的三个表达式都可以省略,但两个分号 ; 必须保留(如 for (;;) 构成无限循环)。

4. 循环控制:break 与 continue

  • break:强行终止并跳出当前所在的最内层循环。
  • continue:跳过当前循环体中剩余的语句,直接进入下一次循环判定或更新变量阶段。

5. 编写循环时的避坑指南

  • 计数器变量冲突:小心拼写,特别是在多重循环复制粘贴代码时,切勿混淆循环变量(如将 j 误写为 i)。
  • 边界条件:要明确关系运算符是 <、> 还是 <=、>=。
  • 逆序死循环:在进行逆序循环(递减)时,切勿将自减 -- 误写为自增 ++。
实例:求多个数的阶乘值

读入多个正整数 $n$,输出 $n!$ ($n! = 1 \times 2 \times 3 \times \dots \times n$)。当输入为负数时,结束程序。

int n;
long long r = 1;
cin >> n;
while (n > -1) {
    r = 1;
    for (int i = 1; i <= n; i++) {
        r *= i;
    }
    cout << n << "! = " << r << "\n";
    cin >> n;
}

1.4 goto 语句

goto 语句用于无条件跳转。使用时,需先在代码中定义一个标签(标识符后加冒号 :),然后通过 goto 标签名; 跳转。

在结构化编程中,一般不建议过多使用 goto,因为它容易破坏程序的结构、降低可读性。但在某些特定场景下,goto 具有独特的作用,例如快速跳出多重循环:

for (int i = 0; i < 9; i++) {
    for (int j = 0; j < 9; j++) {
        for (int k = 0; k < 9; k++) {
            if (满足某种跳出条件) {
                goto __exited; // 直接跳出三重循环
            }
        }
    }
}
__exited:
// 执行跳转后的后续代码

1.5 C 语言与 C++ 的重要区别

在算法竞赛中,C++ 是基于 C 语言发展而来的,绝大多数 C 语言代码可以直接在 C++ 编译器中运行。以下是两者在竞赛中的主要区别:

  1. 输入与输出:C++ 推荐使用灵活的流输入输出 cin/cout,而 C 语言仅支持 scanf/printf。
  2. 字符串处理:C++ 提供了强大的标准库 std::string 类,极大地简化了字符串操作,避免了传统 C 风格字符数组容易发生的越界、溢出等低级内存错误。
  3. 标准模板库(STL):C++ 拥有极其强大的 STL(包含 vector, queue, stack, set, map 等数据结构及 sort 等算法),而 C 语言不提供这些工具,需要手写。
  4. 头文件命名:C 语言的传统头文件可以在 C++ 中使用,但建议规范写成去 .h 并在前端加 c 的形式(例如 <stdio.h> 写作 <cstdio>,<stdlib.h> 写作 <cstdlib>)。
  5. 运行效率:原生 C 语言的运行效率在部分场景下略优于 C++。但在通过 ios::sync_with_stdio(false) 取消同步后,C++ 的流输入输出效率能与 C 语言基本持平。

1.6 课后推荐练习题

为了熟悉 C++ 的程序基本框架、选择结构与循环结构,推荐在工作台中练习以下题目:

  • 题目编号:1 —— 第一个C++程序与A+B
    • 考点:熟悉 C++ 最基础的程序框架、头文件引用、命名空间以及基本的输入输出流程。
  • 题目编号:5 —— 鸡兔同笼
    • 考点:练习基本的算术运算与 if-else 条件选择结构。在计算出不可能的组合时,需要进行特殊的分支处理。
  • 题目编号:25 —— 倍数判断
    • 考点:练习关系运算符(余数等于 0)和逻辑或运算符 ||。通过分支结构输出对应的字符串结果。
  • 题目编号:33 —— 城市名称查询
    • 考点:本题提供了清晰的映射关系。非常适合用来练习编写多级 if-else if 嵌套结构或 switch-case 分支语句。
  • 题目编号:4 —— 所有约数之和
    • 考点:练习基础的 for 循环。通过循环遍历 1 到 N 之间的每一个整数,利用条件分支判断其是否为约数并累加。
  • 题目编号:46 —— 递增序列输出
    • 考点:练习使用 while 循环读入数据。要求读取一系列整数,并对每一个非零数据通过 for 循环输出对应的递增序列,直到读入 0 时终止程序。
  • 题目编号:56 —— 等差数列与终止条件
    • 考点:练习循环中的输入与控制。在读取每对数据的同时需要进行多重条件判断,一旦读入 0 或负数则需要立即跳出循环结束程序。

—— 本文来自火龙信奥(义乌睿码科技):义乌青少年信息学奥赛与编程教育平台,专注 CSP-J/S、NOIP、GESP 竞赛培训,线上线下融合教学,助力编程升学。网址:hlcoding.com

关于火龙

  • 关于我们
  • 学员获奖
  • 预约试听
  • ACM课程
  • CSP课程
  • 学习指南

帮助中心

  • 用户协议
  • 打字练习
  • 在线画图
  • DevC++下载
  • CSP报名
  • GESP官网

推荐课程

  • C++零基础入门(可试看)
  • C++进阶提升
  • GESP考级辅导
  • GESP打卡
  • CSP-J/S打卡

公众号

火龙信奥公众号二维码

地址:义乌市北门街188号新天地商厦二楼2F 邮箱:wdlok305@126.com

© 2017-2026 义乌市睿码科技有限公司版权所有 浙ICP备2021013995号

火龙信奥
请输入登录信息


请完成安全验证
验证码底图 滑块
向右拖动滑块完成验证
请输入用户名 / 绑定的手机号码



请输入注册信息(手机号验证码注册)





验证码5分钟有效,60秒内不可重复获取,每日最多3次

微信登录

微信登录二维码

正在生成二维码...

账号已过期,请续期。
去续期

绑定手机号

📱

为了更好地保护您的账号安全,享受完整的平台服务

请您尽快绑定手机号码