肯尼斯·里科《C和指针》第6章 指针(3)

news2024/10/5 2:50:19

肯尼斯·里科《C和指针》第6章 指针(1)-CSDN博客

肯尼斯·里科《C和指针》第6章 指针(2)-CSDN博客

前置知识:左值右值

为了理解有些操作符存在的限制,必须理解左值(L-value)和右值(R-value)之间的区别。这两个术语是多年前由编译器设计者所创造并沿用至今的,尽管它们的定义并不与C语言严格吻合。

反正我上课是没专门学过这部分内容的,在还没看这本书之前我的掌握程度是——把等号右边的值赋给左边。但是我发现仅依靠这点认识是没办法理解下面的“指针表达式”的,所以得回头去学。

嘛,不好评价。

左值就是那些可以出现在赋值符号左边的东西。右值就是那些可以出现在赋值符号右边的东西。这里有个例子:

a = b + 25;

a是个左值,因为它标识了一个可以存储结果值的地点;b+25是个右值,因为它指定了一个值。

它们可以互换吗?

b + 25 = a;

原先用作左值的a此时也可以当作右值,因为每个位置都包含一个值。然而,b+25不能作为左值,因为它并未标识一个特定的位置。因此,这条赋值语句是非法的。

注意,当计算机计算b+25时,它的结果必然保存于机器的某个地方。但是,程序员并没有办法预测该结果会存储在什么地方,也无法保证这个表达式的值下次还会存储于同一个地方。其结果是,这个表达式不是一个左值。基于同样的理由,字面值常量也都不是左值。

左值是个表达式,它可以出现在赋值符的左边,表示计算机内存中的一个位置。右值表示一个值,所以它只能出现在赋值符的右边。每个左值表达式同时也是个右值,但反过来就不是这样。

