一.namespace的定义和使用
在C语言和C++中,库中的变量,函数非常多,我们在程序中也会自己定义变量和函数名,这时候就有可能会和库中的变量和函数造成冲突 ,编译就无法通过,为了解决这个问题,我们可以使用命名空间对标识符名称进行本地化,也就是将变量放到另一个域中,避免和库中的变量和函数进行冲突。
cpp
#include<iostream>
int rand = 10;
int main() {
//error C2365: "rand": 重定义;以前的定义是"函数"
printf("%d", rand);
return 0;
}
定义命名空间,需要使用namespace关键字,后面加上命名空间的名字,然后用{ }括起来,这样就能表示这是一个命名空间域了。
注意:命名空间只能定义在全局
cpp
namespace mxj {
int rand = 10;
}
int main() {
printf("%d", mxj::rand);//找mxj域中的rand
}
命名空间还可以嵌套使用
cpp
//namespace只能定义在全局,还能嵌套定义
//项目中如果定义了多个同名的namespace,会被认为是一个namespace不会冲突
namespace mxj {
int rand = 10;
namespace mxj2 {
int rand = 20;
}
namespace mxj3 {
int rand = 30;
}
}
int main() {
printf("mxj::rand: %d\n", mxj::rand);
printf("mxj::mxj2::rand: %d\n", mxj::mxj2::rand);
printf("mxj::mxj3::rand: %d\n", mxj::mxj3::rand);
return 0;
}
使用命名空间内的成员,也有多种使用方法:
cpp
//使用命名空间中的变量,函数,有三种使用方式
//1.指定命名空间访问
int main() {
printf("%d", mxj::rand);
}
//2.using将命名空间中某个成员展开
using mxj::a;
int main() {
printf("%d", a);
printf("%d", mxj::b);
}
//3.展开命名空间的全部成员
//不推荐,有命名冲突时会报错
using namespace mxj;
int main() {
printf("%d", a);
printf("%d", b);
}
二.输入输出流
std::cin 是istream类的对象,主要面向窄字符的标准输入流
std::cout 是ostream类的对象,主要面向窄字符的标准输出流
std::endl 是一个函数,换行符加刷新缓冲区
相较于C语言,输入输出流可以自动识别变量的类型
cpp
int main() {
int a = 0;
double b = 0;
std::cin >> a >>b;
std::cout << a << " " << b << std::endl;
}
//C语言版
int main() {
int a = 0;
double b = 0;
scanf("%d %lf", &a, &b);
printf("%d %lf", a, b);
}
三.缺省参数
声明或定义时函数的参数指定一个缺省值,在调用函数时,如果没有指定的实参,则采用形参的缺省值
cpp
using namespace std;
void fun(int a=0) {
cout << a << endl;
}
int main() {
fun();//没有传参时,使用参数的默认值
fun(10);//有传参时,使用指定的实参
return 0;
}
缺省参数也分 全缺省参数和半缺省参数
cpp
//全缺省
void fun(int a = 10, int b = 20, int c = 30) {
cout << "a=" << a << endl;
cout << "b=" << b << endl;
cout << "c=" << c << endl;
cout<< endl;
}
//C++必须规定从左到右依次给实参,不能跳跃给实参
//半缺省
void fun2(int a, int b = 10, int c = 20) {
cout << "a=" << a << endl;
cout << "b=" << b << endl;
cout << "c=" << c << endl;
cout << endl;
}
int main() {
fun();
fun(10);
fun(10, 10);
fun(10, 10, 10);
fun2(10);
fun2(10, 20);
fun2(10, 20, 30);
}
代码运行结果如下:
函数的声明和定义分离时,缺省参数不能在函数声明和定义中同时出现,规定函数声明给缺省值
假如在一个程序中,头文件和cpp文件是分离的,那么缺省参数只能在函数声明中
cpp
//在.cpp文件中 add函数的定义不能有缺省参数
int add(int x, int y) {
return x + y;
}
//在.h文件中,add函数的声明可以有缺省参数
int add(int x=10, int y=20);
四.函数重载
在C语言中,一个程序不能出现同名的函数,否则就无法通过编译
但是C++就没有这个限制,在同一作用域中允许同命名
但是要求这些函数的形参不同,可以是形参的个数不同,类型不同,返回类型不能区分重载函数
cpp
using namespace std;
//参数类型不同
int add(int a, int b) {
cout << "int add(int a,int b)"<<endl;
return a + b;
}
double add(double a, double b) {
cout << "double add(double a,double b)" << endl;
return a + b;
}
//参数个数不同
void func() {
cout << "void func()" << endl;
}
void func(int a) {
cout << "void func(int a)" << endl;
}
void func(int a, int b) {
cout << "void func(int a,int b)" << endl;
}
//参数类型顺序不同
void f(char a, int b) {
cout << "f(char a,int b)" << endl;
}
void f(int b, char a) {
cout << "f(int b,char a)" << endl;
}
int main() {
add(10, 20);
add(10.1, 20.1);
func();
func(1);
func(1, 2);
f('b', 3);
f(3, 'a');
}
由代码执行结果可知,在C++中函数是可以重载的
但是我们要注意函数在重载时遇到的缺省参数问题:
cpp
//下面两个函数重构会有问题,但能通过编译,调用时出问题
void f1() {
cout << "void f1()" << endl;
}
void f1(int a=10) {
cout << "void f1(int a)" << endl;
}
int main(){
f1();//这里可以看成缺省函数,编译器不知道调用哪个,存在歧义
f1(10);
}
五.引用
引用不是定义一个新变量,而是给一个现存的变量取一个别名,这个操作不会为引用变量开辟新的空间
它和引用的变量共用一块空间
类型& 引用别名=引用对象
cpp
int main() {
int a = 10;
//引用一定要初始化使用
int& b = a; //将a取别名b
int& c = a; //将a取别名c
int& d = a; //将a取别名d
cout << "a:" << a << endl;
cout << "b:" << b << endl;
cout << "c:" << c << endl;
cout << "d:" << d << endl;
//取地址得到的结果是一样的
cout << "a:" << &a << endl;
cout << "b:" << &b << endl;
cout << "c:" << &c << endl;
cout << "d:" << &d << endl;
return 0;
}
对于引用,它也有其自己的特性
cpp
//引用的特性
//1.引用在定义时必须要初始化
//2.一个变量可以有多个引用
//3.引用一旦引用一个实体,再不能引用其他实体
int main() {
int a = 10;
int aa = 100;
int& b = a;
cout << a << endl;
cout << b << endl;
//int& b = aa;//报错:多次初始化
//这里是赋值,b是a的别名,本质上是a==aa
b = aa;
cout << a << endl;
cout << b << endl;
cout << aa << endl;
}
引用也可以代替指针使用:
cpp
//引用的使用
//可以代替指针传参
void Swap(int* x, int* y) {
int tmp = *x;
*x = *y;
*y = tmp;
}
void Swap2(int& rx, int& ry) {
int tmp = rx;
rx = ry;
ry = tmp;
}
int main() {
int a = 10;
int b = 20;
cout << "a:" << a << endl;
cout << "b:" << b << endl;
//Swap(&a, &b);
Swap2(a, b);
cout << "a:" << a << endl;
cout << "b:" << b << endl;
}