C++入门(以c为基础)——学习笔记2
1.引用
引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空
间。在语法层面,我们认为它和它引用的变量共用同一块内存空间。
可以取多个别名,也可以给别名取别名。
b/c/d本质都是别名,对d进行一个++
对于符号&,用其定义时就是引用,其他时候就是取地址
从此,改变一个变量不需要传地址,而可以在形参处定义别名,达到类似指针的效果。
“经典的错误,标准的零分”
为什么a的值还是没有改变?
尽管传入的是别名 ,但是函数接受的参数依然是个数值,是实参的拷贝。应当在形参处建立引用,这样才能真正修改我们希望修改的变量。
这样就成功改变a的值了。
结论:形参是引用,则通过形参就能改变实参,不需要传更高级的指针。
引用中需要注意的细节:
1.1引用在定义时必须先初始化
引用在定义时必须已经初始化(不能先取绰号,再找谁合适这个绰号)
一个引用可以有多个变量,就如上文的a b c d
引用一旦引用一个实体,就不能再改变
可见,不是让y变成z的别名,而是通过y,将z的值赋值给y和x
1.2引用中的权限问题
存在的问题:权限的放大
m是只读的,当n变成m的别名后,n作为int类型的变量是可读可写的。为了避免通过n修改了m这个const类型的变量(权限放大),所以不能通过编译。
这样,是权限的平移,就能通过编译了。
对一个对象(C语言中喜欢称为变量),权限可以缩小和平移,但是不能放大。
此处我可以通过y修改x,修改后z的数值也会改变(相当于z只是没有“write”的权限,z只能访问x, 并不代表这个值真真正正地锁死了)
回忆:const int* int const* int* const
const默认与其左边结合,当左边没有任何东西则与右边结合。
换句话说,const只要在*的左边,限制的就是*p1;const在*右边,限制的就是这个指针,该指针只能指向这个空间,不能改变指向。
上文中的前两种所限制的是一样的,最后一种限制的是指针,不能进行加减法。
报错的原因是:p2是可读可写的,我们可以通过p2去改变p1所指向的空间。但是p1指向的空间是被锁死了的,是不能改变的,又扩大了权限,因此报错。
数值之间没有权限的概念,只有指针和引用之间有权限的概念。
类型转化中的权限问题:
不管是强制类型转化还是隐式类型转化,其底层都是通过建立一个临时变量来进行转化。
我们先用double定义一个变量为12.34:
其转化的本质是把d的整数部分取出,赋给整形类型的临时变量,再通过临时变量赋给i。
既然是这样的赋值方法,就不难理解下图为什么会报错了:
在82行代码执行时,d先将其整数部分赋值给临时变量,但是临时变量具有常性(像一个常数一样,不可被改变),而按照int& j的方法接受该临时变量后,j作为别名,可以通过j修改该临时变量,这是不被允许的。
但如果我给这个变量定义为“只读”类型,也就是const int& k=d;
权限没有被放大,就合规了。
所有的表达式运算也会产生临时变量
int x=1;
int y=2;
x+y;
没有用变量接受x+y,但是x+y还是会进行计算,计算出的结果会放进临时变量。
同理,有变量接受x+y时也一样,x+y的值放入临时变量,所以r2前面必须加const(只读)才能保证不越界。
1.3传参和传引用效率比较
直接传值会拷贝整个变量(形参是实参的copy),传参效率弱于引用传参。
再利用一个测试函数:
(将传值执行10000次,再将传引用执行10000次,0表示其所消耗的时间是小于1ms的)
1.4从底层看引用
我们在语法层面认为:别名不开空间,存地址的变量(指针)是需要开辟空间的。
但是在汇编层面:
通过底层可知,定义指针p和引用b的汇编代码是一样的。
不过在日常的语法层面,我们依然认为引用不开空间,指针变量要开空间。
1.5指针和引用的区别
1. 引用概念上定义一个变量的别名,指针存储一个变量地址。2. 引用 在定义时 必须初始化 ,指针没有要求3. 引用 在初始化时引用一个实体后,就 不能再引用其他实体 ,而指针可以在任何时候指向任 何一个同类型实体4. 没有 NULL 引用 ,但有 NULL 指针5. 在 sizeof 中含义不同 : 引用 结果为 引用类型的大小 ,但 指针 始终是 地址空间所占字节个数 (32 位平台下占4 个字节 )6. 引用自加即引用的实体增加 1 ,指针自加即指针向后偏移一个类型的大小7. 有多级指针,但是没有多级引用8. 访问实体方式不同, 指针需要显式解引用,引用编译器自己处理9. 引用比指针使用起来相对更安全
不过对于第四点,可以单独说明一下:
不是说没有NULL引用吗?
结合底层思考为什么没有报错
通过观察汇编,我们可以发现,并没有发生解引用这一步骤。
因为其本质是和指针一样的汇编代码,所以并没有发生报错。
cpp的引用为什么不能替代指针?
如:链表:
引用不能改变指向,如果用引用的方法存下下一个节点,当你想改变链接方式时,如何处理?
所以next必须使用指针。这单纯的是语法设计的原因,因为本贾尼是按照c为基础设计的,并没有想过要完全替代C语言。在Java中,引用就是可改变的,因此java没有指针。
2.内联函数
对于一些小型的、会大量重复调用的函数,如(Swap,Add等)。不停的建立函数栈帧性价比太低,C语言使用含参数的宏来解决这个问题。
宏没有栈帧消耗,但是容易出语法问题:复杂、没有类型检查、无法调试
cpp虽然兼容c的所有用法,但是cpp更倾向于使用内联函数(inline修饰):
以 inline 修饰 的函数叫做内联函数, 编译时 C++ 编译器会在 调用内联函数的地方展开 ,没有函数调 用建立栈帧的开销,内联函数提升程序运行的效率。本质是一种空间换时间的做法。
用inline修饰函数
注意:在debug模式下,为了调试方便,依然会执行call语句,像以前的函数一样建立栈帧。
没有执行call语句,也就是没有按照函数去调用,而是直接展开。
内联函数的特点:
编译器并没有把是否展开的权利完全释放给你,而是会自己选择是否展开。
当函数中的语句过多时,就不会展开
inline对于编译器只是一种建议,编译器会自己决定是否展开(如递归等就一定不会展开)
为什么有的函数语句过多时不会展开?
大函数展开的缺点:
若我们要对一个100行的代码调用10000次:
导致编译出的可执行程序变大。可执行程序大了是一件很麻烦的事情。
最后,内联函数不能声明和定义相分离
因为内联函数是直接展开的,没有函数的地址,在链接过程中是找不到的。
其本质就是一个小型功能直接展开。
3.auto
随着程序越来越复杂,程序中用到的类型也越来越复杂,经常体现在:1. 类型难于拼写2. 含义不明确导致容易出错
根据赋值的内容,自动识别i的类型。
当然,typedef有类似的功能,但是typedef有时候会有些问题:
pstring p1 与 char* const p1是一个意思,p1 作为一个被const的变量,也具有常性,必须初始化,所以此处报错。
tips:typeid可以用来查看变量的类型名:
typeid(a).name();
auto修饰的限定
auto可以根据后面的内容进行赋值内容的条件限制。
规定:auto不能直接用来声明数组
4.基于范围的for循环
基于auto的用法,cpp抄了python的作业,使用自动循环:
for循环迭代的范围必须是确定的
for (auto e: array){e/=2;
}
auto可以改成具体的类型(int、double)等都可以,只要匹配就行
但是遍历方式是写死了的,只能从数组首到数组尾遍历。
但是传参进入的数组不能使用范围for
数组的传参本质是传入数组首元素地址,会退化。(c/cpp追求效率,在语言层进行了优化,传的是首元素地址)
而针对一个数组首元素地址,该数组循环迭代的范围是不确定的,所以不能执行。
5.nullptr和NULL
cpp的设计缺陷:
将NULL作为一个宏,代表0,而不是之前的空指针。因此,cpp中的NULL会被当作整形的int而不是空指针
所以,引入了关键字nullptr
主函数中:第一个f调用第一个函数,第二个f也调用第一个函数,第三个f调用第二个函数,第四个函数调用第二个函数。
nullptr作为关键字,是不需要包含任何头文件的
6.小结
本篇中多为零碎的c过渡到cpp的语法知识,先进行铺垫和了解,在之后会有具体而详细的使用。
相关文章:

