一、单独编译

头文件

不要将函数定义或者变量声明放到头文件中,引入多个文件时可能会造成同一个函数定义多次

引入头文件

  1. #include "文件名"

File1.h

  1. #ifndef FILE1_H_
  2. #define FILE1_H_
  3. struct Student
  4. {
  5. int age;
  6. };
  7. #endif // !FILE1_H_

File2.h

  1. #include "File1.h"

main.cpp

  1. #include<iostream>
  2. #include "File1.h"
  3. #include "File2.h"
  4.  
  5. using namespace std;
  6.  
  7. void main() {
  8. Student stu = {};
  9. cout << stu.age << endl;
  10. }

这里的

  1. #ifndef FILE1_H_
  2.  
  3. .....code
  4. #endif

如果File2.h引入了头文件File1.h,并且main.cpp 同时引入了File1和File2两个头文件,这样会导致 Stuendt 会引入两回,编译器遇到这种情况会报编译错误。有了ifndef就会忽略重复引入的问题。

这里的

  1. #define FILE1_H_

当以前没有使用预处理器编译指令#define定义的名称 FILE1_H_时,才处理#ifndef #endif之间的语句。

2.

预编译会把.cpp 引用的头放入 cpp代码中

例如 file1.cpp file2.cpp 都包含了 test.h 则,test.h的代码即会添加到file1文件,也会添加到file2文件。

二、作用域

作用域:变量等的使用范围。

链接性:外部链接性(变量作用范围)可在文件间共享---全局变量,内部链接性只在当前文件中,无链接性只能在当前函数或代码块中---局部变量。

1.自动变量

函数内声明的变量,作用域只在函数内。

如果代码块内部的变量名和外部的变量名相同,则内部变量作用在内部,外部变量作用在外部

  1. auto a = ; //C++11后相当于 c# var

这种变量存在栈中

2.静态变量

静态变量生命周期比自动变量的寿命更长,静态变量的数目在程序运行期间是不变的,所以不需要栈来管理,编译器会分配固定的内存块来存储它们,默认初始化为0。

(1).如果想有外部链接性的静态变量

必须在外部声明,并且不带static

(2).如果想有内部链接性的静态变量

必须在外部声明,并且带static

(3).如果想有无链接性的静态变量

必须在代码块内部声明,并且带static

  1. #include<iostream>
  2. using namespace std;
  3. int g = ;//具有外部链接性的静态函数
  4. int static a = ;//具有内部链接性的静态函数
  5. void main() {
  6.  
  7. }
  8. void func() {
  9. int static b = ;//无链接性的静态函数
  10. int c = ;//自动变量,
  11. }

 3.静态和外部

(1)单定义规则:整个程序中全局变量只能定义一次。

C++有两种变量声明,1是定义声明(简称定义)给变量分配内存空间,2是引用声明(简称声明)不给变量分配内存空间因为它引用已有的变量。

使用extern关键字并且不初始化,表示引用声明。用来表示该变量是来自外部的全局变量

  1. int a = ;//定义声明
  2. extern int b = ; //定义声明,因为进行了初始化
  3. extern int c;//这是真正的引用声明,不分配内存

(2) 如果在文件中声明了一个与外部同名的变量,则该变量属于自动变量

main.cpp

  1. #include<iostream>
  2. using namespace std;
  3. int a = ;
  4. void main() {
  5.  
  6. }

test.cpp

  1. void func1() {
  2. extern int a;//全局变量
  3. }
  4.  
  5. void func2() {
  6. int a;//自动变量
  7. }

4.静态与内部 5.静态与无链接 略

6.说明符和限定符

volatile、mutable 待补

const

被const修饰的全局变量会变成内部链接性

  1. const int a = ;//内部链接性
  2. void main() {
  3.  
  4. }

7.函数和链接性

C++的链接性为静态的,整个程序执行期间都一直存在。

