【C++初阶】--入门基础(二)

目录

一.C++输出与输入

二.缺省参数 

1.概念 

2.缺省参数分类 

(1) 全缺省参数

(2)半缺省参数 

三.函数重载 

1.概念 

2.C++支持函数重载的原理--名字修饰

四.引用 

1.概念 

2.语法 

3.引用的特性 

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

(2)引用时不能改变指向 

(3)一个变量可以有多个引用

4.引用的使用场景 

(1)做参数 

①输出型参数

②对象比较大,减少拷贝,提高效率

(2)做返回值 

①正常情况 

②返回引用的情况

五.引用和指针的区别 


一.C++输出与输入

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

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

以及按命名空间使用方法使用std。

2. cout和cin是全局的流对象,endl是特殊的C++符号,表示换行输出,他们都包含在包含<

iostream >头文件中。

3. <<是流插入运算符,>>是流提取运算符

4. 使用C++输入输出更方便,不需要像printf/scanf输入输出时那样,需要手动控制格式。

C++的输入输出可以 自动识别变量类型

注意:早期标准库将所有功能在全局域中实现,声明在.h后缀的头文件中,使用时只需包含对应头文件即可,后来将其实现在std命名空间下,为了和C头文件区分,也为了正确使用命名空间,规定C++头文件不带.h;旧编译器(vc 6.0)中还支持<iostream.h>格式,后续编译器已不支持,因此推荐使用<iostream>+std的方式。

  •  图示

二.缺省参数 

1.概念 

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

  • 示例 
void Func(int a = 0)
{
	cout << a << endl;
}
int main()
{
	Func(); // 没有传参时,使用参数的默认值
	Func(10); // 传参时,使用指定的实参
	return 0;
}

2.缺省参数分类 

(1) 全缺省参数

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

(2)半缺省参数 

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

  • 注意 

1. 半缺省参数必须从右往左依次来给出,不能间隔着给。

2. 缺省参数不能在函数声明和定义中同时出现。(最好在声明给,如果声明没有给,那定义处也不要给)。

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

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

三.函数重载 

1.概念 

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

  • 示例 
 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;
}
  • 结果显示 

2.C++支持函数重载的原理--名字修饰

  •  为什么C++支持函数重载,而C语言不支持函数重载呢?

在C/C++中,一个程序要运行起来,需要经历以下几个阶段:预处理、编译、汇编、链接
预处理:展开头文件、进行宏替换、条件编译、去掉注释

编译:检查语法

汇编:把汇编代码转成二进制机器码

链接:完成文件中各种调用的函数以及库的连接,并将它们一起打包合并形成可执行文件

1. 实际项目通常是由多个头文件和多个源文件构成,而通过C语言阶段学习的编译链接,我们可以知道,【当前a.cpp中调用了b.cpp中定义的Add函数时】,编译后链接前,a.o的目标

文件中没有Add的函数地址,因为Add是在b.cpp中定义的,所以Add的地址在b.o中。那么

怎么办呢?

2. 所以链接阶段就是专门处理这种问题, 链接器看到a.o调用Add,但是没有Add的地址,就

会到b.o的符号表中找Add的地址,然后链接到一起
 

  • 链接的时候面对相关函数,链接接器会使用哪个名字去找呢? 

 使用C语言编译器:

可以看到在C语言编译器下函数名字的修饰没有发生改变。

使用C++编译器:

在C++编译器下函数名字的修饰发生改变,编译器将函数参数类型信息添加到修改后的名字中。

  • 总结 

在不同编译器下函数被修饰后函数名发生了变化,C语言中函数名没有改变而C++中函数名的形式变为【_Z+函数长度+函数名+参数类型首字母(指针的话为Pi)】 .这里可以了解C语言无法支持重载是因为无法区分函数名,而C++通过修饰函数名来进行区分,只要参数类型不同,即视为不同函数,也就支持了重载。

四.引用 

1.概念 

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

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

2.语法 

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

void TestRef()
{
	int a = 10;
	int& ra = a;//<====定义引用类型
	printf("%p\n", &a);
	printf("%p\n", &ra);
}
int main()
{
	TestRef();
	return 0;
}

注意:引用类型必须和引用实体是同种类型的。

3.引用的特性 

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

void TestRef1()
{
	int a = 10;
	// int& ra; 该条语句编译时会出错
	int& ra = a;
}

(2)引用时不能改变指向 

void TestRef2()
{
	int a = 10;
	int& ra = a;

	int b = 2;
	ra = b;//产生歧义
}

ra=b这条语句,不是改变了让指向,而是赋值。

(3)一个变量可以有多个引用

void TestRef2()
{
	int a = 10;
	int& ra = a;
	int& rra = ra; 
	printf("%p %p %p\n", &a, &ra, &rra);
}

4.引用的使用场景 

(1)做参数 

①输出型参数
void Swap(int& left, int& right)
{
	int temp = left;
	left = right;
	right = temp;
}
int main()
{
	int a = 1;
	int b = 2;
	Swap(a, b);
	cout << "a==" << a  << endl;
	cout << "b==" << b << endl;
	return 0;
}
 ②对象比较大,减少拷贝,提高效率
