【时时三省】(C语言基础)善于利用指针

山不在高,有仙则名。水不在深,有龙则灵。 ----CSDN 时时三省

指针是C语言中的一个重要概念,也是C语言的一个重要特色。正确而灵活地运用它,可以使程序简洁、紧凑、高效。每一个学习和使用C语言的人,都应当深入地学习和掌握指针。可以说,不掌握指针就是没有掌握C的精华。

指针的概念比较复杂,使用也比较灵活,因此初学时常会出错,务请在学习内容时十分小心,多思考、多比较、多上机,在实践中掌握它。

指针是什么

为了说清楚什么是指针,必须先弄清楚数据在内存中是如何存储的,又是如何读取的。

如果在程序中定义了一个变量,在对程序进行编译时,系统就会给这个变量分配内存单元。编译系统根据程序中定义的变量类型,分配一定长度的空间。例如,VisualC++为整型变量分配4个字节,为单精度浮点型变量分配4个字节,为字符型变量分配1个字节。内存区的每一个字节有一个编号,这就是“地址”,它相当于旅馆中的房间号。

在地址所标志的内存单元中存放的数据则相当于旅馆房间中居住的旅客。由于通过地址能找到所需的变量单元,可以说,地址指向该变量单元。打个比方,一个房间的门口挂了一个房间号2008,这个2008就是房间的地址,或者说,2008“指向”该房间。因此,将地址形象化地称为“指针”。意思是通过它能找到以它为地址的内存单元。

说明:对计算机存储单元的访问比旅馆要复杂一些,在C语言中,数据是分类型的,对不同类型的数据,在内存中分配的存储单元大小(字节数)和存储方式是不同的(如整数以补码形式存放,实数以指数形式存放)。如果只是指定了地址1010 ,希望从该单元中调出数据,这是做不到的,虽然能找到所指定的存储单元,但是,无法确定是从1个字节中取信息(字符数据),还是从2个字节取信息(短整型),抑或是从4个字节取信息(整型)。也没有说明按何种存储方式存取数据(整数和单精度实数都是4个字节,但存储方式是不同的)。因此,为了有效地存取一个数据,除了需要位置信息外,还需要有该数据的类型信息(如果没有该数据的类型信息,只有位置信息是无法对该数据进行存取的)。C语言中的地址包括位置信息(内存编号,或称纯地址)和它所指向的数据的类型信息,或者说它是“带类型的地址”。如& a,一般称它为“变量a的地址”,确切地说,它是“整型变量a的地址”。后面提到的“地址”,都是这个意思。

请思考:若有int型变量a和float型变量b,如果先后把它们分配在2000开始的存储单元中,& a和& b的信息完全相同吗?答案是不相同的,虽然存储单元的编号相同,但它们的数据类型不同。

请务必弄清楚存储单元的地址和存储单元的内容这两个概念的区别,假设程序已定义了3个整型变量i,j,k,在程序编译时,系统可能分配地址为2000 ~ 2003的4个字节给变量i,2004 ~ 2007的4个字节给j,2008 ~ 2011的4个字节给k(不同的编译系统在不同次的编译中,分配给变量的存储单元的地址是不相同的)。

在程序中一般是通过变量名来引用变量的值,例如:

printf (”% d\n”,i );

由于在编译时,系统已为变量i分配了按整型存储方式的4个字节,并建立了变量名和地址的对应表,因此在执行上面语句时,首先通过变量名找到相应的地址,从该4个字节中按照整型数据的存储方式读出整型变量i的值,然后按十进制整数格式输出。

注意:对变量的访问都是通过地址进行的。假如有输入语句

scanf (”% d”,& i );

在执行时,把键盘输入的值送到地址为2000开始的整型存储单元中。如果有语句

k = i + j;

则则从2000 ~ 2003字节取出i的值( 3 ),再从2004 ~ 2007字节取出j的值( 6 ),将它们相加后再将其和( 9 )送到k所占用的2008 ~ 2011字节单元中。这种直接按变量名进行的访问,称为“直接访问”方式。

还可以采用另一种称为“间接访问”的方式,即将变量i的地址存放在另一变量中,然后通过该变量来找到变量i的地址,从而访问i变量。

在C语言程序中,可以定义整型变量、浮点型(实型)变量、字符变量等,也可以定义一种特殊的变量,用它存放地址。假设定义了一个变量i _ pointer(变量名可任意取),用来存放整型变量的地址。可以通过下面语句将i的地址( 2000 )存放到i _ pointer中。

i _ pointer = & i;/ /将i的地址存放到i _ pointer中

这时,i _ pointer的值就是2000(即变量i所占用单元的起始地址)。

