lesson0-C++入门(6000余字详细配图讲解)

news2025/1/11 4:28:58

个人主页:Lei宝啊 

愿所有美好如期而遇


目录

1. C++关键字

2. 命名空间

​编辑

3. C++输入&输出

4. 缺省参数

5. 函数重载

6. 引用

7. 内联函数


1. C++关键字

C++总计63个关键字,C语言32个关键字,C++兼容%99的C语言,只有极少部分在C++中不可使用,后面我们会提到,关键字没有必要现在全部知道,后面可以慢慢学。

2. 命名空间

 首先我们通过几个C语言代码引入。

假如说我们今天引入一个<stdlib.h>头文件,里面有一个函数叫做rand()

#include <stdio.h>
#include <stdlib.h>

int rand = 0;

int main()
{

	printf("%d", rand);

	return 0;
}

首先我们知道stdlib头文件展开后,rand函数就也在全局出来了,于是和我们定义的rand就命名冲突了,如果说我们定义在主函数中,那么就是局部优先,不会冲突。

#include <stdio.h>
#include <stdlib.h>

int main()
{
	int rand = 0;
	printf("%d", rand);
	return 0;
}

那么我们如何去避免命名冲突这种情况发生?很遗憾,C语言无法避免,于是C++里解决了这个问题,他引入了命名空间,命名空间里变量和函数的生命周期还是全局,但是如果不展开或者使用域作用限定符,那么命名空间里的一系列变量和函数都无法使用,看例子:

域作用限定符 ::

 一个命名空间就定义了一个新的作用域,命名空间中的所有内容都局限于该命名空间中 

#include <iostream>
using namespace std;

namespace jj_jntm
{
	int a = 0;
	int Add(int x = 0, int y = 0)
	{
		return x + y;
	}
	
	void COUT()
	{
		int x = a;
		cout << x << endl;
	}
}

int main()
{

	int a = 1;
	cout << a << endl;
	cout << jj_jntm::a << endl;
	cout << jj_jntm::Add(1, 2) << endl;

	a = 2;
    //外面的a改变不会影响命名空间里的a,两者是独立的。
	jj_jntm::COUT();
    
    //只有命名空间里的a改动时,命名空间里调用的该a才会改变
	jj_jntm::a = 3;
	jj_jntm::COUT();

	return 0;
}

命名空间还可以嵌套。

#include <iostream>
using namespace std;

namespace jj_jntm
{
	int a = 0;
	int Add(int x = 0, int y = 0)
	{
		return x + y;
	}
	  
	void COUT()
	{
		int x = a;
		cout << x << endl;
	}

	namespace basketball
	{
		int kk = 0;
	}
}

int main()
{

	cout << jj_jntm::basketball::kk << endl;

	return 0;
}

同一个工程允许命名空间的名字相同,因为编译器最后会将他们合成一个命名空间。

使用 using 将命名空间中某个成员引入
#include <iostream>
using namespace std;

namespace jj_jntm
{
	int a = 0;
	int Add(int x = 0, int y = 0)
	{
		return x + y;
	}
	  
	void COUT()
	{
		int x = a;
		cout << x << endl;
	}

	namespace basketball
	{
		int kk = 0;
	}
}

using jj_jntm::a;
using jj_jntm::COUT;

int main()
{

	int a = 9;
	COUT();
	//cout << jj_jntm::basketball::kk << endl;

	return 0;
}

为什么呢?我们使用using展开部分命名空间,但是这与头文件展开完全是不同的,using仅仅是允许编译器进入namspace里对其进行搜索,我们不展开的时候,或者不指定的时候,编译器默认不会进去搜索的。

所以我们展开a和COUT,意思就是允许编译器在命名空间里去寻找了,而后定义的a赋值9不会影响到命名空间里的a,因为他是重新定义了一个局部变量。

这个就是在主函数中找不到a,我们就去全局找,又因为我们展开了a,所以可以在命名空间里找到a,于是命名空间里的a被修改为了6。

 使用using namespace 命名空间名称 引入(展开到全局)

#include <iostream>
using namespace std;

namespace jj_jntm
{
	int a = 0;
	int Add(int x = 0, int y = 0)
	{
		return x + y;
	}
	  
	void COUT()
	{
		int x = a;
		cout << x << endl;
	}

