c语言:指针与数组

目录

使用指针访问数组

使用第一个元素获取数组首地址

使用数组名获取数组首地址

使用指针访问数组等价于下标访问


使用指针访问数组

指针类型的加减运算可以使指针内保存的首地址移动。指针类型加n后。首地址向后移动 n * 步长 字节。

指针类型减n后。首地址向前移动 n * 步长 字节。

步长为指针所指向的类型所占空间大小。例如:

int *p = (int *)100;

p + 1,结果为首地址向移动sizeof(int)字节,即104p - 1,结果为首地址向移动sizeof(int)字节,即96

因此,指针加减运算对于访问在内存中连续排布的数据对象非常方便。

而数组这种数据对象,每个元素在内存中一定是连续排布的。下面,我们来探究怎样使用指针访问数组。


使用第一个元素获取数组首地址

 既然数组元素在内存中的存储可以保证是连续的,那么第一个元素的首地址,就是整个数组的首地址。我们可以使用取地址运算符&,获取第一个元素的首地址和空间大小,即获取一个 int * 类型的指针。

 int *p = &arr[0];   // 从第1个元素获取数组首地址

p;      // 指向第1个元素

p + 1; // 指向第2个元素

p + 2; // 指向第3个元素

p + 3; // 指向第4个元素

p + 4; // 指向第5个元素

通过取值运算符*,可以使用指针中的首地址和空间大小访问或修改目标数据对象。 

 

注意,表达式 p + 1 必须先被括号包裹,再使用取值运算符*。这是因为取值运算符*的优先级高于算术运算符。

我们需要先让首地址移动,再进行取值操作。

若不使用括号, *p 会先被取值,之后值再被加1

不使用括号:

*p 的值为111*p + 1 的结果为112

使用括号:

(p + 1) 使得首地址移动到第二个元素, *(p + 1) 得到结果为222

 


使用数组名获取数组首地址

有没有更方便地获取数组首地址的办法呢?

有的,可以通过数组名获取首地址。 

&arr[0] 的结果为一个指向数组第一个元素的指针,其值6814140为第一个元素的首地址,而数组名 arr 的值居然也是首地址。

既然值一样了,那么我们继续探究它们的类型是否一样呢?我们知道,不同数据类型的指针是不能直接相互赋值的。我们可以通过这个办法,试试看数组名是否是一个 int * 类型。

 

编译可以通过,并且成功地访问了数组中各个元素的值。那么,你自然会认为数组名的类型就是一个指向元素的指针了。

为了验证这个猜想,我们使用sizeof测量一下数组名的大小,如果数组名是一个指针,那么它的大小在

32位程序下为4,在64位程序下为8

示例中使用32位进行编译。

arr 的大小为20

p 的大小为8

arr + 1 的大小为8

p 是一个指针大小为4是理所当然的。

但是 arr 的大小为20,那么 arr 应该不是一个指针类型才对,但是它却又可以成功赋值给 int * 。而 arr + 1 的大小却又为4

这是为什么呢?

规则:设数组元素类型为T

T arr[5]; // T为元素数组arr

T *p; // 指向T的指针

类型为T为元素的数组arr指向T的指针p之间存在密切的关系。

当数组名arr出现在一个表达式当中,数组名arr将会被转换为指向数组第一个元素的指针。但是,这个规则有两个例外:

  1. 对数组名arr使用sizeof时。
  2. 对数组名arr使用&时。

也就是说,数组名arr的类型其实是 int [5] ,因此 sizeof(arr) 的结果才会是20

数组名arr出现在表达式 int *p = arr 中,会被转换为指向数组第一个元素的指针,即 int [5] 转为 int * 类型。之后进行赋值运算。

arr + 1 也是一个表达式,数组名 arr 被转换为 int * 类型,进行加法运算后,仍然为 int * 类型。

 


使用指针访问数组等价于下标访问

 

现在我们学会了访问数组元素的两种办法:

  1. 数组名[下标]
  2. *(数组名 + 偏移量)

其中,偏移量就是指针指向的地址与数组首地址之间相差几个元素。访问第2个元素:

1. 数组名[1]

2. *(数组名 + 1)

