C++入门(1)

news2024/11/24 11:07:41

一、关键字

C语言中只有32个关键字,C++有63个关键字,将近翻了一倍。
在这里插入图片描述

二、命名空间

在编写代码的时候,会遇到定义的变量名和库中的函数名重复,出现命名冲突的情况。在C++中有变量名、函数名还有类名,这些都会存在全局域中,在大项目中很难避免命名重复的问题。为了解决这种问题,通过namespace关键字去命名一块空间,用于存放变量名、函数名还有类名。而这种空间通称为命名空间,命名空间中的定义的这些变量、函数或者类其实还在全局域(静态区)中。

1.命名空间的使用

首先需要定义一块命名空间

#include<stdio.h>
namespace new1
{
	int a = 0;
	int b = 10;
}

int main()
{
	//printf("%d\n", a);//错误用例,报错信息为a为定义
	printf("%d\n", new1::a);//正确用例
	return 0;
}

为什么说定义的变量在全局中,但是不可以直接使用呢?举个例子,现实生活中拿东西,你得先看到物品在哪,才能去拿。如果说这个物品隐身了,你看不到它,自然无法拿到。namespace定义了new1的命名空间,这个空间在全局中,但是new1中的空间内容默认是不可见的。new1::a中的"::"是作用域限定符,左边是作用域名称(全局域就不用写),右边是成员名称。作用域限定符相当于帮你拿到你看不到空间中存在的物品。这样子可以避免命名冲突,只要存在的命名空间不一样,就没有问题。

2.在一个工程中可以存在多个名字相同的命名空间

#include<stdio.h>
namespace new1
{
	int a = 10;
}
namespace new1
{
	int b = 10;
}

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

这因为编译器最后会对名字相同的命名空间进行合并。

3.命名空间可以嵌套

#include<stdio.h>
namespace A
{
	int test1 = 10;
	namespace B
	{
		int test2 = 20;
	}
}

int main()
{
	printf("%d\n", A::test1);
	printf("%d\n", A::B::test2);
	return 0;
}

命名空间嵌套定义,在使用时一层一层解开,如声明代码中的test2变量,A::B::test2可以看做A::(B::test2),和俄罗斯套娃一样。

4.using剥掉命名空间隐身衣

有人觉得自己就做个题,不想每次都用作用域限定符写。那可以直接用using将想要用的命名空间的隐身衣剥去,让它暴露在人们的视野里。

#include<stdio.h>
namespace A
{
	int test1 = 10;
	namespace B
	{
		int test2 = 20;
	}
}
using namespace A;//将命名空间A的内容暴露在当前作用域内
using namespace B;//将命名空间B的内容暴露在当前作用域内
//如果只想要B中的内容,可以 using namespace A::B;
int main()
{
	printf("%d\n", test1);
	printf("%d\n", test2);
	return 0;
}

有人又觉得自己只需要其中的某个变量或者函数等等,可以using A::test1,之后就可以直接使用test1变量了。个人推荐后一种方法,前一种虽然方便,但是潜在风险比较大。namespace本身就是降低命名冲突问题的,using可以让每个人更自由的去使用命名空间中的内容,namespace相当于主力军,using相当于辅助,大多数情况下,不会有人让辅助去当主力军的。

三、输入输出

#include<iostream>
using std::cin;
using std::cout;
using std::endl;

int main()
{
	int a;
	cin >> a;
	cout << "hello world!"<<endl <<"hello doudou!"<<endl;
	return 0;
}

cout是标准输出对象(控制台),cin是标准输入对象(键盘输入)。cin和cout后面的>> 和 << 分别是流提取运算符和流输入运算符,endl相当于换行。cin、cout、endl都在iostream库中的std命名空间中定义。正常情况头文件都有带.h,为什么C++的iostream库没有.h后缀,主要是和C中的iostream.h库做区分。可以看出iostream库中有命名空间std的存在,而C中没有命名空间这个概念,当然有些旧版的C++编译器仍然支持iostream.h格式。
有人说cout、cin比printf和scanf慢,在早些时候这个差距会比较明显一些,但是随着机械部件不断迭代更新,这种差距基本上忽略不计。用哪种方法看个人习惯或者具体运用事例,哪种方便就用哪种。

四、缺省参数

缺省参数就是给函数参数给定一个默认数值,当调用函数时有传入数值,就正常进行传值操作,没有就采用默认值。
缺省参数又分为全缺省参数和半缺省参数

1.全缺省参数