struct A { int a[10000]; };
void TestFunc1(A a) {}
void TestFunc2(A& a) {}
void TestRefAndValue()
{
	A a;
	// 以值作为函数参数
	size_t begin1 = clock();
	for (size_t i = 0; i < 10000; ++i)
		TestFunc1(a);
	size_t end1 = clock();
	// 以引用作为函数参数
	size_t begin2 = clock();
	for (size_t i = 0; i < 10000; ++i)
		TestFunc2(a);
	size_t end2 = clock();
	// 分别计算两个函数运行结束后的时间
	cout << "TestFunc1(A)-time:" << end1 - begin1 << endl;
	cout << "TestFunc2(A&)-time:" << end2 - begin2 << endl;
}
int main()
{
	TestRefAndValue();
	return 0;
}

(2)做返回值 

①正常情况 
int func()
{
	int a = 0;
	return a;
}
int main()
{
	int ret = func();
	cout << ret << endl;
	return 0;
}
  • 细节理解

​​​​​​​​​​​​​​

函数调用完成后生命周期结束,栈帧销毁,此时变量a销毁或是复制给另一个临时变量(可能为寄存器或者其他已经开辟好的一块空间。这个临时变量生命周期较长,能将其值复制给ret变量),此时若用a当做返回值,返回的很可能是随机值(根据平台不同来定)。

 ②返回引用的情况
int& func()
{
	int a = 0;
	return a;
}
int main()
{
	int ret = func();
	cout << ret << endl;
	return 0;
}

这里返回a的别名,也就是func函数中变量a自身,由于函数调用结束,栈帧销毁,这里返回的具体是什么要看函数销毁后变量a所占的那块空间销毁是否销毁,如果销毁了,那么返回随机值,如果没销毁可能可以拿到变量a本身的值,也可能是类型及大小相同的另一个函数,被调用后所留下的另一个值。 

  • 总结 

 返回的变量(如局部变量)出了函数作用域后生命周期结束,不能用引用返回。

全局变量、静态变量、堆上变量等就可以用引用返回

五.引用和指针的区别 

1. 引用概念上定义一个变量的别名,指针存储一个变量地址。

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

9. 引用比指针使用起来相对更安全。

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

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

相关文章

区间时间检索

前端 <el-col :md"6" v-if"advanced"><el-form-item :label"$t(inRecord.column.createTime)"><el-date-pickerstyle"width: 100%;"v-model"daterangeCreateTime"value-format"yyyy-MM-dd"type&qu…

装饰你的APP:使用Lottie-Android创建动画效果

装饰你的APP&#xff1a;使用Lottie-Android创建动画效果 1. Lottie-Android简介 Lottie-Android是一个强大的开源库&#xff0c;由Airbnb开发&#xff0c;旨在帮助开发者轻松地在Android应用中添加高质量的动画效果。它基于Adobe After Effects软件中的Bodymovin插件&#x…

【项目简记】逆向工程裸机内核镜像

本教程将是裸机逆向工程系列的一部分。 自从拆解了几部安卓手机后&#xff0c;我对嵌入式系统的兴趣越来越大。 虽然手机本身并不是嵌入式系统&#xff0c;但我知道手机最终会取代计算机&#xff1b;因此&#xff0c;我想学习更多关于它们的知识。 就在那时&#xff0c;我开始…

Linux 系统开始配置

文章目录 备份源为root 设置密码安装基本工具切换root 用户删除snap从 Ubuntu 移除 Snap 后使用 deb 文件安装软件商店和 Firefox在 Ubuntu 系统恢复到 Snap 软件包总结 删除 vim安装neovim在线安装neovim压缩安装neovim安装lazyvim安装剪切板 安装qt配置 Qt 环境不在sudoers文…

SAP 消息号 FAGL_CLOSING_ACT011

在S4当中&#xff0c;月末外币评估的时候&#xff0c;会出现如下报错&#xff1a; 解决方法是&#xff1a; “创建错误更正和暂记会计核算运行标识的编号范围、 在ECS中创建凭证编号范围” 给以上2个事务&#xff0c;添加号码范围即可。

关于破解IDEA后启动闪退的问题

问题描述&#xff1a;2023.1启动不了&#xff0c;双击桌面图标&#xff0c;没有响应。 解决办法&#xff1a; 打开C:\Users\c\AppData\Roaming\JetBrains\IntelliJIdea2023.1\idea64.exe.vmoptions 这个文件。 内容如下所示&#xff1a; 删除红框的数据以后&#xff0c;再登录…

使用 IDEA 开发一个简单易用的 SDK

目录 一、什么是 SDK 二、为什么要开发 SDK 三、开发 SDK 的详细步骤 四、导入 SDK 进行测试 附&#xff1a;ConfigurationProperties 注解的介绍及使用 一、什么是 SDK 1. 定义&#xff1a;软件开发工具包 Software Development Kit 2. 用于开发特定软件或应用程序的工…

LLM之Agent(十一)| 多智能体框架CrewAI与AutoGen相比

