C++入门

欢迎来到本期节目- -

C++入门基础

入门必备

命名空间- - namespace

本质:

|------------------------------|
| 命名空间是一个域,是对作用域的特殊抽象。 |
| 在c++中,域有函数局部域,全局域,类域以及命名空间域。 |

作用:

|-------------------------------------------|
| 解决命名冲突的问题 |
| 由于编译时,编译器按照语法查找(变量/函数)的声明或定义的出处时, |
| 在同一个域不能出现相同标识符,所以命名空间域,起到了域隔离的作用,解决了命名冲突。 |

应用:

++namesapce关键字,后面跟该域的名称(标识符),然后跟{}++

cpp 复制代码
namespace my_room
{
	int var;	//变量
	
	void func()//函数
	{
		//....
	}
	
	class A	//类
	{
		public:
		A()
		{
			//....
		}
		private:
		char ch;
	}
	
	namespace nested_room	//命名空间
	{
		//....
	}
}

小知识

|---------------------|
| 命名空间域和类域不影响变量的生命周期。 |


注意事项

  • 命名空间只能定义在全局或者嵌套;
  • 在同一个域(全局域,命名空间域)或者多文件中,同名的namespace可以认为是一个命名空间域;
  • 但是在不同的域中(既嵌套的namespace),同名的namespace是不同的命名空间域;

例如:

cpp 复制代码
#include<iostream>
using namespace std;

namespace my_room
{
	void print1()
	{
		cout<<"my_room::print1()"<<endl;
	}
	
	namespace my_room	//该命名空间域和外层的my_room没有命名冲突,只是受到了外层的命名空间域的限制,是独立的域
	{
		void print1()
		{
			cout<<"my_room::my_room::print1()"<<endl;
		}
	}
}

namespace my_room	//该命名空间域与上方最外层的my_room在同一全局域,又名称相同,既在同一命名空间域,相当于把print2()函数定义在上方的my_room。
{
	void print2()
	{
		cout<<"my_room::print2()"<<endl;
	}
}

|----------------|
| 如何使用命名空间域中的成员? |

  • 指定方式
    • 通过 ++作用域操作符++ : : 指定成员
cpp 复制代码
#include<iostream>
namespace my_room
{
	int a = 1;
	void print()
	{
		printf("hihihi\n");
	}
}

int main()
{
	int a = 10;
	printf("%d\n", a);
	printf("%d\n", my_room::a);
	my_room::print();
	return 0;
}

输出结果:

cpp 复制代码
10
1
hihihi
  • 展开方式

    • 使用using关键字

      • 展开个别命名空间成员
      • 展开整个命名空间
cpp 复制代码
#include<iostream>
namespace my_room
{
	int a = 1;
	void print()
	{
		printf("hihihi\n");
	}
}

using my_room::a;	//相当于将a的作用域延伸到了全局域

int main()
{
	printf("%d\n",a);
	printf("%d\n",my_room::a);
	
	return 0;
}

输出结果:

cpp 复制代码
1
1

cpp 复制代码
#include<iostream>
namespace my_room
{
	int a = 1;
	void print()
	{
		printf("hihihi\n");
	}
}

using namespace my_room;	//展开整个命名空间

int main()
{
	printf("%d\n",a);
	print();
	return 0;
}

输出结果:

cpp 复制代码
1
hihihi

c++输入&输出

|---------------------------------------------|
| <*iostream>*是c++标准的输入/输出流库,std是该标准库的命名空间。 |

|--------------------------------------|
| std::cin是istream类的对象,主要面向窄字符的标准输入流。 |
| std::cout是ostream类的对象,主要面向窄字符的标准输出流。 |

|-------------------------|
| <<流插入运算符,一般练习中通常用于输出; |
| >>流提取运算符,一般练习通常用于输入。 |

|---------------------------------------|
| std::endl是一个函数,流插入输出时相当于一个换行符加上刷新缓冲区。 |

|------------------------------|
| c++流插入和流提取可以通过函数重载,自动识别变量类型。 |

缺省参数

拥有缺省参数的函数在声明和定义分离时,规定必须函数声明给缺省值。

定义:

|-----------------------------|
| 缺省参数是函数声明或定义时为函数的形参指定一个缺省值。 |
| 在调用该函数时,若没有指定实参,则使用该缺省值。 |

分类:

  • 全缺省参数
    • 全部形参给缺省值。
  • 半缺省参数
    • 部分形参给缺省值

注意事项:

  • 缺省参数只能从右往左依次给定。
  • 函数调用时的实参只能从左往右依次给定。

函数重载

定义:

|------------------------------------|
| c++支持在同一作用域中,出现同名函数,但是要求同名函数的形参不同。 |

构成函数重载的条件:

  • 同一作用域
  • 相同函数名
  • 形参类型 或 形参类型顺序 或 形参个数 不同

栗1:

cpp 复制代码
#include<iostream>

int add(int a, int b)	
{
	return a+b;
}

float add(float a, float b)
{
	return a+b;
}

|-------------------------------|
| 在同一域中,同名的add函数的形参类型不同,构成函数重载。 |

栗2:

cpp 复制代码
#include<iostream>
using namespace std;

void func(int x,double y)
{
	cout<<"func(int x,double y)"<<endl;
}

void func(double y,int x)
{
	cout<<"func(double y,int x)"<<endl;
}