	namespace basketball
	{
		int kk = 0;
	}
}

using namespace jj_jntm;

int main()
{
	int a = 3;
	cout << Add(a, 2) << endl;
	cout << Add(jj_jntm::a, 2) << endl;
	COUT();
	//cout << jj_jntm::basketball::kk << endl;

	return 0;
}

 

3. C++输入&输出

使用cout标准输出对象(控制台)cin标准输入对象(键盘)时,必须包含< iostream >头文件

输入:std::cin 

输出:std::cout

换行:std:endl

>> << 可以看做流向。

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

int main()
{

	int a = 0;
    //从键盘输入数据流入a中
	std::cin >> a;
    //a先流出到屏幕上,而后是换行符
	std::cout << a << std::endl;

	int b = 0;
	cin >> b;
	cout << b << std::endl;

	return 0;
}

 

当然,我们最好是能在输入前有个提示。

4. 缺省参数

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

我们来看代码:

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

int Add(int a = 0, int b = 0)
{
	return a + b;
}

int main()
{

	cout << Add(1, 1) << endl;
	cout << Add() << endl;
	cout << Add(1) << endl;

	return 0;
}

 值得注意的是,实参必须从左向右给,缺省值必须从右向左缺。

int Add(int a = 1, int b = 2, int c = 3)
{
	return a + b + c;
}

int main()
{

	cout << Add() << endl;
	cout << Add(2) << endl;
	cout << Add(2,3) << endl;
	cout << Add(2, 3, 4) << endl;

	return 0;
}

你也许会有疑问,我能不能跳着给实参,或者跳着缺省?

那么如果是这样,我怎么能知道这个2是传给b的还是传给c的,也就是说,1和2有一个是传给b的,那剩下的那个是给哪个缺省值呢?无法区分。 

另外,如果函数的声明和定义不在同一个文件,而我们又想给函数缺省值,那么就给在声明,不可同时给。

这显然不可以,所以不能同时给,就是为了避免这样的情况。

至于说我难道不能给定义吗?一定要给声明?好好好,我写了一个函数,但是不给你源码,只给你用,给你个接口,你说我缺省在定义里,你怎么知道这个函数该不该缺省,所以说写在声明里。

5. 函数重载

C语言中,假设我们有一个函数,叫做

int Add(int a,int b),这是一个加法函数,返回值为int类型,当我们想做double类型的两个数相加时,那么就要再写一个函数,并且重新起一个名字,不管是叫Add_double也好,还是叫什么,如果我们有多个加法函数,那么要起多少个名字?总之是给我们带来了不便,我们就想,能不能不改名字,还能找到这样的函数,C语言不可以,于是C++有了函数重载。

1 、参数类型不同
#include <iostream>
using namespace std;

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

double Add(double a, double b)
{
	return a + b;
}

int main()
{

	cout << Add(1314.0, 0.0);
	cout << Add(500, 20) << endl;
	return 0;
}

2、参数个数不同 

#include <iostream>
using namespace std;

void f()
{
	cout << "我没有参数" << endl;
}

void f(int a)
{
	cout << "哈哈,我有参数:" << a << endl;
}

int main()
{

	f();
	f(6);
	return 0;
}

 3、参数类型顺序不同

#include <iostream>
using namespace std;

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

int Add(int a, int b, int c)
{
	return a + b + c;
}

int main()
{

	cout << "两个参数:>" << Add(1, 2) << endl;
	cout << "三个参数:>" << Add(1, 2, 3) << endl;

	return 0;
}

6. 引用

引用概念
引用 不是新定义一个变量,而 是给已存在变量取了一个别名 ,编译器不会为引用变量开辟内存空 间,它和它引用的变量共用同一块内存空间

类型& 引用变量名(对象名) = 引用实体 

int main()
{
	int a = 6;
	int& b = a;

	cout << "a地址> " << &a << " b地址> " << &b << endl;

	return 0;
}

所以b就是a的别名,好比你的大名和小名,不管叫那个都是你。

void Swap(int* a, int* b)
{
	int temp = *a;
	*a = *b;
	*b = temp;
}

int main()
{
	int a = 1;
	int b = 2;
	Swap(&a, &b);

	cout << "a = " << a  <<  " b = " << b << endl;

	return 0;
}