事实上,这两种形式是等价的。

中括号 [] ,被称作下标运算符,它的优先级高于一切其他运算符。通常的形式为:

A[k]

而表达式运算时,最终会将下标运算符展开为:

*(A + k)

我们可以做一个小测试,验证这个规则

arr[2] 展开为 *(arr + 2)

2[arr] 展开为 *(2 + arr)

因此,使用指针访问数组等价于下标访问。

 

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

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

相关文章

了解油封的压力额定值

油封是各种机械系统中的关键部件。它们可以防止润滑剂泄漏和污染物侵入。选择油封时要考虑的一个关键因素是其压力等级。 一、了解压力等级: 油封的压力等级是指密封件在不失效的情况下所能承受的压力。该额定值通常以磅每平方英寸(psi)或bar单位进行测量。 二、…

Linux(21):软件安装 RPM,SRPM 与 YUM

软件管理员简介 以原始码的方式来安装软件,是利用厂商释出的Tarball来进行软件的安装。 不过,你每次安装软件都需要侦测操作系统与环境、设定编译参数、实际的编译、最后还要依据个人喜好的方式来安装软件到定位。这过程是真的很麻烦的。 如果厂商先在他…

mysql 数据库

一、mysql 数据库 安装 sudo apt-get install mysql-server sudo systemctl status mysql二、基本使用 1、mysql 登陆 sudo mysql -u root -p # 默认密码可能被设置为"root","admin"或者是空的2、创建用户 # 创建用户 newuser,改…

openHarmony添加system_basic权限安装报错

openHarmony添加system_basic权限安装报错 12/14 13:49:57: Install Failed: [Info]App install path:D:\huawei\project\FCTTest\entry\build\default\outputs\default\entry-default-signed.hap, queuesize:0, msg:error: failed to install bundle. error: install failed …

成绩分级 C语言xdoj53

问题描述 给出一个百分制的成绩&#xff0c;要求输出成绩等级A,B,C,D,E。90分以上为A&#xff0c;80~89分为B,70~79分为C,60~69分为D&#xff0c;60分以下为E。 输入说明 输入一个正整数m&#xff08;0<m<100&#xff09; 输出说明 输出一个字符 输入样例 …

centos7配置国内源

文章目录 说明操作遇到网络错误 说明 作者因为经常需要使用到&#xff0c;所以自己手动记录一下 操作 安装wget工具&#xff08;这个工具很小&#xff0c;直接使用官方镜像源&#xff0c;进行安装即可&#xff09; sudo yum install wget备份当前的源文件 sudo cp /etc/yu…

有效的括号,成对字符合法性检测

说在前面 &#x1f388;不知道大家对于算法的学习是一个怎样的心态呢&#xff1f;为了面试还是因为兴趣&#xff1f;不管是出于什么原因&#xff0c;算法学习需要持续保持。 一、题目描述 给定一个只包括 ‘(’&#xff0c;‘)’&#xff0c;‘{’&#xff0c;‘}’&#xff0…

DatabaseMetaData详解

DatabaseMetaData详解 大家好&#xff0c;我是免费搭建查券返利机器人赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; 深入了解Java DatabaseMetaData&#xff1a;揭秘数据库元数据的奥秘 作为Java程序员&#…

​_thread --- 底层多线程 API​

该模块提供了操作多个线程&#xff08;也被称为 轻量级进程 或 任务&#xff09;的底层原语 —— 多个控制线程共享全局数据空间。为了处理同步问题&#xff0c;也提供了简单的锁机制&#xff08;也称为 互斥锁 或 二进制信号&#xff09;。threading 模块基于该模块提供了更易…

Unity中实现ShaderToy卡通火(移植篇)

文章目录 前言一、准备好我们的后处理基础脚本1、C#&#xff1a;2、Shader&#xff1a; 二、开始逐语句对ShaderToy进行转化1、首先&#xff0c;找到我们的主函数 mainImage2、其余的方法全部都是在 mainImage 函数中调用的方法3、替换后的代码(已经没报错了&#xff0c;但是效…

七.子查询

