4 C++ 复合类型:引用和指针
复合类型是指基于其它类型定义的类型。C++ 有几种复合类型,包括引用、指针。
1 引用
引用(reference)为对象起了另外一个名字,引用类型引用另外一种类型。通过将声明符写成&d的形式来定义引用类型,其中d是声明的变量名:
int ival = 1024;
int &refval = ival; // refval 指向 ival(是 ival 的另一个名字)
int &refval2; // 错误:引用必须被初始化
一般在初始化变量时,初始值会被拷贝到新建的对象中。然而定义引用时,程序把引用和它的初始值绑定在一起,而不是将初始值拷贝给引用。一旦初始化完成,引用将和它的初始值对象一直绑定在一起。因为无法令引用重新绑定到另外一个对象,因此引用必须初始化。
定义了一个引用之后,对其进行的所有操作都是在与之绑定的对象上进行的。为引用赋值,实际上是把值赋给了与引用绑定的对象。获取引用的值,实际上是获取了与引用绑定的对象的值。同理,以引用作为初始值,实际上是以与引用绑定的对象作为初始值。
因为引用本身不是一个对象,所以不能定义引用的引用。
允许在一条语句中定义多个引用,其中每个引用标识符都必须以符号&开头。除了两种例外情况,其它所有引用的类型都要和与之绑定的对象严格匹配。而且,引用只能绑定在对象上,而不能与字面值或某个表达式的计算结果绑定在一起。
int &refVal1 = 10; // 错误:引用类型的初始值必须是一个对象
double dval = 3.14;
int &refVal2 = dval; // 错误:此处引用类型的初始值必须是 int 型对象
2 指针
指针是 “指向” 另外一种类型的复合类型。与引用类似,指针也实现了对其它对象的间接访问。然而指针和引用相比又有很多不同点。其一,指针本身就是一个对象,允许对指针赋值和拷贝,而且在指针的生命周期内,它可以先后指向几个不同的对象。其二,指针无须在定义时赋初值。和其它内置类型一样,在块作用域内定义的指针如果没有被初始化,也将拥有一个不确定的值。
定义指针类型的方法是将声明符写成*d的形式,其中d是变量名。如果在一条语句中定义了几个指针变量,每个变量前面都必须有符号*:
int *ip1, *ip2; // ip1 和 ip2 都是指向 int 型对象的指针
double dp, *dp2; // dp2 是指向 double 型对象的指针,dp 是 double 型对象
2.1 获取对象的地址
指针存放某个对象的地址,要想获取该地址,需要使用取地址符&:
int ival = 42;
int *p = &ival; // p 存放变量 ival 的地址,或者说 p 是指向变量 ival 的指针
第二条语句把p定义为一个指向int型对象的指针,随后初始化p令其指向名为ival的int对象。因为引用不是对象,没有实际地址,所以不能定义指向引用的指针。
除了两种例外情况,其它所有指针的类型都要和它所指向的对象严格匹配。
2.2 指针值
指针的值(即地址)应属于下列 4 种状态之一:
- 指向一个对象。
- 指向紧邻对象所占空间的下一个位置。
- 空指针,意味着指针没有指向任何对象。
- 无效指针,也就是上述情况之外的其它值。
试图拷贝或以其它方式访问无效指针的值都将引发错误。编译器并不负责检查此类错误,这一点和试图使用未经初始化的变量是一样的。
2.3 利用指针访问对象
如果指针指向了一个对象,则允许使用解引用符*来访问对象:
int ival = 42;
int *p = &ival; // p 存放着变量 ival 的地址,或者说 p 是指向变量 ival 的指针
std::cout << *p; // 由符号 * 得到指针 p 所指的对象,输出 42
对指针解引用会得出所指的对象,因此如果给解引用的结果赋值,实际上也就是给指针所指的对象赋值。解引用操作仅适用于那些确实指向了某个对象的有效指针。
2.4 空指针
空指针不指向任何对象,在试图使用一个指针之前可以先检查它是否为空。以下列出了几个生成空指针的方法:
int *p1 = nullptr; // 等价于 int *p1 = 0;
int *p2 = 0; // 直接将 p2 初始化为字面值常量 0
int *p3 = NULL; // 等价于 int *p3 = 0; 需要 #include <cstdlib>
nullptr是一种特殊类型的字面值,它可以被转换成任意其它的指针类型。NULL是一个预处理变量,它的值就是 0。当用到一个预处理变量时,预处理器会自动地将它替换为实际值,因此用NULL初始化指针和用 0 初始化指针是一样的。
把int变量直接赋给指针是错误的操作,即使int变量的值恰好等于 0 也不行。
2.5 赋值和指针
指针和引用都能提供对其它对象的间接访问,然而在具体实现细节上二者有很大不同,其中最重要的一点就是引用本身并非一个对象。一旦定义了引用,就无法令其再绑定到另外的对象,之后每次使用这个引用都是访问它最初绑定的那个对象。
指针和它存放的地址之间就没有这种限制了。和其它变量(只要不是引用)一样,给指针赋值就是令它存放一个新的地址,从而指向一个新的对象。
2.6 其它指针操作
只要指针拥有一个合法值,就能将它用在条件表达式中。和采用算术值作为条件遵循的规则类似,如果指针的值是 0,条件取false,任何非 0 指针对应的条件值都是true。
对于两个类型相同的合法指针,可以用相等操作符==或不相等操作符!=来比较它们,比较的结果是布尔类型。如果两个指针存放的地址值相同,则它们相等;反之它们不相等。这里两个指针存放的地址值相同有三种可能:它们都为空、都指向同一个对象、都指向了同一个对象的下一个地址。需要注意的是,一个指针指向某对象,同时另一个指针指向另外对象的下一地址,此时也有可能出现这两个指针值相同的情况,即指针相等。
2.7 void*指针
void*是一种特殊的指针类型,可用于存放任意对象的地址。一个void*指针存放着一个地址,这一点和其它指针类似。不同的是,我们对该地址中到底是个什么类型的对象并不了解。
利用void*指针能做的事比较有限:拿它和别的指针比较、作为函数的输入或输出,或者赋给另外一个void*指针。不能直接操作void*指针所指的对象,因为我们并不知道这个对象到底是什么类型,也就无法确定能在这个对象上做哪些操作。
概括来说,以void*的视角来看内存空间也就仅仅是内存空间,没办法访问内存空间中所存的对象。
3 理解复合类型的声明
3.1 指向指针的指针
一般来说,声明符中修饰的个数并没有限制。当有多个修饰符连写在一起时,按照其逻辑关系详加解释即可。以指针为例,指针是内存中的对象,也有自己的地址,因此允许把指针的地址再存放到另一个指针当中。
通过*的个数可以区分指针的级别。也就是说,**表示指向指针的指针,***表示指向指针的指针的指针,以此类推。对应的,解引用时也有相应的级别。
3.2 指向指针的引用
引用本身不是一个对象,因此不能定义指向引用的指针。但指针是对象,所以存在对指针的引用。
相关文章:
4 C++ 复合类型:引用和指针
复合类型是指基于其它类型定义的类型。C 有几种复合类型,包括引用、指针。 1 引用 引用(reference)为对象起了另外一个名字,引用类型引用另外一种类型。通过将声明符写成&d的形式来定义引用类型,其中d是声明的变量…...
ABAP关于PS模块CJ20N中项目物料的屏幕和字段增强CI_RSADD
网上搜关于CJ20N的屏幕增强,基本都是关于项目定义(CI_PROJ)、项目WBS(CI_PRPS)、项目网络活动工序(CI_AFVU)的字段与屏幕增强,几乎没有关于项目物料(CI_RSADD)的字段屏幕增强,我在这里做一个分享。 主要逻辑:实现badi增强,并自建一个函数组后创建屏幕,在badi里面调用…...
探索IDE的无限可能:使用技巧与插件推荐
在软件开发的世界里,集成开发环境(IDE)是开发者的得力助手,它不仅提供了代码编辑、编译、调试等功能,还通过各种插件扩展了其功能,使得开发工作更加高效和便捷。本文将带你探索IDE的使用技巧和一些实用的插…...
自动化生成测试用例:利用OpenAI提升电商网站测试覆盖率
导语 自动化生成测试用例是软件测试领域一个强大的应用,通过OpenAI的语言模型,测试工程师可以快速生成高质量的测试用例,尤其是在处理边界条件和极端情况时,提升测试覆盖率。本篇文章将结合一个典型的电商网站案例,介绍…...
时间序列关于可解释性值得关注的论文汇总-第2篇
前言 这是时序可解释性论文汇总的第二篇,第一篇见这里(后台回复:“论文合集”可直接获取整理的文章)。深度学习的可解释性研究一直是热门,而时间序列的可解释性同样非常重要。这是因为时序模型被大量应用到特定领域&a…...
Vulnhub:DC-4靶机渗透——土豆片的靶机渗透练习
攻击机:kali 靶机:DC-4 一,信息收集 1.主机发现 找寻同网段下存活的主机 arp-scan -l2.端口扫描 查看此主机上有哪些开放端口 nmap -sV -p- 192.168.126.136发现22,80端口,远程连接跟网站(大概&…...
【云原生系列--Longhorn的部署】
Longhorn部署手册 1.部署longhorn longhorn架构图: 1.1部署环境要求 kubernetes版本要大于v1.21 每个节点都必须装open-iscsi ,Longhorn依赖于 iscsiadm主机为 Kubernetes 提供持久卷。 apt-get install -y open-iscsiRWX 支持要求每个节点都安装 N…...
Java集合(Collection+Map)
Java集合(CollectionMap) 为什么要使用集合?泛型 <>集合框架单列集合CollectionCollection遍历方式List:有序、可重复、有索引ArrayListLinkedListVector(已经淘汰,不会再用) Set…...
微信小程序02-页面制作
微信小程序页面制作指南 目录 微信小程序页面制作 1. 个人信息展示小程序 案例分析 需求背景:许多大学生毕业后需要求职,因此制作一个展示个人信息的微信小程序对招聘人员快速了解求职者非常有帮助。页面布局:页面分为头像区域和详细信息…...
zabbix监控端界面时间与服务器时间不对应
1. 修改系统时间 # tzselect Please select a continent, ocean, "coord", or "TZ".1) Africa2) Americas3) Antarctica4) Asia5) Atlantic Ocean6) Australia7) Europe8) Indian Ocean9) Pacific Ocean 10) coord - I want to use geographical coordina…...
端对端加密是如何通过SDK防御实现的?
端对端加密(End-to-End Encryption,E2EE)是一种确保数据在传输过程中不被第三方截获和篡改的技术。随着网络安全威胁的日益增多,端对端加密在即时通讯、文件传输等领域变得越来越重要。本文将详细介绍如何通过SDK(Soft…...
Flutter:input输入框
输入框: // 是否显示关闭按钮 bool _showClear false; // 文字编辑控制器,监听搜索框的变化。 final TextEditingController _controller TextEditingController(); // 输入框发生变化事件 void _onChange(String value){if(value.length > 0){setS…...
RabbitMQ 与 PHP Swoole 实现
RabbitMQ 与 PHP Swoole 的结合实现 一、概述 RabbitMQ 是一个开源的消息队列中间件,允许通过异步消息传递来解耦应用程序的各个部分。Swoole 是一个高性能的 PHP 扩展,支持异步编程和协程,适用于构建高并发的网络服务。将 RabbitMQ 与 Swo…...
【计算机体系架构】 MESI缓冲一致性
高并发学习参考 https://blog.csdn.net/MrYushiwen/article/details/123049838 https://cloud.tencent.com/developer/article/2197857 ESI 是指Cache 行的三种一致性状态:E(Exclusive,独占),S(Shared&…...
STM32设计学生宿舍监测控制系统
目录 前言 一、本设计主要实现哪些很“开门”功能? 二、电路设计原理图 电路图采用Altium Designer进行设计: 三、实物设计图 四、程序源代码设计 五、获取资料内容 前言 随着科技的飞速发展和智能化时代的到来,学生宿舍的安全、舒适…...
企业生产环境-麒麟V10(ARM架构)操作系统部署kafka高可用集群
前言:Apache Kafka是一个分布式流处理平台,由LinkedIn开发并捐赠给Apache软件基金会。它主要用于构建实时数据流管道和流应用。Kafka具有高吞吐量、可扩展性和容错性的特点,适用于处理大量数据。 以下是Kafka的一些核心概念和特性࿱…...
awk(常用)
这个有点难 O.o 一、awk # 语法 awk 参数 模式 {动作} 文件# 第一列,包含p的 $1~"p" # 第一列,不包含p的 $1!~"p" # 开始时干嘛,结束时干嘛 awk BEGIN{开始时做的事}END{结束时做的事}{print $0} 文件 1、内置变量&…...
Amazon Web Services (AWS)
一、Amazon Web Services (AWS)介绍 1、简介 2、产品 AWS 提供了各种云计算服务,包括 DynamoDB、S3、EC2、Lambda 等等。 登录aws后点击所有服务也可以看到amazon的所有服务: 3、免费试用产品 除了免费的Amazon Step Functions、Amazon Lambda&#…...
Java EE 技术基础知识体系梳理
1. Java EE 平台概述 1.1 发展历程 Java EE 从 J2EE 发展而来,经历了多个版本的演进,从早期的 J2EE 1.2 到最新的 Jakarta EE。 1.2 架构特点 多层架构: 客户端层:用户界面,如 Web 浏览器、移动应用等。Web 层&…...
【2025最新计算机毕业设计】基于SpringBoot+Vue电脑在线装机指南教程网站【源码+文档】
作者简介:✌CSDN新星计划导师、Java领域优质创作者、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流。✌ 主要内容:🌟Java项目、Python项目、前端项目、PHP、ASP.NET、人工智能…...
测试微信模版消息推送
进入“开发接口管理”--“公众平台测试账号”,无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息: 关注测试号:扫二维码关注测试号。 发送模版消息: import requests da…...
业务系统对接大模型的基础方案:架构设计与关键步骤
业务系统对接大模型:架构设计与关键步骤 在当今数字化转型的浪潮中,大语言模型(LLM)已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中,不仅可以优化用户体验,还能为业务决策提供…...
CTF show Web 红包题第六弹
提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框,很难让人不联想到SQL注入,但提示都说了不是SQL注入,所以就不往这方面想了 先查看一下网页源码,发现一段JavaScript代码,有一个关键类ctfs…...
R语言AI模型部署方案:精准离线运行详解
R语言AI模型部署方案:精准离线运行详解 一、项目概述 本文将构建一个完整的R语言AI部署解决方案,实现鸢尾花分类模型的训练、保存、离线部署和预测功能。核心特点: 100%离线运行能力自包含环境依赖生产级错误处理跨平台兼容性模型版本管理# 文件结构说明 Iris_AI_Deployme…...
【JVM】- 内存结构
引言 JVM:Java Virtual Machine 定义:Java虚拟机,Java二进制字节码的运行环境好处: 一次编写,到处运行自动内存管理,垃圾回收的功能数组下标越界检查(会抛异常,不会覆盖到其他代码…...
关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案
问题描述:iview使用table 中type: "index",分页之后 ,索引还是从1开始,试过绑定后台返回数据的id, 这种方法可行,就是后台返回数据的每个页面id都不完全是按照从1开始的升序,因此百度了下,找到了…...
关于 WASM:1. WASM 基础原理
一、WASM 简介 1.1 WebAssembly 是什么? WebAssembly(WASM) 是一种能在现代浏览器中高效运行的二进制指令格式,它不是传统的编程语言,而是一种 低级字节码格式,可由高级语言(如 C、C、Rust&am…...
深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南
🚀 C extern 关键字深度解析:跨文件编程的终极指南 📅 更新时间:2025年6月5日 🏷️ 标签:C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言🔥一、extern 是什么?&…...
使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台
🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...
力扣-35.搜索插入位置
题目描述 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...
