当前位置: 首页 > news >正文

【C++】C++入门基础讲解(二)

💗个人主页💗
⭐个人专栏——C++学习⭐
💫点击关注🤩一起学习C语言💯💫

导读

接着上一篇的内容继续学习,今天我们需要重点学习引用。

1. 引用

在C++中,引用是一种特殊的变量,用于别名一个已经存在的对象或变量。通过引用,可以使用别名来操作原始对象,而不是创建一个新的副本。
引用提供了一种简洁和高效的方式来传递参数、返回值和修改变量的值。

1.1 引用特性

  1. 引用在定义时必须初始化
  2. 一个变量可以有多个引用
  3. 引用一旦引用一个实体,再不能引用其他实体
void TestRef()
{int a = 10;int& ra = a;//<====定义引用类型printf("%p\n", &a);printf("%p\n", &ra);
}
int main()
{TestRef();return 0;
}

在这里插入图片描述

上述代码我们可以发现两者的地址是相同的,a和r指向是完全一样的
注意:
引用类型必须和引用实体是同种类型的

1.2 做参数使用

引用作为函数参数,意味着在函数调用时,我们将一个变量的引用传递给函数。这样,函数可以直接操作原始变量,而不是对其进行拷贝。

void swap(int& a, int& b) {int temp = a;a = b;b = temp;
}int main() {int x = 10;int& ref = x; // 引用xcout << "x = " << x << endl;   // 输出: x = 10cout << "ref = " << ref << endl; // 输出: ref = 10ref = 20; // 修改ref,实际上是修改xcout << "x = " << x << endl;   // 输出: x = 20cout << "ref = " << ref << endl; // 输出: ref = 20int a = 5;int b = 10;swap(a, b); // 传递a和b的引用,修改原始变量cout << "a = " << a << endl;   // 输出: a = 10cout << "b = " << b << endl;   // 输出: b = 5return 0;
}

在这里插入图片描述

1.3 做返回值使用

函数返回引用时需要确保返回的引用仍然指向有效的内存空间。通常,可以返回类成员变量的引用、静态变量的引用、函数内静态局部变量的引用等。
同时要注意的是,返回引用时需要避免返回对局部变量的引用,因为局部变量在函数结束后会被销毁,返回对其引用可能会导致未定义行为。

int& Max(int& a, int& b)
{return (a > b) ? a : b;
}int main()
{int x = 10, y = 20;int& max = Max(x, y);max = 30;  // 修改了y的值cout << "y: " << y << endl;  // 输出: 30return 0;
}

在这里插入图片描述
我们再来看一下下面的代码:

int& Add(int a, int b)
{int c = a + b;return c;
}
int main()
{int& ret1 = Add(1, 2);int& ret2 = Add(3, 4);cout << "Add(1, 2) is :" << ret1 << endl;cout << "Add(3, 4) is :" << ret2 << endl;return 0;
}

按照我们的预期,我们输出的两个数应该是3和7,然而:
在这里插入图片描述
这是为什么呢?

在函数 Add 中,局部变量 c 的生命周期仅限于函数内部。
当函数执行完毕后,c 被销毁,而返回的引用 ret 将指向一个不存在的对象。
当再次使用这个引用时,就会出现未定义的行为。

因此,应该避免将局部变量作为返回值的引用类型返回

1.4 引用和指针的区别

  1. 指针使用*来定义,而引用使用&来定义。
int* ptr; // 声明一个指针
int& ref = *ptr; // 定义一个引用,引用指针所指向的变量
  1. 指针可以被初始化为null或指向任意变量的地址,而引用必须在声明时初始化,并且不能为null。
int* ptr = nullptr; // 指针为空
int x = 5;
int& ref = x; // 引用x,ref指向x的地址
  1. 指针可以被重新赋值为指向其他变量的地址,而引用一旦初始化后就不能重新赋值为引用其他变量。
int x = 5;
int y = 10;
int* ptr = &x; // ptr指向x的地址
ptr = &y; // ptr现在指向y的地址int& ref = x; // ref引用x
ref = y; // 修改了x的值,ref仍然引用x
  1. 指针可以为空指针,即指向空地址,而引用不可以为空。
