前言:
C++的诞生,一定程度上源于C语言的缺陷,C语言是结构化、模块化的语言,适合较小规模的程序,面对大型、复杂的问题时,C语言暴露了许多的问题。为了解决这样那样的问题,20世纪80年代,计算机界提出了OOP(object oriented programming:面向对象)思想,支持面向对象的程序设计语言应运而生。
1982年,祖师爷Bjarne Stroustrup博士在C语言的基础上引进并扩充了面向对象的概念,发明了一种新的语言。为了表示该语言与C语言之间的承继关系,该语言被命名为C++;
下面,我的C++学习路,从学习C++对C语言有了哪些优化开始:
就如同刚开始学C语言一样,我们C++学习的第一句代码也是"hello world!",但是较于C语言,C++的形式发生了极大的变化:
一、命名空间:
1、命名冲突
在C语言中我们从未见过这段代码:using namespace std;对它的作用也不了解。实际上,这段代码的作用是用来区分不同作用域下相同名字的函数、类、变量。简单点来说,就是为了防止命名冲突。
那什么是命名冲突呢?请看VCR(不是,请看下面的这例子):
我们都知道C语言中有一个库函数rand是用来生成伪随机数的,那么在包了它的头文件#include<stdlib.h>的情况下,我们重新定义了一个同名变量rand就产生了二者之间(程序员和库)的命名冲突。
两个同名变量x,我打印的到底是0?还是1?如果我就想打印1,C语言怎么实现呢?即我们如何在局部作用域中访问全局变量呢?
2、命名空间的定义:
要让namespace发挥作用,就要遵守它的规则:1、定义命名空间,需要使用到 namespace 关键字 ,后面跟 命名空间的名字 ,然 后接一对 {} 即可, {} 中即为命名空间的成员。命名空间的名字可随意起名。命名空间中可以定义变量/函数/类型2、命名空间可嵌套:3. 同一个工程中允许存在多个相同名称的命名空间,编译器最后会合成同一个命名空间中。 当然,合并了你还是不能产生同名变量。
通过作用域限定符 :: ,实现不同命名空间中的同名变量x 的访问。
那作用域限定符 :: 又是什么呢?
3、作用域限定符 ::
作用域限定符 :: 是C++中用来区别同名的全局变量的。通过它,可以实现在局部域中对全局变量的访问。下图,就是访问全局变量的格式,而如果全局变量位于命名空间中,则需要像上图一样携带命名空间名。
还有一种特殊的使用方式,是结构体的使用:
值得注意的是,作用域限定符 :: 仅适用于全局变量。而我们通过 :: 使用命名空间的成员的,因此,在namespace中包含的全部都是全局变量;
一个命名空间就定义了一个新的作用域,命名空间中的所有内容都局限于该命名空间中。
4、命名空间使用
命名空间的使用有三种方式:
1、加命名空间名称及作用域限定符:当你想访问某个命名空间中的成员时,可以直接在成员名称前加上命名空间的名称和作用域限定符 ::
。
2、使用using
将命名空间中某个成员引入:如果你只想引入命名空间中的一个或几个成员,而不是整个命名空间,可以使用using
声明。这样可以避免在每次引用这些成员时都使用命名空间的名称。
3、使用using namespace 命名空间名称
引入: 如果你想在当前作用域中引入整个命名空间的成员,可以使用using namespace
指令。这样,命名空间中的所有成员在当前作用域中都可以直接使用,而不需要加上命名空间前缀。
using namespace std;
二、 缺省参数
1、缺省参数的概念
缺省参数是声明或定义函数时为函数的参数指定一个缺省值。在调用该函数时,如果没有指定实参则采用该形参的缺省值,否则使用指定的实参。
2、缺省参数的使用:
1、全缺省参数:
2、半缺省参数:
半缺省参数比全缺省参数可就坑多了。
首先,半缺省参数,要求从右向左给定缺省值,不能间隔着给。
其次,半缺省参数,函数调用时,必需给定参数。半缺省参数是指在一个函数的参数列表中,从右往左开始,部分参数有默认值,而部分参数没有默认值。在调用这样的函数时,你可以提供所有参数的值,也可以只提供部分参数的值(即那些没有默认值的参数),而省略那些有默认值的参数。如果你省略了所有有默认值的参数,那么你可以不传递任何参数。
上图,函数有三个参数,但只有
b
和c
有默认值。因此,在调用函数时,你可以省略b
和c
,但你不能省略a
,因为a
没有默认值。如果你尝试调用foo()
而不提供任何参数,编译器将会报错,因为它不知道如何为a
提供一个值。所以,半缺省函数调用并不要求至少提供1个参数,而是要求你至少提供那些没有默认值的参数。
第三,缺省值必须是常量或者全局变量