#include<iostream>
using namespace std;//测试用例就偷个懒,不建议做项目这样写
//全缺省参数
void f(int a = 1, int b = 2, int c = 3)
{
	cout << a << endl;
	cout << b << endl;
	cout << c << endl;
}
int main()
{
	f();
	f(10);
	f(10, 20);
	f(10, 20, 40);
	return 0;
}

顾名思义,就是所有参数都是缺省参数。调用可以传入数值,如果有传入数值,必须按顺序传。如上面代码中的f函数,不可以用f( , 20,);这样的方式调用函数,想要传入某个参数,其前面的所有参数都需要传入数值,后面的可以不用。

2.半缺省参数

半缺省参数是指函数有一个或者一个以上的缺省参数,且没有全部参数都为缺省参数。

#include<iostream>
using namespace std;//测试用例就偷个懒,不建议做项目这样写
//半缺省参数
void f(int a, int b = 2, int c = 3)//半缺省参数函数
{
	cout << a << endl;
	cout << b << endl;
	cout << c << endl;
}
//void f(int a, int b, int c = 3)//半缺省参数函数
//{
//	cout << a << endl;
//	cout << b << endl;
//	cout << c << endl;
//}
int main()
{
	f();
	f(10);
	f(10, 20);
	f(10, 20, 40);
	return 0;
}

半缺省参数函数定义时,只能按顺序定义,函数定义的缺省参数后面必须都是缺省参数。半缺省参数函数调用方式和全缺省类似,没有缺省参数的地方依旧正常传数值,有缺省参数的地方,依旧是想要传入的参数,其前面的所有参数都需要传入数值,后面的可以不用。

五、函数重载

C++中支持同个作用域内可以声明定义多个名字相同功能相识的函数,当然是有规则的。现在就要讲讲什么时候可以定义名字相同的函数,且能被识别出来。主要三个方面,第一个是函数参数个数不同,第二个是函数参数类型不同,第三个是函数参数顺序不同。

这三个规则通过代码的修饰展现:

//1.参数类型不同
int Add(int a, int b)
{
	cout << "int Add(int a, int b)" << endl;
	return a + b;
}
double Add(double a, double b)
{
	cout << "double Add(double a, double b)" << endl;
	return a + b;
}

//2.参数个数不同
void Number(int a)
{
	cout << "void Number(int a)" << endl;
}
void Number(int a, int b)
{
	cout << "void Number(int a, int b)" << endl;
}

//3.参数顺序不同
void Order(int a, char b)
{
	cout << "void Number(int a, char b)" << endl;
}
void Order(char b, int a)
{
	cout << "void Number(char b, int a)" << endl;
}

int main()
{
	Add(1, 2);
	Add(1.1, 2.2);
	Number(1);
	Number(1, 2);
	Order(1, 'a');
	Order('a', 2);

	return 0;
}

这三个规则一定在什么时候都适用吗?真要细究不一定,这主要是第三个会有些问题,例如我定义一个函数中的参数类型都是一样的,就算参数的顺序不同,依旧会报错。为什么会这样?我们得去为什么可以实现函数重载。C语言中没有函数重载的概念,在C++中为什么有,因为编译器对于函数的命名规则不一样。这边先补充一个知识点,一个项目的文件中的程序是如何运行起来的。首先需要经过预编译,然后是编译,在之后是汇编,最后就是链接。预编译是处理一些预编译指令的,编译就是经过编译器生成一串串的汇编代码,汇编就是将这些汇编代码转化二进制指令,形成符号表。链接就是合并这个项目中的所有符号表。就是将这些这里不深讲,大致讲个过程,后面会单独出一章讲解这些过程中的细节。
编译器负责的就是编译的过程。在编译过程中,C语言的函数是直接用函数名修饰的,也就是说两个同样函数名的函数,即使参数不一样,C语言也分辨不出来。Liunx下的C++编译器对于函数名的修饰规则是_Z+函数长度+函数名+参数类型首字母。可以看出同名函数想要区分得靠最后一个参数类型做区分,这里也可以看出为什么类型相同的参数,调换顺序也无法识别出来,因为类型相同无法区分。上面三条规则为什么能适用,哪里会存在问题,记住这条规则便可。

六、引用

引用就相当于是给一个人或则一个东西取了一个别名。就像棍子,有的人也叫它棒子,东西还是同一个,名字不同罢了。那引用也一样,就是给一个变量多了一个变量名称,地址都一样,不开辟新空间。

1.引用的使用方法

想使用,得先定义吧,那就先看一下如何定义引用。

#include<iostream>

int main()
{
	int a = 10;
	int& b = a;
	printf("a = %d, b = %d\n", a, b);
	printf("a = %p, b = %p\n", &a, &b);
	return 0;
}

