- 对于相同变量名的变量,CPP会覆盖作用域大的变量,而使用作用域小的变量,如果想在函数体内使用全局的变量可以在变量名前加上::加以区分,比如warm=3会使得局部的warm变量等于3,而::warm=3会使得全局的warm=3 。
-
存储描述 持续性 作用域 链接性 声明 举例 自动变量 自动 代码块 无 在代码块函数中 int a = 0; 静态,无链接性变量 静态 代码块 无 在代码块函数中,使用关键字static static int a = 0;(函数体内) 静态,外部链接性变量 静态 文件 外部 不在任何函数内,放置在全局 int a = 0;(全局) 静态,内部链接性变量 静态 文件 内部 不在任何函数内,使用static声明 static int a = 0;(全局)
namespace element{namespace fire{int flame;}int water}
命名空间具有传递性,如下图using namespace myth;等于using namespace elemet;加上using namespace myth;
namespace myth{using std::cout;using std::cin;using namespace element; }
可以给命名空间建立别名。
namespace myth=very_myth_namespace;
可以通过一下方式简化对于嵌套命名空间的使用
namespace MEFF=myth::element::fire;using MEF::flame;
可以使用没有名字的命名空间
namespace {int ice;}
可以在不同文件对同一命名空间添加相关数据,但是,但是如果有文件没有包含某个文件,但是包含其他和该文件一样命名空间的文件,那么是不能使用该文件的相关数据的。
5. 定位new运算符可以从程序员选择的指定位置分配一块空间给变量,其作用是设置该变量的内存管理规程,处理需要通过特定地址进行访问的硬件或者在特定位置创建对象。
#include<iostream>#include<new>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;}
Memory addresses:heap: 000001AE8B4685E0 static:00007FF72FC9F440Memory contents:1000 at 000001AE8B4685E0; 1000 at 00007FF72FC9F4401020 at 000001AE8B4685E8; 1020 at 00007FF72FC9F4481040 at 000001AE8B4685F0; 1040 at 00007FF72FC9F4501060 at 000001AE8B4685F8; 1060 at 00007FF72FC9F4581080 at 000001AE8B468600; 1080 at 00007FF72FC9F460Memory contents:1000 at 000001AE8B468570; 1000 at 00007FF72FC9F4401040 at 000001AE8B468578; 1040 at 00007FF72FC9F4481080 at 000001AE8B468580; 1080 at 00007FF72FC9F4501120 at 000001AE8B468588; 1120 at 00007FF72FC9F4581160 at 000001AE8B468590; 1160 at 00007FF72FC9F460Memory contents;1000 at 000001AE8B468490; 1000 at 00007FF72FC9F4681060 at 000001AE8B468498; 1060 at 00007FF72FC9F4701120 at 000001AE8B4684A0; 1120 at 00007FF72FC9F4781180 at 000001AE8B4684A8; 1180 at 00007FF72FC9F4801240 at 000001AE8B4684B0; 1240 at 00007FF72FC9F488
定位new运算符将pd2放在buffer数组里面,但是程序会将buffer数组进行强制转换成(void *)。
定位new运算符将不识别哪些内存单元已经被使用过,也不查找未使用的内存块,仅仅根据程序员分配的位置作为起始位置来分配地址
delete只能处理指向常规new运算符分配的堆内存,而不处理定位new运算符,所以通过使用定位new运算符分配的空间不能使用delete处理。