C++的一些基础知识总结

1. 命名空间

C++库中的所以的东西都是放在std命名空间中 ,如果将命名空间全部展开,自定义变量不能于std命名空间的变量冲突。

自己也可以创建命名空间,命名空间可以嵌套。

namespace N1
{
	int a = 0;
	int Add(int left, int right)
	{
		return left + right;
	}
	namespace N0     //命名空间可以嵌套
	{
		int b;
	}
}
using namespace N1;

2. cout 和 cin

cout是将数据输出

cout<<i<<j<<endl;

数据i和j通过箭头的方向流向控制台,通过屏幕输出。

cin将数据输入,从控制台获取数据,流向变量。

cout和cin都可以自动识别数据的类型。

3. 缺省传参

缺省参数(默认参数)是一种功能,它允许在声明或定义函数时为函数的参数指定一个默认值。当调用函数而没有提供相应的实参时,将采用这个默认值。

缺省参数-->备胎,如果传了实参,就不用缺省参数  

 全缺省,半缺省  

 缺省从右往左缺省    传参从左往右传参

void Funcl(int a = 10, int b = 20, int c = 30)
{
	cout << "a=" << a << endl;
	cout << "b=" << b << endl;
	cout << "c=" << c << endl;

}

半缺省参数必须从右向左依次且连续给出,不能间隔着给。这意味着如果你为一个参数提供了默认值,那么它右边的所有参数也都必须有默认值。

4. 函数重载

函数重载(允许函数名相同),参数不同,(类型/参数的个数/不同类型顺序)其中有一个不同就行   对返回值没有要求(只是返回值不同,不能构成重载)。

4.1 C++是如何支持函数重载的

我们要了解系统编译的过程分为预处理编译汇编链接。

void fun(int n,size_t m)
{
	cout << "int" << endl;
}

void fun(char pt)
{
	cout << "int*" << endl;
}

void test8()
{
	int a = 1;
	fun(a,2);
	fun('c');
}

主要在链接的时候,重载函数的地址不同。

在经过预处理,编译,汇编之后,两个函数将会变成如下,只有声明。

call fun(?)


call fun(?)

同时会生成符号表

两个函数会到符号表中去找对应的地址,打开反汇编,看看他们地址的区别。

可以看出,在反汇编码中,他们的地址不同,声明了的函数会去找对应的地址。

在linux下,命名规则显而易见了

5. 引用的使用

给一个变量在取一个名字,不会开辟新的空间,一个改变,其他的都改变(在类型后面加&就是引用)(直接在数据前面加&就是取地址)。

5.1 引用的特性:

1.引用必须在定义时初始化

2.已经引用了不能在引用其他数

3.权限的缩小和放大(适用于引用和指针)

void test1()
{
	const int a = 1;
	//int& b = a;      //a是只读,b是可读可写,权限放大  EOF
	const int& b = a;
	int c = 2;
	const int& d = c;   //可以,权限缩小


	int i = 0;
	double db = i;
	const double& rd = i;
	  ///   double& rf = i;    //此处有隐士类型转换
	const double& rf = i;


	//对指针
	const int* cp = &a;
	  //  int* p1 = cp;   //权限放大

	const int* p2 = cp;
}

5.2 隐式类型的转换

int Add_(int r1,int r2)
{
	return r1 + r2;
}

int& Add1(int r1, int r2)
{
	int c = r1 + r2;
	return c;
}
int& Add2(int r1,int r2)
{
	static int c = r1 + r2;
	return c;
}
void test3()
{
	int a = 2;
	int b = 3;
	const int& ret = Add_(a, b);  //返回的数据是将r1+r2和拷贝的数据,是一个临时变量,具有常性,引用时要用const
	cout << ret << endl;


	int& ret1=Add1(a,b);
	Add1(3, 4);
	cout << ret1 << endl;  //  ret1 是7 ,因为c的生命周期只在Add1函数中,结束后销毁,而ret1又是c的别称,指向的是c的空间,该处内存的数据被覆盖(如果ret仅接收c的值,而非别称,就没事)


	int& ret2 = Add2(a, b);
	Add2(3, 4);
	cout << ret2 << endl;  //  用static 改变了c的生命周期

}

一般用值返回用别名(引用)接收时, 应该加const (例:const int& b  =   Add(a,b) int  Add(int x  ,int y);   因为返回的是对返回数据的拷贝(是临时变量具有常性,不能修改)。

5.3 指针与引用的区别

1.引用概念上定义一个变量的别名,指针存储一个变量地址。
2.引用在定义时必须初始化,指针没有要求
3.引用在初始化时引用一个实体后,就不能再引用其他实体,而指针可以在任何时候指向任何
一个同类型实体
4.没有 NULL 引用,但有 NULL 指针
5.在 sizeof 中含义不同:引用结果为引用类型的大小,但指针始终是地址空间所占字节个数(32
位平台下占4个字节)
6.引用自加即引用的实体增加1,指针自加即指针向后偏移一个类型的大小
7.有多级指针,但是没有多级引用
8.访问实体方式不同,指针需要显式解引用,引用编译器自己处理
9.引用比指针使用起来相对更安全

6. auto

作为一个新的类型指示符来指示编译器,auto声明的变量必须由编译器在编译时期推导而得。

使用auto定义变量时必须对其进行初始化,在编译阶段编译器需要根据初始化表达式来推导auto 的实际类型。因此auto并非是一种“类型”的声明,而是一个类型声明时的“占位符”,编译器在编译 期会将auto替换为变量实际的类型。

auto不能推导的场景      

1. auto不能作为函数的参数    

2. auto不能直接用来声明数组

7. 范围for

与普通循环类似,可以用continue来结束本次循环,也可以用break来跳出整个循环.

for循环迭代的范围必须是确定的

对于数组而言 就是数组中第一个元素和最后一个元素的范围。

对于类而言, 应该提供begin和end的方法,begin和end就是for循环迭代的范围。(获取begin和end的迭代器,对迭代器解引用,如果是自定义的类,需要自己写函数实现)(不停的对begin()返回值做加法,解引用,直到遇到end())。

8.C++中的NULL和nullptr

NULL可能被定义为常量 0,也可能定义为void*类型

用nullptr代替NULL更具有安全性

void fun(int n)
{
	cout << "int" << endl;
}

void fun(int* n)
{
	cout << "int*" << endl;
}

void test8()
{
	fun(NULL);
	fun(nullptr);
}

结果:NULL被判定为int 类型

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值