• cpp primer plus笔记07-内存模型和命名空间


    1. 对于相同变量名的变量,CPP会覆盖作用域大的变量,而使用作用域小的变量,如果想在函数体内使用全局的变量可以在变量名前加上::加以区分,比如warm=3会使得局部的warm变量等于3,而::warm=3会使得全局的warm=3 。
    2. 存储描述持续性作用域链接性声明举例
      自动变量自动代码块在代码块函数中int a = 0;
      静态,无链接性变量静态代码块在代码块函数中,使用关键字staticstatic int a = 0;(函数体内)
      静态,外部链接性变量静态文件外部不在任何函数内,放置在全局int a = 0;(全局)
      静态,内部链接性变量静态文件内部不在任何函数内,使用static声明static int a = 0;(全局)
    3. 静态外部链接性变量可以在不同文件中使用,但是只能有一个文件定义一个该变量,其他文件必须使用关键字extern声明改变量,例如extern int a;相同的变量名放置在不同文件全局,如果不使用以上方法的话,只能设置为一个是外部链接和一个是内部链接的变量。 4. 命名空间注意点: 命名空间可以是全局的,也可以位于另一个命名空间。
    	namespace element
    	{
    		namespace fire
    		{
    			int flame;
    		}
    		int water
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    命名空间具有传递性,如下图using namespace myth;等于using namespace elemet;加上using namespace myth;

    	namespace myth
    	{
    		using std::cout;
    		using std::cin;
    		using namespace element;		
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    可以给命名空间建立别名

    	namespace myth=very_myth_namespace;
    
    • 1

    可以通过一下方式简化对于嵌套命名空间的使用

    	namespace MEFF=myth::element::fire;
    	using MEF::flame;
    
    • 1
    • 2

    可以使用没有名字的命名空间

    	namespace 
    	{
    		int ice;
    	}
    
    • 1
    • 2
    • 3
    • 4

    可以在不同文件对同一命名空间添加相关数据,但是,但是如果有文件没有包含某个文件,但是包含其他和该文件一样命名空间的文件,那么是不能使用该文件的相关数据的。
    5. 定位new运算符可以从程序员选择的指定位置分配一块空间给变量,其作用是设置该变量的内存管理规程,处理需要通过特定地址进行访问的硬件或者在特定位置创建对象。

    	#include
    	#include
    	const int BUF = 512;
    	const int N = 5;
    	char buffer[BUF];
    	int main()
    	{
    		double* pd1, * pd2;
    		int i;
    		pd1 = new double[N];
    		pd2 = new (buffer) double[N];
    		for (int i = 0; i < N; ++i)
    		{
    			pd2[i] = pd1[i] = 1000 + 20.0 * i;
    		}
    		std::cout << "Memory addresses:\n";
    		std::cout << "heap: " << pd1 << " static:" << (void*)buffer << std::endl;
    		std::cout << "Memory contents:\n";
    		for (int i = 0; i < N; ++i)
    		{
    			std::cout << pd1[i] << " at " << &pd1[i] << "; ";
    			std::cout << pd2[i] << " at " << &pd2[i] << std::endl;
    		}
    		double* pd3, * pd4;
    		pd3 = new double[N];
    		pd4 = new (buffer) double[N];
    		for (int i = 0; i < N; ++i)
    		{
    			pd3[i] = pd4[i] = 1000 + 40.0 * i;
    		}
    		std::cout << "Memory contents:\n";
    		for (int i = 0; i < N; ++i)
    		{
    			std::cout << pd3[i] << " at " << &pd3[i] << "; ";
    			std::cout << pd4[i] << " at " << &pd4[i] << std::endl;
    		}
    		delete[] pd1;
    		pd1 = new double[N];
    		pd2 = new (buffer + N * sizeof(double)) double[N];
    		for (int i = 0; i < N; ++i)
    			pd2[i] = pd1[i] = 1000 + 60.0 * i;
    		std::cout << "Memory contents;\n";
    		for (int i = 0; i < N; ++i)
    		{
    			std::cout << pd1[i] << " at " << &pd1[i] << "; ";
    			std::cout << pd2[i] << " at " << &pd2[i] << std::endl;
    		}
    		delete[] pd1;
    		delete[] pd3;
    		return 0;
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    	Memory addresses:
    	heap: 000001AE8B4685E0 static:00007FF72FC9F440
    	Memory contents:
    	1000 at 000001AE8B4685E0; 1000 at 00007FF72FC9F440
    	1020 at 000001AE8B4685E8; 1020 at 00007FF72FC9F448
    	1040 at 000001AE8B4685F0; 1040 at 00007FF72FC9F450
    	1060 at 000001AE8B4685F8; 1060 at 00007FF72FC9F458
    	1080 at 000001AE8B468600; 1080 at 00007FF72FC9F460
    	Memory contents:
    	1000 at 000001AE8B468570; 1000 at 00007FF72FC9F440
    	1040 at 000001AE8B468578; 1040 at 00007FF72FC9F448
    	1080 at 000001AE8B468580; 1080 at 00007FF72FC9F450
    	1120 at 000001AE8B468588; 1120 at 00007FF72FC9F458
    	1160 at 000001AE8B468590; 1160 at 00007FF72FC9F460
    	Memory contents;
    	1000 at 000001AE8B468490; 1000 at 00007FF72FC9F468
    	1060 at 000001AE8B468498; 1060 at 00007FF72FC9F470
    	1120 at 000001AE8B4684A0; 1120 at 00007FF72FC9F478
    	1180 at 000001AE8B4684A8; 1180 at 00007FF72FC9F480
    	1240 at 000001AE8B4684B0; 1240 at 00007FF72FC9F488
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    定位new运算符将pd2放在buffer数组里面,但是程序会将buffer数组进行强制转换成(void *)。
    定位new运算符将不识别哪些内存单元已经被使用过,也不查找未使用的内存块,仅仅根据程序员分配的位置作为起始位置来分配地址
    delete只能处理指向常规new运算符分配的堆内存,而不处理定位new运算符,所以通过使用定位new运算符分配的空间不能使用delete处理。

  • 相关阅读:
    Apifox入门实用教程
    单例模式(常用)
    Windows如何启动MySQL
    9.20 校招 实习 内推 面经
    Java 版本任你发,我用Java8.(Java 15 新功能介绍 )
    迟到的秋招经验分享贴,希望能帮到大家
    wxFormBuilder + wxPython的wxListbook实现页面切换菜单
    CSS基础(超详解)
    SSM框架原理【超级详细】
    企业电子招投标采购系统——功能模块&功能描述+数字化采购管理 采购招投标
  • 原文地址:https://blog.csdn.net/LEVIATHANq/article/details/133648703