要存取变量i的值,既可以用直接访问的方式,也可以采用间接访问的方式:先找到存放“变量i的地址”的变量i _ pointer,从中取出i的地址( 2000 ),然后到2000字节开始的存储单元中取出i的值( 3 ),。

打个比方,为了开一个A抽屉,有两种办法,一种是将A钥匙带在身上,需要时直接找出该钥匙打开抽屉,取出所需的东西。另一种办法是:为安全起见,将该A钥匙放到另一部量B中锁起来。如果需要打开A抽屉,就需要先找出B钥匙,打开B抽展,取出A钥匙,再打开A抽屉,取出A抽屉中之物,这就是“间接访问”。

为了表示将数值3送到变量中,可以有两种表达方法:

( 1 )将3直接送到变量i所标识的单元中,例如“i = 3;”。

( 2 )将3送到变量i _ pointer所指向的单元(即变量i的存储单元),例如“* i _ pointer = 3;”,其中* i _ pointer表示i _ pointer指向的对象。指向就是通过地址来体现的。

假设i _ pointer中的值是变量i的地址( 2000 ),这样就在i pointer和变量i之间建立起一种联系,即通过i _ pointer能知道i的地址,从而找到变量i的内存单元。

由于通过地址能找到所需的变量单元,因此说,地址指向该变量单元(如同说,一个房间号“指向”某一房间一样)。将地址形象化地称为“指针”。意思是通过它能找到以它为地址的内存单元(如同根据地址2000就能找到变量i的存储单元一样)。

如果有一个变量专门用来存放另一变量的地址(即指针),则它称为“指针变量”。上述的ipointer就是一个指针变量。指针变量就是地址变量,用来存放地址,指针变量的值是地址(即指针)。

注意:区分“指针”和“指针变量”这两个概念。例如,可以说变量i的指针是2000,而不能说i的指针变量是2000。指针是一个地址,而指针变量是存放地址的变量。

 

 

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

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

相关文章

单点登录进阶:基于芋道(yudao)授权码模式的单点登录流程、代码实现与安全设计

最近遇到需要单点登录的场景,我使用的是芋道框架,正好它手动实现了OAuth2的功能,可以为单点登录提供一些帮助,结合授权码的模式,在改动最小的情况下实现了单点登录。关键业务数据已经隐藏,后续将以以主认证…

关于Seata的一个小issue...

文章目录 引言原因🤓解决方法😵总结❤️ 引言 某一天,笔者在逛着Github的时候,突然看到seata有个有趣的issue,是一个task。 相关描述: While running the DruidSQLRecognizerFactoryTest.testIsSqlSynta…

FTTR+软路由网络拓扑方案

文章目录 网络拓扑软路由配置FTTR光猫路由器TPLink路由器配置WAN设置LAN设置 参考 网络拓扑 软路由配置 配置静态IP地址:192.168.1.100设置网关指向主路由的IP 设置自定义DNS服务器 开启DHCP 这一步很关键,可以让连上wifi的所有设备自动趴强。 FTTR光猫…

RPC - 服务注册与发现模块

为什么要服务注册,服务注册是做什么 服务注册主要是实现分布式的系统,让系统更加的健壮,一个节点主机将自己所能提供的服务,在注册中心进行登记 为什么要服务发现,服务发现是要做什么 rpc调用者需要知道哪个节点主机…

分布式缓存:应对突发流量的缓存体系构建

文章目录 缓存全景图Pre背景与目标说明缓存原则与设计思路缓存体系架构缓存预热与缓存预加载库存操作与缓存结合防刷、限流与缓存缓存一致性与失效异步落地与消息队列监控与指标容灾与扩展示例小结 缓存全景图 Pre 分布式缓存:缓存设计三大核心思想 分布式缓存&am…

华为云Flexus+DeepSeek征文|CCE容器高可用部署搭建Dify-LLM平台部署AI Agent

华为云FlexusDeepSeek征文|CCE容器高可用部署搭建Dify-LLM平台部署AI Agent 前言 Dify是一款开源的大语言模型应用开发平台,融合了后端即服务和LLMOps的理念,使开发者可以快速搭建生产级的生成式AI应用,本文将详细介绍如何使用华…

Postman 的 Jenkins 管理 - 手动构建

目录 一、准备工作 二、postman 项目脚本准备并导出 1. 打开已完成并测试无误的 postman 项目脚本。 再次执行测试。 ​编辑2. 导出( 测试用例集、环境变量 两个文件)**“不 支 持 中 文”** —— 全部改成英文! ​编辑3. 文件所在目录…

音视频之H.264/AVC解码器的原理和实现