int* ptr = nullptr; // 指针为空
int& ref; // 错误,引用必须初始化
  1. 有多级指针,但是没有多级引用

1. 5 const引用

常引用可以引用普通变量,可以引用常变量,可以引用字面变量。
我们来看下面示例:

常变量:

const int a = 10;
int& ra = a;		// 错误
const int& ra = a;	//正确

int& ra = a; 试图将 a 绑定到一个非常引用 ra 上,这是错误的。常量对象不能通过非常引用进行修改。
因此这里应该使用 const int& ra = a; 来将 a 绑定到一个常引用 ra 上。

字面值:

int& b = 10;		// 错误
const int& b = 10;	// 正确

int& b = 10; 试图将字面值 10 绑定到一个非常引用 b 上,这是错误的。字面值是一个临时值,不能通过非常引用进行修改。
正确的做法应该是将 b 声明为常引用: const int& b = 10;

类型转换:

double d = 12.34;
int& rd = d;			// 错误
const double& rd = d;	// 正确

int& rd = d; 试图将 d 绑定到一个非常引用 rd 上,这是错误的。
d 是一个 double 类型的变量,不能通过非常引用来绑定到 int 类型的引用上。
正确的做法是将 rd 声明为 const 引用: const double& rd = d;

将 const 修饰符用于 int 类型的引用,可以确保在引用对象上不会进行修改操作,保护对象的不可变性,避免意外的修改导致数据不一致或错误的计算结果。

常引用的声明方式与普通引用相同,只是在引用类型前添加const关键字。常引用主要用于函数参数传递和对象成员访问,以确保访问的对象不会被修改。

void Print(const int& value) 
{// value 为 const 引用,不能修改其值cout << "Value: " << value << endl;// value = 10;  // 错误,不能修改 const 引用的值
}int main() 
{int num = 5;Print(num);  // 传递 num 的值给 printValue 函数return 0;
}

2. 内联函数

以inline修饰的函数叫做内联函数,是C++中的一种函数,它的定义和调用都被嵌入到调用该函数的地方,而不是通过函数调用的机制进行调用,没有函数调用建立栈帧的开销。
内联函数的主要目的是为了提高函数的执行效率,减少函数调用的开销。

inline int add(int a, int b) {return a + b;
}
int main()
{int ret = add(10, 20);return 0;
}

内联函数的使用有以下几点需要注意:

  1. 内联函数应该比较短小,避免过长的函数体,因为内联函数的定义会被嵌入到调用处,过长的函数体会导致代码冗长。

  2. 内联函数适合用于频繁执行的函数,例如在循环中反复调用的函数。

  3. 内联函数不能包含复杂的控制流语句,例如循环或递归,因为内联函数的展开是通过复制代码来实现的,这样的代码会导致代码膨胀。

  4. 编译器对内联函数的展开是有一定的自由度的,它可以根据实际情况决定是否展开函数体,因此对于内联函数的定义和使用应该在同一个文件中,以便编译器能够进行函数体的展开。

3. auto关键字

auto关键字是C++中的一个关键字,用于声明变量时自动推导变量的类型。
使用auto关键字可以省略变量类型的声明,编译器会根据变量的初始化表达式推导出变量的类型。
例如:

auto a = 10; // a的类型为int 
auto b = 3.14; // b的类型为double 
auto c = "hello"; // c的类型为const char*

使用auto关键字可以使代码更加简洁和易读,特别是当变量的类型较为复杂或者不确定时,auto关键字可以减少类型声明的冗余。

注意:
auto关键字在编译器推导类型时是静态的,即编译时就确定了类型,无法在运行时动态改变变量的类型。

auto与指针和引用结合起来使用:

当auto与指针和引用结合使用时,auto会推导出指针或引用的类型。

int x = 10;
auto *ptr = &x; // ptr的类型为int*float y = 3.14;
auto *ptr2 = &y; // ptr2的类型为float*

使用auto声明引用类型变量示例:

int x = 10;
auto &ret = x; // ref的类型为int&float y = 3.14;
auto &ret2 = y; // ref2的类型为float&

4. 基于范围的for循环

基于范围的for循环是一种简化的循环结构,用于遍历一个序列(如字符串、列表、元组等)中的每个元素。

语法形式如下:

for 变量 in 序列: 循环体

变量表示当前迭代的元素,序列表示需要遍历的序列,循环体表示需要执行的操作。
我们常用下面的这种方式来遍历数组:

int main()
{int arr[] = { 1, 2, 3, 4, 5 };for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); ++i)arr[i] *= 2;for (int* p = arr; p < arr + sizeof(arr) / sizeof(arr[0]); ++p)cout << *p << endl;return 0;
}

今天我们来看范围for的使用。

int main()
{int arr[] = { 1, 2, 3, 4, 5 };for (auto& e : arr)e *= 2;for (auto e : arr)cout << e << " ";return 0;
}

注意:

  1. for循环迭代的范围必须是确定的
  2. 迭代的对象要实现++和==的操作。

相关文章:

【C++】C++入门基础讲解(二)

&#x1f497;个人主页&#x1f497; ⭐个人专栏——C学习⭐ &#x1f4ab;点击关注&#x1f929;一起学习C语言&#x1f4af;&#x1f4ab; 导读 接着上一篇的内容继续学习&#xff0c;今天我们需要重点学习引用。 1. 引用 在C中&#xff0c;引用是一种特殊的变量&#xff…...

Requestly工具快速提升前端开发与测试的效率

痛点 前端测试 在进行前端页面开发或者测试的时候&#xff0c;我们会遇到这一类场景&#xff1a; 在开发阶段&#xff0c;前端想通过调用真实的接口返回响应在开发或者生产阶段需要验证前端页面的一些 异常场景 或者 临界值 时在测试阶段&#xff0c;想直接通过修改接口响应来…...

Node+Express写分页接口

后端逻辑 router.js文件 const express require(express); const router express.Router();//导入函数处理,数据 const articleMessage require(../router_handle/artcle)//文章列表 router.get(/list,articleMessage.articleList)module.exports router; router_handle.js…...

ifconfig 主机ip url记录

ifconfig 容器Pods相关主机与url信息 一文搞懂网络知识&#xff0c;IP、子网掩码、网关、DNS、端口号_关于ip,网关。端口-CSDN博客 计算机网络知识之URL、IP、子网掩码、端口号_ip地址和url-CSDN博客 阅读看下以上文章 由此可知 1.主机ip 10.129.22.124 10.129.22 是网段…...

RT-Thread: STM32 SPI使用流程

1.添加驱动 ①点开设置界面 ②勾选看门 SPI 驱动 ③点击保存 ④查看添加的驱动文件 drv_spi.c 2.打开驱动头文件定义 ①打开配置文件 ②打开定义 3.打开需要开启的SPI总线 打开 drivers 目录下的 board.h 用SPI搜索&#xff0c;找到如下文字&#xff0c;打开对应的宏。 /*-…...

Qt 基于海康相机 的视频标绘

需求&#xff1a; 基于 视频 进行 标注&#xff0c;从而进行测量。 曾经搞在线教育时&#xff0c;尝试在视频上进行文字或者图形的绘制&#xff0c;但是发现利用Qt widget 传sdk 句柄的方式&#xff0c;只能使用窗口叠加的方式&#xff08;Qt 基于海康相机的视频绘图_海康相…...

【UEFI实战】Redfish的BIOS实现——生成EDK数据

生成Redfish文件 Redfish数据的表示形式&#xff0c;最常用的是JSON。将JSON表示的数据转换成C语言可以操作的结构体&#xff0c;是必不可少的步骤。当然如果手动转换的话&#xff0c;需要浪费大量的时间&#xff0c;因此DMTF组织开发了一个工具&#xff0c;用于将JSON数据快速…...

VUE--VUEX

一、什么是Vuex Vuex就是一个vue的状态&#xff08;数据&#xff09;管理工具&#xff0c;是vue项目实现大范围数据共享的技术方案。能够方便、高效的实现组件之间的数据共享。 Vuex的好处&#xff1a; &#xff08;1&#xff09;数据的存储一步到位&#xff0c;不需要层层传递…...

【NodeJS】004- NodeJS的模块化与包管理工具

