命名空间
在C语言当中,我们知道命名是不能重复的,那么写代码的时候很容易遇到这种问题,引头文件的时候,里面会包含很多库函数,有些时候我们并不是很了解这个头文件里面有什么库函数,这时候如果我们自定义的函数或者是变量和库函数的命名冲突就很令人头疼,有时候想名字都要想半天,C++当中namespace关键字的出现就是针对这种问题的。
例:
rand是随机值的函数名,所以报错是rand重定义,也就是命名冲突。
使用命名空间的目的是对标识符的名称进行本地化, 以避免命名冲突或名字污染。
定义
正常的命名空间定义
#include <stdio.h> #include <stdlib.h> namespace baiye//baiye是命名,这里也不能有命名冲突的情况,比如这里用rand进行命名就会与头文件stdlib.h中的rand函数名冲突 { int rand = 10;//这些定义的变量,函数,类型等等就是baiye的成员 int add(int x, int y) { return x + y; } struct app { int a; int* p; struct app* next; }; }
注意定义在函数中才是局部变量,这里并不是局部变量,是全局变量,并不影响生命周期,只是被限制查找。
命名空间的嵌套
namespace N1 { int rand = 10; int add(int x, int y) { return x + y; } namespace N2 { int x = 20; } }
命名空间的合并
同一个工程中允许存在多个相同名称的命名空间,编译器最后会合成同一个命名空间中。
//test.cpp namespace N1 { int rand = 10; int add(int x, int y) { return x + y; } }
//test.h namespace N1 { int x = 20; }
当程序运行起来之后就是这样的:
namespace N1 { int rand = 10; int add(int x, int y) { return x + y; } int x = 20; }
注意:一定要命名空间的名字相同且在同义级才可以。上面的嵌套两个命名空间就不是同一级。
注意:一个命名空间就定义了一个新的作用域,命名空间中的所有内容都局限于该命名空间中。命名空间是限定域。
命名空间只能影响查找规则,查找是局部优先,然后才是全局查找,在命名空间的话需要指定的方式去查找。
命名空间的使用
命名空间就像在整个程序中在某个空间盖起了一个房子,然后加了一把锁,防止房子里面的成员命名与外面冲突,如果我们要访问就需要去开锁。
::是域作用限定符,前面加上命名空间的域名,后面是这个域中你要访问的成员,如果不加就是全局查找
加命名空间名称及作用域限定符
#include <stdio.h> #include <stdlib.h> namespace N1 { int rand = 10; int add(int x, int y) { return x + y; } } int main() { printf("%d\n", N1::rand);//在这里N1::就相当于命名空间N1这个域的钥匙一样 return 0; }
使用using将命名空间中某个成员引入
#include <stdio.h> #include <stdlib.h> namespace N1 { int x = 10; int y = 20; int add(int x, int y) { return x + y; } } using N1::x;//这里就像域N1中的x走出了房子,所以x和全局变量没有区别了,也不会被限制查找 int main() { printf("%d\n", N1::y); printf("%d\n", x); return 0; }
使用using namespace 命名空间名称 引入
#include <stdio.h> #include <stdlib.h> namespace N1 { int x = 10; int y = 20; int add(int x, int y) { return x + y; } } using namespace N1;//这个相当于把N1这个房子给拆了,成员都成为了不被限制搜索的全局变量 int main() { printf("%d\n", y); printf("%d\n", x); return 0; }
C++输入&输出
#include <iostream> //std是C++标准库的命名空间名,C++将标准库的定义实现都放到这个命名空间中 using namespace std;//把标准库直接展开,使用cout等方便,不然就要std::cout,很麻烦 int main() { cout << "Hello world!!!" << endl; return 0; }
说明:
- 使用cout标准输出对象(控制台)和cin标准输入对象(键盘)时,必须包含< iostream >头文件以及按命名空间使用方法使用std。
- cout和cin是全局的流对象,endl是特殊的C++符号,表示换行输出,他们都包含在包含< iostream >头文件中。
- <<是流插入运算符,>>是流提取运算符。
- 使用C++输入输出更方便,不需要像printf/scanf输入输出时那样,需要手动控制格式。C++的输入输出可以自动识别变量类型。
- 实际上cout和cin分别是ostream和istream类型的对象,>>和<<也涉及运算符重载等知识,这里先不过多解释
这里就是将你要输入或者是打印的东西插入流中,包括换行等等操作也是插入流中,要注意顺序。
自动识别数据类型
#include <iostream> using namespace std; int main() { int x; double y; char w; cin >> x;//输入 cin >> y; cin >> w; cout << w << endl;//输出 cout << x << endl; cout << y << endl; return 0; }
因为C++兼容C的语法,所以有些情况下用C的输入输出更加方便。
缺省参数
定义
缺省参数是声明或定义函数时为函数的参数指定一个缺省值。在调用该函数时,如果没有指定实参则采用该形参的缺省值,否则使用指定的实参。
#include <iostream> using namespace std; int add(int x = 10, int y = 15) { return x + y; } int main() { int sum; sum = add(); cout << sum << endl; sum = add(1); cout << sum << endl; sum = add(1, 2); cout << sum << endl; return 0; }
#include <iostream> using namespace std; int add(int x, int y = 15, int z = 5)//半缺省参数,必须从右往左依次来给出,不能间隔着给 { return x + y + z; } int main() { int sum; sum = add(1);//这里必须有一个参数 cout << sum << endl; sum = add(1, 2); cout << sum << endl; return 0; }
注意:1.缺省参数不能在函数声明和定义中同时出现。(如果声明和定义同时出现,编译器就不知道应该用哪个缺省值)2.缺省值必须是常量或者全局变量