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,一经查实,立即删除!

相关文章

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; 输出说明 输出一个字符 输入样例 …

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

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

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;被占据&…

大模型应用_PrivateGPT

https://github.com/imartinez/privateGPT 1 功能 整体功能&#xff0c;想解决什么问题 搭建完整的 RAG 系统&#xff0c;与 FastGPT相比&#xff0c;界面比较简单。但是底层支持比较丰富&#xff0c;可用于知识库的完全本地部署&#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 开…

5键键盘的输出 - 华为OD统一考试

OD统一考试 题解&#xff1a; Java / Python / C 题目描述 有一个特殊的 5键键盘&#xff0c;上面有 a,ctrl-c,ctrl-x,ctrl-v,ctrl-a五个键。 a 键在屏幕上输出一个字母 a; ctrl-c 将当前选择的字母复制到剪贴板; ctrl-x 将当前选择的 字母复制到剪贴板&#xff0c;并清空选择…

机器视觉【1】相机的成像(畸变)模型

零、前言 很久没写文章&#xff0c;简单唠一唠。 不知道巧合还是蜀道同归&#xff0c;部门领导设定了些研究课题&#xff0c;用于公司部门员工的超前发展&#xff0c;该课题是“2D to 3D的三维重建”&#xff0c;这一块刚好是我个人看中的一个大方向&#xff0c;所以就有了这…

leetcode-21-合并两个有序链表(C语言实现)

题目&#xff1a; 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例 1&#xff1a; 输入&#xff1a;l1 [1,2,4], l2 [1,3,4] 输出&#xff1a;[1,1,2,3,4,4]示例 2&#xff1a; 输入&#xff1a;l1 [], l2 [] 输出…

一文读懂FastAPI:Python 开发者的福音

FastAPI是一个基于Python的现代化Web框架&#xff0c;它提供了快速、简单和高性能的方式来构建API。 它结合了Python的静态类型检查和自动化文档生成的功能&#xff0c;使得开发API变得更加容易和高效。 下面将介绍如何使用FastAPI快速开发接口&#xff0c;并且利用自动生成的…

《LeetCode力扣练习》代码随想录——字符串(KMP算法学习补充——针对next数组构建的回退步骤进行解释)

《LeetCode力扣练习》代码随想录——字符串&#xff08;KMP算法学习补充——针对next数组构建的回退步骤进行解释&#xff09; 学习路径 代码随想录&#xff1a;28. 实现 strStr() CSDN&#xff1a;【详解】KMP算法——多图&#xff0c;多例子&#xff08;c语言&#xff09; …

【Qt之QNetworkAccessManager】概述及示例

概述 QNetworkAccessManager类允许应用程序发送网络请求和接收应答 网络访问API是围绕一个QNetworkAccessManager对象构建的&#xff0c;该对象为它发送的请求保存通用配置和设置。它包含代理和缓存配置&#xff0c;以及与此类问题相关的信号&#xff0c;以及可用于监视网络操…

Antd Select 添加中框

默认antd 的 Select中间并没有竖框&#xff0c;但是ui design设计了&#xff0c;所以记录一下如何添加 默认&#xff1a; CSS&#xff1a; .custom-select-suffix-icon {display: flex;align-items: center; }.custom-select-suffix-icon::before {content: ;height: 31px; …