基于LLM构建的Agent中有一个明显的现象就是多智能体体系结构的表现要超越单智能体&#xff0c;即使单智能体使用无可挑剔的提示策略。本文将探索另一个有趣的多智能体框架——CrewAI。 一、CrewAI整体优势 CrewAI可以应用在生成环境中。它在发言人的反应和编排上牺牲了一点灵活…

【BIAI】Lecture 9-Motor system 1

Motor System 专业词汇 skeletal muscle 骨骼肌 smooth muscle 平滑肌 cardiac muscle 心肌 flexor reflex 屈曲反射 central pattern generators 中央模式生成器 bio-inspired bipedal robots 仿生双足机器人 myotatic stretch reflex 肌肉自伸展反射 Cortex optic nerve 视皮…

架构整洁之道-软件架构-概述、独立性、划分边界与边界剖析

6 软件架构 6.1 什么是软件架构 “架构”这个词给人的直观感受就是充满了权力和神秘感&#xff0c;因此谈论架构总让人有一种正在进行责任重大的决策或者深度技术分析的感觉。而软件架构师的工作内容究竟是什么呢&#xff1f; 软件架构师自身需要是程序员&#xff0c;并且必须…

C语言指针学习 之 指针变量

前言&#xff1a; 通过学习我们认识了什么是指针&#xff0c;就让我们一起来分析一个例子。 #include<stdio.h> int main() {int a100;int * hz; hz &a;printf("a%d \n",a);printf("*hz%d \n",*hz);return 0; }a100 *hz100 PS C:\csay\cyuya…

spring boot yaml文件中如何设置duration对象值

Spring Boot对表示持续时间有专门的支持。如果您公开java.time.Duration属性&#xff0c;则应用程序对应Duration类型的属性有以下格式可用: long类型的常规表示(使用毫秒作为默认单位&#xff0c;除非指定了DurationUnit)java.time.Duration 使用的标准ISO-8601格式其中值和单…

【巧用异或】单身狗2题解

✨✨欢迎大家来到Celia的博客✨✨ &#x1f389;&#x1f389;创作不易&#xff0c;请点赞关注&#xff0c;多多支持哦&#x1f389;&#x1f389; 所属专栏&#xff1a;【每日刷题】C语言 个人主页&#xff1a;Celias blog~ 题目 一个数组中只有两个数字是出现一次&#xff0c…

应对手机数据丢失的5大安卓数据恢复软件

我们都去过那里。您的手机上的数据丢失了&#xff0c;现在无法恢复。这尤其令人恐惧&#xff0c;因为我们的手机上都有如此多的信息。从图片、应用程序、个人信息&#xff0c;甚至是来自可能已不复存在的亲人的短信和语音邮件。这种情况确实发生了&#xff0c;而且也不仅仅是An…

【Java程序设计】【C00239】基于Springboot的漫画之家管理系统(有论文)

基于Springboot的漫画之家管理系统&#xff08;有论文&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的漫画之家系统 本系统分为系统功能模块、管理员功能模块以及用户功能模块。 系统功能模块&#xff1a;在系统首页可以查看首页&a…

【Tomcat与网络3】Tomcat的整体架构

目录 1.演进1&#xff1a;将连接和处理服务分开 2演进2&#xff1a;Container的演进 3 再论Tomcat的容器结构 4 Tomcat处理请求的过程 5 请求的处理过程与Pipeline-Valve管道 在前面我们介绍了Servlet的基本原理&#xff0c;本文我们结合Tomcat来分析一下如何设计一个大型…

Flutter开发2:安装Flutter

在本篇博客中&#xff0c;我们将详细介绍如何安装Flutter开发环境。安装Flutter是开始使用Flutter进行跨平台移动应用开发的第一步。让我们开始吧&#xff01; 官方安装文档 步骤1&#xff1a;下载Flutter SDK 打开浏览器&#xff0c;访问Flutter官方网站&#xff1a;https://…

latex multirow学习

今天搞了一晚上的这个multirow&#xff0c;总算弄出来了几个比较好的例子&#xff0c;主要是这个multirow的语法我没看懂&#xff0c;这个逻辑我是没理解&#xff0c;就很尴尬&#xff0c;一改就报错&#xff0c;只能先弄几个例子&#xff0c;自己慢慢试 \documentclass{artic…

Apache Doris 整合 FLINK CDC + Iceberg 构建实时湖仓一体的联邦查询

1概况 本文展示如何使用 Flink CDC Iceberg Doris 构建实时湖仓一体的联邦查询分析&#xff0c;Doris 1.1版本提供了Iceberg的支持&#xff0c;本文主要展示Doris和Iceberg怎么使用&#xff0c;大家按照步骤可以一步步完成。完整体验整个搭建操作的过程。 2系统架构 我们整…

vscode实时预览markdown效果

安装插件 Markdown Preview Enhanced 上面是搜索框 启动预览 右键->Open Preview On the Side 效果如下&#xff1a; 目录功能 目录功能还是使用gitee吧 push后使用gitee&#xff0c;gitee上markdown支持侧边生成目录