目录
2.引用
1.命名空间
在C语言中,多人一起开发一个工程时经常会出现你使用的全局变量名和我使用的全局变量名重名了的情况。C++为了解决这个问题,引入了命名空间的概念,关键字为:namespace
正常命名空间的定义:
//zh为自己给这块命名空间取的名字
namespace zh
{
// 命名空间中可以定义变量/函数/类型
int rand = 10;
int Add(int left, int right)
{
return left + right;
}
struct Node
{
struct Node* next;
int val;
};
}
//2. 命名空间可以嵌套
//test.cpp
namespace N1
{
int a;
int b;
int Add(int left, int right)
{
return left + right;
}
namespace N2
{
int c;
int d;
int Sub(int left, int right)
{
return left - right;
}
}
}
//3. 同一个工程中允许存在多个相同名称的命名空间,编译器最后会合成同一个命名空间中。
// ps:一个工程中的test.h和上面test.cpp中两个N1会被合并成一个
// test.h
namespace N1
{
int Mul(int left, int right)
{
return left * right;
}
}
命名空间的使用:
#include<iostream>
using namespace std;
namespace zh
{
// 命名空间中可以定义变量/函数/类型
int a = 0;
int b = 1;
int Add(int left, int right)
{
return left + right;
}
struct Node
{
struct Node* next;
int val;
};
}
//命名空间中的变量的使用方法是在变量前面加 命名空间名::
int main()
{
//a = 1//报错,找不到a这个变量
zh::a = 1;//没问题,zh中的a被改成1了
int c = zh::Add(zh::a, zh::b);//c为1 + 1即2
//注意使用命名空间中的结构体类型创建结构体变量时,
//需要在结构体名字前加zh::
struct zh::Node a;
//这里结构体a前面不需要加zh::,因为a是在main函数这个作用域中创建的,
//不属于zh这个命名空间中的变量.
a.next = nullptr;
a.val = 0;
return 0;
}
有时候命名空间中的变量需要大量使用,而且该命名空间中的变量很难与外面全局变量重名,就可以考虑使用using,具体用法如下:
#include<iostream>
using namespace std;
namespace zh
{
// 命名空间中可以定义变量/函数/类型
int a = 0;
int b = 1;
int Add(int left, int right)
{
return left + right;
}
struct Node
{
struct Node* next;
int val;
};
}
//1.使用using将命名空间中某个成员引入
using zh::a;//相当于把命名空间zh中的a展开成全局变量
int main()
{
a = 1;//zh中的a就可以不加命名空间名修饰了
a++;
zh::a++;//当然使用zh修饰也没任何问题
return 0;
}
//2.使用using namespace 命名空间名称 引入
using namespace zh;//代表zh中的所有东西都展开到全局
int main()
{
printf("%d\n", zh::a);
printf("%d\n", b);
Add(10, 20);
return 0;
}
2.引用
引用是一种类型,相当于给一个变量取别名,话不多说上代码:
int main()
{
int a = 0;
//这里b是a的引用,就类似C语言中的指针,不过指针存的是地址,需要开四字节的空间
//而C++中的引用我们则认为没有开空间,这里b就相当于a的别名,b和a是同一个东西,
//就类似鲁迅和周树人都是同一个人,只不过名字不同
int& b = a;
b = 1;//b改成1,那a就也变成1,因为它们两是同一个东西,只不过名字不同
int& c = b;//c是b的别名,那当然也是a的别名;c,b,a都是同一个东西
c = 2;//c改了那a和b也都跟着改了
int& d;//这句会报错,C++规定引用必须初始化,也没有空引用这个类似于空指针的概念
//这句的意思是a的内容不能通过e这个别名改变,相当于e这个别名的权限缩小了
//但是a,b,c还是能改变,并且e会随着它们变
const int& e = a;
return 0;
}
不过我们认为b并没有开空间这其实只是方便我们理解,实际上b还是开了空间的,看汇编
看汇编代码实际上引用c和指针pb都开了四字节的空间,它们的使用方法不同,各有各的优点;
注意:引用不能像指针一样改引用的对象,引用的对象一单确定就不能更改.
引用和指针的不同点:
1. 引用概念上定义一个变量的别名,指针存储一个变量地址。
2. 引用在定义时必须初始化,指针没有要求
3. 引用在初始化时引用一个实体后,就不能再引用其他实体,而指针可以在任何时候指向任何一个同类型 实体
4. 没有NULL引用,但有NULL指针
5. 在sizeof中含义不同:引用结果为引用类型的大小,但指针始终是地址空间所占字节个数(32位平台下占 4个字节)
6. 引用自加即引用的实体增加1,指针自加即指针向后偏移一个类型的大小
7. 有多级指针,但是没有多级引用
8. 访问实体方式不同,指针需要显式解引用,引用编译器自己处理
9. 引用比指针使用起来相对更安全
3.auto关键字
C++11中,标准委员会赋予了auto全新的含义即:auto不再是一个存储类型指示符,而是作为一个新的类型 指示符来指示编译器,auto声明的变量必须由编译器在编译时期推导而得
int TestAuto()
{
return 10;
}
int main()
{
int a = 10;
auto b = a;
auto c = 'a';
auto d = TestAuto();
cout << typeid(b).name() << endl;
cout << typeid(c).name() << endl;
cout << typeid(d).name() << endl;
//auto e; 无法通过编译,使用auto定义变量时必须对其进行初始化
return 0;
}
auto的使用细则
1. auto与指针和引用结合起来使用 用auto声明指针类型时,用auto和auto*没有任何区别,但用auto声明引用类型时则必须加&
int main()
{
int x = 10;
auto a = &x;
auto* b = &x;
auto& c = x;
cout << typeid(a).name() << endl;
cout << typeid(b).name() << endl;
cout << typeid(c).name() << endl;
*a = 20;
*b = 30;
c = 40;
return 0;
}
2.auto不能推导的场景
1. auto不能作为函数的参数
// 此处代码编译失败,auto不能作为形参类型,因为编译器无法对a的实际类型进行推导
void TestAuto(auto a)
{}
2. auto不能直接用来声明数组
void TestAuto()
{
int a[] = {1,2,3};
auto b[] = {4,5,6};
}
以上就是全部内容,如有错误请一定要指出!