🌈个人主页:godspeed_lucip
🔥 系列专栏:《C++程序设计》阅读笔记
本文对应的PDF源文件请关注微信公众号程序员刘同学
,回复C++程序设计
获取下载链接。
- 1 程序结构
- 1.1 外部存储类型
- 1.2 静态存储类型
- 1.2.1 静态全局变量
- 1.2.2 静态函数
- 1.3 作用域
- 1.3.1 局部作用域
- 1.3.2 函数作用域
- 1.3.3 函数原型作用域
- 1.3.4 命名空间作用域
- 1.3.5 文件作用域
- 1.4 生命期
- 1.4.1 静态生命期
- 1.4.2 局部生命期
- 1.4.3 动态生命期
- 1.5 多文件结构
- 1.6 编译预处理
- 1.6.1 #include指令
- 1.6.2 #define(宏定义)指令
- 1.6.3 条件编译指令
- 2 总结
1 程序结构
1.1 外部存储类型
extern
关键字用于声明一个全局变量或函数,指示该变量或函数是在其他源文件中定义的,而不是当前文件中。主要的作用是告诉编译器在其他地方有该变量或函数的定义,从而防止出现重复定义错误。
注意:下面的示例中变量都是全局的。因此a在链接时,会发生两个地方都定义了a(多次定义)。假如file2.cpp中是extern int b,就不会报错。而由于两个文件中都是extern int c,都表示有一个int c在另外一个文件中,但是两个文件中都没有。因此会报错。
1.2 静态存储类型
1.2.1 静态全局变量
在全局变量前加一个 static,使该变量只在这个源文件中可用,称之为全局静态变量。(全局变量是所有文件都可以共享的)
全局静态变量就是静态全局变量
注意:
假设file1.cpp中有extern int c。且file2.cpp中有static int c。那么在链接时会报错,因为static int c是只可以供file2.cpp独享的
1.2.2 静态函数
函数的声明和定义默认情况下在整个程序中是外部(extern)的。
有时候,我们可能需要使某个函数只在一个源文件中有效,不能被其他源文件所用,这时在函数前面加上 static。
inline函数默认是static类型
1.3 作用域
1.3.1 局部作用域
稍微注意一下下面这两个例子:
特别关注一个例子:
注意a虽然是形式参数,在函数的开头,但是它是局部作用域,而不是函数作用域
1.3.2 函数作用域
即使一个局部变量被定义在函数的开头,这个局部变量也不会具有函数作用域。(准确来说,应该是这个局部变量具有一个从函数开头到函数结尾的块作用域)。
标号是唯一具有函数作用域的标识符(一般有goto语句使用)
1.3.3 函数原型作用域
在定义函数原型时,编译器只关心参数的类型,并不关心参数的名字
1.3.4 命名空间作用域
•例
namespace SomeNs {
class SomeClass { ... };
}
SomeNs::SomeClass obj1;
using语句有两种形式:
-
using 命名空间名::标识符名;
-
using namespace 命名空间名;
特殊的命名空间
-
全局命名空间:默认的命名空间(也就是说,当我们创建的变量、函数、类等不指定命名空间,那么它们就属于全局命名空间)
-
匿名命名空间:对每个源文件是唯一的。也就是不写出命名空间的名字
1.3.5 文件作用域
解释:就是整个cpp文件都可以用的。全局标识符的作用域是文件作用域(包括全局变量和静态全局变量)
头文件中包含的标识符的作用域也是文件作用域(#include<iostream>
)
1.4 生命期
1.4.1 静态生命期
这种生命期与程序的运行期相同,只要程序一开始运行,这种生命期的变量就存在。只有在整个程序结束时,它才会被释放。
全局变量、静态全局变量、静态局部变量都具有静态生命期。
注意:静态局部变量只对定义它的函数始终有效。静态全局变量对整个文件中的函数都有效
注意:静态局部变量是局部作用域,但是具有静态生命期
1.4.2 局部生命期
一般都是局部变量的生命期。所有具有局部生命期的变量都存储在栈区
1.4.3 动态生命期
存储在内存堆区。
一般使用malloc和new创建,并使用free何delete释放
手动创建、手动释放
1.5 多文件结构
多文件结构中,C++项目运行的示意图:
1.6 编译预处理
1.6.1 #include指令
#include<文件名>
这种格式用于嵌人 C++提供的头文件。这些头文件一般存于 C++系统目录中的include 子目录下。C++预处理器遇到这条指令后,就到 include 子目录下搜索给出的文件。并把它嵌入到当前文件中。这种方式是标准方式,
#nclude "文件名"
预处理器遇到这种格式的包含指令后,首先在当前文件所在目录中进行搜索,如果找不到,再按标准方式进行搜索。这种方式适合于规定用户自己建立的头文件
1.6.2 #define(宏定义)指令
基本上没有啥用了
1.6.3 条件编译指令
作用:一个源文件可能包含其中的几个头文件,这样会使得编译给出“一个符号重复定义多次”的错误。这时,需要在每个头文件中使用条件编译指令。
#ifdef DEBUG
// 只在定义了 DEBUG 宏时编译这部分代码
// 例如:gcc -DDEBUG myprogram.c
#endif
#ifndef NDEBUG
// 只在没有定义 NDEBUG 宏时编译这部分代码
#endif
#if defined(WIN32) || defined(_WIN32)
// 只在在Windows平台下编译这部分代码
#endif
2 总结
C++,犹如编程的交响乐, 在代码的海洋中奏响和谐的旋律。
它是创造者的笔,雕刻着无尽可能,
是思想的翅膀,让梦想飞翔的天空。
无拘无束,灵活多变。
C++,是程序员心中的宝藏,永不凋零的花朵。
渴望挑战C++的学习路径和掌握进阶技术?不妨点击下方链接,一同探讨更多C++的奇迹吧。我们推出了引领趋势的💻C++专栏:《C++程序设计》阅读笔记,旨在深度探索C++的实际应用和创新。🌐🔍