【C++详解】C++入门(一)命名空间、缺省参数、函数重载
文章目录
- 一、命名空间
- 命名空间的基本特性
- 命名空间的使用
- 二、C++输入输出用法
- 三、缺省参数(默认参数)
- 定义
- 用法
- 四、函数重载
一、命名空间
命名空间的基本特性
#include <stdio.h>
#include <stdlib.h>int rand = 10;int main()
{// 编译报错:error C2365: “rand”: 重定义;以前的定义是“函数”printf("%d\n", rand);return 0;
}
C语言其实一直存在命名冲突的问题,我们看上面这段代码,这里打印rand出现了报错,原因是rand既在全局变量定义为一个整型变量10,也在头文件里有定义,出现了命名冲突编译器就会报错。这里我们介绍的命名空间就是用来解决这类问题的。
定义命名空间,需要用到namespace关键字,后面跟命名空间的名字,命名空间可以定义变量\函数\类型等,用法如下所示:
namespace wusaqi
{int rand = 10;int Add(int left, int right){return left + right;}struct Node{struct Node* next;int val;};
}
为什么命名空间的出现就能解决命名冲突的问题呢?首先我们要理解C\C++的一个语法规则,当要使用一个变量或者函数的时候都需要编译器找到它的出处(声明或定义),当找不到时编译器就会报错。命名空间本质是定义出了一个域(有关域我们之前有接触到全局域和局部域,同一域不能定义同名的变量或函数),这个域跟全局域各自独立,不同的域可以定义同名变量,所以用下面这种方法rand就不再冲突了。
printf("%d\n", wusaqi::rand);
- 这里出现了一个我们比较陌生的操作符 “::”,它叫做域作用限定符,在要使用的变量或函数前使用,在这个操作符前面加上在哪个指定域里找,若操作符前面不加任何东西则默认在全局域里找。
补充:没有指定域,默认先局部找再全局找,不会访问命名空间域
指定域,直接去这个域找,若这个域没有要找的变量或函数,则会报错
一些特性:
1、局部域和全局域除了会影响编译查找逻辑,还会影响变量的生命周期,命名空间域和类域不影响变量生命周期。
2、namespace只能定义在全局,因为局部变量基本不会冲突,当然它也可以嵌套定义。
3、若在项目工程中多个文件里定义的同名namespace会认为是一个namespace,不会冲突。
4、C++标准库都放在一个std(standard)的命名空间中。
命名空间的使用
当编译器要查找一个变量的声明/定义时会先到局部域找,再到全局域找,一般不会到命名空间域里找,所以当我们要使用命名空间里定义的变量/函数时,有以下三种方法:
一:指定命名空间访问,当我们开发大型项目时推荐用这种。
二、using将命名空间中某个成员展开(展开后编译器会去展开区域寻找变量的定义/声明,注意和展开头文件区分,展开头文件指的是在预处理阶段会把头文件拷贝过来),项目中经常访问的不存在冲突的推荐这种方式。
三、展开命名空间中全部成员,项目中不推荐,冲突风险很大,日常练习为了方便可以使用。
namespace N
{int a = 1;int b = 2;
}int main()
{//指定命名空间访问printf("%d", N::a);printf("%d", N::b);
}int main()
{//using将命名空间某个成员展开using N::b;printf("%d", N::a);printf("%d", b);
}int main()
{//展开命名空间中全部成员using namespace N;printf("%d", a);printf("%d", b);
}
二、C++输入输出用法
我们看上面这段用C++语法写的输入输出代码,乍一看是不是很懵,让小编来慢慢解释。
1、首先我们看它先包了一个<iostream>的头文件,这是C++里定义的标准输入输出流库,定义了标准输入输出对象。由于IO流涉及很多类和对象的知识,这些知识小编还没有介绍,所以这里只简单介绍一下C++IO流的用法。
2、然后我们可以看到三个操作符cout\cin\endl,我来一一解释:
cout/cin:cout是ostream类的对象,cin是isream类的对象,它们分别是标准输出/输入流,并且是面向宅字符的,指的是不管你输入什么类型的数据都要先被转换成字符输出到cout,输入的数据也要先被转换成字符再通过cin输入,所以为什么in和out前面要加一个c。
endl:它是一个函数,流插入输出时,相当于一个换行符加刷新缓冲区,这里先把它简单理解成换行符。
3、在头文件下面一行代码展开一个名叫std的命名空间,原因是cout\cin\endl它们都属于C++标准库,C++标准库都放在一个std的命名空间中,所以要通过命名空间的方式去用它们。
4、我们还可以看到两个在C语言中接触过的操作符:<<和>>,在C语言中它们是位运算的左移操作符和右移操作符,在C++中它们分别是流插入和流提取。
5、C++的输入输出不用像C语言那样手动指定格式,它可以自动识别变量类型(本质是通过函数重载实现的,这个以后会讲到)。并且相较C语言只支持原生定义类型(如int,double)的输入输出,C++可以支持输入输出任意类型,如类类型。
三、缺省参数(默认参数)
定义
缺省参数是声明或定义函数时为函数的参数指定一个缺省值,在函数调用时,如果参数对应位置没有传实参则用该缺省形参当实参,否则使用传过去的实参,缺省参数分为全缺省和半缺省参数。
用法
1、全缺省指的时全部参数给缺省值,半缺省指的是部分参数给缺省值,缺省参数只能从右往左依次缺省,不能跳跃或则间断缺省。
2、带缺省参数的函数调用,C++语法规定只能从左到右依次给实参,不能跳跃或者间断给。 (这里注意缺省的顺序和传参的顺序,祖师爷规定的只用记住就行了,没有特别的原因)
3、当函数声明和定义分离时(如声明和定义在两个不同的文件里),缺省参数不能在声明和定义中同时出现,规定只能在声明处给缺省值。
using namespace std;
void Func1(int a = 10, int b = 20, int c = 30)
{cout << "a = " << a << endl;cout << "b = " << b << endl;cout << "c = " << c << endl;
}void Func2(int a, int b = 20, int c = 30)
{cout << "a = " << a << endl;cout << "b = " << b << endl;cout << "c = " << c << endl;
}int main()
{//全缺省Func1();Func1(1);Func1(1, 2);Func1(1, 2, 3);//半缺省Func2(1);return 0;
}
四、函数重载
我们知道C语言语法规定同一作用域不能出现同名函数,但在C++中,由于有函数重载(重载可以简单理解成一词多义),所以在同一作用域中可以出现同名函数,但是要求这里同名函数的形参不同,可以是参数类型不同或者个数不同或者顺序不同(用来区分同名函数)。
using namespace std;int Add(int x, int y)
{return x + y;
}double Add(double x, double y)
{return x + y;
}int main()
{int a1 = 1;int a2 = 2;double b1 = 5.2;double b2 = 8.8;cout << Add(a1, a2) << endl;cout << Add(b1, b2) << endl;return 0;
}
注意:
1、函数返回值不同不能作为重载条件,因为调用时无法区分不同返回值。
2、有时候两个函数虽然构成重载,但是有可能存在歧义,调用时编译器也不知道该调用谁,像下面这个例子,两个函数虽然构成重载(参数个数不同),但是调用时都可以不传参调用。
void f1()
{cout << "f()" << endl;
}void f1(int a = 10)
{cout << "f(int a)" << endl;
}
以上就是小编分享的全部内容了,如果觉得不错还请留下免费的赞和收藏
如果有建议欢迎通过评论区或私信留言,感谢您的大力支持。
一键三连好运连连哦~~