专栏分类:C语言初阶 C语言进阶 数据结构初阶 Linux C++初阶
欢迎大家点赞,评论,收藏。
一起努力,一起奔赴大厂
目录
一.前言
在前面我们学过C语言,在这里我们就要进入我们的C+ +环节,说到C++我们不得不说说的我们的C++祖师爷Bjarne Stroustrup,当我们学完C++后你不得不感叹祖师爷真的是祖师爷,他的思想是真的牛。在这篇文章中我们将涉及到命名空间,缺省参数,半缺省参数,其中的内容真的是非常的good。
二.命名空间
2.1命名冲突的例子
在一个很大的工程中,我们的代码是非常非常的多,甚至能达到几百万行,由于代码是很多人进行编写,就会造成我们的命名冲突,还记得c语言中我们有一个代码是
cpp
#include<stdio.h>
int x=1;
int main()
{
int x=0;
printf("%d\n",x);
return 0;
}
我们可以看到我们的变量x即是全局变量又是局部变量,我们的输出结果是0,说明程序是先检测局部变量,再检测全局变量,在我们的程序编写中命名冲突会带来很严重的影响,我们看下面代码:
cpp
#include<stdio.h>
#include<stdlib.h>
int rand = 1;
int main()
{
return 0;
}
我们可以看到出现了报错
在我们的stdlib.h的文件中有一个函数的名字是rand,我们定义了一个全局变量是rand,因此发生了重定义的现象,还有一种我们的一个程序
一个人写的是
cpp
struct SNode {
int*a;
int size;
int capacity;
};
void Init(struct SNode*s)
{
//..
}
void Push(struct SNode* s)
{
}
另一个人写的是
cpp
struct QNode {
int val;
struct QNode* next;
};
void Init(struct QNode* q)
{
}
void Push(struct QNode* q)
{
}
我们可以看到他们的函数名字相同,从而引发了错误。
2.2解决方案
在以上的集中问题中,祖师爷在设计c++中给出了完美的结局方案,那就是我们的命名空间,这个需要我们的关键字namespace,命名空间相当于一个带有门锁的房子,当这个门锁打开时它就是全局变量。例如下面的代码:
cpp
#include<iostream>
namespace bite1 {
int x = 1;
}
namespace bite2
{
int x = 2;
}
int main()
{
std::cout << bite2::x << std::endl;
std::cout << bite1::x << std::endl;
return 0;
}
我们的运行结果为
命名空间完美解决了命名冲突的问题。
2.3命名空间的使用
2.3.1命名空间嵌套使用
在上面我们就是一个命名空间的使用,命名空间可还可以嵌套使用,例如下面:
cpp
#include<iostream>
namespace bite1 {
int x = 1;
namespace bite2
{
int x = 2;
}
}
int main()
{
std::cout << bite1::bite2::x << std::endl;
return 0;
}
我们的运行结果为2.
2.3.2命名空间在结构体中的使用
cpp
#include<iostream>
namespace bite1 {
struct SNode {
int data;
};
}
int main()
{
struct bite1::SNode s;
s.data = 1;
std::cout << s.data << std::endl;
return 0;
}
我们的结构体在一个命名空间中,我们想定义一个接着结构体的变量,我们的定义方式不是先写命名空间的名字,需要我们先写struct,当然我们也可以写成bite1::SNode s,这是因为struct是类,至于类是什么可以看我后面的文章,我将会给大家进行详细解析。
2.3.3命名空间中函数的引用
cpp
namespace bite {
int Add(int x, int y)
{
return x + y;
}
}
int main()
{
int ret = bite::Add(1, 2);
std::cout << ret << std::endl;
return 0;
}
在使用函数时我们需要加上我们的命名空间域,当然我们的声明和定义分离时我们需要在命名空间的函数声明,在外面进行定义。
2.3.4命名空间的展开
命名空间能全部展开,也能部分展开,在全部展开时我们们需要我们的using namespace 名字,对其进行展开,我们知道在寻找变量时是先找局部再找全局,由于namspace定义的既不是局部又不是全局,他是一个单独的,当我们加入这句话后就可以进行访问,它也就变成了全局,例如我们经常使用的using namespace std;就是将iostream文件中的std中的函数(cout,endl等)变更成全局的。例如下面的代码就是我们进行展开。
cpp
#include"test.h"
using namespace std;
using namespace bite;
int main()
{
int ret = Add(1, 2);
cout << ret << endl;
return 0;
}
我们知道如果将这些全部展开相当于namespace就白白出现了,所以在我们的工作中我们通常是不会使用using namespace 名字的,但是我们有时候会经常使用一些,例如我们经常使用bite中的Add函数,但是我们却不想将bite中其他的进行放开,所以就出现了我们部分放开,
cpp
#include"test.h"
using bite::Add;
int main()
{
int ret = Add(1, 2);
std::cout << ret << std::endl;
return 0;
}
三.缺省参数
3.1缺省参数是什么
缺省参数是C++一种特有的参数形式,遵循从右到左进行给值,声明或定义函数时为函数的参数指定一个缺省值。在调用该函数时,如果没有指定实参则采用该形参的缺省值,否则使用指定的实参。(也就是说我们在定义函数时我们没有进行传参,这个函数也能正常编译,它的值是我们写函数是预设的值)。例如下面的代码:
cpp
#include<iostream>
int Add(int x = 1, int y = 2)
{
return x + y;
}
int main()
{
std::cout << Add(3, 3) << std::endl;
std::cout << Add(3) << std::endl;
std::cout << Add() << std::endl;
return 0;
}
我们运行后可以看到
所以我们知道了缺省参数当我们给值是,它正常运行,当我们不给值时它按照预定的值进行给值,我们需要注意我们打缺省参数定义的函数需要从右向左进行设定值,我们传参时需要从左向右进行传参,否则会出现错误。
3.2缺省参数应用场景
在我们顺序表中,我们需要进行初始化和扩容,在那我们初始化为4,这是一个固定的数据,假如我们初始的数据为300,1000等这就会造成扩容多次,所以在那里我们就需要我们的半缺省参数,代码如下:
cpp
#include<iostream>
struct SNode {
int* a;
int size;
int capacity;
};
void Init(SNode* s1, int x = 4)
{
s1->a = (int*)malloc (sizeof(int) * x);
s1->size = 0;
s1->capacity = x;
}
int main()
{
SNode s;
Init(&s, 10);
}
我们通过修改我们的初始值的大小来改变我们初始的空间的大小,在这里缺省参数有很重要的作用,半层参数就是没有全部对参数进行赋值,上面这段代码就是半缺省参数,我们的s1没有进行赋值,半缺省参数我们一定要遵行从右向左进行赋值,从左向右给值。
四.总结
我们需要知道命名空就相当于一个房子,只有这块房子才有访问的权限,我们只有通过using进行权限的打开就像Linux中的chmod进行权限的修改一样,命名空间在我们的以后工作中有非常重要的作用,其能极大程度上避免命名冲突的问题,我们的缺省参数也有非常重要的作用,希望大家可以认真学习一下,最后希望大家可以一键三连一下。