C++编程语言 01:从 Python 到 C++ 的启航
引言:欢迎来到 C++ 的世界!
各位同学,大家好!很高兴能和大家一起开启 C++ 的学习之旅。相信大家已经掌握了 Python 编程的基础,对编程的思想和逻辑有了初步的认识。那么,为什么要学习 C++ 呢?C++ 又会给我们带来什么新的体验和挑战呢?这就是我们今天课程要探讨的内容。
一、 C++ 与 Python 的对比:理解差异,扬长避短
我们首先来对比一下 C++ 和大家熟悉的 Python,了解它们的优势和适用场景,从而更好地理解学习 C++ 的意义。
速度和效率:
- C++: 编译型语言,执行速度快,效率高。 C++ 代码在运行前会被完整地编译成机器可以直接执行的二进制代码,这使得 C++ 在执行效率上具有天然的优势,尤其是在处理大量计算和对性能有极致要求的场景下。
- Python: 解释型语言,执行速度相对较慢,但开发效率高。 Python 代码在运行时逐行解释执行,这牺牲了一部分执行效率,但换来了更快的开发速度和更简洁的语法,非常适合快速原型开发和脚本编写。
内存管理:
- C++: 需要手动管理内存。 C++ 允许程序员直接控制内存的分配和释放,这赋予了开发者更高的灵活性和优化空间,但也带来了内存泄漏等风险。
- Python: 自动内存管理(垃圾回收机制)。 Python 自动处理内存分配和回收,降低了开发者的心智负担,但也可能在某些情况下带来性能上的开销。
应用领域:
- C++: 性能敏感型应用、系统级编程、游戏开发、嵌入式系统、高性能计算等。 由于其高效的执行速度和对硬件的直接控制能力,C++ 在这些领域扮演着重要的角色。
- Python: 数据分析、人工智能、Web 开发、自动化脚本、快速原型开发等。 Python 的简洁语法和丰富的库使其在这些领域非常受欢迎。
为什么人工智能班级学习 C++?
- 深入理解底层原理,为算法优化提供基础。 AI 的核心算法往往涉及大量的计算,了解 C++ 可以帮助我们理解这些算法在底层是如何高效执行的,从而为算法优化提供思路。
- 部分高性能库和框架使用 C++ 开发,学习 C++ 有助于更好地使用和理解这些工具。 许多流行的深度学习框架(如 TensorFlow、PyTorch 的底层)都是用 C++ 实现的,掌握 C++ 可以更深入地了解它们的运行机制,甚至进行二次开发。
- 提升编程技能和代码效率。 C++ 的学习能够锻炼我们对内存管理、性能优化等方面的理解,提升我们的编程基本功,并编写出更高效的代码。
二、 C++ 的发展与平台:历史的脉络与选择
了解 C++ 的发展历程和它所运行的平台,有助于我们更好地理解这门语言的特点和应用场景。
C++ 的发展历程:从机器到现代
- 机器语言: 计算机最早只能理解的语言,用二进制代码表示指令,例如
0001101000
。非常难以理解和编写。 - 汇编语言: 用助记符代替二进制代码,例如
mov
,jmp
,add
。相较于机器语言更容易理解,但仍然很底层,开发效率不高。 - 高级语言 (C语言): 更接近人类语言,更容易理解和编写,例如
int x = 5;
。提高了开发效率,但仍然偏向过程式编程。 - C++: 在C语言基础上发展而来, 由 Bjarne Stroustrup 于 1979 年在贝尔实验室开发。增加了面向对象特性(类、继承、多态),并持续引入泛型编程、Lambda 表达式等现代特性,兼顾开发效率和执行效率。 C++ 可以看作是 C 语言的增强版,它既保留了 C 的高效性,又加入了许多现代编程的特性。
- 机器语言: 计算机最早只能理解的语言,用二进制代码表示指令,例如
C++版本:不断进化的语言
- C++98/03: C++ 的早期稳定版本。
- C++11: 一个重要的里程碑版本,引入了大量现代特性,如智能指针、Lambda 表达式、自动类型推断等,是学习现代 C++ 的基础。
- C++14, C++17, C++20...: 后续版本不断引入新特性和改进,使 C++ 更加强大和易用。我们建议学习最新的稳定版本,目前 C++20 或更新版本是主流。
三、 C++ 编译原理:从代码到执行
与 Python 的解释执行不同,C++ 是一门编译型语言。理解编译过程对于学习 C++ 至关重要。
Python:解释型语言,逐行解释执行代码。 就像我们阅读文章一样,Python 解释器会一行一行地理解并执行代码。
C++:编译型语言,需要先将代码编译成机器语言才能执行。 C++ 代码需要经过一个“翻译”的过程,将其转化为计算机能够理解的机器语言。
编译过程详解:
预处理 (Preprocessing):
- 处理以
#
开头的预处理指令。 - 例如:
#include <iostream>
:将iostream
头文件的内容复制到当前文件中。#define PI 3.14159
:将代码中的PI
替换为3.14159
。
- 预处理的输出结果是一个包含了所有必要代码的源文件。
- 处理以
编译 (Compilation):
- 将预处理后的 C++ 代码翻译成汇编语言。
- 汇编语言是一种更接近机器语言的低级语言,使用助记符表示机器指令。
汇编 (Assembly):
- 将汇编语言代码翻译成机器语言(也称为目标代码)。
- 机器语言是由二进制指令组成的,计算机可以直接执行。
- 汇编器的输出结果是一个或多个目标文件 (
.obj
或.o
文件)。
链接 (Linking):
- 将多个目标文件和所需的库文件(包含已经编译好的函数和代码)合并成一个最终的可执行文件 (
.exe
或无后缀文件)。 - 链接器负责解决符号引用问题,例如将函数调用与函数定义连接起来。
- 将多个目标文件和所需的库文件(包含已经编译好的函数和代码)合并成一个最终的可执行文件 (
四、 C++ 开发环境搭建:工欲善其事,必先利其器
选择合适的开发环境能大大提高我们的学习和开发效率。
推荐使用 CLion:
- 跨平台开发工具,支持 Windows、Linux、macOS 等平台。 无论你使用哪种操作系统,CLion 都能提供一致的开发体验。
- 专为 C++ 设计的集成开发环境 (IDE),提供代码补全、语法高亮、调试、重构等强大功能。 这些功能可以帮助我们更快更准确地编写代码,并更容易发现和修复错误。
- 与 CMake 构建系统无缝集成,方便项目管理。 CMake 是一个流行的跨平台构建工具,CLion 的集成使得管理复杂的 C++ 项目变得更加容易。
CLion 安装演示:
下载 CLion 安装包:
运行安装程序,根据提示完成安装。
启动 CLion,配置 C++ 工具链。
- CLion 需要一个 C++ 编译器才能工作。常见的编译器有 GCC、Clang 和 Visual Studio 的 MSVC。
- 在首次启动 CLion 时,它会提示你选择或配置编译器。
- 在 Windows 上,通常会选择 MinGW 或安装 Visual Studio Community,并配置其编译器。
- 在 Linux 和 macOS 上,通常系统已经自带 GCC 或 Clang。
TIP
其他开发环境:
- GCC/G++: 开源编译器,使用命令行操作,适合有一定基础的开发者,可以更深入地了解编译过程。
- Visual Studio: 微软开发的集成开发环境,功能强大,尤其在 Windows 平台开发中表现优秀,但体积较大。
- VS Code with C/C++ Extension: 轻量级但功能强大的代码编辑器,通过安装 C/C++ 扩展可以获得代码补全、调试等功能,适合喜欢自定义配置的开发者。
五、 第一个 C++ 程序:迈出 C++ 编程的第一步
让我们一起编写并运行你的第一个 C++ 程序!
#include <iostream> // 引入 iostream 头文件,提供输入输出功能
using namespace std; // 使用标准命名空间,简化代码
int main() { // 主函数,程序执行的入口
cout << "Hello, world!" << endl; // 使用 cout 输出字符串到控制台,并换行
return 0; // 返回值 0 表示程序正常结束
}
好的,我将你提供的 C++ 基础数据类型部分进行补充和完善,使其成为更完整的第一节课后半部分内容。
六、C++ 数据类型
我们已经了解了 C++ 的一些基本特性,现在让我们深入了解 C++ 中的数据类型,这是构建任何程序的基础。
1. 基本数据类型:
int
:整型(Integer)- 用于存储整数(没有小数部分的数字),例如:
-10
,0
,123
。 - 通常占用 4 个字节(32位),可以存储的范围通常为 -231 到 231-1。
- 注意: 实际大小可能因编译器和操作系统而异,可以使用
sizeof(int)
查看。
- 用于存储整数(没有小数部分的数字),例如:
char
:字符型(Character)- 用于存储单个字符,例如:
'a'
,'B'
,'1'
,'$'
. - 通常占用 1 个字节(8位),可以存储 ASCII 码表中的字符。
- 用于存储单个字符,例如:
float
:单精度浮点型(Floating-point)- 用于存储带有小数部分的数值,精度有限。例如:
3.14
,-0.5
,2.0f
(注意f
后缀)。 - 通常占用 4 个字节,提供约 7 位有效数字的精度。
- 用于存储带有小数部分的数值,精度有限。例如:
bool
:布尔类型(Boolean)- 用于存储逻辑值,只有两个可能的值:
true
(真)或false
(假)。 - 通常占用 1 个字节,但实际存储可能只用一个比特位。
- 用于存储逻辑值,只有两个可能的值:
void
:空类型- 表示没有值。
- 主要用于以下两种情况:
- 函数返回值: 如果函数不返回任何值,则将其返回类型声明为
void
。 - 函数参数: 如果函数不接受任何参数,则参数列表可以写为
void
或空着。
- 函数返回值: 如果函数不返回任何值,则将其返回类型声明为
2.算术运算符:
+
加法:将两个操作数相加。-
减法:将第二个操作数从第一个操作数中减去。*
乘法:将两个操作数相乘。/
除法:将第一个操作数除以第二个操作数。%
取余(模):返回两个整数相除后的余数。sizeof()
大小运算符:用于获取数据类型或变量所占用的内存大小(以字节为单位)。整数除法的重要特性:
- 截断行为: 当两个整数进行除法运算时,结果会被截断为整数部分,小数部分会被直接舍弃,不会进行四舍五入。
- 示例:
7 / 3
的结果是2
,而不是2.333...
。
取余运算的应用:
- 判断整除性: 如果
a % b
的结果为0
,则表示a
可以被b
整除。 - 获取个位数字:
n % 10
可以获取整数n
的个位数字。 - 循环处理: 常用于循环中,例如限制索引在一定范围内。
- 判断整除性: 如果
3. 其他基本数据类型 (大小和范围可能因系统和编译器而异):
short int
(简写为short
):短整型- 通常占用 2 个字节,存储范围比
int
小,但可以节省内存。
- 通常占用 2 个字节,存储范围比
long int
(简写为long
):长整型- 通常占用 4 或 8 个字节,存储范围比
int
大。在现代 64 位系统中,通常为 8 字节。
- 通常占用 4 或 8 个字节,存储范围比
long long int
(简写为long long
):更长的整型- 通常占用 8 个字节,提供更大的整数存储范围。
浮点型 (精度和范围不同):
double
:双精度浮点型- 精度比
float
更高,可以存储更多位的小数。 - 通常占用 8 个字节,提供约 15 位有效数字的精度。推荐在需要较高精度的浮点数计算中使用。
- 精度比
long double
:扩展精度浮点型- 提供比
double
更高的精度,但具体大小和精度取决于编译器和平台。 - 通常占用 10 或 16 个字节。
- 提供比
无符号类型(Unsigned):
- 在整数类型(如
int
,short
,long
,long long
,char
)前加unsigned
关键字,表示该类型不存储符号位,只能存储非负数(零和正数)。 - 优点: 可以扩展正数的表示范围。例如,
unsigned int
的正数范围是int
的两倍。 - 缺点: 不能存储负数。
- 示例:
unsigned int
,unsigned short
,unsigned long long
,unsigned char
。
- 在整数类型(如
代码示例分析:
#include <iostream>
using namespace std;
int main() {
// 声明变量并赋值
int age = 25;
char initial = 'J';
float height = 1.75;
bool isStudent = true;
// 打印变量值
cout << "Age: " << age << endl;
cout << "Initial: " << initial << endl;
cout << "Height: " << height << endl;
cout << "Is student? " << isStudent << endl;
// 算术运算
int a = 10;
int b = 3;
int sum = a + b;
int difference = a - b;
int product = a * b;
int quotient = a / b;
int remainder = a % b;
cout << "Sum: " << sum << endl;
cout << "Difference: " << difference << endl;
cout << "Product: " << product << endl;
cout << "Quotient: " << quotient << endl; // 输出 3,因为是整数除法
cout << "Remainder: " << remainder << endl; // 输出 1
// 使用 sizeof 运算符
cout << "Size of age: " << sizeof(age) << " bytes" << endl;
cout << "Size of float: " << sizeof(float) << " bytes" << endl;
return 0;
}
代码示例解释:
变量声明和初始化:
int age = 25;
:声明一个整型变量age
并赋值为25
。char initial = 'J';
:声明一个字符型变量initial
并赋值为字符'J'
。float height = 1.75;
:声明一个单精度浮点型变量height
并赋值为1.75
。bool isStudent = true;
:声明一个布尔类型变量isStudent
并赋值为true
。
使用
cout
打印变量的值:cout << "Age: " << age << endl;
:使用cout
将字符串和变量age
的值输出到控制台。
算术运算示例:
- 演示了加、减、乘、除和取余运算。
- 特别注意
quotient
的结果,展示了整数除法的截断行为。
使用
sizeof
运算符:cout << "Size of age: " << sizeof(age) << " bytes" << endl;
:使用sizeof
运算符获取变量age
所占用的内存大小,并输出到控制台。这可以帮助我们验证不同数据类型的大小。
总结:
理解 C++ 的基本数据类型及其特性是编写有效和高效 C++ 代码的关键。选择合适的数据类型可以帮助我们节省内存,提高程序的性能,并避免潜在的错误。在后续的课程中,我们将学习更多关于如何使用这些数据类型进行更复杂的操作。
作业:
温度转换器
编写一个 C++ 程序,实现华氏温度到摄氏温度的转换。
- 程序开始时,提示用户输入一个华氏温度值(可以使用
int
或double
类型存储)。 - 使用以下公式将华氏温度转换为摄氏温度:
摄氏温度 = (华氏温度 - 32) * 5 / 9
- 将计算得到的摄氏温度值输出到控制台,并注明单位(摄氏度)。
- 扩展练习(可选): 让程序也能实现摄氏温度到华氏温度的转换。用户可以选择进行哪种转换。
示例输出:
请输入华氏温度:68 对应的摄氏温度为:20 摄氏度 或者 (扩展练习) 请选择转换类型 (1. 华氏转摄氏, 2. 摄氏转华氏):1 请输入华氏温度:68 对应的摄氏温度为:20 摄氏度
- 程序开始时,提示用户输入一个华氏温度值(可以使用
参考实现如下:
#include <iostream>
#include <iomanip> // 用于设置输出精度
using namespace std;
int main() {
int choice;
double temperature, convertedTemperature;
// 提示用户选择转换类型
cout << "请选择转换类型 (1. 华氏转摄氏, 2. 摄氏转华氏):";
cin >> choice;
if (choice == 1) {
// 华氏转摄氏
cout << "请输入华氏温度:";
cin >> temperature;
convertedTemperature = (temperature - 32) * 5.0 / 9.0;
cout << "对应的摄氏温度为:" << fixed << setprecision(2) << convertedTemperature << " 摄氏度" << endl;
} else if (choice == 2) {
// 摄氏转华氏
cout << "请输入摄氏温度:";
cin >> temperature;
convertedTemperature = (temperature * 9.0 / 5.0) + 32;
cout << "对应的华氏温度为:" << fixed << setprecision(2) << convertedTemperature << " 华氏度" << endl;
} else {
cout << "无效的选择,请重新运行程序。" << endl;
}
return 0;
}