系列文章: 1、音视频之视频压缩技术及数字视频综述 2、音视频之视频压缩编码的基本原理 3、音视频之H.264/AVC编码器原理 4、音视频之H.264的句法和语义 5、音视频之H.264/AVC解码器的原理和实现 6、音视频之H.264视频编码传输及其在移动通信中的应用 7、音视…

【智能安全帽新升级】搭载VTX316TTS语音合成芯片,让安全“听得见”!

在工地轰鸣的机械声中,一句清晰的指令可能比任何文字都更有力量。 当智能安全帽遇上VTX316语音合成芯片,安全防护从“被动响应”进化为“主动交互”,为高危行业戴上了一顶“会说话的智慧大脑”! 传统安全帽的“沉默”危机 在建筑…

【目标检测】非极大值抑制(NMS)的原理与实现

🧑 博主简介:曾任某智慧城市类企业算法总监,目前在美国市场的物流公司从事高级算法工程师一职,深耕人工智能领域,精通python数据挖掘、可视化、机器学习等,发表过AI相关的专利并多次在AI类比赛中获奖。CSDN…

DB-GPT启动提示please install by running `pip install cryptography`

DB-GPT项目需要 cryptography 库来处理加密功能,但环境中没有安装它。cryptography 是一个用于安全和加密操作的Python库,许多项目(包括DB-GPT)依赖它来处理敏感数据的加密存储。 解决方案 1. 安装 cryptography 库 在激活的环…

局域网文件共享及检索系统

标题:局域网文件共享及检索系统 内容:1.摘要 随着信息技术的飞速发展,局域网在企业、学校等场景中得到广泛应用,大量文件在局域网内存储和流转。然而,目前局域网内文件共享与检索存在效率低、管理困难等问题。本文旨在设计并实现一个高效的局…

Spring Boot医疗系统高并发难题:达梦数据库死锁排查与优化实战

Spring Boot医疗系统高并发难题:达梦数据库死锁排查与优化实战 引言:医疗系统中的并发挑战 在现代医疗系统中,检查申请处理是关键业务场景之一,每天需要处理数以万计的检查记录。当多个操作同时更新同一患者的申请状态时,数据库层面的死锁问题成为高并发环境下的典型痛点…

Go语言中的文件与IO:bufio 和 scanner

Go 标准库中的 bufio 包提供了带缓冲的读写功能,可以显著提高文件和数据处理效率。而 bufio.Scanner 则是读取文本文件中每一行的利器,常用于日志、配置等文本处理场景。 一、为什么使用 bufio? 直接对文件进行 os.File.Read() 或 os.File.W…

ABP微服务架构中网关层NullReferenceException问题解析与HTTP配置优化

ABP微服务架构中网关层NullReferenceException问题解析与HTTP配置优化 一、网关层System.NullReferenceException问题解析 1.1 问题现象与原因分析 在ABP微服务架构开发过程中,网关层启动后调用微服务接口时出现以下异常: System.NullReferenceExcep…

啊啊啊啊啊啊啊啊code

前序遍历和中序遍历构建二叉树 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) { this.val val; }* TreeNode(int val, TreeNode left, TreeNod…

【算法 day06】LeetCode 454.四数相加II | 15. 三数之和 | 18. 四数之和

454.四数相加II 题目链接 | 文档讲解 |视频讲解 : 链接 1.思路: 0.定义一个count,计算最终出现的次数 1.先遍历nums1和nums2,求出两者的和,map的key是和,value是出现的次数 2.再遍历nums3和nums4,求出0-两者的和 3…

【项目实训】【项目博客#09】HarmonySmartCodingSystem系统后端智能API检索与代码助手实现(6.2-6.15)

【项目实训】【项目博客#09】HarmonySmartCodingSystem系统后端智能API检索与代码助手实现(6.2-6.15) 文章目录 【项目实训】【项目博客#09】HarmonySmartCodingSystem系统后端智能API检索与代码助手实现(6.2-6.15)项目博客概述一…

【JVM】- 类加载与字节码结构3

类加载阶段 1. 加载 加载:将类的字节码载入方法区中,内部采用C的instanceKlass描述java类。如果这个类的父类还没加载,则先加载父类加载和链接可能是交替运行的 通过全限定名获取字节码 从文件系统(.class 文件)、JA…

Qt蓝图式技能编辑器状态机模块设计与实现

设计概述 这个模块是一个基于Qt的蓝图式技能编辑器状态机,主要用于游戏开发中的技能状态管理。核心功能包括: 状态节点(开始、结束、普通状态)的可视化 状态间连线的绘制与管理 状态转换逻辑的可视化编辑 动作选择与配置 核…