天天看点

c++---初始函数重载、缺省参数、命名空间等

  • c++的关键字
  • 命名空间
  • c++自己的输入输出
  • 缺省参数
  • 函数重载
  • 引用
  • 内联函数r
  1. c++关键字

    c++的关键字包括了我们的asm、do、if、return、try、continue、auto、double、inline、short、typedef、for、bool、dynamic_case、int、signed、typeid、public、break、else、long、sizeof、typename、throw、case、enum、mutable、static、union、wchar_t、catch、explicit、namespace、static_cast、unsigned、default、char、export、new、struct、using、friend、class、extern、operator、switch、virtual、register、const、false、private、template、void、true、const_cast、float、protected、this、volatile、while、delete、goto、reinterpret_cast。我们将在学习c++过程中慢慢接触到我们的关键字。c++在不断的更新,可能以后我们的关键字会改变,但是万变不离其宗,大多数的关键字还是会保留的。

  2. 命名空间

    命名空间就是用来解决命名冲突的,在一个大项目中,可能自己和别人定义的变量名或者函数名重复的时候就需要使用命名空间。定义命名空间需要使用到那么谁趴厕关键字,后面跟命名空间的名字,然后使用一对{}。在{}中就是我们定义的变量那个或者函数。

    命名空间需要注意的点

  • 命名空间中的内容可以是函数,也可以是变量
  • 命名空间可以嵌套定义
  • 同一个工程中存在多个相同命名空间的时候,编译器会合成所以的命名空间,只使用一个来包含所有的命名空间中的内容
namespace N1{
	int a;
	int b;
	int add(int x,int y){
		return x+y;
	}
}
namespace N2{
	int a;
	namespace N3{
		int y;
	}
}
namespace N1{
	int c;
}
           

在最后一个N1的命名空间的时候我们相当于下面的

namespace N1{
	int a;
	int b;
	int c;
	int add(int x,int y){
		return x+y;
	}
}
           

我们定义好了一个命名空间又怎样去使用它呢,我们使用命名空间的方法有三种

  • 命名空间名称+作用域限定符
  • 使用using将命名空间中成员引入
  • 使用using namespace 命名空间名称引入

    我们推荐前两种,因为在最后一种全部展开的时候是最容易引起命名冲突的。

  1. c++输入输出

    c++有自己的输入输出,在c++中我们使用cin和cout来进行数据的输入和输出,使用cout标准输出和cin标准输入时,需要包含我们的头文件以及我们的std标准命名空间

#include <iostream>
using namespace std;
int main(){
	int i;
	cin >> i;
	cout << "hello world" << endl;
	return 0;
}
           

可能你会想问我们的>><<是干什么用的,这不是我们c语言中的左移和右移。他是指向我们的数据流向的,endl是我们c++中的换行符号,就与我们c语言中的\n是一样的。

  1. 缺省参数

    在c语言中我们的函数在定义的时候我们只能给出我们函数参数的类型,并不能给我们的参数赋值。在我们的c++中我们就可以在函数的参数给于初值,在我们调用函数的时候我们就可以不用给函数赋值。也就是相当于我们生活中的备胎,如果没有给于初值,就使用我们在函数定义的时候给于的初值,在我们给于了值后我们就使用我们调用函数给于的值

  • 全缺省参数

    就是函数中所有的参数都给定了默认的值

  • 半缺省参数

    在函数中只有一部分的参数给定了默认的值

    注意点:

    半缺省参数必须从右到左一次来给出,不能间隔

    缺省参数不能在函数声明和定义中同时出现

    缺省值必须是常量或者全局变量

    c语言不支持

int add(int a,int b = 10);
           

在调用的时候我们就可以

cout << add(4) <<endl;
cout << add(4,20) <<endl;
           

输出的结果就是14和24;

  1. 函数重载

    函数重载就是函数名相同,函数的参数的个数类型,顺序必须不同就是函数的重载。

int add(int x,int y){
	return x+y;
}
double add(int x,int y){
	return x+y;
}
           

上面两个函数就是重载的函数

那为什么c++能够去支持我们的函数重载呢?

