【C++语言】冲突-C语言:命名冲突(输入输出、缺省参数、引用、内联函数)

在这里插入图片描述


文章目录

  • 前言
  • 正文
  • 2. C++的输入与输出:
  • 3.缺省参数
    • 3.1 缺省参数的概念:
    • 3.2 缺省参数的分类:
      • 全缺省参数:
      • 半缺省参数:
  • 4.函数重载
    • 4.1 函数重载的概念:
  • 5.引用
    • 5.1 引用的基本概念:
    • 5.2 引用的特性:
    • 5.3 常引用:
    • 5.4 引用使用场景:
  • 6.内联函数
    • 6.1 概念:
    • 6.2 特性:
  • C++语言系列学习目录


前言

这里是对上篇推文的衔接。


正文

2. C++的输入与输出:

了解了上面的知识,确实这样写就不大好了,当然如果是竞赛,全部展开还会影响代码速度。

#include<iostream>
// std是C++标准库的命名空间名,C++将标准库的定义实现都放到这个命名空间中
using namespace std;
int main()
{
cout<<"Hello world!!!"<<endl;
return 0;
}

这里就不如单独展开,或者单独访问

#include<iostream>

using  std::cout;
using  std::endl;
int main()
{
cout<<"Hello world!!!"<<endl;
std::cout<<"Hello world!!!"<<std::endl;
return 0;
}

说明:

  1. 使用cout标准输出对象(控制台)和cin标准输入对象(键盘)时,必须包含< iostream >头文件以及按命名空间使用方法使用std。
  2. cout和cin是全局的流对象,endl是特殊的C++符号,表示换行输出,他们都包含在包含< iostream >头文件中。
  3. <<是流插入运算符,>>是流提取运算符。
  4. 使用C++输入输出更方便,不需要像printf/scanf输入输出时那样,需要手动控制格式。C++的输入输出可以自动识别变量类型
  5. 实际上cout和cin分别是ostream和istream类型的对象,>>和<<也涉及运算符重载等知识。

3.缺省参数

3.1 缺省参数的概念:

  • 缺省参数是声明或定义函数时为函数的参数指定一个缺省值。在调用该函数时,如果没有指定实参则采用该形参的缺省值,否则使用指定的实参。
    在这里插入图片描述

3.2 缺省参数的分类:

全缺省参数:

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

半缺省参数:

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

注意:

  1. 半缺省参数必须从右往左依次来给出,不能间隔着给
    解释:我们函数输入参数是按照从左向右的顺序,如果半缺省参数也从左向右的顺序来,那么就很有可能后面的参数没有默认值,导致参数缺少;

  2. 缺省参数不能在函数声明和定义中同时出现,在声明给缺省。
    理由:在预处理阶段—编译阶段我们都只能看到声明文件,不包含定义文件,所以如果是声明没有给缺省,我们传入参数数量若少于声明参数数量则会报错。所以我们就在声明给缺省。

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

  4. C语言不支持(编译器不支持)

4.函数重载

4.1 函数重载的概念:

函数重载: 是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的形参列表(参数个数 或 类型 或 类型顺序)不同,常用来处理实现功能类似数据类型不同的问题。

#include<iostream>
using namespace std;
// 1、参数类型不同
int Add(int left, int right)
{
	cout << "int Add(int left, int right)" << endl;
	return left + right;
}
double Add(double left, double right)
{
	cout << "double Add(double left, double right)" << endl;
	return left + right;
}
// 2、参数个数不同
void f()
{
	cout << "f()" << endl;
}
void f(int a)
{
	cout << "f(int a)" << endl;
}
// 3、参数类型顺序不同
void f(int a, char b)
{
	cout << "f(int a,char b)" << endl;
}
void f(char b, int a)
{
	cout << "f(char b, int a)" << endl;
}
int main()
{
	Add(10, 20);
	Add(10.1, 20.2);
	f();
	f(10);
	f(10, 'a');
	f('a', 10);

	return 0;
}

5.引用

5.1 引用的基本概念:

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

比如:李逵,在家称为 铁牛 ,江湖上人称黑旋风。只是别名。

在这里插入图片描述
在代码中引用的格式:类型& 引用变量名(对象名) = 引用实体;

5.2 引用的特性:

#include<stdio.h>
int main()
{
	int a = 10;
	int b = 20;
	//int& b;这里会报错,原因引用必须初始化
	int& ra = a;//这里就是定义ra为a的别名
	int& rra = a;//一个变量可以有多个引用
	//int& ra=b;//这里会报错,引用只能引用一个引用实体,引用在C++中是不能更改的;
	printf("%d %d %d\n", a, ra,rra);
	//打印结果为:10  10  10
	printf("%p %p %p\n", &a, &ra,&rra);
	//打印结果为:00B3F70C 00B3F70C 00B3F70C
	ra=b;//赋值操作,a.ra.rra为同一空间,一个改变其他肯定改变,值是统一的,只是称呼不同罢了
	printf("%d %d %d\n", a, ra,rra);
	//打印结果为:20  20  20
}

从上面代码我们可以得出引用的特性:

    1. 引用定义必须初始化,也就是必须有引用实体;
    1. 一个变量可以有多个引用;
    1. 引用一旦引用一个实体,再不能引用其他实体;

5.3 常引用:

#include<stdio.h>
int main()
{
	//引用过程中权限不能扩大,但可以平移和缩小
	const int a = 10;
	//int& ra = a; // 该语句编译时会出错,a为常量--权限扩大(x)
	int c = 20;
	const int& rc = c;//权限缩小
	const int& ra = a;//权限平移
}
  • 结论:引用过程权限只能平移或者缩小,不能扩大
// int& b = 10; // 该语句编译时会出错,b为常量--权限扩大(x)
	const int& b = 10;
	
	double d = 12.34;
	//int& rd = d; // 该语句编译时会出错,类型不同--权限扩大(x)
	const int& rd = d;//为什么不报错呢?为什么加个const就可以了

再看这个例子,const int& rd = d;//为什么不报错呢?为什么加个const就可以了?其实这个对比上面局的b的例子或许能得出答案;

  • 10是一个常量,类型可以看做为const int类型,所以第一句是权限扩大,会报错。所以加const修饰就可以,实现权限平移,不会报错
  • 第二个是会发生强制类型转化,但转换过程中会用到中间临时变量,临时变量具有常性,为一个常量,所以理由同上;
int func1()
{
	int x = 10;
	return x;
}

int& func2()
{
	int x = 10;
	return x;
}

int main()
{
	int ret = func1();//拷贝
	//int& ret = func1();报错,权限扩大(x)
	const int& ret = func1; //和上面一样,返回值的话是需要通过临时变量的,也就同上

	int& ret = func2();//这就没有问题,这里的func2()相当于对x的取别名,这里就相当于再次取别名
	const int& ret = func2();//权限的缩小;
}

5.4 引用使用场景:

  1. 做参数:
//拿交换函数来举个例子:
void Swap(int& left,int& right)
{
	int tem = left ;
	left = right;
	right =tem;
}

Swap(a,b);

在上述代码中,其实我们传入的a,b就不在是a,b的值拷贝了,而是a,b的别名,所以更改left,right就可以实现更改a,b;

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

  1. 做返回值:
//传值返回
#include<stdio.h>
#include<iostream>
using namespace std;

int& count(int x)//返回一个n的别名
{
	int n = x;
	n++;
	return n;
}

int main()
{
	int& ret = count(10);//别名的多层复用
	cout << ret << endl;//运行结果:11

	count(20);
	rand();
	cout << ret << endl;//运行结果:随机值
}

为什么这里会出现错误,而不是和我们上面所说的一样,n一改变其他别名也会改变呢?其实这里依旧是这个原理,但不一样的是这里的n为局部变量,n在调用过后栈区间会清除(并非销毁空间,归还区间访问权,清理该区间的数据)。那问题来了,为什么第一个答案是11是正确的呢,这可能跟编译器有关,编译器没有在清除该区域,只是收回了访问权(比如:指针就无法访问到这片空间,但值或许没变),但在调用rand()函数或者随机一个函数时,会开辟空间,就可能会利用到n那片空间,系统在栈帧操作过程中,就会有赋值,所以当我们引用继续访问时,发现值已经改变;

总结:传参引用都可以使用,但作为返回值需要考虑传回参数是否会出作用域后被清除。

6.内联函数

6.1 概念:

