C++11 基础知识与编程环境讲义
本讲义系统梳理计算机基础知识、NOI(全国青少年信息学奥林匹克)竞赛历史与规范、文件和系统操作,以及编译器 g++ 的基本命令与集成开发环境(IDE)的使用。所有程序设计示例均基于 C++11 标准。
1. 计算机基础知识
1.1 计算机的基本构成
现代计算机主要基于冯·诺依曼体系结构(Von Neumann Architecture),其核心思想是“程序存储”与“二进制计算”。
┌────────────────────────┐
│ CPU │
┌─────────────┐ │ ┌──────────────────┐ │ ┌─────────────┐
│ ├────>│ │ 控制器 (CU) │ │────>│ │
│ 输入设备 │ │ └────────┬─────────┘ │ │ 输出设备 │
│ │ │ │ │ │ │
└─────────────┘ │ ┌────────▼─────────┐ │ └─────────────┘
│ │ │ 算术逻辑单元(ALU)│ │ ▲
│ │ └────────┬─────────┘ │ │
│ └───────────┼────────────┘ │
│ │ │
└────────────────────────┼─────────────────────────┘
│
┌─────────▼────────┐
│ 存储器 (Memory)│
└──────────────────┘
计算机硬件主要由以下五大部件组成: 1. 控制器 (Control Unit, CU):计算机的指挥中心,负责分析指令并发出控制信号。 2. 运算器 (Arithmetic Logic Unit, ALU):负责执行算术运算(加减乘除)和逻辑运算(与或非、比较)。 * 注:控制器与运算器集成在一起,合称为 中央处理器 (CPU, Central Processing Unit)。 3. 存储器 (Memory):用于存储数据和程序。 * 内存储器 (RAM/ROM):CPU 可以直接读写,读写速度快但断电后 RAM 中的数据会丢失。 * 外存储器 (硬盘、U盘等):容量大、断电后数据不丢失,但读写速度较慢,需装载到内存中才能被 CPU 处理。 4. 输入设备 (Input Device):向计算机输入数据(如键盘、鼠标、扫描仪等)。 5. 输出设备 (Output Device):将计算机处理结果展示给用户(如显示器、打印机、扬声器等)。
1.2 操作系统 (OS) 基本概念与常见操作
1. 操作系统的概念
操作系统是管理计算机硬件与软件资源的系统软件,为用户和应用程序提供交互接口。常见操作系统包括: * Windows:微软公司开发,图形界面友好,普及率高。 * Linux:开源的类 Unix 操作系统,稳定性高,常用于服务器和竞赛环境(NOI 官方竞赛环境为基于 Ubuntu 的 NOI Linux 2.0)。
2. Linux 终端常见命令
在 Linux 系统下,命令行是高效管理文件的工具:
* ls:列出当前目录下的文件和子目录(-l 参数可查看详细信息)。
* cd <目录名>:切换工作目录(如 cd .. 切换到上一级目录)。
* mkdir <目录名>:创建新目录。
* rm <文件名>:删除文件(-r 参数可递归删除目录)。
* cp <源文件> <目标位置>:复制文件或目录。
* mv <源文件> <目标位置>:移动文件或重命名文件。
1.3 计算机网络与 Internet 基础
- IP 地址 (IP Address):计算机在网络中的唯一数字标识(如 IPv4 地址
192.168.1.1)。 - DNS (Domain Name System):域名系统,负责将人类易读的域名(如
www.noi.cn)解析为计算机识别的 IP 地址。 - MAC 地址:网卡的物理地址,出厂时烧录在网卡上,全球唯一。
- TCP/IP 协议族:Internet 的基础协议:
- TCP (传输控制协议):面向连接的、可靠的传输协议。
- IP (网际协议):负责寻址和路由选择。
- 局域网 (LAN) 与 广域网 (WAN):局域网范围较小(如学校机房),广域网范围大(如因特网)。
1.4 计算机历史与常见用途
- 历史进程:
- 第一代:电子管计算机(如 1946 年诞生的 ENIAC,公认为第一台通用电子计算机)。
- 第二代:晶体管计算机。
- 第三代:集成电路(IC)计算机。
- 第四代:大规模和超大规模集成电路(VLSI)计算机(现代计算机)。
- 奠基人物:
- 阿兰·图灵 (Alan Turing):计算机科学之父,提出“图灵机”理论模型,奠定了可计算性理论的基础。
- 约翰·冯·诺依曼 (John von Neumann):现代计算机之父,提出了二进制思想及“程序存储”的冯·诺依曼体系结构。
- 主要用途:科学计算(数值计算)、数据处理(信息管理)、辅助设计(CAD)、过程控制、人工智能、虚拟现实等。
2. NOI 相关活动历史与规则
2.1 NOI 及其相关活动历史
- CCF (中国计算机学会):信息学奥林匹克相关活动的组织和主办方。
- NOI (全国青少年信息学奥林匹克):自 1984 年 开始举办,是我国开展最早的学科竞赛之一。
- NOIP (全国青少年信息学奥林匹克联赛):自 1995 年 开始举办。
- CSP-J/S (非专业级别软件能力认证):自 2019 年 推出,分入门级(Junior)和提高级(Senior),包含两轮。
2.2 竞赛规则规范
- 语言限制:自 2022 年起,NOI 系列活动中 Pascal、C 语言被正式停止使用,仅支持 C++ 语言。
- 评测环境:统一在 NOI Linux(目前为 NOI Linux 2.0 64位环境)下进行评测。
- 运行要求:
- 选手程序必须通过标准输入输出(
stdin/stdout)或题目要求的文件重定向进行输入输出。 - 禁止在程序中创建子进程、进行网络连接或尝试读写系统敏感文件。
- 禁止使用类似
system("pause")等依赖外部终端特性的系统调用。 - 注意内存限制(避免静态数组开得过大导致栈溢出或静态内存超限)。
- 选手程序必须通过标准输入输出(
3. 编程与系统操作
3.1 位、字节与字
计算机在底层仅以二进制($0$ 和 $1$)的形式存储和处理数据。
1. 定义
- 位 (Bit, 比特):计算机中最小的信息单位,表示一个二进制数位($0$ 或 $1$)。
- 字节 (Byte):计算机中存储容量的基本单位。 $$1 \text{ Byte} = 8 \text{ Bits}$$
- 字 (Word):CPU 一次性处理二进制数据的字长。
- 在 32 位系统下,一个“字”为 32 位(4 字节)。
- 在 64 位系统下,一个“字”为 64 位(8 字节)。
2. 容量单位转换
$$1 \text{ KB} = 2^{10} \text{ Bytes} = 1024 \text{ Bytes}$$ $$1 \text{ MB} = 2^{10} \text{ KB} = 1024 \text{ KB}$$ $$1 \text{ GB} = 2^{10} \text{ MB} = 1024 \text{ MB}$$ $$1 \text{ TB} = 2^{10} \text{ GB} = 1024 \text{ GB}$$
3. C++11 数据类型大小验证示例
#include <iostream>
int main() {
// 验证不同类型在当前机器上占用的字节数 (Bytes)
std::cout << "char: " << sizeof(char) << " Byte(s)\n"; // 1 字节
std::cout << "int: " << sizeof(int) << " Byte(s)\n"; // 通常为 4 字节
std::cout << "long long: " << sizeof(long long) << " Byte(s)\n"; // 通常为 8 字节
std::cout << "pointer (word size): " << sizeof(void*) << " Byte(s)\n";
// 若输出 8 说明是 64 位字长系统,若输出 4 说明是 32 位字长系统
return 0;
}
3.2 程序设计语言与编译
- 机器语言:由二进制 $0/1$ 机器指令构成,计算机能直接执行。
- 汇编语言:用助记符(如
ADD,MOV)代替机器指令,需要通过汇编器翻译成机器指令。 - 高级语言:面向人类阅读(如 C++, Python)。
- 编译型语言(如 C++):先由编译器将源代码转换为机器语言目标程序,再进行链接生成独立的可执行文件,运行时效率高。
- 解释型语言(如 Python):运行期逐行由解释器翻译执行,效率较低,但无需提前编译。
3.3 图形界面基本操作与 IDE
- 文件管理:熟练利用 Windows 资源管理器或 Linux 文件管理器完成新建文件夹、复制(
Ctrl+C)、粘贴(Ctrl+V)、剪切/移动(Ctrl+X)与删除(Del)等基础文件操作。 - 常用 IDE:
- Windows 下的 Dev-C++:轻量级集成开发环境,内置 GCC 编译器,适合新手在 Windows 环境下调试单文件程序。
- Linux 下的 Code::Blocks / Geany:NOI Linux 下内置的常见 IDE,支持代码高亮、自动对齐及断点调试。
3.4 常用编译命令 g++ 编译参数详解
在命令行下直接使用 g++ 编译器是 NOI 活动中标准的操作方式。
1. 基础用法
g++ main.cpp
效果:编译 main.cpp,默认在当前目录下生成名为 a.out(Linux下)或 a.exe(Windows下)的可执行文件。
2. 常用选项说明
| 选项名称 | 作用 | 示例 |
|---|---|---|
-o <filename> |
指定生成的可执行文件名 | g++ main.cpp -o main |
-std=c++11 |
开启 C++11 标准 支持 | g++ -std=c++11 main.cpp -o main |
-O2 |
开启 2 级代码编译优化 | g++ -O2 main.cpp -o main |
-Wall |
开启所有常见的警告提示(强烈推荐,有助于查错) | g++ -Wall main.cpp -o main |
-Wextra |
开启一些额外的更严格的警告提示 | g++ -Wextra main.cpp -o main |
-g |
包含调试信息,方便使用 GDB 工具调试 | g++ -g main.cpp -o main |
3. 推荐使用的编译指令
在平时练习和备赛时,推荐采用以下命令以最严格的标准编译程序,这有助于提前发现隐藏的逻辑和类型错误:
g++ -std=c++11 -O2 -Wall -Wextra main.cpp -o main
4. 综合练习题与解析
练习题 1:位与字节的计算
题目描述: 某图片的分辨率为 $1024 \times 768$ 像素,每个像素由 $24$ 位真彩色表示。请计算: 1. 存储这幅图片的总位数(Bits)。 2. 这幅图片在不压缩的情况下,占用的存储空间大约是多少兆字节(MB)?(保留 2 位小数)。
解析与计算过程
- 总位数计算: $$\text{总位数} = 1024 \times 768 \times 24 \text{ bits}$$ $$1024 \times 768 = 786432 \text{ 像素}$$ $$786432 \times 24 = 18,874,368 \text{ bits}$$
- 单位转换(转换为 MB): 首先转换为字节(Bytes): $$\text{字节数} = \frac{18874368}{8} = 2,359,296 \text{ Bytes}$$ 转换为千字节(KB): $$\text{KB数} = \frac{2359296}{1024} = 2304 \text{ KB}$$ 转换为兆字节(MB): $$\text{MB数} = \frac{2304}{1024} = 2.25 \text{ MB}$$
答案: 1. 总位数为 $18,874,368 \text{ bits}$。 2. 占用的存储空间为 $2.25 \text{ MB}$。
练习题 2:C++11 检测整数在不同位宽下的溢出临界点
题目描述:
编写一个符合 C++11 标准的控制台程序,利用内置的 <limits> 库,输出 int 型与 long long 型在当前编译系统下的最大可能存储值,并利用编译指令 -std=c++11 编译执行。
C++11 代码实现与分析
#include <iostream>
#include <limits> // 包含标准库中获取数值极限的类模板
int main() {
// 使用 std::numeric_limits 模板类获取类型的极限信息
int int_max = std::numeric_limits<int>::max();
long long ll_max = std::numeric_limits<long long>::max();
std::cout << "Max value of int: " << int_max << "\n";
std::cout << "Max value of long long: " << ll_max << "\n";
// 演示发生整型溢出(Overflow)的情况
int overflow_test = int_max + 1;
std::cout << "Overflow test (int_max + 1): " << overflow_test << "\n";
return 0;
}
编译命令:
g++ -std=c++11 -Wall overflow.cpp -o overflow
解析:
* 在一般的 32 位及 64 位系统下,int 类型占 4 字节(32位),其最大值为 $2^{31}-1 = 2,147,483,647$。
* 当执行 int_max + 1 时,产生了有符号整型溢出。在计算机的补码表示下,符号位由 0 变为 1,数值回绕变成了最小的负数 $-2,147,483,648$。
* 在 NOI 竞赛中,如果计算中间结果超过了 $2 \times 10^9$,必须将变量类型声明为 long long(其最大值约为 $9.22 \times 10^{18}$),以防产生因整型溢出导致的非预期错误。
—— 本文来自火龙信奥(义乌睿码科技):义乌青少年信息学奥赛与编程教育平台,专注 CSP-J/S、NOIP、GESP 竞赛培训,线上线下融合教学,助力编程升学。网址:hlcoding.com