文章目录
c++关键字
c语言中一共有32个关键字,c++一共有63个关键字

这里只是初步做一个了解,等以后见到了,会具体展开的讲。
命名空间
c语言命名冲突问题
我们先来看一个代码

在c/c++语言中,会先从离代码最近的地方进行查找(先局部后全局),虽然有一个函数scanf但是由于int scanf离代码最近,所以编译器并不会把scanf当作函数。这就造成了错误。且c语言不能实现scanf和scanf变量一起达成正确使用的目的,所以c++有了一个好的解决办法。
命名空间
为了弥补c语言的缺陷,c++引入了命名空间namespace的定义,要想解决冲突问题,只能使用命名空间,命名空间实际上是一个域。
如果想要实现不同的功能,指出来源即可,其中std就是一个域,c++把所有库表示符的名字都放在了std这个命名空间里面。

命名空间的定义
定义命名空间,需要使用到namespace关键字,后面跟命名空间的名字,然后接一对{}即可,{}中即为命名空间的成员。
//1. 普通的命名空间
namespace N1 // N1为命名空间的名称
{
// 命名空间中的内容,既可以定义变量,也可以定义函数
int a;
int Add(int left, int right)
{
return left + right;
}
}
//2. 命名空间可以嵌套
namespace N2
{
int a;
int b;
int Add(int left, int right)
{
return left + right;
}
namespace N3
{
int c;
int d;
int Sub(int left, int right)
{
return left - right;
}
}
}
//3. 同一个工程中允许存在多个相同名称的命名空间,编译器最后会合成同一个命名空间中。
namespace N1
{
int Mul(int left, int right)
{
return left * right;
}
}
标准库的使用
我们要使用标准库内的东西,有三种方式
(1)指定命名空间,比较麻烦,每个地方都要指定,但是他是最规范的方式。上图就是第一种方式
int main()
{
printf("%d\n", N::a);
return 0;
}
(2)把std整个展开相当于库里面的东西都到全局域里了,看起来也方便了不少,但是如果我们自己定义的东西和库冲突就没办法解决了,我们为了图方便,平日里日常练习用的就是这种方式。
using namespce N;
int main()
{
printf("%d\n", N::a);
printf("%d\n", b);
Add(10, 20);
return 0;
}
(3)对常用的库里面的东西展开,以后做项目经常用这种方式,这种方式是方式一和方式二的折中办法
using N::b;
int main()
{
printf("%d\n", N::a);
printf("%d\n", b);
return 0;
}
缺省参数
缺省参数的概念
缺省参数是声明或定义函数时为函数的参数指定一个默认值。在调用该函数时,如果没有指定实参则采用该默认值,否则使用指定的实参。
void TestFunc(int a = 0) {
cout<<a<<endl; }
int main()
{
TestFunc(); // 没有传参时,使用参数的默认值
TestFunc(10); // 传参时,使用指定的实参
}
缺省参数分类
全缺省参数
void TestFunc(int a = 10, int b = 20, int c = 30) {
cout<<"a = "<<a<<endl;
cout<<"b = "<<b<<endl;
cout<<"c = "<<c<<endl; }
半缺省参数
void TestFunc(int a, int b = 10, int c = 20) {
cout<<"a = "<<a<<endl;
cout<<"b = "<<b<<endl;
cout<<"c = "<<c<<endl; }
需要注意的是
- 半缺省参数必须从右往左依次来给出,不能间隔着给
- 缺省参数不能在函数声明和定义中同时出现,最好声明给缺省,但是定义不给。