概念:以inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开,没有函数调用建立栈帧的开销,内联函数提升程序运行的效率。
在这里插入图片描述
如果在上述函数前增加inline关键字将其改成内联函数,在编译期间编译器会用函数体替换函数的调用。查看方式:

  1. 在release模式下,查看编译器生成的汇编代码中是否存在call Add
  2. 在debug模式下,需要对编译器进行设置,否则不会展开(因为debug模式下,编译器默认不会对代码进行优化)

6.2 特性:

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

C++语言系列学习目录

提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加,添加超链接

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

系统工程学思想

系统工程学思想 大项目或复杂问题的实施和解决&#xff0c;需要按照系统工程学理论进行&#xff0c;以系统的方法完整、全面的分析&#xff0c;而不是零星的处理问题&#xff0c;沿着逻辑推理的路径&#xff0c;去解决哪些原本靠直觉判断处理的问题。 系统分析过程逻辑结构分为…

A Review on Influence Dissemination in Social Networks

Abstract 影响力传播研究是社交网络信息传播的关键问题。由于影响力分析在营销、广告、个性化推荐、舆情监测等方面的现实意义&#xff0c;研究人员从不同角度研究了该问题并提出了解决方案。在本文中&#xff0c;我们回顾了社交网络中的影响力传播&#xff0c;并得出结论&…

淘宝APP详情数据抓取技术揭秘:用Python实现自动化数据获取(附代码实例)

获取淘宝APP详情数据接口通常涉及到网络爬虫技术&#xff0c;因为淘宝作为一个大型电商平台&#xff0c;其数据并不直接对外公开提供API接口供第三方开发者使用。然而&#xff0c;通过模拟浏览器行为或使用淘宝开放平台提供的API&#xff08;如果有的话&#xff09;&#xff0c…

借助剪映软件生成原创视频(真人人声,免VIP)

civilpy&#xff1a;借助各大模型的优点生成原创视频&#xff08;真人人声&#xff09;Plus0 赞同 0 评论文章​编辑 是的&#xff0c;剪映也出了声音克隆了&#xff0c;只需要十几秒的录音就可以克隆自己的声音&#xff0c;虽然微瑕&#xff0c;但是对于不习惯机器音的很多创…

【面试】Elasticsearch 在部署时,对 Linux 的设置有哪些优化方法?

Elasticsearch 在部署时&#xff0c;对 Linux 的设置有哪些优化方法&#xff1f; Elasticsearch是一个分布式搜索和分析引擎&#xff0c;它在Linux环境下的性能和稳定性可以通过一些优化方法进行提升。以下是一些针对Linux环境下Elasticsearch部署的优化方法&#xff1a; 1. 内…

职场人必备!效率翻倍的多微信号必备管理工具大揭秘

在职场中&#xff0c;高效率的工作方式是非常重要的。而为了提高工作效率&#xff0c;合理运用一些工作神器也是必不可少的。今天给大家分享一个多微信号管理工具——微信管理系统&#xff0c;它能够帮助职场人员管理多个微信号&#xff0c;让工作变得更加高效。 首先&#xf…

嵌入式开发——基础元器件

目录 1. 电阻 2. 电容 3. 电感 4. 二极管 5. 三极管 6. MOS管 7. 晶振 8. 磁珠 9. LDO 10. 电源 11. 接地 12. 线路 13. 电压表 14. 电流表 1. 电阻 根据欧姆定理&#xff0c;UI*R&#xff0c;通过某段导体的电流跟这段导体两端的电压成正比&#xff0c;跟这段导…

教你六个步骤完成本地知识库搭建

用通俗易懂的语言说&#xff0c;本地知识库就是一个放在公司电脑或服务器上的知识大宝库。这个宝库里可以放入各种知识&#xff0c;比如公司的规章制度、产品介绍、销售技巧、市场分析报告等等&#xff0c;只要是公司里觉得有用的知识&#xff0c;都可以放进去。 有了它&#x…

如何本地部署Elasticsearch+cpolar实现公网查询与管理内网数据

文章目录 系统环境1. Windows 安装Elasticsearch2. 本地访问Elasticsearch3. Windows 安装 Cpolar4. 创建Elasticsearch公网访问地址5. 远程访问Elasticsearch6. 设置固定二级子域名 正文开始前给大家推荐个网站&#xff0c;前些天发现了一个巨牛的 人工智能学习网站&#xff…

