前言:首先感谢每一位老粉丝们的陪伴,从一开始的C语言初阶到C语言进阶,作者用了三个月的时间才学完并更新完对应的博客,后边数据结构初阶部分(数据结构进阶的内容会混在C++当中)又花了大概俩个多月的时间,接下来就开启新篇章啦,进入C++部分!
开篇之前先膜下 本贾尼·斯特劳斯特卢普 老爷子,希望大家C++学得都顺利哈!!!
其实为什么一开始要先学习C语言,而不是一下子直接上手C++呢?因为作者本人是非科班的学生,主要还是考虑到基础必须打牢的原因!!!在确定转码的学习路线过程当中作者本人也要到了不少985科班同学们的培养方案,与一些前辈们交流之后认为C语言的学习对于后续计算机知识的学习会大有裨益。
事实上C语言当中有的内容,比如函数、循环、结构体、宏等等内容,C++也都有,所以大家千万不要认为C语言白学了哈!因为之前已经完整更新过C语言的博客(有需要可以往前翻),所以C++这里直接介绍C++相对C语言当中新增的内容,而本章引入的内容是C++的关键字、命名空间、缺省参数、IO、函数重载。
1.关键字
我们在C语言中学习了32个关键字,既然C++是对C语言内容的补充和添加,那么C++中也含有关键字,其中就除了C语言中的32个关键字,C++又新增了31个关键字,一共63个关键字。
2.命名空间
相信这俩行代码大部分读者都见过,但你知道第二行代码using namespace std; 具体是干嘛的吗?
#include <iostream>
using namespace std;
这就要先讲讲为什么会有命名空间了?
在C语言中,一个工程的建立我们可能需要创建大量的变量、函数、类等,而这些内容都将存在于全局域中,如果在相同作用域下声明相同名字变量,函数等编译器将会报错,于是为了解决这种情况,C++提出了命名空间的概念。
那为什么会有在相同作用域下声明相同名字变量,函数的需求呢?
这是因为当所有人都在为同一个项目工作时,一个工程项目的实现往往需要拆解成很多块,具体给到不同的程序员手里,每个人负责的板块不一样,这样就会出现一个问题。比如程序员A和程序员B都要实现一个加法函数(这个加法函数具体功能可能不同),程序员A和程序员B可能都会想到为自己的加法函数起名为ADD,就会导致函数重名,编译器报错,所以需要命名空间。
2.1 命名空间的定义
定义 命名空间时,我们现在知道需要namespace这个关键字,后面更加命名空间的名字,然后像创建一个函数一样,用{}进行内容的包裹,而这其中的内容就是命名空间的成员。一个命名空间就相当于定义了一个新的作用域,命名空间中的所有内容都局限于命名空间中。
代码1
定义个叫“linmanman”的命名空间中,在这个空间中定义变量和函数
namespace linmanman
{
int a = 10;
int b = 20;
int Add(int x, int y)
{
return x + y;
}
}
代码2
命名空间的嵌套定义
namespace linmanman
{
int a = 10;
int b = 20;
namespace lin
{
int x = 10;
int y = 20;
int Add(int x, int y)
{
return x + y;
}
}
}
代码3
命名空间可合并,当有多个一样的命名空间时,编译器会自动将他们整合在一起。
namespace linmanman
{
int a = 10;
int b = 20;
int Add(int x, int y)
{
return x + y;
}
}
namespace linmanman
{
int x = 10;
int y = 20;
}
2.2 命名空间的使用方法
2.2.1 全部直接展开到全局
namespace lin
{
int a = 20;
int b = 10;
}
using namespace lin;
int main()
{
printf("a的值为:%d\n", a);
return 0;
}
2.2.2 使用命名空间名称+作用域限定符::
如命名空间名::成员名
namespace lin
{
int a = 20;
int b = 10;
}
int main()
{
printf("a的值为:%d\n", lin::a);
//这里我们可以理解为作用域限定符"::"的使用,让我们在lin这个命名空间中找到了a这个变量
return 0;
}
2.2.3 使用using将命名空间中常用的成员引入
namespace lin
{
int a = 20;
int b = 10;
}
using lin::a;
int main()
{
printf("a的值为:%d\n", a);
return 0;
}
3.输入&输出
同样是“hellow world”,让我们看看在C++这门编译语言中,我们应该如何实现这句代码呢?在C++中的实现和C语言有什么区别呢?下面让我们先看实现的代码,然后我们再进行分析。
#include<iostream>
using namespace std;
int main()
{
cout << "Hellow world" << endl;
double b;
char c;
cin >> b >> c;
cout << b << " " << c << endl;
return 0;
}
知识点分析
1.使用cout标准输出(控制台)和cin标准输出(控制台)时,必须包含头文件以及std标准命名空间。
2.cin可以不再像scanf那样该一个变量输入值需要取地址 且按照相应的格式,比如%d ,cin的输入格式为cin >> 变量名; cout的使用不像c语言中的printf 一样需要按照各种格式输出,而是直接按照格式cout << 变量名;
3.有没有注意到,C语言中输入输出需要考虑数据的类型,而在C++中进行输入输出时,是不需要考虑数据的类型的。
4.缺省参数
4.1缺省参数的定义
缺省参数是声明或者定义函数时为函数的参数指定一个默认值,在调用函数的时,如果没有指定实参则采用该默认值,否则使用指定的实参。
实例:
void Test(int a = 1)
{
cout << a << endl;
}
int main()
{
Test();
Test(100);
return 0;
}
分析:
在Test()中,没有传参,默认使用缺省参数,a的输出值为1;
在Test(100)中,有传参,这时不使用缺省参数,a的输出值为100。
4.2 缺省参数的分类
4.2.1全缺省参数
所有参数我们都将其设置为缺省参数
void Test(int a = 10; int b = 20; int c = 30)
{
cout << "a = " << a << endl;
cout << "a = " << b << endl;
cout << "a = " << c << endl;
}
4.2.2 半缺省参数
将函数中的部分参数设置为缺省参数,注意缺省参数其必须从右到左设置,且不能间隔设置。
void TestFunc(int a, int b = 10, int c = 20)
{
cout<<"a = "<<a<<endl;
cout<<"b = "<<b<<endl;
cout<<"c = "<<c<<endl;
}
缺省参数不能在函数声明和定义中同时出现,原因一样,所以一般是在声明中写默认参数。
5.函数重载
5.1 函数重载的定义
函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的形参列表(参数个数 或 类型 或 顺序)必须不同,常用来处理实现功能类似数据类型不同的问题。
举例如下代码均为函数重载
函数返回类型无所谓,关键在于形参列表(参数个数 或 类型 或 顺序)必须不同。
int Add(int a, int b)
{
return a + b;
}
int Add(int a, double b)
{
return a + b;
}
double Add(double a, double b)
{
return a + b;
}
5.2 为什么C++有函数重载,C语言却没有,C++是如何实现函数重载的呢?
我们知道,c程序在链接阶段,会把所有目标文件进行整合,最终形成.exe文件,而在整合过程中,会有一步符号表汇聚,所以,在c语言中如果有多个相同名字的函数,链接阶段将不知道所调用的函数到底是同名函数中的具体哪一个,进而导致编译器报错。
那为什么C语言会有函数重载,编译器不会报错呢?
因为在C++中,形成符号表的时候,会对重名函数进行修饰,修饰原则是_Z n name t.其中n是函数名长度,name是函数名,t是所有参数类型的首字母缩写.
例如
int Add(int a, int b)
{
return a + b;
}
int Add(int a, double b)
{
return a + b;
}
当我们在C++的环境中时,我们通过编译的一些方式可以获得如下内容,能观察到函数重载之后这俩Add函数的地址是不同的。
我们清楚了函数重载的原理,要求参数不同,这样修饰出来的名字也就不同了。
5.3 如果去修改编译器,能不能实现函数名相同、参数相同但返回值不同时,也构成重载?
结论:不行!
比如以下这俩func函数,仅仅是函数返回值不同,尝试把返回值引入修饰规则当中,即便编译器层面过得去,语法调用层面也很难通过!
C++的关键字、命名空间、缺省参数、IO、函数重载内容到此介绍结束了,感谢您的阅读!!!如果内容对你有帮助的话,记得给我三连(点赞、收藏、关注)——做个手有余香的人。
|