定义方法就是:类型 & 引用名 = 引用变量名;
那有人就说了,我不初始化不行吗?我就定义一个引用不行吗?不行,一定要初始化,不然编译不过。语法规定好的,别去钻牛角尖。

一个人有多个外号可以吗?当然可以,那引用也一样,一个变量可以有多个引用名,对引用名进行引用,本质上还是对同一个问题取外号,都是指向同一个变量。
下面是代码验证:

#include<iostream>

int main()
{
	int a = 10;
	int& b = a;
	int& c = a;
	int& d = c;

	printf("a = %d, b = %d, c = %d, d =%d\n", a, b, c, d);
	return 0;
}

引用需要注意的一点,一旦对一个变量进行引用就不可以将这个引用名转到另一个变量上。例如我给a取了引用名为c,那c就只能是a的引用名,不可以把它变成b的引用名。所以,引用一旦完成,就会从一而终。和指针这个渣男不一样,可以换对象。

2.常引用

常引用就是通过const对引用进行修饰。
下面是使用案例:

#include<iostream>

int main()
{
	const int a = 10;
	//int& b = a;//a为常量,权限不同报错
	//int& b = 10;//10为常量,报错
	const int& a1 = a;
	const int& b = 10;

	double c = 1.22;
	//int& d = c;//报错,类型不同
	const int& d = c;
	printf("%f", d);
	return 0;
}

上面举了几个典型例子,现在来讲解一下为了有些地方不行。常变量a是只能读不能修改的,但是主函数第二行的引用名b是既能读又能改的,两者权限不一样。权限可以缩小,但是不能放大。如果对常变量a取一个变量类型的别名b,那相当于是放大了a的权限,因为b是可以对a进行修改的,a和b就是同一个东西,所以不可以通过,合情合理。第三行也是同样的道理,10是常量,b是变量,常量的权限小于变量,不可以通过。
那第四行和第五行为什么可以通过,就是大家权限相同。
第八行不能通过是因为d和c的类型不一样,所以报错。当然有人就会说那第二行和第三行就不能是类型不一样吗?我只能说每个人的理解不一样,你就得可以都解释的通就行。
第九行就是反驳点了,你说类型不一样就会报错,为什么第9行不报错?这就是我前面第二三行为什么要说是权限问题报错,变量为什么可以给常变量,就是权限大的可以缩小,变量的权限比常变量大,能通过合情合理。但是这里会有个问题,d是常变量只能看不能改,但是c是变量啊,它能改,这有问题,还是不对。确实有问题,但是这个问题有个巧妙的地方让这个问题消失了。当d给c做引用时,其实给的不是c,给的是c的整数,也就是说c是1.22,给到b的其实是1,这个1是一个临时变量的值。也就是说,c先将其整数值给到临时变量,再将这个临时变量给到d。那d和c是没有半毛钱关系的,后面修改c不会改变d的值,引用始终如一。

3.为什么使用引用?

有人觉得引用可以做到的事情,指针不一样行吗?确实如此,引用的产生是为了将一些指针能做的事情做的更方便,因为指针过于复杂,引用相当于一个平替,可以完成大多数指针可以完成的事情,用起来简单。像链表就不能用引用去完成,引用没有指针灵活。

引用主要应用在两个地方,一个是函数参数,一个是函数返回值。我们先说使用方法,再谈为什么这样做。

#include<stdio.h>
void Swap(int& a, int& b)
{
	int tmp = a;
	a = b;
	b = tmp;
}

int& A()
{
	int d = 30;
	int& c = d;
	return c;
}
int main()
{
	int a = 10;
	int b = 20;
	Swap(a, b);
	printf("a = %d b = %d\n", a, b);
	int c = A();
	printf("c = %d\n", c);

	return 0;
}

上面代码在有些环境下是可以通过的,这不代表代码没问题,先声明一点,上面代码是存在问题的。函数参数使用引用是没有问题的,可以很方便的使用,并且不会对参数进行拷贝,在数据量很大的情况下,可以有明显的效率提高。举个例子,我传一个10万字节的结构体,如果用传值调用,在函数调用建立函数栈帧时,函数得开辟一个10万字节的空间对这个结构体进行拷贝,这里存在时间的消耗是很明显的。

