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