Mysql高阶语句—子查询、视图、NULL

目录 一、子查询 1.1 select 1.1.1 相同表查询 1.1.2 多表查询 1.1.3 NOT 取反,将子查询的结果&#xff0c;进行取反操作 1.2 insert 1.3 update 1.4 delete 1.5 exists 1.6 as别名 二、MySql视图 2.1 创建单视图表 2.2 创建多视图表 2.3修改视图表数据 2.4…

Gui guider使用自定义字体总结

在实际开发中&#xff0c;我们通常是使用自定义字体。 在 LVGL 中&#xff0c;用户需要使用自定义的字库&#xff0c;其实现方法可分为两类&#xff1a; ① 通过 C 语言数组&#xff08;内部读取&#xff09;&#xff1b; ② 通过文件系统读取字库&#xff08;外部读取&#…

Databend 开源周报第 137 期

Databend 是一款现代云数仓。专为弹性和高效设计&#xff0c;为您的大规模分析需求保驾护航。自由且开源。即刻体验云服务&#xff1a;https://app.databend.cn 。 Whats On In Databend 探索 Databend 本周新进展&#xff0c;遇到更贴近你心意的 Databend 。 支持查询匹配倒…

大型网络游戏设计与AI赋能-4

接上文---- 第一个要去搭建的就是这个运行平台层。在此之上&#xff0c;我们会引入一些第三方SDK包。 为什么要引入第三方的SDK包&#xff1f;大家要知道一点&#xff0c;任何研发一款软件从来都不会从头造轮子。就是我们在开发一款软件的时候&#xff0c;从来都不会从头造轮子…

PyTorch使用cuda场合与Apple M1的GPU MPS的转换

此示例仅仅是一个简单的VGG模型调用。

T2. 排队选人 - 小米前端笔试编程题解

考试平台&#xff1a; 赛码 题目类型&#xff1a; 20道选择 2道编程题 考试时间&#xff1a; 2024-03-23 &#xff08;两小时&#xff09; 题目描述 小D是一名老师&#xff0c;他想选出一些同学参加一个团体比赛。 总共有n个同学&#xff0c;每个同学有一个能力值x和一个合作…

深入探讨iOS开发:从创建第一个iOS程序到纯代码实现全面解析

iOS开发作为移动应用开发的重要领域之一&#xff0c;对于开发人员具有重要意义。本文将深入探讨iOS开发的各个方面&#xff0c;从创建第一个iOS程序到纯代码实现iOS开发&#xff0c;带领读者全面了解iOS应用程序的开发流程和技术要点。 &#x1f4f1; 第一个iOS程序 在创建第…

【数据结构】 HashMap源码分析(常量+构造方法+方法)

文章目录 HashMap源码分析一、成员常量二、构造方法三、方法1.此时假定为进行了无参构造&#xff0c;没有分配内存2.当发生有参构造时&#xff0c;完成对容量的大小判断后&#xff0c;将容量大小&#xff0c;传进tableSizeFor方法中&#xff1a; HashMap源码分析 一、成员常量…

IDEA2023版本创建spring boot项目时,Java版本无法选择Java8问题解决

先简单说下出现本问题的原因&#xff1a; spring boot3.0发布时提到未来Java17将会成为主流版本&#xff0c;所有的Java EE Api都需要迁移到Jakarta EE上来。而spring boot3.0及以上版本已经不支持Java8了&#xff0c;支持Java17及以上版本。同时官方支持项目初始化的 Spring B…

FreeRTOS(三)

第二部分 事件组 一、事件组的简介 1、事件 事件是一种实现任务间通信的机制&#xff0c;主要用于实现多任务间的同步&#xff0c;但事件通信只能是事件类型的通信&#xff0c;无数据传输。其实事件组的本质就是一个整数(16/32位)。可以是一个事件发生唤醒一个任务&#xff…

微服务(基础篇-006-Docker)

Docker是一个开源的应用容器引擎&#xff0c;它让开发者可以打包他们的应用以及依赖包到一个可移植的容器中&#xff0c;然后发布到任何Linux机器上&#xff0c;也可以实现虚拟化。容器是完全使用沙箱机制&#xff0c;相互之间没有任何接口&#xff08;类似 iPhone 的 app&…