重点一个c/c++程序要运行的话就需要尽力预处理、编译、汇编、链接四个步骤。在我们的https://blog.csdn.net/boke_fengwei/article/details/88724548博客中讲解了我们的四个步骤的详细过程。在c语言中名字修饰就在函数的名字前面加上下划线,在c语言中如果有相同的函数名的时候就会链接错误,因为在底层有两个相同的函数名字,但是在c++中我们是使用的函数名加上我们的参数类型来命名的。比如我们上面的两个函数会命名成_addii和_adddd就形成了两个不同的函数。c语言对于两个函数都会形成_add。这就是为什么我们的c++满足函数重载,但是我们的c语言不支持函数重载。

挖根揭底就是我们的函数名的修饰规则导致了我们的c++能够支持函数重载。保证了我们的名字在底层的全局唯一性。

  1. 引用

    引用是我们c++中的一个新类型。它并不是定义了一个新的变量,而是给已存在的遍历取了一个别名而已,编译器不会给引用变量开辟内存空间。

    使用方法:类型& 引用变量名 = 引用实体 (引用的类型必须和引用实体的类型相同)

void test{
	int a = 10;
	int& newa = a;
}
           

引用的特性:

  • 引用在定义的时候必须初始化。

    这个你可以理解在我们不初始化的时候我们定义的引用并不知道我们的引用指向的内存是哪里,防止我们在未让我们的引用指向一块有效空间前使用它我们需要在定义的时候就初始化

  • 一个变量可以有多个引用

    就相当于我们每个人就有很多的称谓一样,但是实质上这个称谓都是指向的是你。

  • 引用一旦引用一个实体,再不能引用其他实体

    这个其实跟我们的引用底层实现的本质有关。

引用的使用:

  • 常引用:就是引用我们的常量的时候我们不能按照正常的引用,需要加上关键字const来修饰
void test(){
	const int a = 10;
	//int &ra = a;此时会报错
	const int &ra = a;
}
           
  • 做参数和返回值

    做参数的时候就是传递的我们引用类型,就是相当于传递的一个值,他的地址指向我们函数调用的值。跟我们c语言中传递指针类似。在函数中对引用类型的修改,其实就是对我们的原数据进行修改。在c语言中我们传递我们的结构体的时候使用的是传递指针的方式,用于减少我们的拷贝的消耗,在c++中使用我们的引用同样也可以达到效果,比我们直接传值开销更少。

//做参数
void Swap(int &a,int &b){
	int temp = a;
	a = b;
	b = temp;
}
           

做返回值的时候就相当于返回的实体对象

//做返回值
int& add(int& a){
	a+=10;
	return a;
}
           

注意:如果函数返回时,离开函数作用域后,其栈上空间已经返给系统,因此不能用栈上空间作为引用类型作为返回值。如果要使用引用类型作为返回值的话,返回值的声明周期必须不受函数的限制,也就是说要比函数的声明周期长。

引用和指针的不同点:

  • 引用在定义时我们需要初始化,指针不需要
  • 引用在初始化一个实体之后我们就不能在指向其他实体,但是指针可以在任何时候指向任何一个实体
  • 没有NULL引用,但是有NULL指针
  • 引用自加自减是实体加减1,指针自加自减向前/后偏移一个类型的大小
  • sizeof的含义不同。引用返回的是一个实体的大小,但是指针返回跟系统有关系
  • 返回实体的方式不同,指针需要解引用,引用编译器自己处理
  • 引用比指针使用起来更加安全

    引用的底层实现:

    引用在底层就是用常量指针来实现的。

  1. 内联函数

    以inline修饰的函数叫做内联函数,编译时c++编译器会在调用内联函数的地方展开。没有函数的压栈,所以效率很高。

inline int add(int x,int y){
	return x+y;
}
int main(){
	int x =  10;
	int y = x+add(x,x);
}
           

此时会替换成

inline int add(int x,int y){
	return x+y;
}
int main(){
	int x =  10;
	int y = x+(x,x);
}
           

特性:

  • 以空间换时间的做法,省去了调用函数额外的开销,
  • inline对于编译器而言只是一个建议,编译器会自动优化,如果定义的inline函数体内有循环等等,编译器优化时会忽略掉内联
  • 不加我们的inline关键字的时候我们的函数也可以是内联函数,这都是我们的编译器作出的优化。

宏的优缺点?

优点:增强代码的复用性,提高性能

缺点

  • 不方便调试
  • 导致代码可读性差,可维护性差,容易误用
  • 没有类型安全检查

    c++对于宏的替换

  • 常量第一换用const
  • 函数定义换用内联函数。