命名空间
在工作时,一个项目一般由几个人或者小组来处理,但是由于在c语言中给函数取名字却是一个不小的问题,一个人取完名字,第二个人就得避开这个名字以免重名,当人多时,这样明显会降低工作效率,所以,为了解决这个问题,我们的c++之父——本贾尼·斯特劳斯特卢普,就想到了重新定义一个域的方法
#include<stdio.h>
#include<stdlib.h>
int rand = 10;
int main()
{
printf("%d\n", rand);
return 0;
}
namespace
namespace本质是定义出⼀个域,这个域跟全局域各自独立,不同的域可以定义同名变量,所以重名冲突就不存在了
定义命名空间,需要使⽤到namespace关键字,后⾯跟命名空间的名字,然后接⼀对{}即可,{}中 即为命名空间的成员。命名空间中可以定义变量/函数/类型等。
编译查找⼀个变量的声明/定义时,默认只会在局部或者全局查找,不会到命名空间⾥⾯去查找。
所以使用namespace里的变量时,我们需要 :: ,这个符号,代码格式为命名空间的名字::变量名。例:test1::rand.
namespace只能定义在全局,当然他还可以嵌套定义。
namespace test1
{
namespace test2
{
int i=0;
}
使用namespace test2里的变量时,格式为test1 :: test2 :: i 。
但如果需要频繁使用namespace里的变量或者其嵌套的另一个namespace时,我们可以使用using来将其展开(注:展开命名空间中全部成员,项⽬不推荐,冲突⻛险很⼤,⽇常⼩练习程序为了⽅便推荐使用)
c++的输入和输出
在了解c++的输入输出前,我们需要了解的东西
iostream是InputOutputStream的缩写,是标准的输⼊、输出流库,定义了标准的输⼊、输 出对象;
<<是流插入运算符,>>是流提取运算符 (C语⾔还⽤这两个运算符做位运算左移/右移);
cout/cin/endl等都属于C++标准库,C++标准库都放在⼀个叫std(standard)的命名空间中,所以要 通过命名空间的使⽤⽅式去⽤他们。
std::cin 是istream类的对象,它主要⾯向窄字符(narrowcharacters(oftypechar))的标准输 ⼊流。
std::cout 是iostream类的对象,它主要⾯向窄字符的标准输出流。
std::endl 是⼀个函数,流插⼊输出时,相当于插⼊⼀个换⾏字符加刷新缓冲区。
这⾥我们没有包含include,也可以使⽤printf和scanf,在包含iostream间接包含了;
通过这段代码我们发现c++的输入输出都是靠cin和cout来实现的,相比c语言的scanf和printf,它不需要声明你所输出或输入的格式,即%d,可以实现自动识别变量的类型;
那么就有人问了,printf的%d后加上\n可以实现换行操作,在d后加上一个空格可以实现每次输出时都加上一个空格来使输出的格式更好看,这些cout其实都可以做到;
例如换行:endl可以实现换行的操作
至于其他的有关输出的操作,就需要后续的学习了
缺省参数
缺省参数是声明或定义函数时为函数的参数指定⼀个缺省值。在调⽤该函数时,如果没有指定实参 则采⽤该形参的缺省值,否则使⽤指定的实参,缺省参数分为全缺省和半缺省参数。(有些地⽅把 缺省参数也叫默认参数)
全缺省就是全部形参给缺省值,半缺省就是部分形参给缺省值。C++规定半缺省参数必须从右往左 依次连续缺省,不能间隔跳跃给缺省值
带缺省参数的函数调⽤,C++规定必须从左到右依次给实参,不能跳跃给实参
函数声明和定义分离时,缺省参数不能在函数声明和定义中同时出现,规定必须函数声明给缺省 值
函数重载
我们在c语言实现例如两数相加add,这样的简单函数时,面对不同的变量需要设置不同的形参,这意味着我们需要不同的函数来实现,例两浮点型的变量相加需要创建函数,一整型一浮点型相加有需要创建一个函数,这些函数都只是为了实现两数相加也就是add,确实需要创建这么多函数且不能重名,创建函数还好,可以copy一下,但在取名字上,可就犯了难;
而函数重载就是为了解决这些问题;
C++⽀持在同⼀作⽤域中出现同名函数,但是要求这些同名函数的形参不同,可以是参数个数不同或者 类型不同。注意:返回值不同不能作为重载条件,因为调⽤时也⽆法区分;
#include<iostream>
using namespace std;
//函数参数不同
int Add(int left, int right)
{
cout << "int Add(int left, int right)" << endl;
return left + right;
}
double Add(double left, double right)
{
cout << "double Add(double left, double right)" << endl;
return left + right;
}
//函数参数数量不同
void f()
{
cout << "f()" << endl;
}
void f(int a)
{
cout << "f(int a)" << endl;
}
//参数类型顺序不同
void f(int a, char b)
{
cout << "f(int a,char b)" << endl;
}
void f(char b, int a)
{
cout << "f(char b, int a)" << endl;
}
这样,我们就可以用一个add,来实现各种类型变量的相加,甚至是各种数量的相加
引用
1.引用的概念与定义
引⽤不是新定义⼀个变量,⽽是给已存在变量取了⼀个别名,编译器不会为引⽤变量开辟内存空间, 它和它引⽤的变量共⽤同⼀块内存空间。
定义:类型& 引⽤别名=引用对象;
引用的特点
重点:引用在定义时必须初始化、⼀个变量可以有多个引用、引用⼀旦引用⼀个实体,再不能引用其他实体
引用的实际运用
1.引用在实践中主要是于引用传参和引用做返回值中减少拷贝提高效率和改变引用对象时同时改变被 引用对象;
2.引用传参跟指针传参功能是类似的,引用传参相对更方便⼀些;
3.引用和指针在实践中相辅相成,功能有重叠性,但是各有特点,互相不可替代;
(1)语法概念上引用是⼀个变量的取别名不开空间,指针是存储⼀个变量地址,要开空间;
(2)引用在定义时必须初始化,指针建议初始化,但是语法上不是必须的;
(3) 引用在初始化时引用⼀个对象后,就不能再引用其他对象;而指针可以在不断地改变指向对象 ;
(4)引用可以直接访问指向对象,指针需要解引用才是访问指向对象 ;
(5)sizeof中含义不同,引用结果为引用类型的大小,但指针始终是地址空间所占字节个数(32位平台下 占4个字节,64位下是8byte);
(6)指针很容易出现空指针和野指针的问题,引用很少出现,引用使用起来相对更安全⼀些;
//利用引用来实现互换
#include<iostream>
using namespace std;
void Swap(int& rx, int& ry)
{
int tmp = rx;
rx = ry;
ry = tmp;
}
int main()
{
int x = 0, y = 1;
cout << x << " " << y << endl;
Swap(x, y);
cout << x << " " << y << endl;
return 0;
}
const引用
可以引用⼀个const对象,但是必须用const引用。const引用也可以引⽤普通对象,因为对象的访 问权限在引用过程中可以缩小,但是不能放大