模块化 1. 介绍 1.1.什么是模块化与模块 ? 将一个复杂的程序文件依据一定规则(规范)拆分成多个文件的过程称之为 模块化 其中拆分出的 每个文件就是一个模块 ,模块的内部数据是私有的,不过模块可以暴露内部数据以便其他模块使用 1.2 什么是模块化项目 ? 编码时是按照模…...

Linux浅学笔记02

目录 grep-wc-管道符 echo-tail-重定向符 vi编辑器 grep-wc-管道符 grep命令(过滤文件内容) //更准确的来说&#xff0c;是筛选包括“所需字符”的一句内容或多句内容。 语法&#xff1a;grep [-n] 关键字 文件路径 //-n&#xff1a;可选&#xff0c;表示在结果中匹配的行…...

速盾:服务器CDN加速配置的技术文章

CDN&#xff08;内容分发网络&#xff09;是一种通过分布在不同地理位置的服务器来加速网站内容传输的技术。在本文中&#xff0c;我们将介绍如何使用服务器CDN加速配置&#xff0c;以提高网站的性能和用户体验。 一、什么是CDN加速&#xff1f; CDN加速是通过将网站的静态内…...

【服务器Midjourney】创建部署Midjourney网站

目录 🌺【前言】 🌺【准备】 🌺【宝塔搭建MJ】 🌼1. 给服务器添加端口 🌼2. 使用Xshell连接服务器 🌼3. 安装docker 🌼4. 安装Midjourney程序 🌼5. 绑定域名+申请SSL证书 🌼6. 更新网站...

羊奶的营养成分和食疗价值

羊奶的营养成分和食疗价值 羊奶是一种营养非常丰富的乳制品&#xff0c;含有多种人体所需的营养成分&#xff0c;具有较高的食疗价值。下面将详细介绍羊奶的营养成分和其对人体健康的益处。 羊奶富含蛋白质&#xff0c;不仅含有人体所需的必需氨基酸&#xff0c;而且其蛋白质…...

23寒假预备役第二次测试

目录 B - Leftover Recipes C - We Got Everything Covered! D - A Balanced Problemset? E - Lame King F - Grid Ice Floor B - Leftover Recipes 问题描述 你的冰箱里有N种食材。我们将它们称为食材1、……和食材N。你有Qi​克的食材i。 你可以制作两种菜肴。制…...

测试用例相关问题

1.什么是测试用例 测试用例是指对一项特定的软件产品进行测试任务的描述&#xff0c;体现测试方案、方法、技术和策略。其内容包括测试目标、测试环境、输入数据、测试步骤、预期结果、测试脚本等&#xff0c;最终形成文档。简单地认为&#xff0c;测试用例是为某个特殊目标而…...

scrapy的入门使用

1 安装scrapy 命令: sudo apt-get install scrapy或者&#xff1a; pip/pip3 install scrapy2 scrapy项目开发流程 创建项目: scrapy startproject mySpider生成一个爬虫: scrapy genspider itcast itcast.cn提取数据:     根据网站结构在spider中实现数据采集相关内…...

网络爬虫详解

网络爬虫&#xff08;Web Crawler&#xff09;是一种自动化程序&#xff0c;用于在互联网上获取和提取数据。它们可以遍历互联网上的网页、收集数据&#xff0c;并进行处理和分析。网络爬虫也被称为网络蜘蛛、网络机器人等。 网络爬虫的工作原理主要是通过模拟浏览器的行为&…...

一个SSE(流式)接口引发的问题

前言 最近我们公司也是在做认知助手&#xff0c;大模型相关的功能&#xff0c;正在做提示词&#xff0c;机器人对话相关功能。想要提高用户体验&#xff0c;使用SSE请求模式&#xff0c;在不等数据完全拿到的情况下边拿边返回。 之前做过一版&#xff0c;但不是流式返回&…...

开发工具之GIT协同开发流程和微服务部署实践与总结

GIT协同开发流程和微服务部署的实践&#xff0c;并总结经验和教训。通过合理的GIT协同开发流程和良好的微服务部署策略&#xff0c;团队可以更高效地开发和部署软件。 ## 引言 在当今快节奏的软件开发环境中&#xff0c;采用合适的工具和流程对于实现高效协同开发和可靠部署至…...

数据库操作