void Swap(int& a, int& b)
{
	int temp = a;
	a = b;
	b = temp;
}

int main()
{
	int a = 1;
	int b = 2;
	Swap(a, b);

	cout << "a = " << a  <<  " b = " << b << endl;

	return 0;
}

引用特性

1. 引用在 定义时必须初始化
2. 一个变量可以有多个引用
3. 引用一旦引用一个实体,再不能引用其他实体

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

	cout << a << b << c << d << endl;
	return 0;
}

int main()
{

	int a = 0;
	int b = 1;

	int& c = a;
	c = b;

	cout << c << endl;

	return 0;
}

int main()
{

	int a = 0;
	int b = 1;

	int& c = a;
	c = b;

	cout << c << endl;
	cout << "&a = " << &a << "\n&c = " << &c << "\n&b = " << &b << endl;

	return 0;
}

常引用

 

const int a = 0;

const int& c = a;
const int& e = 10;

//这是OK的
const double& d = a;

至于上面的const限定的为什么可以,我们先来看代码。

int main()
{

	int a = 9;
	double c = a;

	return 0;
}

这里为什么可以呢?

在强制类型转换时,会生成一个临时变量,将临时变量的值强制转换后在赋值。

 

使用场景

1. 做参数

我们上面的交换函数就是。

2.做返回值
int& Add(int a, int b)
{
	static int c = a + b;
	return c;
}

int main()
{

	int& a = Add(3, 5);
	cout << a << endl;

	a = 98;
	a = Add(a, 2);
	cout << a << endl;

	return 0;
}

怎么会是98呢?不应该是100吗?
注意:static 修饰的变量只会初始化一次,再次调用时跳过初始化语句。
int& Add(int a, int b)
{
	static int c;
	c = a + b;
	return c;
}

int main()
{

	int& a = Add(3, 5);
	cout << a << endl;

	a = 98;
	a = Add(a, 2);
	cout << a << endl;

	return 0;
}

 那么问题是,我直接返回值不好吗,为什么要引用返回呢?

1.以值作为参数或者返回值类型,在传参和返回期间,函数不会直接传递实参或者将变量本身直 接返回,而是传递实参或者返回变量的一份临时的拷贝,因此用值作为参数或者返回值类型,效 率是非常低下的,尤其是当参数或者返回值类型非常大时,效率就更低.

引用和指针的区别

 语法概念上引用就是一个别名,没有独立空间,和其引用实体共用同一块空间。

int main()
{
	int a = 10;
	int& ra = a;
	cout << "&a = " << &a << endl;
	cout << "&ra = " << &ra << endl;

	return 0;
}

底层实现上 实际是有空间的,因为 引用是按照指针方式来实现 的。

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

对5的解释:

int main()
{

	char a = 4;

	char* pa = &a;
	char& b = a;

	cout << sizeof(pa) << endl;
	cout << sizeof(b) << endl;

	return 0;
}

对9的解释:

不会有野指针这样的风险,而且频繁使用“*指针变量名”的形式进行运算容易产生错误而且可阅读性较差。

7. 内联函数

inline放在我们写的函数的前面,如:inline int Add(int a,int b);

inline 修饰 的函数叫做内联函数, 编译时 C++ 编译器会在 调用内联函数的地方展开 ,没有函数调 用建立栈帧的开销,内联函数提升程序运行的效率。

内联函数有什么作用? 

简单来说就是减少栈帧的开销,我们来看调用一个函数的过程。

我们要给这个函数建立栈帧,然后执行下面一系列操作。

但是inline函数就相当于这样。

不需要call 函数的地址,进入后再去执行。

当我们将源文件编译结束,如果编译器响应的话,未忽略我们的inline建议,那么此时我们已经找不到这个函数的地址,他已经完成了替换,也就少了call 函数地址这个过程。

 特性

1. inline 是一种 以空间换时间 的做法,如果编译器将函数当成内联函数处理,在 编译阶段,会
用函数体替换函数调用 ,缺陷:可能会使目标文件变大,优势:少了调用开销,提高程序运
行效率。
2. inline 对于编译器而言只是一个建议,不同编译器关于 inline 实现机制可能不同 ,一般建
议:将 函数规模较小 ( 即函数不是很长,具体没有准确的说法,取决于编译器内部实现 )
是递归、且频繁调用 的函数采用 inline 修饰,否则编译器会忽略 inline 特性。
3. inline 不建议声明和定义分离,分离会导致链接错误。因为 inline 被展开,就没有函数地址
了,链接就会找不到。

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

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

