【C++初阶】C++入门(上)
🥕个人主页:开敲🍉
🔥所属专栏:C++🥭
🌼文章目录🌼
[0. 前言](#0. 前言)
[1. C++关键字](#1. C++关键字)
[2. C++输入输出](#2. C++输入输出)
[3. 命名空间](#3. 命名空间)
[3.1 命名空间的用法和定义](#3.1 命名空间的用法和定义)
[3.2 命名空间使用](#3.2 命名空间使用)
[4. 缺省参数](#4. 缺省参数)
[4.1 缺省参数的概念](#4.1 缺省参数的概念)
[4.2 缺省参数的分类](#4.2 缺省参数的分类)
[5. 函数重载](#5. 函数重载)
[5.1 函数重载的概念](#5.1 函数重载的概念)
0. 前言
C++是在C的基础之上,容纳进去了面向对象的编程思想,并增加了许多有用的库以及编程范式
等。熟悉C语言之后,对C++学习有一定的帮助,本文主要目标:
① 补充C语言语法的不足,以及C++是如何对C语言设计不合理的地方进行优化的,比如:作用
域方面、IO方面、函数方面、指针方面、宏方面等。
② 为后续学习类和对象打基础
1. C++关键字
C++总计63个关键字,C语言32个关键字:
2. C++输入输出
新生婴儿会以自己独特的方式向这个崭新的世界打招呼,C++刚出来后,也算是一个新事物,那C++是否也应该向这个美好的世界来声问候呢?我们来看下C++是如何来实现问候的。
说明:
① 使用cout标准输出对象(控制台)和cin标准输入对象(键盘)时,必须包含< iostream >头文件
以及按命名空间使用方法使用std。
② cout和cin是全局的流对象,endl是特殊的C++符号,表示换行输出,他们都包含在包含<
iostream >头文件中。
③ << 是流插入运算符;>> 是流提取运算符。
④ 使用C++输入输出更方便,不需要像printf/scanf输入输出时那样,需要手动控制格式。
C++的输入输出可以自动识别变量类型。
⑤ 实际上cout和cin分别是ostream和istream类型的对象,>>和<<也涉及运算符重载等知识,
这些知识我们我们后续才会学习,所以我们这里只是简单学习他们的使用。后面我们还有有
一个章节更深入的学习IO流用法及原理。
注意:早期标准库将所有功能在全局域中实现,声明在.h后缀的头文件中,使用时只需包含对应头文件即可,后来将其实现在std命名空间下,为了和C头文件区分,也为了正确使用命名空间,规定C++头文件不带.h;旧编译器(vc 6.0)中还支持<iostream.h>格式,后续编译器已不支持,因此推荐使用<iostream>+std的方式**。**
此外,这种输出形式还可以自动识别变量的类型:
std命名空间的使用惯例:
std是C++标准库的命名空间,如何展开std使用更合理呢?
① 在日常练习中,建议直接using namespace std即可,这样就很方便。
② using namespace std展开,标准库就全部暴露出来了,如果我们定义跟库重名的类型/对
象/函数,就存在冲突问题。该问题在日常练习中很少出现,但是项目开发中代码较多、规模
大,就很容易出现。所以建议在项目开发中使用,像std::cout这样使用时指定命名空间 +
using std::cout展开常用的库对象/类型等方式。
3. 命名空间
在我们实际的编程中,我们有时会遇到定义的函数或者变量等的名字发生冲突,在过去学习C语言时遇到这类冲突我们往往只能够修改发生冲突的其中一个或者几个。而当我们学习了C++后,就可以很好地避免这类问题------命名空间。
3.1 命名空间的用法和定义
来看下面一段代码:
可以看到,我们创建了一个rand地变量并想要打印rand的值,但是却出错了,这是为什么呢?
这是因为,我们包含了<stdlib.h>的头文件,而这个头文件中有一个名为rand的函数,正是因为这个函数和我们的变量名冲突了,因此发生了错误,当我们不包含这个头文件时,就不会出错:
但是我们总不能因为这个变量名冲突就不包含这个头文件吧,但是我们又不想修改变量名,这就可以用到我们C++中的命名空间,定义命名空间,需要使用到namespace关键字,后面跟命名空间的名字,然后接一对{}即可{}中即为命名空间的成员:
但是这里又出现了一个新的问题,为什么打印出来的rand是个随机值呢?这就跟访问命名空间中的成员有关了。
3.2 命名空间使用
在我们需要访问某一命名空间中的成员时,需要在前面加上命名空间名及作用域限定符 **::**如下:
这样就可以访问其中的成员了。
同时我们也可以在命名空间中定义函数:
使用时同样也遵循上面的访问形式:
我们还可以在命名空间中定义结构体:
访问时我们就需要自己创建结构体变量,通过结构体变量访问数据:
命名空间的使用总共有三种方法:
① 加命名空间名及作用域限定符:
②****使用using将整个命名空间引入:
命名空间可以看作是一堵墙,当我们没有将整个命名空间引入时,我们只能爬上这堵墙去访问墙里面的成员;当我们将整个命名空间引入后,就相当于这堵墙被我们拆掉了,就不用再爬上这堵墙去访问墙里面的成员了。
③****使用using将命名空间中的某个成员引入:
将命名空间中的某个成员引入就相当于在命名空间这堵墙上开了专属于这个成员的洞,只有这个成员能够通过这个洞,未引入的成员则不行。
4. 缺省参数
4.1 缺省参数的概念
缺省参数是声明或定义函数时为函数的参数指定一个缺省值。在调用该函数时,如果没有指定实
参则采用该形参的缺省值,否则使用指定的实参。
4.2 缺省参数的分类
① 全缺省参数:
② 半缺省参数:
注意:
① 使用半缺省参数时必须遵顼从左往右连续缺省,不能出现如下情况:
② 使用半缺省参数时,有多少个非缺省参数就要传多少个值:
③ 缺省值必须为常量或者全局变量
④ C语言不支持缺省参数
5. 函数重载
自然语言中,一个词可以有多重含义,人们可以通过上下文来判断该词真实的含义,即该词被重
载了。比如:以前有一个笑话,国有两个体育项目大家根本不用看,也不用担心。一个是乒乓球,一个是男足。前者是"谁也赢不了!",后者是"谁也赢不了!
5.1 函数重载的概念
函数重载 :是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这
些同名函数的形参列表 (参数个数 或 类型 或 类型顺序 )不同,常用来处理实现功能类似数据类型
不同的问题。
当我们不懂函数重载是什么的时候,光看上面的代码会觉得十分荒谬,因为在我们之前学习C语言时,调用同一个函数时一定是去到同一个函数当中运算,就像上面,都是调用Add函数,那么应当去到其中一个函数中完成两次的运算,但是很显然,上面的结果是两个不同的运算得出的结果。
这就是函数重载,接下来介绍三种函数重载的出现:
① 参数类型不同:
如图,两个函数虽然函数名相同,都为Add,但是它们的参数类型不相同。第一个Add的参数类型都是int;第二个Add的参数类型都是double,这就出现了函数重载。当你传递不同的类型的值时,它们会调用不同的函数。当传int类型的值时,它会调用第一个Add完成运算;当传double类型的值时,它会调用第二个Add进行运算。
注意:这里虽然两个Add函数返回的参数类型不同,但是这并不影响函数的重载,函数的重载跟返回值的类型没有任何关系。
② 参数个数不同:
如图,两个函数虽然函数名相同,但是它们的参数个数不同。第一个Add有两个参数x和y;第二个Add有三个参数x、y和z,这样就出现了函数重载。当你传递不同个数的参数时,它们会调用不同的函数。当传2个参数时,它会调用第一个Add完成运算;当你传递三个参数时,它会调用第二个Add完成运算。
③ 类型顺序不同:
如图,两个函数虽然函数名相同,但是它们的类型顺序不同。第一个Add的第一个参数是int类型,第二个参数是double类型;第二个Add的第一个参数是double类型,第二个参数是int类型,这就出现了函数重载。根据你传递参数的类型顺序,它们会调用不同的函数。当你先传int类型的参数,后传double类型的参数时,它会调用第一个Add完成运算;当你先传double类型的参数,后传int类型的参数时,它会调用第二个Add完成运算。