此专栏为移动机器人知识体系的 C {\rm C} C++基础,基于《深入浅出 C {\rm C} C++》(马晓锐)的笔记, g i t e e {\rm gitee} gitee链接: 移动机器人知识体系.
1.C++概述
1.1 C++概述
-
计算机系统分为硬件系统和软件系统。
- 硬件系统:指组成计算机的电子元件和相关设备,如:中央处理器 ( C e n t r a l P r o c e s s i n g U n i t , C P U ) ({\rm Central\ Processing\ Unit,CPU}) (Central Processing Unit,CPU)、内存储器、输入/输出设备、外存储器等;
- 软件系统:指使计算机硬件系统能够处理信息所需要的程序和相关文档;
-
硬件和软件结合形成完整的计算机系统,硬件提供计算机系统处理信息的基础,软件控制如何利用硬件来处理信息;
-
计算机程序设计语言是一套具有特定的语法、词法等规则的系统,通过计算机程序设计可以用特定的方法描述世界,再将这些描述传递给计算机,达到计算机识别世界的目的;
-
C {\rm C} C++几乎继承了 C {\rm C} C语言的所有特点,同时添加了面向对象的特征, C {\rm C} C++既支持面向过程的程序设计,又支持面向对象的程序设计;
-
C {\rm C} C++程序由类 ( c l a s s ) ({\rm class}) (class)和函数 ( f u n c t i o n ) ({\rm function}) (function)组成,开发人员可以用多个小的软件模块构成 C {\rm C} C++程序;
-
标准 C {\rm C} C++库中主要有标准 C {\rm C} C库、 I / O {\rm I/O} I/O流技术、 S t r i n g {\rm String} String、容器、算法;
-
C {\rm C} C++程序的开发通常分为:编辑 ( E d i t ) ({\rm Edit}) (Edit)、预处理 ( P r e p r o c e s s ) ({\rm Preprocess}) (Preprocess)和编译 ( C o m p i l e ) ({\rm Compile}) (Compile)、链接 ( L i n k ) ({\rm Link}) (Link)、加载 ( L o a d ) ({\rm Load}) (Load)和执行 ( E x c u t e ) ({\rm Excute}) (Excute);
-
编辑阶段:开发者用编辑器编辑 C {\rm C} C++程序,将程序存放在磁盘等的辅助存储设备上, C {\rm C} C++程序文件名通常以 . c p p 、 . c x x 、 . C {\rm .cpp、.cxx、.C} .cpp、.cxx、.C扩展名结尾, C {\rm C} C++常见文件扩展名及其说明:
文件扩展名 文件扩展名 文件扩展名 说明 说明 说明 . h {\rm .h} .h C 语言和 C {\rm C}语言和{\rm C} C语言和C++ 语言程序的头文件 {\rm 语言程序的头文件} 语言程序的头文件 . h p p {\rm .hpp} .hpp C {\rm C} C++ 语言程序的头文件 语言程序的头文件 语言程序的头文件 . h x x {\rm .hxx} .hxx C {\rm C} C++ 语言程序的头文件 语言程序的头文件 语言程序的头文件 . c {\rm .c} .c C 语言程序的实现文件 ( 源文件 ) {\rm C}语言程序的实现文件(源文件) C语言程序的实现文件(源文件) . C {\rm .C} .C C {\rm C} C++ 语言程序的实现文件 ( 源文件 ) 语言程序的实现文件(源文件) 语言程序的实现文件(源文件) . c p p {\rm .cpp} .cpp C {\rm C} C++ 语言程序的实现文件 ( 源文件 ) 语言程序的实现文件(源文件) 语言程序的实现文件(源文件) . c x x {\rm .cxx} .cxx C {\rm C} C++ 语言程序的实现文件 ( 源文件 ) 语言程序的实现文件(源文件) 语言程序的实现文件(源文件) -
预处理和编译阶段:编译器将 C {\rm C} C++程序翻译成机器语言代码(目标码)的过程,这个过程分为预处理阶段和编译阶段;
-
链接阶段:将目标码与其他默认功能的代码链接起来,建立执行程序映像;
-
加载和执行阶段:编译后文件经过链接,生成可执行文件。
-
1.2 C++的常量和变量
-
常量是在定义后值不能被改变的量,变量在定义后可以再赋值,即值可以被改变;
-
常量亦称为常数,在程序运行过程中一直保持不变的量,常量一般在程序中可以从字面形式上判断出来,这样的常量称为字符常量或直接常量,亦可用标识符号代表常量;
-
定义常量的方式:
// 1.利用预处理命令#define定义常量(宏常量、符号常量); // 格式:#define 常量名 值 #define MAX_LEN 100 // 定义符号常量; // 2.利用const定义常量(const常量) // 格式:const 数据类型 常量名 = 值; const int nMaxLen = 100; // 3.利用constexpr定义常量 // 格式:constexpr 数据类型 常量名 = 值; constexpr int MaxLen = 100;
- # d e f i n e {\rm define} define定义的符号常量,在程序编译时由预处理器进行值替换,即将程序中出现的符号常量由真实值来替换, c o n s t 、 c o n s t e x p r {\rm const、constexpr} const、constexpr定义的常量是在编译和运行阶段进行处理;
- 利用# d e f i n e {\rm define} define定义的符号常量没有类型, c o n s t 、 c o n s t e x p r {\rm const、constexpr} const、constexpr定义的常量有具体类型;
- 在定义符号常量时,标识符一般采用全大写形式,与变量标识符区分;
-
符号常量实例 ( e x a m p l e 1 _ 1. c p p ) ({\rm example1\_1.cpp}) (example1_1.cpp):
/** * 作者:罗思维 * 时间:2023/09/22 * 描述:已知圆的半径,计算圆的面积 */ #include <iostream> using namespace std; #define PI 3.1415926 int main() { int nRadius = 10; double fAcreage; fAcreage = PI * nRadius * nRadius; cout << "半径为10的圆的面积为:" << fAcreage << endl; return 0; }
-
定义常量的优点
- 含义清楚、容易理解,使用规范化的命名方式定义符号常量可以"见名知义";
- 修改常量方便,需要修改符号常量时,只需要修改常量定义处,即可做到"一改全改";
-
变量:值可以改变的量称为变量,变量一般用一个标识符标识,这个标识符称为变量名,变量实际的值存储在内存的存储单元中,这个值称为变量值,变量遵循"先定义,后使用"的规则;
-
变量定义形式:
// 1.变量定义: // 格式:数据类型 变量标识符;
-
变量名与变量值的关系图:
- 变量名代表一个地址,这个地址是存储变量值的内存地址;
- 在定义一个变量时,编译系统给这个变量分配一个对应的存储单元,变量值存储在这个存储单元中,这个存储单元有一个地址,变量名则代表这个地址;
- 当程序需要从变量中取值时,会通过变量名找到相应的内存地址,然后从这个地址上的存储单元中读取数据;
1.3 C++程序的基本元素
-
关键字: C {\rm C} C++保留的预定义标识符,亦称保留字,每个关键字都代表特殊意义,不允许开发者利用这些字符进行其他操作,常用的关键字如下:
b r e a k {\rm break} break c a s e {\rm case} case c h a r {\rm char} char c o n s t {\rm const} const c o n t i n u e {\rm continue} continue d e f a u l t {\rm default} default d o {\rm do} do d o u b l e {\rm double} double e l s e {\rm else} else e n u m {\rm enum} enum e x t e r n {\rm extern} extern f l o a t {\rm float} float f o r {\rm for} for g o t o {\rm goto} goto i f {\rm if} if i n t {\rm int} int l o n g {\rm long} long r e t u r n {\rm return} return s h o r t {\rm short} short s i g n e d {\rm signed} signed s i z e o f {\rm sizeof} sizeof s t a t i c {\rm static} static s t r u c t {\rm struct} struct s w i t c h {\rm switch} switch t y p e d e f {\rm typedef} typedef u n i o n {\rm union} union u n s i g n e d {\rm unsigned} unsigned v o i d {\rm void} void w h i l e {\rm while} while b o o l {\rm bool} bool c a t c h {\rm catch} catch c l a s s {\rm class} class d e l e t e {\rm delete} delete f a l s e {\rm false} false f r i e n d {\rm friend} friend i n l i n e {\rm inline} inline n a m e s p a c e {\rm namespace} namespace n e w {\rm new} new o p e r a t o r {\rm operator} operator p r i v a t e {\rm private} private p r o t e c t e d {\rm protected} protected p u b l i c {\rm public} public t e m p l a t e {\rm template} template t h i s {\rm this} this t h r o w {\rm throw} throw t r u e {\rm true} true t r y {\rm try} try t y p e n a m e {\rm typename} typename u s i n g {\rm using} using v i r t u a l {\rm virtual} virtual -
标识符:开发者定义的用来表示程序中实体名称的有效字符序列,标识符由字符、数字、下划线等组成,标识符的构成规则:
- 以大写字母、小写字母或下划线 ( _ ) (\_) (_)开始,不能以数字和数字之外的标点符号开始;
- 可以由大写字母、小写字母、下划线 ( _ ) (\_) (_)或数字 ( 0 ~ 9 ) (0~9) (0~9)组成;
- C {\rm C} C++对标识符的大小写是敏感的,大写字母和小写字母代表不同的标识符,即标识符区分大小写;
- 标识符不能和 C {\rm C} C++的关键字同名;
-
运算符:在程序中用于实现各种运算的符号,亦称操作符,运算符分为:算术运算符、关系运算符、逻辑运算符、位运算符。
- 算术运算符: C {\rm C} C++中的算术运算符包括加法运算符 ( + ) (+) (+)、减法运算符 ( − ) (-) (−)、乘法运算符 ( ∗ ) (*) (∗)、除法取整运算符 ( / ) (/) (/)、取余运算符 ( % ) (\%) (%)、增量运算符 ( + + ) (++) (++)、减量运算符 ( − − ) (--) (−−);
- 关系运算符:包括等于 ( = = ) (==) (==)、大于 ( > ) (>) (>)、小于 ( < ) (<) (<)、大于或等于 ( > = ) (>=) (>=)、小于或等于 ( < = ) (<=) (<=)、不等于 ( ! = ) (!=) (!=);
- 逻辑运算符:包括逻辑非 ( ! ) (!) (!)、逻辑与 ( & & ) (\&\&) (&&)、逻辑或 ( ∣ ∣ ) (||) (∣∣),逻辑非用于改变条件表达式的真假值,即将 1 1 1变为 0 0 0,将 0 0 0变为 1 1 1,逻辑与和逻辑或用于求两个条件表达式的逻辑与和逻辑或;
-
标点符号:在程序中起分隔内容和界定范围作用的一类符号,主要标点符号如下:
标点符号 标点符号 标点符号 名称 名称 名称 作用描述 作用描述 作用描述 空格 空格 空格 语句中各成分之间的分隔符 语句中各成分之间的分隔符 语句中各成分之间的分隔符 ; ; ; 分号 分号 分号 语句的结束符 语句的结束符 语句的结束符 ′ ' ′ 单引号 单引号 单引号 字符常量的起止标记符 字符常量的起止标记符 字符常量的起止标记符 ′ ′ '' ′′ 双引号 双引号 双引号 字符串量的起止标记符 字符串量的起止标记符 字符串量的起止标记符 # \# # 井字号 井字号 井字号 预处理命令的开始标记符 预处理命令的开始标记符 预处理命令的开始标记符 { \{ { 左大括号 左大括号 左大括号 复合语句的开始标记符 复合语句的开始标记符 复合语句的开始标记符 } \} } 右大括号 右大括号 右大括号 复合语句的结束标记符 复合语句的结束标记符 复合语句的结束标记符 / / // // 双斜杠 双斜杠 双斜杠 行注释的标记符 行注释的标记符 行注释的标记符 / ∗ /* /∗ 斜杠和星号 斜杠和星号 斜杠和星号 块注释的开始标记符 块注释的开始标记符 块注释的开始标记符 ∗ / */ ∗/ 星号和斜杠 星号和斜杠 星号和斜杠 块注释的结束标记符 块注释的结束标记符 块注释的结束标记符 -
实例:
-
增量运算符和减量运算符实例 ( e x a m p l e 1 _ 2. c p p ) ({\rm example1\_2.cpp}) (example1_2.cpp)
/** * 作者:罗思维 * 时间:2023/09/23 * 描述:定义一个整数,对其进行增量运算和减量运算 */ #include <iostream> using namespace std; int main(int argc, char *argv[]) { int number1 = 584, number2 = 520; int number3 = 13, number4 = 14; cout << "初始化的number1的值为:" << number1 << endl; cout << "初始化的number2的值为:" << number2 << endl; cout << "初始化的number3的值为:" << number3 << endl; cout << "初始化的number4的值为:" << number4 << endl; cout << "==========================" << endl; cout << "number1++的值:" << number1++ << endl; cout << "++number2的值:" << ++number2 << endl; cout << "number3--的值:" << number3-- << endl; cout << "--number4的值:" << --number4 << endl; cout << "==========================" << endl; cout << "缓存区中的number1的值:" << number1 << endl; cout << "缓存区中的number3的值:" << number3 << endl; return 0; }
-
逻辑运算符实例 ( e x a m p l e 1 _ 3. c p p ) ({\rm example1\_3.cpp}) (example1_3.cpp)
/** * 作者:罗思维 * 时间:2023/09/24 * 描述:利用关系运算符和逻辑运算符判断学生成绩是否合格。 */ #include <iostream> using namespace std; int main() { int nScore1 = 90, nScore2 = 100; if (nScore1 >= 60 && nScore2 >= 60) { cout << "成绩合格,请及时打印成绩." << endl; } else { cout << "成绩不合格,请重新考试." << endl; } return 0; }
-
1.4 C++程序的基本结构
-
m a i n {\rm main} main函数: m a i n {\rm main} main函数亦称主函数,所有的 C {\rm C} C++程序必须有且只有一个 m a i n {\rm main} main函数,程序在运行时,系统会自动地首先调用 m a i n {\rm main} main函数,是程序的入口函数, m a i n {\rm main} main函数原型如下:
// main函数原型: int main(int argc,char *argv[]) // 参数说明: // argc:指明有多少个参数将被传递给main(); // argv[]:参数以字符串数组的形式进行传递;
-
预处理命令:对程序代码在正式编译前的一些预先处理,常见的预处理有:文件包含、条件编译、布局控制和宏替换;
- 文件包含:# i n c l u d e {\rm include} include预处理,主要作用是引用其他文件的内容到本文件中;
- 条件编译:# i f {\rm if} if、# i f n d e f {\rm ifndef} ifndef、# i f d e f {\rm ifdef} ifdef、# e n d i f {\rm endif} endif、# u n d e f {\rm undef} undef预处理,主要作用是进行编译时有选择性地处理;
- 布局控制:# p r o g m a {\rm progma} progma预处理,主要作用是为编译程序提供非常规的控制流信息;
- 宏替换:# d e f i n e {\rm define} define预处理,可以定义符号常量、函数功能、重新命名、字符串的拼接等各种功能;
-
常见的预处理命令及其含义:
指令 指令 指令 指令含义 指令含义 指令含义 # d e f i n e {\rm define} define 定义宏 定义宏 定义宏 # u n d e f {\rm undef} undef 取消定义宏 取消定义宏 取消定义宏 # i n c l u d e {\rm include} include 包含文件 包含文件 包含文件 # i f d e f {\rm ifdef} ifdef 其后的宏已定义时激活条件编译块 其后的宏已定义时激活条件编译块 其后的宏已定义时激活条件编译块 # i f n d e f {\rm ifndef} ifndef 其后的宏未定义时激活条件编译块 其后的宏未定义时激活条件编译块 其后的宏未定义时激活条件编译块 # e n d i f {\rm endif} endif 终止条件编译块 终止条件编译块 终止条件编译块 # i f {\rm if} if 其后表达式非零时激活条件编译块 其后表达式非零时激活条件编译块 其后表达式非零时激活条件编译块 # e l s e {\rm else} else 对应 对应 对应# i f d e f {\rm ifdef} ifdef、# i f n d e f 或 {\rm ifndef}或 ifndef或# i f 指令 {\rm if}指令 if指令 # e l i f {\rm elif} elif # e l s e 和 {\rm else}和 else和# i f 的结合 {\rm if}的结合 if的结合 # l i n e {\rm line} line 改变当前行号或文件名 改变当前行号或文件名 改变当前行号或文件名 # e r r o r {\rm error} error 输出一条错误信息 输出一条错误信息 输出一条错误信息 # p r a g m a {\rm pragma} pragma 为编译程序提供非常规的控制流信息 为编译程序提供非常规的控制流信息 为编译程序提供非常规的控制流信息 -
C {\rm C} C++基本输出/输出
-
C {\rm C} C++语言中没有专门的输入/输出语句,输入/输出操作是由一组标准 I / O {\rm I/O} I/O流类的类库提供的;
-
输入/输出是一种数据传送操作,可以看作字符序列在主机和外设之间的流动, C {\rm C} C++中将数据从一个对象到另一个对象的流动抽象为"流";
-
"流"具有方向性:流既可以表示数据从内存中传送到某个设备,此时与输出设备相联系的流称为输出流;流也可以表示数据从某个设备传送给内存中的变量,此时与输入设备相联系的流称为输入流;
-
流通过重载运算符">>“和”<<“执行输入/输出操作,输入操作是从流中获取数据,”>>“称为提取运算符,输出操作是向流中插入数据,”<<"称为插入运算符;
-
标准输出:默认情况下,程序的标准输出设备是屏幕, C {\rm C} C++定义流对象 c o u t {\rm cout} cout来使用它, c o u t {\rm cout} cout与插入运算符"<<"一起使用;
// 1.插入运算符"<<"可以在一条语句中多次使用; cout << "I " << "am " << "Willard." << endl; // 2.需要输出一组变量和常量或多于一个变量时,可重复使用插入运算符; int age = 27; cout << "I am " << age << " years old this year." << endl; // 3.cout不自动换行,换行需要加换行符"\n"或"endl"; cout << "My name is Willard.\n"; cout << "My name is Willard." << endl;
-
标准输入:默认情况下,程序的标准输入设备是键盘,被定义的 C {\rm C} C++流对象是 c i n {\rm cin} cin, c i n {\rm cin} cin与提取操作符">>"一起使用;
// 1.提取操作符可以从同一个输入流中提取多个数据项给其后的多个变量赋值, // 要求输入流的数据项用空格进行分隔; int radius; cin >> radius; // 2.cin能正确识别用户输入的数据,如果输入整数,则得到整数;如果输出字符,则得到字符; int radius; char c; cin >> radius; cout << radius; // 输入1,则输出1; cin >> c; cout << c; // 输入字符W,则输出字符W; // 3.cin支持一次性读入多个数据; int number1,number2; cin >> number1 >> number2;
-
注释:注释是程序中的说明性语句,程序的注释一般分为:序言性注释和功能性注释;
- 序言性注释:出现在程序首部,用于说明程序名称、开发日期等;
- 功能性注释:出现在每一个具有独立功能的模块前,用于说明模块的功能及调用格式等;
- C {\rm C} C++提供多行注释和单行注释,多行注释采用"/*“和”*/“表示,单行注释采用”//"表示;
- 注释语句对程序代码起到说明和解释的作用,可以提高程序的可读性,可以帮助其他人阅读和理解程序,在运行程序时,注释语句不使计算机执行任何操作;
-
1.5 实战
项目需求:提示学生用户输入学号和三门课程,计算其平均分数并输出。
需求分析:需求分为三部分,即输入信息、处理信息和输出信息。
- 输入信息:使用 c i n {\rm cin} cin处理输入信息;
- 输出信息:使用 c o u t {\rm cout} cout处理输出信息;
- 处理信息:对三门课程的成绩累加后除以 3 3 3;
程序流程:
代码实现:
/**
* 作者:罗思维
* 时间:2023/09/24
* 描述:提示学生用户输入学号和三门课程,计算品平均分并输出。
*/
#include <iostream>
using namespace std;
int main()
{
/**
* 参数说明:
* nStudentID: 学生学号;
* dScore1,dScore2,dScore3: 第1,2,3门课程成绩;
* dAveScore: 平均成绩;
*/
int nStudentID;
double dScore1, dScore2, dScore3;
double dAveScore;
cout << "请输入学生学号:";
cin >> nStudentID;
cout << "请输入学生第1门课程成绩:";
cin >> dScore1;
cout << "请输入学生第2门课程成绩:";
cin >> dScore2;
cout << "请输入学生第3门课程成绩:";
cin >> dScore3;
dAveScore = (dScore1 + dScore2 + dScore3) / 3;
cout << "学号为" << nStudentID << "的学生的平均成绩为:" << dAveScore << endl;
return 0;
}