函数返回值的代码是有问题的,下面就具体讲讲这个问题是什么。首先要明确的一点是,函数在调用时,会建立函数栈帧,函数结束后,函数栈帧会销毁。上面将函数A中的d变量作为返回值给了c,乍一看好像是这样。实际上,c是拿到了函数A中b变量空间的引用,换句话将,本质上c变量得到的是b的地址中的内容的引用名。这里面就存在隐患了,因为函数结束后函数栈帧是会销毁的,函数栈帧相当于是系统临时给函数分配的空间,一旦函数结束,这片空间就会回收,有的系统会对空间内容进行清理,有的系统不会,这就是为什么说有的环境下可以通过这个代码的原因。这时候就有人说了,那我知道了我的系统不会对销毁的函数空间进行清理,那我不就可以正常使用了。
片面了,这也是为什么要说函数栈帧的原因,因为函数栈帧销毁后,空间会被系统回收,而这块回收的空间又在别的函数建立时被占用。函数栈帧销毁,空间是会被系统回收的,也就是说这个空间的内容不可以随意被访问,没有权限。能拿到只是没被检查出来,实际上就是违法访问空间。如果说,别的函数使用了这块空间,那c和一个会被随时会被更改的空间建立了引用关系,这就违背了作者的初心,c的值也会变幻莫测。
关键点:函数返回值做引用正确使用方法是什么?返回对象出了作用域还在,就可以使用。如果空间归还给系统,就不推荐这样使用。

如有不当之处,感谢各位大佬指正。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/20776.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

两种方式实现websocket获取数据库查询进度

两种方式实现websocket获取数据库查询进度 本文实现了两种方式用websocket连接实现前端通过API获取数据库查询进度&#xff0c;作为websocket初步学习的参考 内容目录概要&#xff1a; 使用额外接口获取指定数据库查询进度&#xff0c;查询进度的接口与获取数据的接口分开实…

SAP S4 FI后台详细配置教程- PART3 (财务凭证相关配置篇)

本篇主要介绍凭证相关的配置&#xff0c;希望对学习SAP财务的同学有帮助。 1、定义凭证类型 概念功能说明&#xff1a; • 凭证类型是区分不同交易类型的方法并决定能够被过帐的会计形式。 例如&#xff0c; 可将所有的会计凭证按业务类分成&#xff1a; 总帐凭证、收款…

基础选择器

一、任务目标 掌握基础选择器的应用 二、任务背景 CSS&#xff08;层叠样式表&#xff09;选择器是CSS规则的一部分&#xff0c;用来指定需要设置样式的HTML元素。通过选择器可以实现CSS对HTML元素的一对一、一对多、多对一的控制。 三、任务内容 选择器类型 描述 示例 通配选…

概率论基础

一、条件概率的三大公式 条件概率中的条件就代表观测变量&#xff0c;观测变量意思就是这个变量的取值是否已经定下来了 1.乘法公式 2.全概率公式 随机现象&#xff1a;在一定的条件下&#xff0c;并不总出现相同结果的现象称为随机现象。随机现象的各种结果会表现出一定的…

分类效果评价(机器学习)

