学习C++之前先来认识一下,C++的创始人本贾尼·斯特劳斯特卢普(祖师爷)
与C语言的不同
C++开发的目的就是弥补C语言的不足。
同时C语言源文件是以 . c .c .c 为后缀的,而C++是以 . c p p .cpp .cpp 为后缀。
域名限定符
回想一下,在C语言中,我们全局域和局部域可以使用重复变量名吗?
答案是可以的,在c语言中我们可以在全局和局部中同时定义 a 变量,但是访问时,优先访问局部域。
编译器默认查找规则:
- 局部域
- 全局域
那我们可不可以直接访问全局域定义的呢?
: : :: :: - 域名限定符(两个冒号连在一块。)
: : :: :: 它左边什么都不写表示访问全局域,后面也可以用来访问命名空间域。
命名空间
这里要明确一件事,C++是包含大部分C语言的。所以我们再 cpp 文件中,也可以写C语言。
命名空间的本质:就是一个域
如上图:
当我们使用c语言的随机数 rand() 函数的时候,如果我们想要再创建一个 rand 变量,那么这是就会与我们的库函数造成冲突。而我们C++新引入了命名空间的概念。
namespace 关键字
n
a
m
e
s
p
a
c
e
+
名字(任意)
namespace + 名字(任意)
namespace+名字(任意)。
如上图,我们定义了一个名为 bit 的域,命名空间本质上其实就是个 域。
通过域名限定符我们就可以访问这个域,找到其中的rand变量,这样就解决了,命名冲突这个问题。
同时,如果我们不在 rand 前面加上 bit:: ,那么编译器就不会取命名空间中查找,所以在默认情况下,编译器不会去命名空间查找。
1. 问题1:如果命名空间出现了重复定义会怎么样呢?
命名空间本质是一个域,在同一个域中定以重复变量 -> 重定义。
这里跟在局部域中定义两个变量 a 是一样的。
2. 问题二:如果代码在多个文件怎么怎样防止和别人的冲突呢?
如下图:我们自己写的栈和队列,和源文件中的冲突了,该怎么办呢?
我们可以分别在栈的定义和声明文件中,分别用命名空间包含进去。这里可以把他们看做是合并,当我们使用的时候,他会去命名空间中去找。
bit内容
展开命名空间
先来看一段代码。
C++兼容C,但和C并不相同,C++引用库文件不需要写.h后缀(老版本需要)。这里的 < i o s t r e a m > <iostream> <iostream>表示输入输出流,C++的输入输出分别用 c o u t cout cout 和 c i n cin cin 来表示。
c
o
u
t
:输出数据到控制台
cout:输出数据到控制台
cout:输出数据到控制台 - 这里的 c 表示 console(控制台)
c
i
n
t
:输入数据到控制台
cint:输入数据到控制台
cint:输入数据到控制台
cout 和 cin 在库中是在一个名为 std 的命名空间中定义的。所以当我们想要用的时候必须加上 std:: 限定符。可是如果我们要用很多次 cout 和 cin未免太麻烦了。这里有一种方式为 展开命名空间
using namespace std;
这句话就相当于给 std 这个命名空间加了个标志,我们就可以直接使用 cout 和 cin 了。
需要注意的是: 展开命名空间和展开头文件不一样,展开头文件是把头文件的内容包含进来,而我们展开命名空间不是。
展开命名空间的坏处:
bit内容见上图
当我们把 bit 展开之后会发现与我们源文件定义的内容冲突了,所以在我们工作时,最好不要展开命名空间,但我们自己写代码随便展开。就是玩
缺省
什么是缺省呢?
缺省的分类:
- 全缺省
- 半缺省
-
缺省是按顺序给参数赋值的,只能从右往左缺省。
如上图半缺省,从右往左我们都是缺省参数。
但是如上图,这样从左向右缺省,却是不行的。 -
缺省在函数的定义和声明不能同时出现。
例如我们栈的初始化。我们原来都是给定一个大小进行初始化,那么如果我们需要插入很多的数据,那么我们就需要扩容很多次,那么就会浪费大量的时间,那我们可以初始化的时候,给定一个想要开辟空间的值,当我们不知道的时候给定一个默认值即可。
如图:
试想一下,如果我们的定义和声明都是用缺省类型,那我们用哪个呢?
所以缺省参数不能同时出现在函数的声明和定义中。