前言:
万事开头难,人们总是对未知的领域会感到一丝恐惧,但其实等到熟悉了之后就会发现,更令人恐惧的还在后头。:-(
C++弥补了一些C语言在编程上的不足,并有着一套自己的编码方式,同时兼容C语言。此篇主要对C++中一些基础的零碎知识加以说明,主要针对菜鸟(我)。
1:命名空间
1.1:命名空间的价值
在学习阶段就应该逐渐明白一点:在未来进入企业后,编写的代码不可能是像现在这样:在一个项目中写几十行代码就能解决的事。而是几个人,几十个人,负责一个拥有多个项以及几千行代码的大项目,每个人负责其中一块。
这个时候,倘若大家都把自己的变量、函数封装在全局域,难免会出现重定义,导致很多冲突。
因此,这个时候就需要用到命名空间。它在C++中的作用便是将变量隔离起来,使其存在于命名空间当中,与全局域中的变量和函数不再冲突
1.2:命名空间的创建和使用
1.2.1:命名空间的创建
namespace date
{
int year = 2024;
int month = 9;
int day = 12;
void Days(int _year, int _month, int _day)
{
printf("%d/%d/%d", _year, _month, _day);
}
}
与C语言中创建结构体类似,但是注意最后不需要加分号。
1.2.2:命名空间的使用
int main()
{
int year = 2024;
int month = 10;
int day = 13;
printf("%d/%d/%d\n", year, month, day);
//命名空间域变量的调用
printf("%d/%d/%d\n", date::year, date::month, date::day);
//命名空间域函数的调用
date::Days(2025, 10, 13);
return 0;
}
如果要调用命名空间中的变量,需要如上代码所示,需要加上 命名空间的名字 + :: + 命名空间域的变量名才能够对其正常访问。
结果如下图所示,可以看到虽然局部域和命名空间域有着相同变量 year 、 month 、 day 但是打印出来的结果完全不同。
其次可以使用 using 将命名空间中的某个成员展开,相当于把这个变量从命名空间域转 变为全局域。
加using前:
加 using 后:
或者可以展开命名空间内所有变量/函数,代码如下:
实战中非常不推荐全部展开,这次仅作了解即可。
1.2.3:其他注意点
①:namespace只能定义在全局,其次namespace可以嵌套定义,定义和使用的代码如下:
namespace s
{
namespace s1
{
char name[] = "zhangsan";
int age = 20;
}
namespace s2
{
char name[] = "wangwu";
int age = 19;
}
void print(char* name, int age)
{
printf("%s %d", name, age);
}
}
int main()
{
s::print(s::s1::name, s::s1::age);
printf("\n");
s::print(s::s2::name, s::s2::age);
return 0;
}
②:项目工程中多个文件定义的同名namespace会认为是同一个namespace,不会冲突
③:C++标准库都放在一个叫做std(standard)的命名空间中
2:C++输入&输出
2.1:简要介绍
C++的 输入&输出 都包含在 <iostream> 标准库函数中,在VS系列编译器内, <iostream> 也会包含 <stdio.h> 。
前面我们提到,C++的标准库放在 std 的命名空间中,因此我们需要在前面加上 命名空间名:: 才能调用对输入&输出。
std::cout <-----> printf;
std::cin <-----> scanf;
std::endl <-----> \n;
2.2:C++输入&输出的使用
注:C++输入&输出相较于C语言中的输入&输出而言,其不需要考虑变量的类型,系统会帮你自动识别
3:缺省参数
3.1:缺省参数的定义:
当函数调用不传实参时,函数则会使用 声明或定义(如果同时存在声明和定义,那么参省值只能在声明中定义) 中给定的惨省值
需要注意:
①:参省值只能从右往左给。(从左往右给没有意义,因为实参不能从左往右省略)
②:实参值的省略只能从右往左省,不能跳过。
如下示意:
3.2:演示代码
正确示范:
错误示范1:
错误示范2:
4:函数重载
4.1:定义
自定义函数会根据实参的类型自动对号入座,即使函数名相同,例如实参传递的是两个 int 数据 ,那么该实参会自动传递给形参也为两个 int 型的函数。
4.1:参数类型不同
4.2:参数个数不同
5:引用
在学习引用之前,必须明确几点
对于指针而言,指针可以访问原变量,但是他们不是一个东西
int a;
int* p = &a;
//定义一个a
//将a的地址存放进p
//此时p有自己对应的地址,p中存放的是a的地址
//p和a的地址不同
而对于引用而言,通过引用定义的变量和原变量两个是同一个,地址是一样的。
就好比三国时期的 "曹操"和"曹孟德" 是指同一个人。
注:
&在数据类型后是:引用
&在变量名前是:取地址
5.1:引用的特性
①:引用在定义时必须初始化,不像指针,指针不初始化它只是一个野指针
错误示范:
正确示范:
②:一个变量可以有多个引用
③:一个变量引用一个实体,不能再引用其他实体
5.2:引用的使用
引用的使用是为了简化程序,避开复杂的指针,它与指针是相辅相成的关系,二者在某些应用场景不可相互替代。
用引用接收实参:
5.3:const引用
const引用会涉及一个权限放大缩小的问题,如下:
变量 a 是由 const 修饰的 可读不可修改的数据;
而底下 p1 则是 可读可修改的数据,这样 a 的权限就被放大了,这是不可行的,因此变量 p1 前也需要加 const 修饰,使其变成 可读不可修改的 的数据,如下:
其次,const引用 除了可以引用const修饰的变量时,也可以引用普通对象, 这属于**权限的缩小,这是可行的,**如下:
需要注意的的是类似 int & rb = a*3 ; double d = 12.34; int& rd = d; 这些场景中 a*3 的结果保存在一个临时对象中,double类型数据d转变为int,在数据类型转变时会产生临时对象存储中间值,也就是说 rb 和 rd 引用的都是临时对象 ,而C++中规定,临时对象具有常性,必须要 const引用 ,否则会报错(权限的放大),如下图:
注:所谓的临时对象,就是:编译器需要一个空间暂存表达式的求值结果,从而临时创建的一个未命名的对象,C++中把这个未命名的对象叫做临时对象。