第1章 C++介绍:1.1 程序与编程语言
第1章 C++介绍
1.1 程序与编程语言
1.1.1 计算机是什么
计算机是一种通用计算设备,能够根据指令处理数据。每台计算机都配备一个 中央处理单元(CPU),它是一块微处理器芯片,负责执行数据处理指令。不同的计算机可能使用不同的 指令集。
计算机指令
计算机通过执行一系列指令来处理任务,并通常会生成某种输出。这类似于人们按照步骤完成任务的方式。例如,“做饭”可以分解为以下步骤:
- 取米并放入洗米盆。
- 用自来水冲洗大米。
- 如果电饭锅未清洗,则清洗电饭锅。
- 将米和水放入电饭锅。
- 插上电源,按下开关。
- 饭煮好后,拔下电源(任务完成)。
虽然人类可以理解复杂的自然语言指令,但计算机只能处理简单的 机器指令,它们使用特定的计算机语言表示。无论多么复杂的计算任务,计算机最终都会将其分解成一系列简单的、逐条执行的 机器指令。这些指令的集合被称为 程序。
以下是几种常见的计算机指令:
- 算术运算:执行加、减、乘、除等运算,通常称为 算术操作。
- 逻辑运算:比较两个数值的大小或判断它们是否相等,通常称为 逻辑操作。
- 控制指令:改变程序执行流程,如跳转到特定指令,通常称为 控制语句。
计算机的组成部分
计算机由四大类核心组件组成:
- 输入设备:用于接收用户输入,例如键盘、鼠标、扫描仪和麦克风。
- 处理单元:执行计算任务的组件,主要是 中央处理单元(CPU)。现代计算机还可能配备 图形处理单元(GPU),最初用于图形处理,但如今也可用于通用计算。
- 存储设备:包括 主存储器(内存) 和 二级存储器(如硬盘、光盘、U 盘等),用于存储程序和数据。
- 输出设备:用于向用户呈现计算结果,例如显示器、扬声器和打印机。
示例:自动售票机
虽然自动售票机并不完全是计算机,但它可以帮助理解计算机的基本组成部分:
- 输入:投币口和选择按钮用于接收用户输入。
- 处理:售票机执行一系列计算,如验证票务信息、检查余额、修改数据库等。
- 存储:售票机需要存储车票库存、价格等信息。
- 输出:显示购票结果并打印车票。
中央处理单元(CPU)
CPU 是计算机的核心,被称为 计算机的大脑,负责计算、数据处理和设备控制。它主要由以下部分组成:
- 算术/逻辑单元(ALU):执行数学运算和逻辑判断。
- 控制单元(CU):决定下一条要执行的指令。
- 寄存器:高速存储区域,用于存放临时数据。
不同类型的 CPU 支持不同的 指令集,例如 Intel x86-64、IBM PowerPC 或 ARM。
存储器
计算机将 程序 和 数据 存储在 存储器(Memory) 中,存储器分为 主存储器 和 辅助存储器。
主存储器(内存,RAM)
- 直接连接 CPU,速度快。
- 断电后数据会丢失(易失性)。
- 由多个存储单元组成,每个单元都有唯一的地址,例如:存储单元地址从
0开始,类似于学号编号。 - 每个存储单元只能存储固定大小的二进制数据,并可随时被 CPU 读取或修改。
辅助存储器(外存)
- 存储容量大,价格低,但访问速度较慢。
- 断电后数据不会丢失(非易失性)。
- 典型设备包括 硬盘、光盘、闪存盘等。
计算机的 操作系统 提供对辅助存储器的管理,允许用户以 文件 形式存储数据,并通过 文件系统 组织文件。例如,Windows 操作系统使用 资源管理器 访问文件和目录。
1.1.2 计算机编程
1. 算法(Algorithm)
算法 是完成特定任务或解决某个问题的一系列步骤(指令)。它类似于菜谱中的制作步骤或数学家祖冲之计算圆周率的方法。
2. 程序与编程
程序 是算法在计算机中的实现,即计算机可执行的指令序列。编程 则是将算法转换为计算机可以理解的程序的过程,使用特定的计算机语言编写指令,使计算机按照既定逻辑执行任务。
3. 二进制
计算机的底层硬件由大量 晶体管 组成,而晶体管只有 "开"(1)和 "关"(0)两种状态。因此,计算机采用 二进制(0 和 1)来表示所有数据,包括整数、字符等。
在计算机中,一个晶体管可以存储 1 个二进制位(bit,简称 b),即 0 或 1。多个晶体管可以组合表示更复杂的数值。例如:
-
8 位(bit) 组成 1 字节(Byte,B),即
种不同的可能值。
-
1024 B = 1 KB(千字节,Kilobyte)。
-
1024 KB = 1 MB(兆字节,Megabyte)。
1024 MB = 1 GB(吉字节,Gigabyte)*。
4. 机器语言
计算机内部的指令和数据都是以 0 和 1 组成的 二进制代码 进行存储和处理。机器语言(Machine Language) 是计算机能够直接理解和执行的一种指令集合。
例如,以下是用 Intel 8086 机器语言执行 17 + 20 的指令:
1011 0000 0001 0001 // 将 17 存入 AL 寄存器
0000 0100 0001 0100 // 将 20 加到 AL 寄存器
1010 0010 0100 1000 0000 0000 // 将 AL 的值存入内存地址 0x0048
解析:
-
1011 0000是 操作码(Opcode),表示“将后面的数存入寄存器 AL”。 -
0001 0001是 立即数(Immediate Value),即 17。 -
0000 0100指示 AL 执行加法操作,0001 0100是 20 的二进制表示。 -
1010 ...负责将结果存入指定内存地址0x0048(采用 小端存储)。
早期编程的挑战
在 20 世纪 40 年代,程序员必须直接使用机器语言进行编程,甚至通过穿孔卡片输入指令。这种方式既繁琐又容易出错,极大地限制了计算机的使用效率。
5. 汇编语言(Assembly Language)**
为了简化机器语言的编写,引入了 汇编语言(Assembly Language)。汇编语言使用 助记符(Mnemonic) 代替二进制代码,使程序更易读,例如:
MOV AL, 17D ; 将 17 存入 AL 寄存器
ADD AL, 20D ; 将 20 加到 AL 寄存器
MOV [0048H], AL ; 将 AL 的值存入内存地址 0x0048
汇编语言的特点
- 每条汇编指令 对应一条机器指令。
- 人类可读,但仍然需要较高的技术背景。
- 需要 汇编程序(Assembler) 将汇编代码转换为机器语言,计算机才能执行。
尽管汇编语言相较于机器语言更加直观,但仍然对程序员要求较高,且代码冗长,不利于开发大型程序。
6. 高级语言(High-Level Languages)
由于汇编语言仍然过于低级,程序员需要书写大量指令才能完成简单任务。因此,开发者创造了 高级语言,如 C、C++、Python、Java 等,使编程更加高效。
在高级语言中,一条指令可能对应多条机器指令,并且采用接近自然语言的表达方式。例如:
sum = 17 + 20;
这行 C++ 代码等效于上面的机器语言和汇编语言指令。高级语言的优点包括:
- 可读性更强,类似人类语言,易于理解和学习。
- 提高编程效率,减少重复性操作,使开发者可以专注于算法和逻辑。
- 可移植性更高,可以在不同的计算机和操作系统上运行,而不需要针对特定 CPU 进行修改。
由于计算机无法直接理解高级语言,必须借助 编译器(Compiler) 或 解释器(Interpreter) 先将其转换为机器语言,然后再执行。
机器语言、汇编语言、高级语言对比
| 语言类型 | 示例 | 特点 |
|---|---|---|
| 机器语言 | 1011 0000 0001 0001 |
计算机直接执行,效率最高,但极难理解 |
| 汇编语言 | MOV AL, 17D |
可读性稍强,但仍然复杂 |
| 高级语言 | sum = 17 + 20; |
可读性好,跨平台,易于编写 |
随着计算机技术的发展,高级语言成为主流,但在底层优化、操作系统开发、嵌入式系统等领域,汇编语言仍然有一定的应用价值。
7 编译器、解释器与 C++ 语言
高级语言编写的程序在计算机执行之前,必须转换为机器语言。这种转换方式主要有两种:编译(Compilation) 和 解释(Interpretation)。
- 编译型语言(Compiled Language):程序源代码被整体翻译为可执行的二进制文件,然后执行。
- 解释型语言(Interpreted Language):程序源代码被逐行翻译并立即执行。
C++ 是一种 编译型语言,它的源代码必须经过 编译器(Compiler) 转换为机器代码,才能运行。
编译器与解释器的区别
| 对比项 | 编译器(Compiler) | 解释器(Interpreter) |
|---|---|---|
| 工作方式 | 先将整个程序翻译成机器代码,然后执行 | 逐行翻译并执行 |
| 执行效率 | 运行速度快,因为已转换为机器语言 | 运行速度较慢,因为需要边翻译边执行 |
| 错误检测 | 只有在编译时发现错误 | 可以在执行时逐行发现错误 |
| 常见语言 | C、C++、Java(编译为字节码后解释执行) | Python、JavaScript、Shell 脚本 |
编译型语言的优势
编译器能对代码进行全局优化,提高运行效率。因此,C++ 在高性能计算、系统编程、嵌入式开发等领域具有广泛应用。相比解释型语言,编译后的 C++ 程序通常运行更快,并且可以直接操纵硬件。
8 C++ 语言概述
C++ 语言的起源与发展
C++ 由 Bjarne Stroustrup 于 1979-1980 年 在 贝尔实验室(Bell Labs) 开发,初衷是对 C 语言 进行扩展,使其支持 面向对象编程(OOP)。
- C++ 继承了 C 语言的 高效性 和 底层控制能力,同时增加了 面向对象特性(如类、继承、多态等)。
- 由于其强大的性能和灵活性,C++ 可运行在 Windows、macOS、Linux、UNIX 等多种操作系统上。
- 经过多年的发展,C++ 一直是最受欢迎的编程语言之一,长期位居 全球编程语言排行榜前五。
C++ 的应用领域
C++ 具有高效的执行性能和强大的底层操作能力,被广泛应用于以下领域:
- 操作系统与系统软件(Windows、Linux、macOS 内核,驱动程序)
- 嵌入式开发(物联网、汽车电子、智能家居、芯片编程)
- 游戏开发与游戏引擎(Unity、Unreal Engine、CryEngine)
- 高性能计算(人工智能、数值计算、科学模拟)
- 金融系统(银行、证券、高频交易)
- 数据库与服务器(MySQL、PostgreSQL、Web 服务器)
- 计算机图形学(图像处理、3D 建模、CAD/CAM)
现代 C++ 的演进
在 20 世纪 80 年代至 2000 年初,C++ 语言的标准化进程较为缓慢。然而,自 2011 年 起,C++ 进入了 现代 C++(Modern C++) 时代。
- C++98(1998 年):最早的 C++ 标准,基于 C 语言,增加了面向对象特性。
- C++11(2011 年):现代 C++ 的起点,新增 Lambda 表达式、auto 关键字、智能指针、并发库 等特性。
- C++14(2014 年):对 C++11 进行改进,增加了更简洁的语法和库优化。
-
C++17(2017 年):引入 结构化绑定(Structured Binding)、
std::optional、并行算法 等特性。 - C++20(2020 年):大幅更新,增加 模块化(Modules)、协程(Coroutines)、概念(Concepts) 等新功能。
如今,工业界已普遍采用 现代C++ 进行开发,而传统的 C 语言风格编程逐渐被淘汰。
为何直接学习现代 C++?
在高校教学中,许多课程仍然停留在 C 语言或 C++98 时代,导致学生学习的知识 落后于工业界。相比之下,直接学习 C++17 或 C++20 能够:
- 减少学习负担,避免学习过时的 C 风格代码。
-
掌握更现代、高效的编程方法(如
auto关键字、智能指针、Lambda 等)。 - 与工业界无缝对接,更快适应企业开发需求。
总之,C++ 既是一门 高效、强大 的系统级编程语言,也是不断演进、与时俱进的现代化语言。学习 现代 C++,才能真正发挥 C++ 的优势,适应当前的技术趋势。
9 C++ 程序开发步骤
与其他编程语言类似,使用 C++ 编写程序也需要遵循一定的步骤。这个过程包括以下几个主要阶段:
-
理解问题
首先,需要清楚地理解所面临的问题。关键问题包括:- 输入:程序需要哪些数据?这些数据从哪里来?(如键盘、文件等)
- 输出:程序将输出什么结果?该结果如何显示或保存?(如屏幕显示、保存到文件等)
-
提出算法
根据问题描述,设计出解决问题的步骤和逻辑。算法是用来描述如何解决问题的指令序列,通常用伪代码或流程图来表示。 -
编写程序
将算法转化为 C++ 代码。通过编程语言的语法和规则,将算法实现为可执行的程序。 -
测试
通过不同的测试用例验证程序的正确性。测试时,除了使用有效数据进行验证外,还要考虑非法输入的情况,查看程序是否能够正确处理错误。
举例:计算一组数值的平均值
假设我们要编写一个程序来计算一组数值的平均值,以下是整个开发流程的实例:
-
理解问题
- 输入:这些数值从哪里来?用户是通过键盘输入,还是从文件中读取?
- 输出:程序计算出来的平均值是如何呈现的?是打印在屏幕上,还是保存到文件中?
-
提出算法
算法的核心思想是:- 初始化两个变量,一个用于存储总和,另一个用于计数。
- 循环读取每一个数值,将其加到总和中,并增加计数器。
- 最后,用总和除以计数器,得到平均值。
伪代码示例:
-----------start------------- 总和 sum = 0 计数器 count = 0 重复: 读入一个数值 如果读取失败,结束循环 否则: 将读取的数值加到总和 sum 计数器 count 增加 1 计算平均值:average = sum / count 输出/打印平均值 average -----------end------------- -
编写程序
根据上述算法,使用 C++ 语言将其实现为程序:#include <iostream> using namespace std; int main() { double sum = 0; // 总和 int count = 0; // 计数器 double value; // 输入的数值 while (cin >> value) { sum += value; count++; } if (count > 0) { double average = sum / count; cout << "平均值为: " << average << endl; } else { cout << "没有输入有效的数值!" << endl; } return 0; } -
测试
运行程序时,输入不同的测试数据,确保其输出结果正确。- 正常情况:输入一系列数字,程序计算并输出正确的平均值。
- 边界情况:没有输入任何数值时,程序应该提示用户没有有效数据输入。
- 非法输入:输入非数值数据(如字符串或特殊字符),程序应当能够适当地处理错误或提示。
示例测试输入:
10 20 30输出结果:
平均值为: 20
通过这种方法,我们可以从理解问题、设计算法、编写程序,到最终的测试,逐步完成一个 C++ 程序的开发过程。