C++入门(以c为基础)——学习笔记2
1.引用 引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空 间。在语法层面,我们认为它和它引用的变量共用同一块内存空间。 可以取多个别名,也可以给别名取别名。 b/c/d本质都是别名&#…...
设计模式-单例模式(懒汉式)
1. 概念 保证一个类只有一个实例并为该实例提供一个全局唯一的访问节点 2. 懒汉式-方式一 2.1 代码示例(方式一) 示例 public class Singleton03 {/*** 构造器私有化*/private Singleton03() {}/*** 成员变量*/private static Singleton03 INSTANCE;…...
算法| ss 回溯
39.组合总数46.全排列—478.子集79.单词搜索—1连续差相同的数字—1 39.组合总数 /*** param {number[]} candidates* param {number} target* return {number[][]}*/ // 思路 // dfs传参,传idx, 剩余target // dfs返回: 0 收集,…...

基于R语言绘制-散点小提琴图
原文链接:R语言绘图 | 散点小提琴图 本期教程 写在前面 本期的图形来自发表在Nature期刊中的文章,这样的基础图形在日常分析中使用频率较高。 获得本期教程数据及代码,后台回复关键词:20240405 绘图 设置路径 setwd("You…...

Arduino开发 esp32cam+opencv人脸识别距离+语音提醒
效果图 低于20厘米语音提醒字体变红 Arduino代码 可直接复制使用(修改自己的WIFI) #include <esp32cam.h> #include <WebServer.h> #include <WiFi.h> // 设置要连接的WiFi名称和密码 const char* WIFI_SSID "gumou"; const char* …...

LeNet卷积神经网络
文章目录 简介conv2d网络层的结构 简介 它是最早发布的卷积神经网络之一 conv2d 这个卷积成的参数先进行介绍一下: self.conv1 nn.Conv2d(in_channels3, out_channels10, kernel_size3, stride1, padding1)先看一下in_channels 输入的通道数,out_cha…...

Python常用算法思想--回溯算法思想详解【附源码】
通过回溯算法解决“组合”问题、“排序”问题、“搜索”之八皇后问题、“子集和”之0-1背包问题、字符串匹配等六个经典案例进行介绍: 一、解决“组合”问题 从给定的一组元素中找到所有可能的组合,这段代码中的 backtrack_combinations 函数使用了回溯思想,调用 backtrack…...

Day5-Hive的结构和优化、数据文件存储格式
Hive 窗口函数 案例 需求:连续三天登陆的用户数据 步骤: -- 建表 create table logins (username string,log_date string ) row format delimited fields terminated by ; -- 加载数据 load data local inpath /opt/hive_data/login into table log…...
01 计算机网络发展与分类
计算机网络:计算机技术与通信技术的结合。 阶段一:早期网络:ARPAnet。 阶段二:厂商独立发展阶段 阶段三:标准化阶段:ISO,TCP/IP 计算机网络分类 计算机网络分类1:通信子网和资源子网 通信子…...

ubuntu安装sublime3并设置中文
安装Sublime Text 3 在Ubuntu上安装Sublime Text 3可以通过以下步骤进行: 打开终端。 导入Sublime Text 3的GPG密钥: wget -qO- https://download.sublimetext.com/sublimehq-pub.gpg | sudo apt-key add - 添加Sublime Text 3的存储库: …...

python调用阿里云短信配置
1. 新增资质和签名 # 访问地址: https://dysms.console.aliyun.com/domestic/text/qualification2. 静静等待几十分钟~~~ 3. 通过sdk去调用,查看有没有python的sdk https://next.api.aliyun.com/api/Dysmsapi/2017-05-25/SendSms?完整代码 # -*- cod…...

MySQL 8.0.13安装配置教程
写个博客记录一下,省得下次换设备换系统还要到处翻教程,直接匹配自己常用的8.0.13版本 1.MySQL包解压到某个路径 2.将bin的路径加到系统环境变量Path下 3.在安装根目录下新建my.ini配置文件,并用编辑器写入如下数据 [mysqld] [client] port…...

【idea快捷键】idea开发java过程中常用的快捷键
含义win快捷键mac快捷键复制当前行或选定的代码块Ctrl DCommand D通过类名快速查找类Ctrl NCommand N通过文件名快速查找文件Ctrl Shift NCommand Shift N通过符号名称快速查找符号(类、方法等)Ctrl Alt Shift NCommand Shift O跳转到声明C…...

2024年腾讯云GPU云服务器配置价格表(内存/系统盘/地域)
腾讯云GPU服务器是提供GPU算力的弹性计算服务,腾讯云GPU服务器具有超强的并行计算能力,可用于深度学习训练、科学计算、图形图像处理、视频编解码等场景,腾讯云百科txybk.com整理腾讯云GPU服务器租用价格表、GPU实例优势、GPU解决方案、GPU软…...

重构数据访问层-优化数据访问的开发
重新整理了一下过去开发的框架,在准备开发新项目时候,重新整理了一下思路,感觉数据访问层还是很鸡肋。过去几年中,急于完成项目开发和交付,框架都是迭代过来的,虽然满足了开发需求,但是…...
云计算概述报告
以下是一篇论述类文章 文章目录 I. 云计算介绍(1)云计算基本概念(2)云计算基本特征 II. 云计算发展历程(1)云计算的起源(2)云计算的发展阶段 III. 云计算特点(1ÿ…...

C++:线程库的使用
文章目录 Windows和Linux平台的线程线程构造函数模板参数包 最近发现C11的线程库还没有进行总结,因此本篇对于C11当中新增的线程库的一些基本用法进行总结 Windows和Linux平台的线程 在Linux平台下是存在一些原生的线程系统调用的,比如有pthread_creat…...

机器学习模型:决策树笔记
第一章:决策树原理 1-决策树算法概述_哔哩哔哩_bilibili 根节点的选择应该用哪个特征?接下来选什么?如何切分? 决策树判断顺序比较重要。可以使用信息增益、信息增益率、 在划分数据集前后信息发生的变化称为信息增益,…...

20.2k stars项目搭建私人网盘界面美功能全
Nextcloud是一套用于创建网络硬盘的客户端-服务器软件。其功能与Dropbox相近,但Nextcloud是自由及开放源代码软件,每个人都可以在私人服务器上安装并执行它。 GitHub数据 20.2k stars561 watching3.2k forks 开源地址:https://github.com/ne…...

卷积篇 | YOLOv8改进之引入全维度动态卷积ODConv | 即插即用
前言:Hello大家好,我是小哥谈。ODConv是一种关注了空域、输入通道、输出通道等维度上的动态性的卷积方法,一定程度上讲,ODConv可以视作CondConv的延续,将CondConv中一个维度上的动态特性进行了扩展,同时了考虑了空域、输入通道、输出通道等维度上的动态性,故称之为全维度…...
【Linux】shell脚本忽略错误继续执行
在 shell 脚本中,可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行,可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令,并忽略错误 rm somefile…...
【Java学习笔记】Arrays类
Arrays 类 1. 导入包:import java.util.Arrays 2. 常用方法一览表 方法描述Arrays.toString()返回数组的字符串形式Arrays.sort()排序(自然排序和定制排序)Arrays.binarySearch()通过二分搜索法进行查找(前提:数组是…...
在rocky linux 9.5上在线安装 docker
前面是指南,后面是日志 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install docker-ce docker-ce-cli containerd.io -y docker version sudo systemctl start docker sudo systemctl status docker …...
连锁超市冷库节能解决方案:如何实现超市降本增效
在连锁超市冷库运营中,高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术,实现年省电费15%-60%,且不改动原有装备、安装快捷、…...

《通信之道——从微积分到 5G》读书总结
第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...

从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)
设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile,新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...

ServerTrust 并非唯一
NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...
JDK 17 新特性
#JDK 17 新特性 /**************** 文本块 *****************/ python/scala中早就支持,不稀奇 String json “”" { “name”: “Java”, “version”: 17 } “”"; /**************** Switch 语句 -> 表达式 *****************/ 挺好的ÿ…...

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)
UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中,UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化…...
Python 包管理器 uv 介绍
Python 包管理器 uv 全面介绍 uv 是由 Astral(热门工具 Ruff 的开发者)推出的下一代高性能 Python 包管理器和构建工具,用 Rust 编写。它旨在解决传统工具(如 pip、virtualenv、pip-tools)的性能瓶颈,同时…...