目录
一.对C++的认识
二.C++的关键字
三.命名空间
3.1命名空间的定义
3.2命名空间的使用
四.C++的输入与输出
五.缺省参数
5.1全缺省参数
5.2半缺省参数
六.函数重载
七.引用
7.1引用的特性
7.2引用和指针的区别
八.内联函数
九.auto关键字(C++11)
十.范围for循环(C++11)
十一.nullptr关键字(C++11)
一.对C++的认识
首先让我们认识一下祖师爷: 本贾尼·斯特劳斯特卢普
接下来我们就需要了解为什么会有C++语言。
C语言是结构化和模块化的语言,适合处理较小规模的程序。对于复杂的问题,规模较大的 程序,需要高度的抽象和建模时,C语言则不合适。为了解决软件危机, 20世纪80年代, 计算机 界提出了OOP(object oriented programming:面向对象)思想,支持面向对象的程序设计语言 应运而生。
1979年,贝尔实验室的本贾尼等人试图分析unix内核的时候,试图将内核模块化,于是在C 语言的基础上进行扩展,增加了类的机制,完成了一个可以运行的预处理程序,称之为C with classes。
1982年,Bjarne Stroustrup博士在C语言的基础上引入并扩充了面向对象的概念,发明了一种新的程序语言。为了表达该语言与C语言的渊源关系,命名为C++。因此:C++是基于C语言而 产生的,它既可以进行C语言的过程化程序设计,又可以进行以抽象数据类型为特点的基于对象的 程序设计,还可以进行面向对象的程序设计。
了解了C++的历史,接下来我们就来进入正文了。
二.C++的关键字
C++完全可以兼容C语言,因此,C语言的关键字也是C++的关键字,而且C++对此作了拓展,C++共有63个关键字,会在后续的学习中逐步接触到。
三.命名空间
目的:对标识符的名称进行本地化来避免命名冲突和名字污染。
3.1命名空间的定义
namespace A
{
int A;
void Init();
//可以定义变量/函数/类型,也可以嵌套
namespace B
{
int B;
}
}
在一个工程中允许存在着多个名称相同的命名空间,编译器会将其自动合并。
3.2命名空间的使用
命名空间共有三种使用方式:
1)加命名空间名称以及作用域限定符
2)使用using将命名空间内的某个成员引入
3)使用using namespace 命名空间名称 引入
1) A::a;
2)using A::a
3)using namespace A;
四.C++的输入与输出
和C语言一样,C++的输入和输出也需要包含头文件,C++的头文件为<iostream>
输入: cout <<流插入运算符
输出: cin >>流提取运算符
C++和C不同的是,C++可以自动识别变量类型。
关于std命名空间的使用:
1.日常练习中,建议直接使用using namespace std;即可
2.项目开发中,直接展开可能会造成命名冲突,建议使用形如 std::cout 这种格式,
或指定展开如 using std::cout;
五.缺省参数
缺省参数是声明 或 定义函数时为函数的参数指定一个缺省值。在调用该函数时,如果没有指定实参则采用该形参的缺省值,否则使用指定的实参。
5.1全缺省参数
例如:void Func(int a=20,int b=30,int c=40);
5.2半缺省参数
例如:void Func(int a,int b,int c=10);
注意:
1.半缺省参数必须从右向左依次给出,不能间隔着给
2.缺省参数不能在声明和定义同时出现
3.缺省值必须是常量或全局变量
4.C语言并不支持
六.函数重载
函数重载:是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这 些同名函数的形参列表(参数个数 或 类型 或 类型顺序)不同,常用来处理实现功能类似数据类型 不同的问题。
#include<iostream>
using namespace std;
// 1、参数类型不同
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;
}
// 2、参数个数不同
void f()
{
cout << "f()" << endl;
}
void f(int a)
{
cout << "f(int a)" << endl;
}
// 3、参数类型顺序不同
void f(int a, char b)
{
cout << "f(int a,char b)" << endl;
}
void f(char b, int a)
{
cout << "f(char b, int a)" << endl;
}
int main()
{
Add(10, 20);
Add(10.1, 20.2);
f();
f(10);
f(10, 'a');
f('a', 10);
return 0;
}
问题:为什么C语言不支持函数重载,而C++支持函数重载?
回答:在编译阶段,源文件经过预编译,编译,汇编生成.obj文件,在此过程中C语言不对函数名进行任何处理,而C++则对函数名进行修饰。接下来,源文件需要与头文件进行链接生成可执行程序。在C语言中,源文件与头文件链接时是直接通过函数名去检索,而C++是使用修饰后的函数名去检索,从而造成差异。
七.引用
引用从某种意义上来说就是给给已经存在的变量取了个别名。编译器并不会为它开辟一块新的空间。
7.1引用的特性
引用在定义时必须初始化。
一个变量可以有多个引用,而一个引用只能对应一个变量。
引用的效率比传值调用要高,因为传值调用需要为新变量开辟空间。
7.2引用和指针的区别
语法上:引用是取别名,没有独立空间。
底层实现上:引用是按指针方式实现的。
但在一般情况下不考虑底层实现。
1. 引用概念上定义一个变量的别名,指针存储一个变量地址。
2. 引用在定义时必须初始化,指针没有要求
3. 引用在初始化时引用一个实体后,就不能再引用其他实体,而指针可以在任何时候指向
任何 一个同类型实体
4. 没有NULL引用,但有NULL指针
5. 在sizeof中含义不同:引用结果为引用类型的大小,但指针始终不变。
6. 引用自加即引用的实体增加1,指针自加即指针向后偏移一个类型的大小
7. 有多级指针,但是没有多级引用
8. 访问实体方式不同,指针需要显式解引用,引用编译器自己处理
9. 引用比指针使用起来相对更安全
八.内联函数
关键字:inline
1)inline对于编译器而言只是建议,而最终的结果取决于编译器。
2)inline不支持声明定义分离,分离会导致链接错误,因为inline被展开没有函数地址,无法链接。
九.auto关键字(C++11)
早期使用auto修饰表示是具有自动存储器的局部变量(自动销毁)。C++11中,auto不再是一个存储类型指示符,而是作为一 个新的类型指示符来指示编译器,auto声明的变量必须由编译器在编译时期推导而得。
十.范围for循环(C++11)
在C++98中遍历数组可以使用如下方式。
void TestFor()
{
int array[] = { 1, 2, 3, 4, 5 };
for (int i = 0; i < sizeof(array) / sizeof(array[0]); ++i)
array[i] *= 2;
for (int* p = array; p < array + sizeof(array)/ sizeof(array[0]); ++p)
cout << *p << endl;
}
而在C++11中提供了另一种遍历方式。for循环后的括号由冒号“ :”分为两部分:第一部分是范 围内用于迭代的变量,第二部分则表示被迭代的范围。
void TestFor()
{
int array[] = { 1, 2, 3, 4, 5 };
for(auto& e : array)
e *= 2;
for(auto e : array)
cout << e << " ";
return 0;
}
十一.nullptr关键字(C++11)
NULL可能被定义为字面常量0,或者被定义为无类型指针(void*)的常量。因此为了提高代码的健壮性,在后续表示指针空值时建议最好使用nullptr。
在C++11中,sizeof(nullptr) 与 sizeof((void*)0)所占的字节数相同