目录 准确率 精确率(precision) 召回率(recall&#xff0c;也称为查全率) 调回平均 对于一般分类问题&#xff0c;有训练误差、泛化误差、准确率、错误率等指标 对于常见的二分类问题&#xff0c;样本只有两种分类结果&#xff0c;将其定义为正例与反例。 那么在进行分类…

基于java大学生就业信息管理系统

随着高校教育体制的改革大学生人数的不断增加&#xff0c;毕业生就业制度发生了根本的变化。单位和学生走向人才市场&#xff0c;双向选择&#xff0c;择优录用。因此在这样的情况下&#xff0c;在INTERNET上开发并运行信息管理系统就能够极大地提高工作效率&#xff0c;弥补了…

VMware 网络模式

VMware提供了三种网络工作模式&#xff0c;它们分别是&#xff1a; Bridged&#xff08;桥接模式&#xff09; NAT&#xff08;网络地址转换模式&#xff09; Host-Only&#xff08;仅主机模式&#xff09; 1、桥连接模式 【NAT 设置】【DHCP 设置】不可编辑 2、仅主机模式 【自…

MySQL并发事务会引起的问题

MySQL事务并发的问题主要分为以上三种 脏读: 比如 事务A 对用户表进行了 一次查询 和一次修改 他将用户1的 部门 从 部门1 改为了 部门2 但事务A 并没有提交 然后事务B 只做了一步查询 查用户表 此时 如果出现脏读 则 事务B查到的 用户1 的所属部门是 部门2 而 这是 事务A其实…

Python画小仓鼠

肉嘟嘟的小动物很是可爱&#xff0c;本文介绍运用Python中的turtle库控制函数绘制小仓鼠。    文章目录一、效果展示二、代码详解1 导入库2 播放音乐3 定义画小仓鼠头的函数4 定义画左眼和右眼的函数5 定义画嘴的函数一、效果展示 在介绍代码之前&#xff0c;先来看下本文的实…

mPEG-Dendro Azide,mPEG-Dendro N3,甲氧基聚乙二醇树状叠氮化物bisMPA树状大分子供应

1、名称 英文&#xff1a;mPEG-Dendro Azide&#xff0c;mPEG-Dendro N3 中文&#xff1a;甲氧基-聚乙二醇-树状叠氮化物 2、CAS编号&#xff1a;N/A 3、所属分类&#xff1a; Azide PEG Methoxy PEG 4、分子量&#xff1a;可定制&#xff0c;甲氧基-PEG-树状叠氮化物 200…

Linux下文件和目录的基础操作

文章目录一、Linux 下文件和目录的特点二、 计算机中文件大小的表示方式三、 ls 命令四、切换目录五、 相对路径和绝对路径六、创建和删除1、touch 创建文件2、mkdir 创建目录3、rm 删除文件和目录七、 查看、移动和复制文件1、tree 浏览目录结构2. cp 复制文件和目录3. mv 移动…

Linux下C/C++实现以十六进制的形式显示命令(xxd)

如果你需要在linux文本文件的十六进制转储&#xff1f;且正在寻找可以执行此操作的命令行实用程序&#xff0c;xxd的命令可以为你做这件事。xxd命令将文件显示为十六进制值和ASCII表示&#xff0c;并允许对其进行编辑。 xxd - 以十六进制形式表示 xxd程序接受文件或标准输入&…

python--函数

目录函数1.1 自定义函数1.2 调用函数1.3 作用域函数 1.1 自定义函数 无参数、无返回值 def function():表达式无参数、有返回值 def function():表达式return 需返回的值tips&#xff1a;函数中可以有多个return语句&#xff0c;但是只要执行一个return语句&#xff0c;就意…

PPT+Visio复现顶刊三维流程图

复现 论文中的图3&#xff0c;改图是研究流程&#xff0c;主要讲了神经网络的流程。 A future land use simulation model (FLUS) for simulating multiple land use scenarios by coupling human and natural effects https://doi.org/10.1016/j.landurbplan.2017.09.019 1.…

【Touchstone 1.02.0数据格式解析】

Touchstone 1.0&2.0数据格式解析 在进行S参数仿真时&#xff0c;一般存储的S参数模型为SnP格式&#xff0c;如双端口模型为S2P格式&#xff0c;四端口模型为S4P格式。了解SnP格式的具体要求&#xff0c;对于S参数的应用具有重要作用。 本质上&#xff0c;S参数是由S参数矩…

对比Python,PySpark 大数据处理其实更香

对于数据分析师、数据科学家和任何使用数据的人来说&#xff0c;能够熟练而有效地处理大数据是一项非常有优势的技能。 如果你已经熟悉运用 Python 和 pandas 做常规数据处理&#xff0c;并且想学习处理大数据&#xff0c;那么熟悉 PySpark&#xff0c;并将用其做数据处理&…

免费搜题系统搭建

免费搜题系统搭建 本平台优点&#xff1a; 多题库查题、独立后台、响应速度快、全网平台可查、功能最全&#xff01; 1.想要给自己的公众号获得查题接口&#xff0c;只需要两步&#xff01; 2.题库&#xff1a; 查题校园题库&#xff1a;查题校园题库后台&#xff08;点击跳…

C语言详细知识点复习(上)

文章目录一、C语言概述1、C语言的主要特点2、算法的概念及特点二、C程序设计的基础语法1、常量和变量2、数据类型3、运算符和表达式4、C 语句5、数据的输入和输出三、选择结构四、循环结构1、循环结构2、break\continue3、循环程序举例一、C语言概述 1、C语言的主要特点 程序…

微信小程序最新用户头像昵称获取规则调整应对措施(2022)

目录一、调整二、应对措施2.1 更新头像2.2 更新昵称三、完整代码一、调整 小程序用户头像昵称获取规则调整公告 以前通过wx.getUserProfile获取用户信息&#xff0c;用户点击同意以后&#xff0c;便可以直接获取相关信息&#xff0c;但是官方最近做出了调整&#xff0c;直接将…

图书管理系统

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 目录 文章目录 前言 一.界面设计 1.管理员菜单 2.用户菜单 3.用户操作&#xff1a; 查找图书借阅图书归还图书显示图书 4.管理员操作 查找图书新增图书删除图…