子查询 1.需求分析与解决问题1.1.实际问题1.2子查询的基本使用1.3子查询分类 2.单行子查询2.1单行比较操作符2.2代码示例2.3HAVING中的子查询2.4CASE中的查询2.5子查询中的空值问题2.6非法使用子查询 3.多行子查询3.1多行比较符操作3.2代码示例3.3空值问题 4.相关子查询4.1相关…

国家开放大学 湖南开放大学形成性考核 平时作业 统一资料

试卷代号&#xff1a;1258 房屋建筑混凝土结构设计 参考试题 一、单项选择题&#xff08;每小题2分&#xff0c;共计40分&#xff09; 1.( )是将框架结构中的部分跨间布置剪力墙或把剪力墙结构的部分剪力墙抽掉改为框架承重。 A.梁板结构体系 B.框…

LeetCode 2132. 用邮票贴满网格图:二维前缀和 + 二维差分

【LetMeFly】2132.用邮票贴满网格图&#xff1a;二维前缀和 二维差分 力扣题目链接&#xff1a;https://leetcode.cn/problems/stamping-the-grid/ 给你一个 m x n 的二进制矩阵 grid &#xff0c;每个格子要么为 0 &#xff08;空&#xff09;要么为 1 &#xff08;被占据&…

ABAP 锁对象问题,针对条目数锁不住解决方法

使用通过锁表函数 ENQUEUE_E_TABLE 针对 函数 varkey 入参&#xff0c;锁表 SFLIGHT varkey |{ sy-mandt }{ |AA| }{ |0017| }{ |20210916| }|. 直接拼接主键就会出现锁表条目数锁不住的情况&#xff0c;SE11、SE16还可编辑 需要改进写法 像下面这样赋值即可针对行项目数…

大模型应用_PrivateGPT

https://github.com/imartinez/privateGPT 1 功能 整体功能&#xff0c;想解决什么问题 搭建完整的 RAG 系统&#xff0c;与 FastGPT相比&#xff0c;界面比较简单。但是底层支持比较丰富&#xff0c;可用于知识库的完全本地部署&#xff0c;包含大模型和向量库。适用于保密级…

静态html网页,怎么增加后台管理

要为静态HTML网页增加后台管理功能&#xff0c;你可以考虑以下几种方法&#xff1a; 服务器端脚本&#xff1a;使用服务器端脚本语言&#xff08;如PHP、Python等&#xff09;来处理后台管理功能。你可以将静态HTML页面与服务器端脚本结合起来&#xff0c;通过在HTML页面中嵌入…

在MFC(Microsoft Foundation Classes)中 CreateThread函数

CreateThread是Windows API中用于创建新线程的函数。以下是对函数参数的详细解释&#xff1a; lpThreadAttributes&#xff08;可选&#xff09;&#xff1a;指向SECURITY_ATTRIBUTES结构的指针&#xff0c;用于指定线程的安全性。可以设置为NULL&#xff0c;表示使用默认安全…

AI抽烟识别系统研发关键

为了设计一个有效的AI抽烟识别系统&#xff0c;我们需要考虑几个关键组成部分&#xff1a;图像捕捉、数据处理、模型训练、以及实际应用场景。下面是这个方案的详细阐述&#xff1a; 1. 图像捕捉与数据收集 摄像头部署&#xff1a;首先&#xff0c;在需要监控的区域安装高分辨…

硬件基础常识【4】--利用戴维宁定理求运放复杂反馈电阻网络的增益

最近学到了一种求带T型电阻网络反馈运放增益的方法 如图所示为T型电阻网络反馈的反相放大器 求解思路 沿X-Y断开&#xff0c;右侧利用戴维宁定理等效成电压源串电阻的形式 由戴维宁定理可得&#xff1a; V T H V o u t ∗ R 4 / ( R 3 R 4 ) ( 式 1 ) VTHVout*R4/(R3R4)…

二叉树题目:从前序遍历还原二叉树

文章目录 题目标题和出处难度题目描述要求示例数据范围 解法思路和算法代码复杂度分析 题目 标题和出处 标题&#xff1a;从前序遍历还原二叉树 出处&#xff1a;1028. 从前序遍历还原二叉树 难度 6 级 题目描述 要求 我们从二叉树的根结点 root \texttt{root} root 开…