//a.h
void TestFunc(int a = 10);
// a.c
void TestFunc(int a = 20)
{}
// 注意:如果生命与定义位置同时出现,恰巧两个位置提供的值不同,那编译器就无法确定到底该用那
个缺省值。
3.缺省值必须是常量或者全局变量
4.c语言不能使用缺省参数
函数重载
函数重载定义
函数重载:是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的形参列表(参数个数 或 类型 或 顺序)必须不同,常用来处理实现功能类似数据类型不同的问题
int Add(int left, int right) {
return left+right;
}
double Add(double left, double right) {
return left+right;
}
long Add(long left, long right) {
return left+right;
}
int main()
{
Add(10, 20);
Add(10.0, 20.0);
Add(10L, 20L);
return 0;
}
要构成函数重载只能参数类型不同,或者参数个数不同,其余都不叫函数重载
问:下面这两个函数构成函数重载吗
short Add(short left, short right) {
return left+right;
}
int Add(short left, short right) {
return left+right;
}
显然是构不成的因为这两个函数参数个数、类型都相同。不满足构成重载函数的条件
问:这两个函数是重载吗?

根据条件,这两个函数参数个数不同,所以构成重载,但是却会发生冲突。至于为什么大家可以自行去编译器试试(提示:f(1,2)到底会调用哪个函数呢?)不明确所以构成冲突
引用(别名)
引用的概念
引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空间,它和它引用的变量共用同一块内存空间。
公式:类型& 引用变量名(对象名) = 引用实体;
void TestRef()
{
int a = 10;
int& ra = a;//<====定义引用类型
printf("%p\n", &a);
printf("%p\n", &ra);
}
引用的特性
- 引用在定义时必须初始化
- 一个变量可以有多个引用
- 引用一旦引用一个实体,再不能引用其他实体
void TestRef()
{
int a = 10;
// int& ra; // 该条语句编译时会出错
int& ra = a;
int& rra = a;
printf(“%p %p %p\n”, &a, &ra, &rra);
}
(超重点)常引用
void TestConstRef()
{
const int a = 10;
//int& ra = a; // 该语句编译时会出错,a为常量
const int& ra = a;
// int& b = 10; // 该语句编译时会出错,b为常量
const int& b = 10;
double d = 12.34;
//int& rd = d; // 该语句编译时会出错,类型不同
const int& rd = d;
}


大家思考一下这两个哪个对,哪个错,思考玩接着往下看。
答案:一错二对。原因就是因为a原本就是一个常变量,如果用int&就那么ra(a的别名就不具有常性了(可以修改)),那么就说明ra的权限大于原本的a了,那是万万不行的。
请大家务必记住下面这个图

大家继续思考下面这个代码,哪个引用才是对的呢?
int c=0;
double &rc=c;
const double &rc=c;
提示(隐式转换和强制转换一样会产生一个临时变量,且临时变量具有常性)
答案2才是对的,原因就是这个代码明显发生了隐式转换,c要转化成临时的double类型的变量,所以这里引用的对象应该的这个double类型的临时变量,而临时变量具有常性。所以应该用第二种方法引用。大家明白了吗?

如何证明呢?大家看看下面这个图

传值返回
函数传值返回返回的是返回对象的临时拷贝


由于c返回的是临时变量具有常性,所以要加const,且引用和c的地址并不相同,而是和临时变量地址相同。
传引用返回
函数传引用返回返回的是返回对象的引用

大家看看上面的题输出什么?答案其实是12。请思考后接着往下看
由于返回的是引用,就是返回了函数变量c的别名,ret和c的地址是一模一样的,由于第一次调用后会销毁栈帧,在此地址上存了一个值3,如果再次调用,会在相同的位置(c的地址处)也就是c的地址上再次覆盖12,由于两次调用储存数据的地址是一模一样的,所以会输出12。
未完待续
这篇就到这里,还有一部分分别是内联函数,atuo,和范围for的使用,下篇接着写
本文详细介绍了C++中的命名空间解决命名冲突,如何使用标准库,包括缺省参数、函数重载和引用的深入理解。特别强调了常引用和传引用的区别,并通过实例演示了关键概念和实践应用。
2113

被折叠的 条评论
为什么被折叠?