|----------------------------------|
| 在同一域中,同名的func函数的形参类型顺序不同,构成函数重载。 |

栗3:

cpp 复制代码
#include<iostream>
using namespace std;

void pear()
{
	cout<<"hehe"<<endl;
}

void pear(int m)
{
	cout<<"haha"<<endl;
}

|--------------------------------|
| 在同一域中,同名的pear函数的形参个数不同,构成函数重载。 |


注意事项:

  • 如果void pear(int m){}给了缺省值,依然构成函数重载,但是存在调用歧义。

引用

定义:

|--------------------------------------------------------|
| 引用是给一个已经存在的变量取了一个别名,编译器不会为引用变量开辟内存空间,引用和引用对象共用同一块内存空间。 |

格式:

|-------------------|
| 类型& 引用别名 = 引用对象; |

cpp 复制代码
#include<iostream>
using namespace std;
int main()
{
	int a = 10;
	
	int& b = a;
	
	cout<< &a <<endl;
	cout<< &b <<endl;
	
	return 0;
}

输出结果:

cpp 复制代码
 0104FCA0
 0104FCA0

引用的特性:

  • 引用必须初始化

  • 引用一旦引用一个实体,就不能引用其它实体(不能改变指向)

  • 一个实体可以有多个引用

cpp 复制代码
int main()
{
	int val = 10;
	int& a = val;
	int& b = val;

	int& c = b;			//a,b,c都是val的引用
	return 0;
}

const引用

c++中,引用和指针的访问权限,只能缩小不能放大。

  • const引用不仅可以引用const对象,还可以引用普通对象,这是访问权限的缩小,

  • 但是普通引用不能引用const对象,不能实现权限放大。


注意:

  • 引用的权限缩小,对引用对象本身没有影响。

cpp 复制代码
int main()
{
	int val = 10;
	const int& b = val;	//虽然不能通过b修改数据,但是可以通过val修改数据。
	val = 30;		//这里val一改,b也跟着改了---因为是同一块空间
	return 0;
}
从以上可以得出结论,const引用真是够花心的,不仅有普通对象,还有const对象,
这样的const引用,会有人喜欢吗?别说,在临时对象眼中,const引用就是唯一。
(冷笑话)

临时对象:

|------------------------------|
| 编译器需要表达式的求值结果而临时创建的一个未命名的对象。 |

|-------------------|
| 那么具体什么时候会创建临时对象呢? |

  • 表达式求值
  • 类型转换
  • 传值返回
cpp 复制代码
int add(int x,int y)
{
	int z = x+y;
	return z;
}
int main()
{
	const int& a = 4*5;//表达式求值,需要临时对象存储结果
	const double& b = a;//类型转换,需要临时对象存储中间值
	const int& ret = add(1,2);//函数返回的是临时对象

	return 0;
}

小知识

|------------------------------|
| c++规定临时对象具有常性,所以只能使用const引用。 |

|----------------------------------|
| 引用和指针有一样的权限缩小放大问题,那么两者之间到底有什么区别? |

指针 引用
创建时开辟空间 语法上不开空间
语法上不必初始化 语法上必须初始化
间接访问对象 直接访问对象
可以改变指向 不能改变指向
sizeof大小是地址大小 sizeof大小是对象大小
空/野指针较多 空引用较少

内联函数- - inline

作用:

  • c++编译器会在调用该函数的地方将其展开,减少了函数栈帧的开销,提高效率。
  • 替代宏替换

注意事项:

  • inline关键字对编译器来说只是建议,不一定会展开,只适合++代码简短,频繁调用++的函数。
  • inline函数的声明和定义不建议分离,会导致链接错误。因为展开意味着没有函数地址。

nullptr关键字

|---------------------------------------------------|
| c++中,nullptr是一个特殊的关键字,它可以转换成任意类型的指针,相当于c语言中的NULL, |
| 而c++中的NULL,是整型0的宏替换。 |

cpp 复制代码
//<stddef.h>

#ifndef NULL
	#ifdef __cplusplus
		#define NULL 0
	#else
		#define NULL ((void *)0)
	#endif
#endif

希望该片文章对您有帮助,请点赞支持一下吧😘💕

相关推荐
tyler_download8 分钟前
golang 实现比特币内核:实现基于椭圆曲线的数字签名和验证
开发语言·数据库·golang
小小小~9 分钟前
qt5将程序打包并使用
开发语言·qt
hlsd#9 分钟前
go mod 依赖管理
开发语言·后端·golang
小春学渗透10 分钟前
Day107:代码审计-PHP模型开发篇&MVC层&RCE执行&文件对比法&1day分析&0day验证
开发语言·安全·web安全·php·mvc
杜杜的man13 分钟前
【go从零单排】迭代器(Iterators)
开发语言·算法·golang
亦世凡华、14 分钟前
【启程Golang之旅】从零开始构建可扩展的微服务架构
开发语言·经验分享·后端·golang
神仙别闹20 分钟前
基于MFC实现的赛车游戏
c++·游戏·mfc
小c君tt28 分钟前
MFC中 error C2440错误分析及解决方法
c++·mfc
测试界的酸菜鱼28 分钟前
C# NUnit 框架:高效使用指南
开发语言·c#·log4j
GDAL28 分钟前
lua入门教程 :模块和包
开发语言·junit·lua