关注小庄 顿顿解馋(ᕑᗢᓫ∗)˒
引言:本篇博客我们开始与C++的第一次约会,C++是兼容c的,本篇博客我们将了解到C++关键字有哪些,C++命名空间,C++输入与输出和缺省参数的内容,请放心食用 ~
文章目录
一 🏠 C++关键字
C++跟C语言一样也有属于它自己关键字,但是由于C++兼容c,关键字中有些是我们的老朋友,有些是新朋友,我们可以在后期慢慢了解
二 🏠 C++命名空间
我们首先看这样的一段代码
#include<stdlib.h> #include<stdio.h> int rand = 0; int main() { printf("%d",rand); return 0; }
这段代码能否正常输出这个全局变量rand的值呢?
答案是否定的,这是因为我们包含了rand函数的头文件,他和rand变量都在全局域中,这导致编译器懵逼了会起冲突。
这里我们补充一个知识点:
我们在用变量/函数..时,编译器默认查找顺序是1.局部域 2.全局域
那有什么解决之法呢 ? C++ 给了一个新技术叫做 命名空间
(namespace)
👿 命名空间的定义
- 语法
namespace 空间名 { int rand = 10; // 定义变量 int Add(int x,int y) { return x + y; } //定义函数 struct Node { }; //定义类型 } //注意这里没有分号 ! !
命名空间里可以定义变量,函数,类型
// 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; } } }
命名空间也可以嵌套命名空间,有什么使用场景呢?
namespace bit { namespace f { void Add(int x, int y) { cout << 2*x + y << endl; } } } namespace f { int x; void Add(int x, int y) { cout << x + y << endl; } struct Node { }; } int main() { bit::f::Add(1, 2); f::Add(1, 2); return 0; }
如上代码 当你想用两个同名命名空间里的东西时,就可以嵌套命名空间。
//test.h #include<iostream> using namespace std; namespace f { void Sub(int x ,int y) { cout << x - y << endl; } } //test.cpp namespace f { int x; void Add(int x, int y) { cout << x + y << endl; } struct Node { }; } #include"test.h" int main() { bit::f::Add(1, 2); f::Add(1, 2); f::Sub(1, 2); return 0; }
输出结果:3 -1 可以正常编译
我们可以发现:同一个工程中允许存在多个相同名称的命名空间,编译器最后会合成同一个命名空间中。
👿 命名空间的使用
📒 加命名空间名称及作用域限定符
:: 是C++中的作用域限定符,左边没东西默认访问全局
namespace f { int x = 2;; void Add(int x, int y) { cout << x + y << endl; } struct Node { }; } int x = 0; int main() { cout << ::x << endl;//使用全局的 bit::f::Add(1, 2); //使用嵌套命名空间的函数 cout << f::x << endl;//使用命名空间定义的变量 f::Add(1, 2); //使用命名空间定义的函数 struct f::Node pnode;//使用命名空间定义的类型 return 0; }
📒 展开命名空间
命名空间的本质是定义一个命名空间域
,展开命名空间实际是增加编译器查找的顺序,除了在局部域和全局域找还在命名空间域找,它实际是一个声明,声明你可以访问这块空间
using namespce N; int main() { printf("%d\n", N::a); printf("%d\n", b); Add(10, 20); return 0; }
对于代码中的b,由于展开了命名空间,先在局部域找,没找到再在全局域,和命名空间域里找,相当于命名空间域暴露在全局域
namespace f1 { int val = 0; } namespace f2 { int val = 1; } using namespace f1; using namespace f2; cout << val << endl;
代码不能正常编译
注意:展开多个命名空间时,空间里有同名的会起冲突,所以尽量不要随意展开!!
📒 指定展开空间的某一个
namespace N { int b = 0; } using N::b; int main() { printf("%d\n", b); return 0; }
如果我们要解决上面的问题可不可以代码是这样的?
namespace N { int rand = 0; } using N::rand; int main() { printf("%d\n", b); return 0; }
在这里编译器会报错,原因是展开指定中的某一个实际是一个声明,声明你可以访问这块命名空间里的rand,但是会与全局域的rand函数冲突,编译器不知道到底要用哪个rand
printf("%d\n", N::b);
这种写法明确告诉你要访问的是N这个命名空间里的rand
注意:命名空间域并不会改变生命周期
三 🏠 C++输入与输出
我们的C++祖师爷对C语言的输入和输出函数感到不足,所也设计了新的输入和输出函数
👿 cout和cin
std
是C++标准库的命名空间名,C++将标准库
的定义实现都放到这个命名空间中
#include<iostream> using namespace std; int a; double b; char c; // 可以自动识别变量的类型 cin>>a; cin>>b>>c; cout << a << "" << b <<endl<<'\n' //换行可以使用endl或‘\n’
注意:
- <<是流插入运算符,>>是流提取运算符
- cin 和 cout 可以自动识别类型
- cout和cin是全局的流对象,endl是特殊的C++符号,表示换行输出,他们都包含在包含< iostream >头文件中。
- 使用cout标准输出对象(控制台)和cin标准输入对象(键盘)时,必须包含< iostream >头文件以及按命名空间使用方法使用std。
使用cout
//1. using nampspace std; //2. std::cout //3. using std:: cout; using std::endl;
关于std命名空间
我们前面说了最好不要随意展开命名空间,这是必须的吗?
- 在日常练习中,建议直接using namespace std即可,这样就很方便
- using namespace std展开,标准库就全部暴露出来了,如果我们定义跟库重名的类型/对象/函数,就存在冲突问题。该问题在日常练习中很少出现,但是项目开发中代码较多、规模大,就很容易出现。所以建议在项目开发中使用.
四 🏠 缺省参数
👿 缺省参数的概念
缺省参数是声明或定义函数时为函数的参数指定一个缺省值。
void Func(int a = 0) { cout<<a<<endl; } int main() { Func(); // 没有传参时,使用参数的默认值 Func(10); // 传参时,使用指定的实参 return 0; }
输出:
0
10
如果没有指定实参则采用该形参的缺省值,否则使用指定的实参
👿 缺省参数的分类
- 全缺省参数
指的是给每个形参一个默认值
void Func(int a = 10, int b = 20, int c = 30) { cout<<"a = "<<a<<endl; cout<<"b = "<<b<<endl; cout<<"c = "<<c<<endl; } Func(1,2,3); //输出1 2 3 Func(1,2);//1 2 30 Func(1);//1 20 30 //不能是Func(1,,3);
- 半缺省参数
指的是给一部分缺省参数
void Func(int a, int b = 10, int c = 20) { cout<<"a = "<<a<<endl; cout<<"b = "<<b<<endl; cout<<"c = "<<c<<endl; } //不能在函数和声明同时缺省 //a.h void Func(int a = 10); // a.cpp void Func(int a = 20) {}
注意:
- 半缺省参数必须从右往左依次来给出,不能间隔着给
- 缺省参数不能在函数声明和定义中同时出现(如果生命与定义位置同时出现,恰巧两个位置提供的值不同,那编译器就无法确定到底该用那个缺省值)
- 缺省值必须是常量或者全局变量
- C语言不支持
应用场景:比如我们给链表扩容时如果知道要扩多少直接给形参,不知道就用缺省参数作为指导扩容值.
看完不妨给个一键三连呀 ~