表示计算机内存中的一个位置,唉,我之前就没有这么理解过,(;′⌒`)。

6.11 指针表达式

唉,要是我当时学的时候看到这个就好了,唉。

现在让我们观察各种不同的指针表达式,并看看当它们分别作为左值和右值时是如何进行求值的。有些表达式用得很普遍,但有些却不常用。这个练习的目的并不是想给你一本这类表达式的“烹调全书”,而是想让你完善阅读和编写它们的技巧。

char ch = 'a';
char *cp = &ch;

现在,我们就有了两个变量,初始化如下:

图中还显示了ch后面的那个内存位置,因为我们所求值的有些表达式将访问它(尽管是在错误情况下才会对它进行访问)。由于我们并不知道它的初始值,因此用一个问号来代替。

首先来个简单的作为开始,如下面这个表达式:

ch

当它作为右值使用时,表达式的值为'a',如下图所示:

粗椭圆提示变量ch的值就是表达式的值。但是,当这个表达式作为左值使用时,它是这个内存的地址,而不是该地址所包含的值,所以它的图示方式有所不同:

要是我当时知道“左”“右”值就好了(捂脸)。

此时该位置用粗方框标记,提示这个位置就是表达式的结果。另外,它的值并未显示,因为它并不重要。事实上,这个值将被某个新值所取代。接下来的表达式将以表格的形式出现。每个表后面的文字是表达式求值过程的描述。

作为右值,这个表达式的值是变量ch的地址。注意,这个值同变量cp中所存储的值一样,但这个表达式并未提及cp,所以这个结果值并不是因为它而产生的。这样,其中的椭圆并不画于cp的箭头周围。第2个问题是,为什么这个表达式不是一个合法的左值?答案很简单,当表达式&ch进行求值时,它的结果应该存储于计算机的什么地方呢?它肯定会位于某个地方,但你无法知道它位于何处。这个表达式并未标识任何机器内存的特定位置,所以它不是一个合法的左值。

你以前曾见到过上面这个表达式。它的右值就是cp的值。它的左值就是cp所处的内存位置。由于这个表达式并不进行间接访问操作,因此不必依箭头所示进行间接访问。

上面这个例子与&ch类似,不过我们这次所取的是指针变量的地址。这个结果的类型是指向字符的指针的指针。同样,这个值的存储位置并未清晰定义,所以这个表达式不是一个合法的左值。

现在我们加入了间接访问操作,所以它的结果应该不会令人惊奇。但接下来的几个表达式就比较有意思。

上面这个表涉及的东西更多,所以让我们一步一步来分析它。这里有两个操作符。*的优先级高于+,所以首先执行间接访问操作(如图中cp到ch的实线箭头所示),我们可以得到它的值(如虚线椭圆所示)。我们取得这个值的一份副本并把它与1相加,表达式的最终结果为字符’b’。图中虚线表示表达式求值时数据的移动过程。这个表达式的最终结果的存储位置并未清晰定义,所以它不是一个合法的左值。

在这个例子中,我们在前面那个表达式中增加了一个括号。这个括号使表达式先执行加法运算,就是把1和cp中所存储的地址相加。此时的结果值是图中虚线椭圆所示的指针。接下来的间接访问操作随着箭头访问紧随ch之后的内存位置。这样,这个表达式的右值就是这个位置的值,而它的左值是这个位置本身。

在这里我们需要学习很重要的一点。注意指针加法运算的结果是个右值,因为它的存储位置并未清晰定义。如果没有间接访问操作,这个表达式将不是一个合法的左值。然而,间接访问跟随指针访问一个特定的位置。这样,*(cp+1)就可以作用左值使用,尽管cp+1本身并不是左值。间接访问操作符是少数几个其结果为左值的操作符之一。

但是,这个表达式所访问的是ch后面的那个内存位置,我们如何知道原先存储于那个地方的是什么东西呢?一般而言,我们无法得知,所以像这样的表达式是非法的。本章的后面我将更为深入地探讨这个问题。

后缀++操作符同样增加cp的值,但它先返回cp值的一份拷贝然后再增加cp的值。这样,这个表达式的值就是cp原来的值的一份副本。

前面两个表达式的值都不是合法的左值。但如果我们在表达式中增加了间接访问操作符,它们就可以成为合法的左值,如下面的两个表达式所示。

这里,间接访问操作符作用于增值后的指针的副本,所以它的右值是ch后面那个内存地址的值,而它的左值就是那个位置本身。

使用后缀++操作符所产生的结果不同:它的右值和左值分别是变量ch的值和ch的内存位置,也就是cp原先所指。同样,后缀++操作符在周围的表达式中使用其原先操作数的值。间接访问操作符和后缀++操作符的组合常常令人误解。优先级表格显示后缀++操作符的优先级高于*操作符,但表达式的结果看上去像是先执行间接访问操作。事实上,这里涉及3个步骤:++操作符产生cp的一份副本;然后++操作符增加cp的值;最后,在cp的副本上执行间接访问操作。

这个表达式常常在循环中出现,首先用一个数组的地址初始化指针,然后使用这种表达式就可以依次访问该数组的内容了。本章后面显示了一些这方面的例子。

在这个表达式中,由于这两个操作符的结合性都是从右向左,因此首先执行的是间接访问操作。然后,cp所指向的位置的值增加1,表达式的结果是这个增值后的值的一份副本。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LLM之LangChain(二)| LangChain中的Agent

在本文中,我们将讨论LangChain中的Agent及其各种类型。但在深入研究Agent之前,让我们先了解一下什么是LangChain和Agent。 一、什么是LangChain? LangChain是一种功能强大的自动化工具,可用于各种任务,它提供了可用于…

卸载Notepad++!事实已证明,它更牛逼……

本文系统全面的介绍了 Sublime Text,旨在成为最优秀的 Sublime Text 中文教程。 前言 Sublime Text 是一款跨平台代码编辑器(Code Editor),从最初的 Sublime Text 1.0,到现在的 Sublime Text 3.0,Sublime …

突破界限:首个国产DeepSeek MoE的高效表现

前言 在人工智能技术的快速发展过程中,国产首个开源MoE(Mixture of Experts)大模型——DeepSeek MoE的推出,不仅标志着中国在全球AI领域的重大突破,而且在计算效率和模型性能上展现了显著的优势。这款160亿参数的模型…

医疗器械生物学评价系列标准

医疗器械生物学评价系列标准(GB/T 16886/ISO 10993)是保障医疗器械安全的基础标准,内容涵盖医疗器械生物学评价基本指导原则、各项生物学试验方法、样品制备方法、理化表征方法等,是医疗器械生物学试验、评价、技术审批的重要依据,是医疗器械…

计算机图形学作业:Cohen-Sutherland和Liang-Barsky 裁剪算法

参考书籍和资料: Liang-Barsky参考下面视频14.2.1 [14.2.1]--讲解经典的梁友栋-巴斯基算法。_哔哩哔哩_bilibili Cohen-Sutherland参考孔令德的计算机图形学实验及课程设计(第二版),实验五直线段的裁剪 题目如下: …

R语言【文章复现】——集成式地绘制高分辨率的多样性分布图,对方法的检验和优化,以及处理思路的思考

参考文献 本文对一篇 2022 年发表在 New Phytologist 的绘图方法文章中的技术路线进行复现。 An integrated high-resolution mapping shows congruent biodiversity patterns of Fagales and Pinales Summary 文中,作者针对在全球尺度上绘制物种分布图提出了一种全新的方法…

大白菜U盘安装系统-戴尔电脑

1. 把U盘插入电脑,启动盘去大白菜官网找,镜像可以去微软官网下,想要专业版的网上找资源。 2. 重启电脑,等出现log之后狂按F12,进入BOSS模式。 3. 选择UEFI...也就是下面白色的,按下回车。 4. 选第一个 5.…

数据结构_C++语言描述_高教出版社

contents 前言一、绪论1.1 数据分析结构存储算法计算1.1.1 逻辑结构1.1.2 存储结构1.1.3 算法实现 1.2 数据类型1.3 算法方法 二、线性表2.1 线性表的逻辑结构2.2 线性表的存储结构2.2.1 顺序存储结构2.2.2 链式存储结构 2.3 线性表的操作算法2.3.1 顺序表的操作算法2.3.2 链表…

RK3568驱动指南|驱动基础进阶篇-进阶3 驱动代码使用Makefile的宏

瑞芯微RK3568芯片是一款定位中高端的通用型SOC,采用22nm制程工艺,搭载一颗四核Cortex-A55处理器和Mali G52 2EE 图形处理器。RK3568 支持4K 解码和 1080P 编码,支持SATA/PCIE/USB3.0 外围接口。RK3568内置独立NPU,可用于轻量级人工…

Nvidia Jetson AGX Orin使用CAN与底盘通信(ROS C++ 驱动)

文章目录 一、Nvidia Jetson AGX Orin使用CAN通信1.1 CAN使能配置修改GPIO口功能1.2 can收发测试 二、通过CAN协议编写CAN的SocketCan ROS1驱动程序2.1 通讯协议2.2 接收数据节点2.3 发送数据节点2.4 功能包配置 三、ROS2驱动程序 一、Nvidia Jetson AGX Orin使用CAN通信 参考…

linux手动安装 vscode-server

适用场景 很多时候,我们需要在本机(比如windows)通过remote ssh访问远程服务器(一般是ubuntu),但经常出现 vscode 一直连不上远程服务器的情况,看一下 log: 这个log表示远程服务器…

【2023年收入最高的10种编程语言】

在过去的一年时间里(2022 年 10 月 1 日到 2023 年 10 月 1 日) ,DevJobsScanner 分析了来自世界各地的超过 1000 万份开发工作机会,以了解市场以及最热门、薪酬最高的编程语言。值得注意的是,本项研究只关注了来自美国…

【Linux】网络诊断 traceroute命令详解

目录 一、traceroute概述 1.1 traceroute命令简介 1.2 命令格式 1.3 原理 1.4 命令功能 二、使用实例 实例1:traceroute 用法简单、最常用的用法 实例2:跳数设置 实例3:设置探测数据包数量 实例4:显示IP地址&#xff0c…

什么是SAMBA?如何配置?方法来了!

/bin/bash 目录 SAMBA SMB协议 SMB连接过程 samba主要有两个进程 Linux下搭建samba服务器实现文件共享 Linux客户端: Windows客户端: SAMBA samba是SMB文件共享协议的应用软件,可以让Linux系统和Windows系统之间相互共享资源。 在Lin…

3d模型素材亮度和对比度如何调整呢?

1、修改材质参数:打开3ds Max后,选择要调整亮度和对比度的3D模型素材。然后,进入材质编辑器,选择相应的材质球。在材质编辑器中,你可以调整材质的漫反射、反射和高光等参数,这些参数将影响模型的亮度和对比…

K8S的dashboard使用账号密码登录

原文网址:K8S的dashboard使用账号密码登录-CSDN博客 简介 本文介绍K8S的dashboard使用账号密码登录的方法。 ----------------------------------------------------------------------------------------------- 分享Java真实高频面试题,吊打面试官&…

美颜技术对比:如何根据项目选择不同的美颜SDK?

各位开发者应该非常清楚,为了在项目中取得最佳效果,选择合适的美颜SDK至关重要。本篇文章,笔者将通过对比不同美颜SDK的关键特性,帮助开发者根据项目需求做出明智的选择。 一、技术原理对比 不同的美颜SDK可能采用不同的技术原理…

如何使用CFImagehost结合内网穿透搭建私人图床并无公网ip远程访问

[TOC] 推荐一个人工智能学习网站点击跳转 1.前言 图片服务器也称作图床,可以说是互联网存储中最重要的应用之一,不仅网站需要图床提供的外链调取图片,个人或企业也用图床存储各种图片,方便随时访问查看。不过由于图床很不挣钱&a…

大数据开发之Hive(压缩和存储)

第 9 章:压缩和存储 Hive不会强制要求将数据转换成特定的格式才能使用。利用Hadoop的InputFormat API可以从不同数据源读取数据,使用OutputFormat API可以将数据写成不同的格式输出。 对数据进行压缩虽然会增加额外的CPU开销,但是会节约客观…

Qt QTableView和QStandardItemModel包含搜索出现的文本及隐藏顶层节点

前言 使用Qt进行开发时,树结构一般是使用QTreeWidget或使用QTreeViewQStandardItemModel结合。 查找 如果要进行查找树的所有项中,是否包含某文本,就需要遍历。 QTreeWidget查找 以下是使用QTreeWidget进行查找: 首先初始化一…