static 修饰函数可以让函数变成内部的,前提是原型和函数定义必须都加上static

8.语言链接性

C++中查询C++库函数和查询C库的方式不同。要区分它们

  1. extern "C" void fun1();//原型,使用C语言方式查找函数
  2. extern "C++" void fun2();//原型,使用C++方式查找函数
  3. extern void fun3();//原型,默认使用C++方式查找函数

9.动态存储

动态分配的内存由new和delet控制,而不是作用域和链接性的规则控制。

编译器通常使用三块独立内存:静态变量、自动变量、动态存储。(可能会细分)

定位new运算符??

定位new一帮用于以下场合

  1. 硬件编程

    如果知道了硬件设备的地址,想要将那个硬件设备与一个C++类直接关联,那么定位new就非常有效了

  2. 实现基础库

    基础库一般为了效率要先预分配内存,然后在预分配的内存上执行构造,几乎所有的C++容器都用到了定位new

三、名称空间

1.C++传统的名称空间

作用域

2.C++名称空间新特性

(1)using声明可以使用单个变量和函数

using声明后在该区域内有效

  1. #include<iostream>
  2. using namespace std;
  3. namespace space1{
  4. int a=;
  5. }
  6. namespace space2 {
  7. int a=;
  8. }
  9. void main() {
  10.  
  11. cout << space1::a;//直接使用
  12. using space2::a;//using声明,避免每次调用时都要加::
  13. cout << a;
  14. }

在外部使用using声明

  1. using space2::a;
  2. void main() {
  3.  
  4. cout << a;//属于space2
  5. }
  6.  
  7. void func1() {
  8. cout << a; //属于space2
  9. }

(2)using 编译可以使用空间下的所有变量和函数

  1. using namespace space2;//使用using编译
  2.  
  3. void main() {
  4.  
  5. cout << a;//使用space2下
  6. }
  7. void func1() {
  8. cout << b; //使用space2下
  9. }

如果using编译指令导入一个已经在函数中声明的名称,则会使用局部定义的变量

  1. void main() {
  2. using namespace space2;//
  3. int a = ;
  4. cout << a;//结果 9
  5. }

如果using声明导入一个已经在函数中声明的名称,会报多重错误

  1. void main() {
  2. using space2::a;//
  3. int a = ;
  4. cout << a;//结果 9
  5. }

全局 ::

  1. #include<iostream>
  2. using namespace std;
  3. int a=;
  4. namespace space1 {
  5. int a = ;
  6. int b = ;
  7. }
  8.  
  9. void main() {
  10. using namespace space1;
  11. int a = ;
  12. cout << ::a;//全局的a 结果8
  13. }

尽量使用using声明减少不必要的麻烦

3.名称空间嵌套

4.未命名名称空间

5.名称空间开放性

几个文件都使用namespace 里面的内容可以组合在一起?

6.多文件