相关文章

【小白使用-已验证】PhpStudy下载安装使用教程23.10.17

1.phpstudy是什么&#xff1f; phpstudy是一个php运行环境的集成包&#xff0c;用户不需要去配置运行环境&#xff0c;就可以使用&#xff0c;phpstudy不仅是一款比较好用的php调试环境工具&#xff0c;并且还包括了开发工具和常用手册&#xff0c;对于新手是有很大帮助的。 一…

AC/DC电源模块工作效率的特点

BOSHIDA AC/DC电源模块工作效率的特点 AC/DC电源模块是一种用来将交流电转换为直流电的设备&#xff0c;在各种电子设备中应用广泛。其中&#xff0c;工作效率是评价AC/DC电源模块性能的关键指标之一。下面将从工作效率的特点方面进行阐述&#xff0c;以帮助读者更好地理解AC/…

符尧:别卷大模型训练了,来卷数据吧!【干货十足】

大家好&#xff0c;我是HxShine。 今天分享一篇符尧大佬的一篇数据工程&#xff08;Data Engineering&#xff09;的文章&#xff0c;解释了speed of grokking指标是什么&#xff0c;分析了数据工程&#xff08;data engineering&#xff09;包括mix ratio&#xff08;数据混合…

DCDC Buck电路地弹造成的影响

很多读者都应该听过地弹&#xff0c;但是实际遇到的地弹的问题应该很少。本案例就是一个地弹现象导致电源芯片工作不正常的案例。 問題描述 如下图1 &#xff0c;产品其中一个供电是12V转3.3V的电路&#xff0c;产品发货50K左右以后&#xff0c;大约有1%的产品无法启动&#…

岩土工程监测利器:多通道振弦数据记录仪应用隧道监测

岩土工程监测利器&#xff1a;多通道振弦数据记录仪应用隧道监测 岩土工程监测在现代工程建设中的作用越来越重要。为了确保工程质量和工程安全&#xff0c;需要对工程过程中的各种参数进行实时监测和记录。而多通道振弦数据记录仪则是一种重要的监测工具&#xff0c;特别适用…

BI工具-DataEase(1) 安装

dataease安装可以在线安装,也可以下载离线安装包进行安装,个人习惯我这里使用离线安装: 下载地址是: 开源社区 - FIT2CLOUD 飞致云 . 使用的版本是 1.18.11 1. 配置完成jdk环境 #JAVA_HOME export JAVA_HOME/home/soft/jdk1.8.0_281 export PATH$JAVA_HOME/bin:$PATH expor…

如果Domino上的邮件无法直接发送到@outlook.com

大家好&#xff0c;才是真的好。 目前将Domino仅仅作为邮件服务器的企业用户还不少。如果Domino服务器版本比较新&#xff08;例如版本为11.0.x、12.0.x等&#xff09;&#xff0c;外发邮件时&#xff0c;没有通过邮件网关中转邮件&#xff0c;而是直接发送到Internet互联网上…

1.16.C++项目:仿muduo库实现并发服务器之HttpContext以及HttpServer模块的设计

文章目录 一、HttpContext模块二、HttpServer模块三、HttpContext模块实现思想&#xff08;一&#xff09;功能&#xff08;二&#xff09;意义&#xff08;三&#xff09;接口 四、HttpServer模块实现思想&#xff08;一&#xff09;功能&#xff08;二&#xff09;意义&#…

斯坦福JSKarel教学编程机器人使用介绍

斯坦福JSKarel教学编程机器人使用介绍 为了避免被编程语言固有的复杂性所困扰&#xff0c;有一个被称为卡雷尔&#xff08;Karel&#xff09;机器人的微型世界&#xff08;microworld&#xff09;的简化环境&#xff0c;可以让编程初学者从中学习理解编程的基本概念&#xff0…

3.4 延迟渲染

一、渲染路径 1.渲染路径 渲染路径&#xff08;Rendering Path&#xff09; 决定光照的实现方式&#xff0c;当前渲染目标使用光照的流程。 二、渲染方式 1.前向渲染 在渲染每一帧时&#xff0c;每个顶点/片元都要执行一次片元着色器代码&#xff0c;这时需要将所有的光照…

