1、双冒号作用域运算符
::代表作用域 如果前面什么都不添加 代表全局作用域
代码语言:javascript复制int atk = 1000;
void test01()
{
int atk = 100;
cout << "atk =" << atk << endl;
//::代表作用域,如果前面什么都不加代表全局作用域
cout << "全局atk = " << ::atk << endl;
}
结果
atk =100 全局atk = 1000
2、namespace命名空间
- 命名空间用途:解决名称冲突
- 命名空间下可以存放 : 变量、函数、结构体、类…
- 命名空间必须要声明在全局作用域
- 命名空间可以嵌套命名空
- 命名空间是开放的,可以随时将新成员添加到命名空间下
- 命名空间可以匿名的
- 命名空间可以起别名
先写一个
为game1 的头文件
代码语言:javascript复制#include"game1.h"
void KingGlory::goAtk()
{
cout << "王者荣耀攻击我" << endl;
}
game2.h的头文件
代码语言:javascript复制#include <iostream>
using namespace std;
namespace LOL
{
void goAtk();
}
game1.c的文件
代码语言:javascript复制#include"game1.h"
void KingGlory::goAtk()
{
cout << "王者荣耀攻击我" << endl;
}
game2.c的文件
代码语言:javascript复制#include"game2.h"
void LOL::goAtk()
{
cout << "LOL攻击我" << endl;
}
代码语言:javascript复制#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
#include "game1.h"
#include "game2.h"
// 1.命名空间用途:解决名称冲突
void test01()
{
KingGlory::goAtk();
LOL::goAtk();
}
//2.命名空间下可以放 变量 函数 结构体 类
namespace A
{
int m_A;
void func();
struct Person
{};
class Animal
{};
}
//3.命名空间 必须声明在全局作用域下
void test02()
{
// namespace B{} 不可以命名到局部作用域
}
//4.命名空间可以嵌套命名空间
namespace B
{
int m_A = 10;
namespace C
{
int m_A = 20;
}
}
//5.命名空间是开放的,可以随时给命名空间添加新成员,重名的命名空间是进行合并操作,而不是覆盖操作
namespace B
{
int m_B = 100;
}
void test04()
{
cout << "B空间下的m_A = " << B::m_A << endl;
cout << "B空间下的m_B = " << B::m_B << endl;
}
void test03()
{
cout << "B空间下的m_A = " << B::m_A << endl;
cout << "C空间下的m_A = " << B::C::m_A << endl;
}
//6.命名空间是可以匿名的
namespace
{
int m_C = 1000;
int m_D = 2000;
}
void test05()
{
cout << "m_C" << m_C << endl;
cout << "m_D" << m_D << endl;
}
//7.命名空间可以起别名
namespace longName
{
int m_E = 10;
}
void test06()
{
namespace LN = longName;
cout << "longName:" << longName::m_E << endl;
cout << "LN:" << LN::m_E << endl;
}
3、using声明以及using编译指令
using 声明
代码语言:javascript复制#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
using namespace std;
namespace KingGlory
{
int sunwukongId = 1;
}
void test01()
{
cout << KingGlory::sunwukongId << endl;
using KingGlory::sunwukongId;
cout << sunwukongId << endl;
}
void test02()
{
int sunwukongId = 2;
//2.当using编译指令和就近原则同时出现的时候会优先使用就近原则
using namespace KingGlory;
cout << sunwukongId << endl;
}
在test02中先使用就近原则,所以输出为当using声明与 就近原则同时出现,出错,尽量避免
using编译指令
- using namespace KingGlory;
- 当using编译指令 与 就近原则同时出现,优先使用就近
- 当using编译指令有多个,需要加作用域 区分
4、C 对C语言的增强
-
- 全局变量检测增强
- int a ;
- int a = 10; C下可以,C 重定义
- 函数检测增强
- 函数的返回值
- 形参类型
- 函数调用参数个数
- 类型转换检测增强
- char * p = (char *)malloc(64) C 下必须等号左右一致类型
- struct 增强
- C 可以在结构体中放函数
- 创建结构体变量 可以简化关键字struct
- bool数据类型扩展
- C 才有bool类型
- 代表真 --- 1 true 假 ---- 0 false
- sizeof = 1
- 三目运算符增强
- C语言下返回的是值
- C 语言下返回的是变量
- const增强
- C语言下
- 全局const 直接修改 失败 间接修改 语法通过,运行失败
- 局部 const 直接修改 失败 间接修改 成功
- C 语言下
- 全局 const 和C结论一样
- 局部 const 直接修改失败 间接修改 失败
- C const可以称为常量
- C语言下
- 全局变量检测增强
4、const链接属性
- C语言下const修饰的全局变量默认是外部链接属性
- C 下const修饰的全局变量默认是内部链接属性,可以加extern 提高作用域
#define _CRT_SECURE_NO_WARNINGS 1
#include <bits/stdc .h>
using namespace std;
//1、对const取地址,会分配零时内存
void test01()
{
const int a = 10;
int* p = (int*)&a;
}
//2、使用普通变量初始化const,可以修改
void test02()
{
int a = 10;
const int b = 10;
int* p =(int *) & b;
*p = 1000;
cout << "b = " << b << endl;
}
// 3、对于自定义数据类型
struct Person
{
string m_name;
int m_Age;
};
void test03()
{
const Person p;
Person * pp = (Person*)&p;
pp->m_name = "Tom";
pp->m_Age = 10;
}
5、const分配内存情况
-
- 对const变量 取地址 ,会分配临时内存
- 使用普通变量 初始化 const变量
对于自定义数据类型
代码语言:javascript复制#define _CRT_SECURE_NO_WARNINGS 1
#include <bits/stdc .h>
using namespace std;
//1、对const取地址,会分配零时内存
void test01()
{
const int a = 10;
int* p = (int*)&a;
}
//2、使用普通变量初始化const,可以修改
void test02()
{
int a = 10;
const int b = 10;
int* p =(int *) & b;
*p = 1000;
cout << "b = " << b << endl;
}
// 3、对于自定义数据类型
struct Person
{
string m_name;
int m_Age;
};
void test03()
{
const Person p;
Person * pp = (Person*)&p;
pp->m_name = "Tom";
pp->m_Age = 10;
}
6、尽量用const代替define
define出的宏常量,没有数据类型、不重视作用域
7、引用
- 目的:起别名
- 语法: 类型(与原名类型必须一致) &别名 = 原名
- 引用必须要初始化
- 引用一旦初始化后,就不可以引向其他变量
- 建立对数组引用
- 直接建立引用
- int arr[10];
- int(&pArr)[10] = arr;
- 先定义出数组类型,再通过类型 定义引用
- typedef int(ARRAY_TYPE)[10];
- ARRAY_TYPE & pArr2 = arr;
#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
using namespace std;
//1.引用的基本作用是起别名
void test01()
{
int a = 10;
int& b = a;
b = 100;
cout << "a = " << a << endl;
cout << "b = " << b << endl;
}
void test02()
{
int a = 10;
// int &b; 引用必须初始化
int& b = a;
// 引用一旦初始化,就不可以引向其他变量
int c = 100;
b = c;
cout << "a = " << a << endl;
cout << "b = " << b << endl;
cout << "c = " << c << endl;
}
void test03()
{
//1、直接建立引用
int arr[10]={0};
int(&pArr)[10] = arr;
for (int i = 0; i < 10; i )
{
arr[i] = 100 i;
}
for (int i = 0; i < 10; i )
{
cout << pArr[i] << endl;
}
}
test01的结果
test02的结果
test03的结果
常量的引用
代码语言:javascript复制#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
using namespace std;
void test01()
{
//int &ref = 10;
const int& ref = 10; //加了const之后,相当于写成int temp = 10;const int &ref = temp
int* p = (int*)&ref;
*p = 1000;
cout << ref << endl;
}
void showValue(const int& a)
{
cout << "a = " << a << endl;
}
//常量引用的使用场景:修饰函数的形参防止无操作
void test02()
{
int a = 100;
showValue(a);
cout << "a = " << a << endl;
}
指针的引用
代码语言:javascript复制#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
using namespace std;
struct Person
{
int age;
};
void allocateSpace(Person** p)
{
//p指向 指针的指针 *p 指针指向的是person本体 **p person本体
*p = (Person*)malloc(sizeof(Person));
(*p)->age = 10;
}
void test01()
{
Person* p = NULL;
allocateSpace(&p);
cout << "p.age = " << p->age << endl;
}
void allocateSpace2(Person*& pp) //Person * pp = p
{
pp = (Person*)malloc(sizeof(Person);
pp->age = 20;
}
void test02()
{
Person* p = NULL;
allocateSpace(p);
cout << "p.age = " << p->age << endl;
}
test01的结果
test02的结果