文章目录
第1章
第2节 C++开发环境与相关工具
C++开发工具:
/usr/bin/time
+运行程序 打印花费的时间和CPU占用率等(Linux)- valgrind
- cppreference.com 网站(C++百科全书)
- Complier Explorer 网站(选择编译器、查看程序对应的汇编)
- C++ insights 网站 代码等价变换 便于程序理解
- Youtube cppcon会议
第3节 C++的编译/链接模型
分块处理:
衍生出的概念:
-
定义/声明: 多个文件使用同一变量,在一处定义,其他文件声明,声明处编译时不查找变量,链接时去查找变量建立链接
-
头文件/源文件:多个文件需要使用同一个变量时,将声明放在一个头文件中,其他源文件引用头文件,编译时会展开头文件,提升写代码的效率
-
翻译单元
- 源文件 + 相关头文件 (直接/间接)- 应忽略的预处理语句 (每个编译器处理的就为一个翻译单元)
-
一处定义原则:同一变量、对象、函数等只有一处定义
- 程序级:一般函数
- 翻译单元级:内连函数、类、模板
预处理
- 将源文件转换为翻译单元
- 防止头文件被***循环展开***(多个头文件互相嵌套,导致头文件一直循环展开)
#ifdef
解决 (可能有名字冲突)#pragma once
解决 (只处理一次)
编译
-
将翻译的那远转换为相应的汇编语言表示
-
编译***优化***
- https://godbolt.org/z/zh9aqx (优化后不能打断点分步调试,但是能提升程序的性能,通常编译分为Debug版本和Release版本,调试结束后使用Release版本重新编译以提升程序性能)
-
增量编译 V.S. 全部编译
链接
- 合并多个目标文件,关联声明和定义
- 连接(Linkage)种类:内部链接、外部链接
- 链接常见错误:找不到定义
第2章
第1节 HelloWorld
获取main函数的返回值语句:echo $?
C++如果没有return值,规定默认返回0。
main只有两种形式:
int main()
int main(int argc,char* argv[])
第2节 系统IO
#include "文件名"
从***当前文件目录***开始寻找,若找不到再从系统目录开始寻找
#include <文件名>
从系统目录开始寻找
(若不确定则使用双引号)
若自己编写头文件加.h后缀,C++标准库没有后缀
输入输出流 iostream
输出流: cout cerr clog
cout
和cerr
在终端打印出显示相同,可以输出定向到不同的文件当中
例如:
./HelloWorld >txt1 2>txt2 //输出到不同的文件
cat ./txt1 //查看不同的文件
cat ./txt2
输出流区别:1.输出目标;2是否立即刷新缓冲区
cerr
错误信息,立即刷新缓冲区
clog
日志信息,不立即刷新缓冲区
刷新缓冲区:std::flush
std::endl
(刷新缓冲区并且换行)
命名空间 namespace
目的:防止不同人写的多段代码有命名冲突
//定义:
namespace NameSpace1{
void fun(){
}
}
//调用1:
NameSpace1::fun();
//调用2:
using namespace NameSpace1;
//调用3:
namespace ns1 = NameSpace1;
ns1::fun();
不推荐在函数外部使用using namespace
,不应在头文件中使用using namespace
,因为所有引用头文件的源文件都有命名冲突的风险
std
标准名字空间
编译得到的.o文件,通过nm + 文件名
命令查看所有外部链接
nm ./main.o
命名空间和名称改编:name mangling
nm ./main.o | c++filt -t
程序中只有一个main函数,所以只有main函数命名改编
使用printf
等C语言输入输出函数时要#include <cstdio>
printf
使用比较直观,但是需要对应不同数据类型要对应不同的占位符。
cout
使用简单不需要占位符,能够自动匹配输出类型。
第3节 猜数字与控制流
const int x = 42;
定义x为常量,不能被改变值
第4节 结构体与自定义数据类型
将相关数据放在一起,通过.来访问元素
定义结构体 struct + 名字
通过.
操作符访问结构体内部元素
引入成员函数,更好表示函数与数据的相关性