电流反馈型运放以及PCB

电流反馈型运放&#xff0c;宽带放大器的布局布线&#xff0c;宽带放大器的PCB绘制的注意事项 控制放大倍数的芯片选择 高压摆率高输出功率只能选择TI THS系列 第&#xff08;6&#xff09;条实现不了整体闭环控制 反向输入端接电容会震荡&#xff0c;不接电容时可能会…

英语——分享篇——每日100词——901-1000

chemical——n.化学品——chemi车迷(拼音)cal(l)打电话(熟词)——车迷打电话买了大量化学品 ordinary——adj.平凡的&#xff0c;普通的——or偶人di弟na那ry人妖——平凡的偶人弟弟变成了那个人妖 container——n.容器——con肯(谐音)tain太闹(拼音)er儿(拼音)——小肯太闹&…

解析几何:计算两条线段的交点

大家好&#xff0c;我是前端西瓜哥。 今天来实现计算两条线段的交点的解析几何算法。 我们要实现 getLineSegIntersection 方法&#xff1a;提供两条线段&#xff0c;计算它们的交点。 每条线段会用两个点坐标表示。 const getLineSegIntersection (p1, p2, p3, p4) > …

多媒体应用设计师 第3章 多媒体信息传输技术

1.数据通信技术 1.1.多媒体通信的服务质量 多媒体服务质量(Qos)指网络服务的良好程度&#xff0c; 衡量QoS的常见指标为:吞吐量&#xff0c;差错率&#xff0c;端到端延迟&#xff0c;延迟抖动,带宽&#xff0c;丢包率&#xff0c;服务可用性等。 1.2.多媒体通信的服务质量类…

MDK Keil开发时出现问题汇总与解决办法--实战成功解决

文章目录 问题1&#xff1a;Error :Flash Download failed "Cortex-M4" 出现无法烧录问题点击烧录时出现下述图片&#xff1a;问题分析&#xff1a;发现没有添加编程算法描述&#xff1a;正确的情况是下面的点击Add按钮&#xff0c;选择主Flash添加&#xff1a;编译后…

windows每天定时重启 Win11 Win10定时重启 windows定时重启系统 windows每天定时重启

windows每天定时重启 Win11 Win10定时重启 windows定时重启系统 windows每天定时重启 使用 Windows 的任务计划程序来设置每天自动重启计算机1. 打开 任务计划程序&#xff1a;2. 在 任务计划程序库 面板中&#xff0c;创建一个基本任务3、设置计划任务权限 使用 Windows 的任务…

你真的了解微服务架构吗?

目录 写在前面 从单体架构说起 聊到分布式架构 聊回到微服务架构 微服务架构的关键技术 写在前面 随着互联网行业的快速发展&#xff0c;对服务的要求也越来越高&#xff0c;服务架构早就从原来单体架构逐渐演变为现在流行的微服务架构。 微服务&#xff08;Micros…

代码随想录算法训练营第二十四天丨 回溯算法part02

216.组合总和III 思路 本题就是在 [1,2,3,4,5,6,7,8,9] 这个集合中找到和为n的k个数的组合。 相对于77. 组合 (opens new window)&#xff0c;无非就是多了一个限制&#xff0c;本题是要找到和为n的k个数的组合&#xff0c;而整个集合已经是固定的了[1,...,9]。 本题k相当于…

目标跟踪数据集分享

360VOT: A New Benchmark Dataset for Omnidirectional Visual Object Tracking 360VOT 是一个新的大规模全景追踪基准数据集&#xff0c;旨在为全景视觉物体追踪提供支持。这个数据集包含了 120 个序列&#xff0c;总计超过 11.3 万张高分辨率帧&#xff0c;采用等距投影。追踪…

ImgPlus:基于CodeFormer的图片增强

背景 最近参与了华为云开发者大会AI赛道&#xff0c;做了一个AI图片增强作品&#xff0c;本片文章来简单介绍一下。 正文 作品名称&#xff1a;ImgPlus 赛题技术领域选择&#xff1a; AI&#xff0c;图片增强 使用技术名称&#xff1a; CodeFormer&#xff0c;ECS&#xff0…