骚年,是不是还在为你的变量名称和库函数冲突而苦恼,是不是还在为了自己的变量名和队友的不一样和发愁
c++作为c语言的升级版,弥补了许多c中的空白和不足。
c++的升级
一:命名空间
演示(肯定是创建命名空间啊)
namespace name(命名空间的名字)//作为全局变量,放到静到区,可以初始化,不能进行运算
{
int rand = 0;
namespace name2//可以进行嵌套
{
int rand1 = 0;
}
}
特点
特点1.可以定义变量,函数,类型(结构体)等
特点2.可以嵌套使用(如上)
特点3.同一个工程中允许存在相同名字的命名空间,系统会自动将其合并
使用方法
1.使用符号
:作用域限定域(::)
例如
int main()
{
printf("%d", name::rand);//空间名::变量名
}
注意(老版):
当进行命名空间中的结构体的使用时,应将struct放与空间名之前(现在不需要)
namespace name
{
struct sp
{
int a = 0;
int b = 0;
};
}
int main()
{
struct name::sp spp;//代表其为结构体,命名在命名空间
spp.a = 1;
}
注意:现在可以支持直接name::sp spp创建结构体,不需要在前面加个struct,因为现在c++已经将结构体归为类中,可直接使用
2.一次性全部展开:
using namespace name(空间名字)
例如你们敲熟练的
#include<iostream>
using namespace std;
std就是在iostream这个头文件中的命名空间,这样子就将std中的函数,变量等在整个程序展开
3.只展开特定函数
#include<iostream>
using namespace std::cout;
这样只展开了std中cout这个函数
二.允许缺省函数的存在
定义:
缺省函数: 就是在声明函数的参数时同时赋予一个缺省值(默认值)(即为初始值),在调用该函数的时候如果没有指定该参数的值,则采用该缺省值(默认值)(即为初始值)。
例如
void Func(int a=0 ,int b=0 ,int c = 0)//在声明的同时提供初始值
{
}
因为有了初始值,所以提供了一个可以方便使用(偷懒)的调用方式,即只需要函数名,不需要传参
int main_1()
{
Func();
return 0;
}
注意:偷懒是有代价的,存在一些必须遵守的规则
1.支持省略的类型:
1.全缺省
全部赋予初始值
void Func(int a=0 ,int b=0 ,int c = 0)//在声明的同时提供初始值
{
}
2.半缺省
不是缺省一半,是省略部分参数,必须从右往左缺省(即提供初始值)
void Func(int a,int b ,int c = 0)//初始化最右边的变量
{
}
void Func(int a ,int b=0 ,int c = 0)//初始化最右边和中间的变量
{
}
注意:
缺省参数不可以同时在声明和定义中出现,建议出现在声明中
如在头文件func.h和func.c中都使用了func函数,并进行了缺省,那么最好在声明中进行缺省,即在func.h中进行缺省
接下来便是重中之重(敲黑板!)
函数重载
(即允许同名函数存在)(蠢蠢的c语言不可能做到的事)
先来看看例子(找不同)
void add(int a, char b)
{
}
void add(char a, int b)
{
}
答案:第一个add中,第一个变量类型为int,第二个为char;第二个add中,第一个变量类型为char,第二个才为int。运行程序不报错。
有此可知,cpp中支持重名函数(即函数重载)
使用规则
1.函数中变量类型不同
如
void add(int a)
{
}
void add(char a)
{
}
2.函数中变量数量不同
如
void add()
{
}
void add(int b)//出现歧义特别是使用add()时
{
}
特别注意:当调用add时使用add(),会引发歧义,应避免这种写法
3.函数中变量顺序不同
void add(int a, char b)
{
}
void add(char a, int b)
{
}
注意:
有两种情况不构成重载
1.只是返回返回值不同不构成重载,原因会在后面的底层原理介绍
2.如果一个函数附初始值,另一个函数不附初始值,不可以构成重构,原因同样会在后面的底层原理介绍。
底层原理
为什么c中不可以实现函数重载,c++可以?
这就要提到编译器对代码实现的操作过程,即编译器的编译过程
编译过程
1.预处理—>头文件展开,宏替换,条件编译,去掉注释 生成func.i
2.编译:检查语法,生成汇编代码func.s
3.汇编,汇编代码转化为二进制机器码func.o
4.链接a.out
c不支持函数重载原因:
因为编译时两个重载函数,编译器给两个函数的函数名相同,编译器都是直接使用函数名去查找,而重载函数函数名相同在func.o中因为名字相同存在歧义和冲突,其次链接的时候名字地址相同也存在歧义和冲突
c++支持原因
c++不是直接使用函数名来标识和查找函数。
1.存在函数名修饰规则
不同编译器的修饰规则不同,如g++编译器中为 : z+函数名长度+函数名+参数首字母(注意:不同编译器下面修饰规则不同)
由此可以解释为什么上面两种情况不构成重载,因为编译器编译后函数的名字是一模一样的
2.因为存在函数名修饰规则
只有参数不同,func.o符号表中的重载函数的名称和地址也是不同的,不存在二义性和冲突,链接的时候,text.o的main函数去调用两个重载函数时查找的地址也是明确的。
夹带点私货
https://music.163.com/song?id=1953104779&userid=1480597654
hanser星穹铁道的角色曲(超燃!hanser超帅!)
(原子dan老师的海伊!)