数据库操作 1、 表之间连接 MYSQL 题 1、取第二高薪2、取第N高薪3、分数排名 inner join&#xff1a;2表值都存在 outer join&#xff1a;附表中值可能存在null的情况。 总结&#xff1a; ①A inner join B&#xff1a;取交集 ②A left join B&#xff1a;取A全部&#…...

MySQL-删除重复数据

在实际应用中&#xff0c;遇到一个这样的问题&#xff0c;MySQL中存储的数据为资讯类数据&#xff0c;在页面展示时会出现多个平台的新闻报导相同的内容&#xff0c;导致页面会出现重复数据。因为数据是每天定期更新&#xff0c;所以最快捷有效的方式是在更新完数据后增加一个去…...

Android Handler完全解读

一&#xff0c;概述 Handler在Android中比较基础&#xff0c;本文笔者将对此机制做一个完全解读。读者可简单参考上述类图与时序图&#xff0c;便于后续理解。 二&#xff0c;源码解读 1&#xff0c;主线程伊始 众所周知&#xff0c;通过Zygote的fork方式&#xff0c;新创建…...

群晖NAS搭建WebDav结合内网穿透实现公网访问本地影视资源

&#x1f525;博客主页&#xff1a; 小羊失眠啦. &#x1f3a5;系列专栏&#xff1a;《C语言》 《数据结构》 《C》 《Linux》 《Cpolar》 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&…...

vmstat 监控虚拟内存,进程,CPU

文章目录 1. 命令格式&#xff1a;2. 命令功能&#xff1a;3. 命令参数&#xff1a;4. 使用实例&#xff1a;实例1&#xff1a;显示虚拟内存使用情况实例2&#xff1a;显示活跃和非活跃内存实例3&#xff1a;查看系统已经fork了多少次实例4&#xff1a;查看内存使用的详细信息实…...

C++: 内联函数

目录 概念&#xff1a; 与宏的对比&#xff1a; 函数膨胀&#xff1a; 内联函数的特性&#xff1a; 概念&#xff1a; 以inline修饰的函数叫做内联函数&#xff0c;编译时C编译器会在调用内联函数的地方展开&#xff0c;没有函数调 用建立栈帧的开销&#xff0c;内联函数…...

ctfshow web72

下载源码&#xff1a; 开启环境&#xff1a; 本题设置了 open_basedir()&#xff0c;将php所能打开的文件限制在指定的目录树中&#xff0c;包括文件本身。 因为 ini_set() 也被限制了&#xff0c;所以 open_basedir() 不能用 ini_set() 重新设置绕过。 使用 php 伪协议 glob:…...

你想要一个什么样的gpt?高准确度和可靠性 问题解答 自主完成任务(智能体) 解决贫困 战争 难题 公平的价值体系

人们对GPT&#xff08;为特定用途定制的ChatGPT版本&#xff09;的期望因用途和需求而异。不过&#xff0c;普遍期望的特征可能包括&#xff1a; 高准确度和可靠性&#xff1a;提供准确、可靠的信息和回答是最基本的要求。用户友好的交互体验&#xff1a;易于使用&#xff0c;…...

VUE中一些概念的理解

Vue 中 computed、mounted 和 methods 的基本理解。 computed 计算属性 (computed)&#xff1a;主要用于根据现有的响应式数据&#xff08;即 data 中的数据或其他 computed 属性&#xff09;进行计算并返回一个新的值。计算属性是基于它们的响应式依赖进行缓存的。只有当依赖…...

【ArcGIS遇上Python】python实现批量XY坐标生成shp点数据文件

单个手动生成:【ArcGIS风暴】ArcGIS 10.2导入Excel数据X、Y坐标(经纬度、平面坐标),生成Shapefile点数据图层 文章目录 一、问题分析二、解决办法三、注意事项一、问题分析 现有多个excel、txt或者csv格式的坐标数据,需要根据其坐标批量一键生成shp点数据,如下X为经度,…...

【C语言】(7)输入输出

输出 printf printf 是 C 语言中最常用的输出函数。它可以将格式化的字符串输出到控制台。 基本语法&#xff1a; int printf(const char *format, ...);format 是格式化字符串&#xff0c;用于指定输出的格式。... 表示可变数量的参数&#xff0c;根据格式化字符串输出相应…...