目录
一、命名空间
1、为什么引入namespace
在C/C++中,变量、函数或者类的名称都存在于全局作用域中,会导致很多冲突,所以说引入namespace来解决名字冲突的问题。
例如在C语言中
#include<stdio.h>
#include<stdlib.h>
int rand = 10;
int main()
{
printf("%d\n",rand);//编译报错
return 0;
}
rand是一个函数,这里的rand进行了重定义,所以会报错。
从而C++引入了namespace。
2、namespace的定义
定义命名空间,需要使⽤到namespace关键字,后⾯跟命名空间的名字,然后接⼀对{}即可,{}中即为命名空间的成员。命名空间中可以定义变量/函数/类型等。
#include <stdio.h>
#include<stdlib.h>
namespace xyz
{
int rand = 10;
}
int main()
{
printf("%d\n",xyz::rand);//这里指定xyz命名空间中的rand
return 0;
}
这里的::是域作用限定符,在::前面加需要访问的命名空间的名字。
namespace本质是定义出⼀个域,这个域跟全局域各⾃独⽴,不同的域可以定义同名变量,所以上面代码中的rand不会再冲突。C++中域有函数局部域,全局域,命名空间域,类域;域影响的是编译时语法查找⼀个变量/函数/类型出处(声明或定义)的逻辑,所有有了域隔离,名字冲突就解决了。
域里面除了可以定义变量还可以定义函数,还可以定义结构体。
在C++中,C++标准库都放在一个叫std(standard)的命名空间中,例如:
std::list
std::cout
std::string
3、namespace的嵌套定义
namespace we
{
namespace yy
{
int rand = 1;
int Add(int left,int right)
{
return (left + right)*10;
}
}
}
namespace zz
{
int rand = 1;
int Add(int left,int right)
{
return (left + right)*10;
}
}
int main()
{
printf("%d\n",we::yy::rand);//这里访问的是命名空间为yy下的rand
printf("%d\n",we::yy::Add(2,3));//这里调用的是yy下的Add函数
printf("%d\n",we::zz::rand);//这里访问的是命名空间为zz下的rand
printf("%d\n",we::zz::Add(2,3));//这里调用的是zz下的Add函数
return 0;
}
4、命名空间的使用
编译查找⼀个变量的声明/定义时,默认只会在局部或者全局查找,不会到命名空间⾥⾯去查找。所以下⾯程序会编译报错。
#include<stdio.h>
namespace abc
{
int a = 0;
int b = 1;
} i
nt main()
{
// 编译报错:error C2065: “a”: 未声明的标识符
printf("%d\n", a);
return 0;
}
所以当我们要使用命名空间中定义的变量或者函数,有三种方式:
(1)指定项目空间:
#include<stdio.h>
namespace abc
{
int a = 0;
}
int main()
{
printf("%d\n",abc::a);//查找命名空间为abc下的a
return 0;
}
(2)using将命名空间中某个成员展开,项目中经常访问的不存在冲突的成员推荐这种方式。
#include<stdio.h>
namespace abc
{
int b = 1;
}
using abc::b;
int main()
{
printf("%d\n",b);
return 0;
}
也可以使用using将命名空间中b这个成员展开,这样就可以直接访问b,用b的时候就可以不用指定了。
(3)展开命名空间中全部成员,但冲突风险比较大,项目不推荐,日常练习可以使用。
#include<stdio.h>
namespace abc
{
int a = 0;
int b = 1;
}
//展开了命名空间中全部成员
using namespace abc;
int main()
{
printf("%d\n",a);
printf("%d\n",b);
return 0;
二、C++输入输出
1、C++的标准输入输出
在C语言中,我们会使用scanf、printf和其他的输入输出函数来进行输入输出操作。在C++中,我们仍然可以使用C语言的输入输出库,但同时C++又引入了一套新的输入输出库,即iostream库。
是Input Output Stream 的缩写,是标准的输入、输出流库,定义了标准的输入、输出对象。
iostream库包含两个基础类型istream和ostream,分别表示输入流和输出流。
cout就跟C语言中的printf作用一样,cin就更C语言中scanf作用一样。
2、 标准输入输出对象
std::cin是istream类的对象,它主要面向窄字符的标准输入流。
std::cout是ostream类的对象,它主要面向窄字符的标准输出流。
#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
using namespace std;
int main()
{
int a = 0;
double b = 0.1;
char c = 'x';
cout << a << " " << b << " " << c << endl;
std::cout << a << " " << b << " " << c << std::endl;
scanf("%d%lf", &a, &b);
printf("%d %lf\n", a, b);
cin >> a;
cin >> b >> c;
cout << a << endl;
cout << b << " " << c << endl;
return 0;
}
注意:
1、std::endl 是一个函数,流输入输出时,相当于插⼊⼀个换⾏字符加刷新缓冲区。endl 即end line。
2、<<是流插⼊运算符,>>是流提取运算符。(C语⾔还⽤这两个运算符做位运算左移/右移)。
3、使⽤C++输⼊输出更⽅便,不需要像printf/scanf输⼊输出时那样,需要⼿动指定格式,C++的输⼊输出可以⾃动识别变量类型。
4、cout/cin/endl等都属于C++标准库,C++标准库都放在⼀个叫std(standard)的命名空间中,所以要通过命名空间的使⽤⽅式去⽤他们。但是如果使用using namespace std指令,则可以直接使用cout而不需要std::前缀。
5、这⾥我们没有包含<stdio.h>,也可以使⽤printf和scanf,在包含< iostream >间接包含了。
三、缺省参数(默认参数)
在C++中,缺省参数就是函数参数的默认值,即声明或者定义函数时为函数的参数指定的缺省值。在调用函数时,如果没有指定实参,则编译器会直接采用形参的缺省值,传实参了就用指定的实参。
缺省参数分为全缺省参数和半缺省参数。
1、全缺省参数
所有的参数都有缺省值。
#include<iostream>
using namespace std;
//全缺省
void func1(int a=1,int b = 2,int c = 3)//缺省参数
{
cout << "a = " << a << endl;
cout <<"b = " << b << endl;
cout << "c = " << c <<endl <<endl;
}
int main()
{
func1();
func1(4);
func1(4,5);
func1(4,5,6);
return 0;
}
如果给实参就用实参,不给实参就用缺省值。
2、半缺省参数
部分参数有缺省值。
#include<iostream>
using namespace std;
//半缺省
void func2(int a,int b = 2,int c = 3)
{
cout << "a = " << a << endl;
cout << "b = " << b << endl;
cout << "c = " << c << endl << endl;
}
int main()
{
func2(10);
func2(10,20);
func2(10,20,30);
return 0;
}
注意:
1 、C++规定半缺省参数必须从右往左依次连续缺省,不能间隔跳跃给缺省值。
2、带缺省参数的函数调用,C++规定必须从左往右依次给实参,不能跳跃给实参。
3、函数声明和定义分离时,缺省参数不能在函数声明和定义中同时出现,规定必须函数声明给缺省值。
四、函数重载
在C语言中,我们利用不同的函数名来加以区分实现功能相同的几个函数,这样写十分不方便,于是在C++中我们进行了改进。
==C++支持在同一作用域出现同名函数,但是要求这些函数的形参不同,可以是参数个数不同或者类型不同。这样就使得使用更加灵活。
1、参数类型不同
#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;
}
int main()
{
Add(1,2);
Add(1.1,2.2);
return 0;
}
上面两个函数虽然函数名相同,但函数类型不同,构成函数重载。
2、参数个数不同
#include<iostream>
using namespace std;
void func()
{
cout << "func()" << endl;
}
void func(int a)
{
cout << "func(int a)" << endl;
}
int main()
{
f();
f(1);
return 0;
}
3、参数顺序不同
void func(int a, char b)
{
cout << "func(int a,char b)" << endl;
}
void func(char b, int a)
{
cout << "func(char b,int a)" << endl;
}
int main()
{
func(1,'f');
func('f',1);
return 0;
}
函数重载使C++函数调用表现出了多态行为,使用更加灵活。
未完待续…大家多多支持哦!