(8)C++ 内存模型与名称空间的更多相关文章

  1. 《C++ Primer Plus》读书笔记之七—内存模型和名称空间

    第九章 内存模型和名称空间 1.不要将函数定义或者变量声明放到头文件中. 2.头文件常包含的内容:函数原型.使用#define或者const定义的常量.结构声明.类声明.模板声明.内联函数. 3.避免 ...

  2. C++ primer plus读书笔记——第9章 内存模型和名称空间

    第9章 内存模型和名称空间 1. 头文件常包含的内容: 函数原型. 使用#define或const定义的符号常量. 结构声明. 类声明. 模板声明. 内联函数. 2. 如果文件名被包含在尖括号中,则C ...

  3. 《C++ Primer Plus》第9章 内存模型和名称空间 学习笔记

    C++鼓励程序员在开发程序时使用多个文件.一种有效的组织策略是,使用头文件来定义用户类型,为操纵用户类型的函数提供函数原型,并将函数定义放在一个独立的源代码文件中.头文件和源代码文件一起定义和实现了用 ...

  4. [C++ Primer Plus] 第9章、内存模型和名称空间(一)程序清单

    程序清单9.9(静态存储连续性.无链接性) #include<iostream> using namespace std; ; void strcount(const char *str) ...

  5. 《C++ Primer Plus 6th》读书笔记 - 第九章 内存模型和名称空间

    1. 单独编译 1.1 头文件中常包含的内容: 函数原型 使用#define或const定义的符号常量 结构声明 类声明 模板声明 内联声明 1.2 只需将源代码文件加入到项目中,而不用加入头文件.这 ...

  6. C++学习 内存模型和名称空间

    1.单独编译 C++鼓励程序员将组件函数放在独立的文件中,如果只修改了一个文件,则可以只重新编译该文件,然后将它与其他文件的编译版本链接. 一般非常有用的组织程序的策略是把程序分成三部分: 头文件:包 ...

  7. C++ Primer Plus读书笔记(九)内存模型和名称空间

    1.作用域和链接 int num3; static int num4; int main() { } void func1() { static int num1; int num2; } 上边的代码 ...

  8. [C++ Primer Plus] 第9章、内存模型和名称空间(二)课后习题

    一.复习题 2.using声明和using编译指令的区别 using声明: using std::cin; using std::cout; using std::endl; using编译指令:us ...

  9. python基础之函数对象,嵌套,名称空间和作用域

    函数对象: 函数是第一类对象的含义是函数可以被当作数据处理 函数可用于: def func(): print(‘func’) 1.引用  f = func  把内存地址赋值给f 2.当作参数传给一个函 ...

随机推荐

  1. 2018-2019 2 20165203 《网络对抗技术》Exp7 网络欺诈防范

    2018-2019 2 20165203 <网络对抗技术>Exp7 网络欺诈防范 实验目的 本实践的目标理解常用网络欺诈背后的原理,以提高防范意识,并提出具体防范方法. 实验内容 (1)简 ...

  2. AST7D08 心率计

    接线: 1.GND 2.+3.3V 3.RST 4. 5.CS 6.READY 7.DI 8.DO 9.CLK

  3. 108、TensorFlow 类型转换

    # 除了维度之外Tensorflow也有数据类型 # 请参考 tf.DataType # 一个张量只能有一个类型 # 可以使用tf.cast,将一个张量从一个数据类型转换到另一个数据类型 # 下面代码 ...

  4. iOS OpenGL ES简单绘制纹理

    OpenGL 中任何复杂的图形都是由点,线 和三角形组成的. 那么一个矩形 就需要有两个三角形组成. 纹理, 可以理解为一张图片, 我么可以将整张or部分图片绘制到圆形, 矩形等目标图形中. 下图表示 ...

  5. 练习1-20 编写程序detab,将输入中的制表符替换成适当数目的空格.

    1.问题描述 编写程序detab,将输入中的制表符替换成适当数目的空格,使空格充满到下一个制表符终止位的地方. 假设制表符终止位的位置是固定的, 换句话说每隔n列就会出现一个制表符终止位. 2.描述 ...

  6. python3+django2 个人简单博客实现 -正在施工

  7. 洛谷P3366 【模板】最小生成树(LCT)

    [模板]最小生成树 题目传送门 解题思路 用LCT来维护最小生成树. 除了把各顶点作为节点外,每条边也都视为一个节点.对于要加入的边\(e\),检查其两顶点\(x\)和\(y\)是否在同一棵树中,如果 ...

  8. LeetCode 求众数 II

    题目链接:https://leetcode-cn.com/problems/majority-element-ii/ 题目大意: 略. 分析: k个一起删, 最后check一下即可. 代码如下: #d ...

  9. js运算符的优先级的顺序列表

    优先级权重 运算符 17 ..[].new 16 () 15 ++.-- 14 !.~.+(单目).-(单目).typeof.void.delete 13 %.*./ 12 +(双目).-(双目) 1 ...

  10. shell整数测试