《C语言程序设计现代方法》note-8 指针和数组的关系
文章目录
- 助记提要
- 12章 指针和数组
- 12.1 指针的算术运算
- 12.2 指针用于数组处理
- 结合使用`*`和`++`运算符
- 12.3 数组名作为指针
- 数组名可以用作指针
- 指针也可以当做数组名
- 数组型实参
- 12.4 指针和多维数组
- 处理每个元素
- 处理行
- 处理列
- 多维数组名做指针
- 12.5 指针和变长数组
助记提要
- 指针支持的算术运算及其含义;
*
和++
运算符结合的4种情况和含义;- 数组名作为指针、指针做为数组名;
- 数组做为实参时的特点;
- 指向数组的指针的特性;
- 如何处理二维数组的行和列;
- 多维数组名做指针时的类型和特性;
- 什么是变量修改类型;
12章 指针和数组
12.1 指针的算术运算
指针可以指向数组元素。&a[i]
是指向数组a中元素i的指针。
int a[10], *p;
// 指向数组元素的指针
p = &a[2];
// 给数组元素赋值
*p = 4
指向数组元素的指针变量可以进行指针算术运算。
- 指针加上整数
得到新的指向后面元素的指针。
若p指向a[i]
,则p+j
指向a[i+j]
。 - 指针减去整数
得到新的指向前面元素的指针。
若p指向a[i]
,则p-j
指向a[i-j]
。 - 指针相减
得到指针的距离(用数组元素的个数衡量)。
若p指向a[i]
,q指向a[j]
,则p-q
等于i-j
。
指向数组元素的指针之间还可以进行比较,相当于把对应的数组元素的下标进行比较。
指针可以指向由复合字面量创建的数组:
int *p = (int []){3, 4, 0, 1, 3};
12.2 指针用于数组处理
指针变量重复自增,可以遍历数组中的元素。
// 对数组求和
int a[10], sum, *p;
...
sum = 0;
for (p = &a[0]; p < &a[10]; p++)sum += *p;
元素a[10]
不存在,但是对它使用取地址运算符是合法的。之后也不会用到它的值。
结合使用*
和++
运算符
*
和++
两种运算符的结合方式有四种:
结合方式 | 含义 |
---|---|
*p++ 或*(p++) | 表达式的值是*p ,之后p 自增 |
(*p)++ | 表达式的值是*p ,之后*p 自增 |
*++p 或*(++p) | 先自增p ,然后计算表达式的值是*p |
++*p 或++(*p) | 先自增*p ,然后计算表达式的值是*p |
*
的优先级低于++
。
*
和--
运算符结合的情况和上面类似。
12.3 数组名作为指针
数组名可以用作指针
数组的名字可以作为指向数组的第一个元素的指针。
int a[10];
// 等价于 a[0] = 7;
*a = 7;
// 等价于 a[1] = 7;
*(a+1) = 12;
通常a+i
等价于&a[i]
,*(a+i)
等价于a[i]
。
*(a + i)
等价于a[i]
,而*(a + i)
和*(i + a)
是一样的,*(i + a)
等价于i[a]
。因此i[a]
和a[i]
的结果是一致的。但是不要这么写。
把数组名作为指针,可以简化指针和数组的操作:
// 改写数组求和
for (p = a; p < a + 10; p++)sum += *p
注意 数组名可以用作指针,但是不可以给数组名赋新值。
// 错误操作
while (*a != 0)a++;// 正确处理
p = a;
while (*p != 0)p++
指针也可以当做数组名
数组名可以作为指针,进行指针的算术运算。
指针也可以看做数组名,进行取下标操作。
编译器会把p[i]
看作*(p+i)
。
数组型实参
数组名在传递给函数时,会被转换为指针。
这个特性会有以下重要结果:
- 由于数组实际参数传递给函数时,没有对本身进行复制,所以做为实际参数的数组是肯呢个被更改的;
- 函数传递数组的时间和数组大小无关;
- 数组型的形式参数
a[]
可以被声明为指针*a
,编译器把这两类形参声明看做完全一样的。对数组a可进行的运算(算术运算和取下标)都是一样的。 - 利用指针,可以给接收数组的函数传递数组的片段。
注意 声明为数组和声明为指针一样的情况仅限于形式参数。
因为变量在声明为数组时,会预留数组元素的空间;而声明为指针时,只会为指针变量分配空间。把指针变量做为数组使用会导致未知的影响。
12.4 指针和多维数组
处理每个元素
二维数组是按行主序存储的,因此可以通过自增指向元素的指针来遍历每一个元素。
有的编译器会进行越界检查,遍历完第一行后,指向元素的指针继续自增会报错。
处理行
指针指向二维数组的第i行的第一个元素:
// 指向i行的首元素
p = &a[i][0];
// 等价表达
p = a[i];
指向某行的首元素后,自增指针即可遍历该行所有元素。
处理列
由于数组不是按列存储的,按列处理比较难。
先定义一个指向长度为数组列数的整形数组的指针(*p)[10]
。
注意 必须使用圆括号,因为*p[10]
会被当做指针数组,而不是指向数组的指针。
指向元素的指针,每次自增,会指向下一个元素;指向数组的指针,每次自增会指向下一个数组。
int main(){int int a[5][10] = {};int (*p)[10];p = a;// 元素之间的距离,指向元素的指针自增的距离printf("%d\n", &a[0][0]);printf("%d\n", &a[0][1]);// 指向数组的指针的自增的距离printf("%d\n", p);printf("%d\n", p+1);return 0;
}
6421824
6421828
6422024
6422064
指向整型元素的指针自增,地址增加值为4。而指向长度为10的整型数组的指针,每次自增,所表示的地址增加的值为40,即跳过了这个数组。
按列遍历数组的方式:
int a[5][10], (*p)[10], i;
...
for (p = &a[0]; p < &a[5]; p++)// *p表示某行,然后选取该行下标为i的元素(*p)[i] = 0;
多维数组名做指针
声明二维数组int a[5][10];
。
作为指针时,C语言认为二维数组名a
不是指向元素a[0][0]
的指针,而是指向行a[0]
的指针。
a的类型是int (*)[10]
,指向长度为10的整型数组的指针。
测试二维数组名做指针的等价情况:
int main() {int a[5][10] = {};printf("a %d\n", a);printf("&a %d\n", &a);printf("a[0] %d\n", a[0]);printf("&a[0] %d\n", &a[0]);printf("&a[0]+1 %d\n", &a[0] + 1);printf("a+1 %d\n", a+1);printf("&a[1] %d\n", &a[1]);printf("&a[0][0] %d\n", &a[0][0]);printf("&a[0][1] %d\n", &a[0][1]);
}
结果如下:
a 6421824
&a 6421824
a[0] 6421824
&a[0] 6421824a+1 6421864
&a[0]+1 6421864
&a[1] 6421864&a[0][0] 6421824
&a[0][1] 6421828
对于接收一维数组的函数int find_largest(int [], int n)
,用于计算出一维数组中的最大值。第一个参数为一维整型数组(即指针),第二个参数n为数组的元素数。
可以让这个函数把二维数组看做一维数组进行计算:
find_largest(a[0], 5*10);
注意 不能写为find_largest(a, 5*10);
。虽然a
和a[0]
指向同一位置,但是a
是int (*)[10]
类型,a[0]
类型为int *
。函数需要的实参类型是int *
。
12.5 指针和变长数组
指针可以指向变长数组中的元素。
变长数组如果是多维的,指针类型取决于除第一维外的每一维的长度。
void f(int m, int n)
{int a[m][n], (*p)[n];p = a;...
}
p的类型依赖于n,把这样的情况称为变量修改类型。
注意 下面的代码可以通过编译,但只有在m=n
时才是正确的。当m不等于n时,会出现未定义的行为。
int a[m][n], (*p)[m];
p = a;
相关文章:
《C语言程序设计现代方法》note-8 指针和数组的关系
文章目录 助记提要12章 指针和数组12.1 指针的算术运算12.2 指针用于数组处理结合使用*和运算符 12.3 数组名作为指针数组名可以用作指针指针也可以当做数组名数组型实参 12.4 指针和多维数组处理每个元素处理行处理列多维数组名做指针 12.5 指针和变长数组 助记提要 指针支持…...
安科瑞电能质量治理产品在分布式光伏电站的应用-安科瑞黄安南
1.概述 随着全球对可再生能源需求的增加,分布式光伏电站的建设和发展迅速。然而,分布式光伏电站的运行过程中面临着一系列问题,比如导致企业关口计量点功率因数过低、谐波污染等。这些问题不仅影响光伏电站自身的运行效率,还会对…...
JavaScript 的原生数组方法和 Vue 的响应式系统之间的差异
发现宝藏 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。【宝藏入口】。 JavaScript 的原生数组方法和 Vue 的响应式系统之间的差异主要体现在 Vue 如何追踪数组的变化,以及 Vue 如何处理数组…...
项目组件框架介绍[bRPC]
文章目录 前言bRPC安装bRPC的简单使用protobuf简单使用Echo服务远程调用Echo服务 与etcd关联 前言 bRPC是百度开源的一款工业级RPC框架,功能强大, 常用于搜索、存储、机器学习、广告、推荐等高性能系统。 bRPC安装 使用源码安装即可, 在安装前要确认依赖 sudo apt…...
基于MobileNetV3架构动物声音分类识别与应用系统实现
1.摘要 本文主要实现了一个基于MobileNetV3架构的深度学习模型用于动物声音分类识别任务。该MobileNetV3是一种轻量级的卷积神经网络,旨在实现高效分类性能,本章在猫、狗、海豚等三个动物声音(.wav数据集)上进行了训练和测试,即在…...
ragflow连ollama时出现的Bug
ragflow和ollama连接后,已经添加了两个模型但是ragflow仍然一直warn:Please add both embedding model and LLM in Settings > Model providers firstly.这里可能是我一开始拉取的镜像容器太小,容不下当前添加的模型,导…...
[大数据]Hudi编译集成
1. 编译环境准备 相关组件版本如下: Hadoop3.3.1Hive3.1.3Flink1.13.6,scala-2.12Spark3.3.1,scala-2.12 1)安装Maven (1)上传apache-maven-3.6.1-bin.tar.gz到/opt/software目录,并解压更名…...
rk3588-ubuntu22.04系统网关实现路由器功能:
rk3588-ubuntu22.04系统网关实现路由器功能: 场景需求描述: 需求背景: 场景一:通过网线eth0/(路由器wlan0)访问外网: 如果网关 和 设备所处的环境可以通过网线联网或者路由器联网,那么不需要将网关配置成…...
Python部署教程-Python项目怎样在Pycharm中运行
大家好,我是程序员徐师兄,今天为大家带来的是Python部署教程-Python项目怎样在Pycharm中运行。Python安装部署教程,包括软件的下载,软件的安装。该系统采用 Python语言开发,flask、Django 框架,MySql 作为数…...
代码随想录算法训练营第51期第14天 | 226. 翻转二叉树、101. 对称二叉树、104.二叉树的最大深度、111.二叉树的最小深度
226. 翻转二叉树 226. 翻转二叉树https://leetcode.cn/problems/invert-binary-tree/1.昨天忘了声明,如果都用C的话,我大概率写不完,所以思路方面,我可能考虑用pyhon先写,后续会用文心一言转换成C 2.这里可以直接用层…...
C/C++常见符号与运算符
C/C常见符号与运算符对照表 符号用法与意义与Java类比:在条件运算符中 (cond ? x : y) 表示条件为假的分支;在 switch-case 中如 case 1:表示标签结束点;在自定义标签如 label: 中用于 goto 跳转Java中? :三元运算相同;switch-case中也有:…...
maven报错“找不到符号“
问题 springboot项目 maven编译打包过程,报错"找不到符号" 解决 很多网上方法都试过,都没用 换jdk,把17->21...
开源数据同步中间件(Dbsyncer)简单玩一下 mysql to mysql 的增量,全量配置
一、什么是Dbsyncer 1、介绍 Dbsyncer是一款开源的数据同步中间件,提供MySQL、Oracle、SqlServer、PostgreSQL、Elasticsearch(ES)、Kafka、File、SQL等同步场景,支持上传插件自定义同步转换业务,提供监控全量和增量数据统计图、应用性能预警…...
【Kubernetes理论篇】容器集群管理系统Kubernetes(K8S)
Kubernetes集群部署基本管理实战 这么好的机会,还在等什么! 01、Kubernetes 概述 K8S是什么 K8S 的全称为 Kubernetes (K12345678S),PS:“嘛,写全称也太累了吧,写”。不如整个缩写 K8s 作为缩写的结果…...
鸿蒙ArkTS语言基础语法详解
文章目录 鸿蒙ArkTS语言基础语法详解一、引言二、ArkTS语言概述1. ArkTS语言特点2. TypeScript基础语法2.1 类型注解2.2 接口2.3 泛型2.4 类的继承2.5 类的访问修饰符 三、ArkTS的基本组成3.1 装饰器3.2 UI描述3.3 自定义组件3.4 系统组件3.5 属性方法和事件方法 四、自定义组件…...
两条链表相同位数相加
优质博文IT-BLOG-CN 一、题目 给你两个非空的链表,表示两个非负的整数。它们每位数字都是按照逆序的方式存储的,并且每个节点只能存储一位数字。请你将两个数相加,并以相同形式返回一个表示和的链表。你可以假设除了数字0之外,这…...
C语言单元总结
黑色加粗表示刷题刷到这样的题 红色加粗表示可能重要 单元一 程序设计宏观认识 C语言程序框架 C语言程序最基本的程序框架由两部分构成,分别是 1) 编译预处理 2) 函数组 C语言程序构成 C程序最大的特点就是所有的程序都是用函数来装配的,函数是构成…...
【Golang】Go语言编程思想(六):Channel,第二节,使用Channel等待Goroutine结束
使用 Channel 等待任务结束 首先回顾上一节 channel 这一概念介绍时所写的代码: package mainimport ("fmt""time" )func worker(id int, c chan int) {for n : range c {fmt.Printf("Worker %d received %c\n",id, n)} }func crea…...
Oracle RAC开启和关闭日志归档Log Archive
一、开启日志归档模式 # srvctl stop database -d <DB_NAME> # srvctl start instance -d <DB_NAME> -i <INSTANCE_NAME> -o mount # 停止 RAC 数据库的所有实例: [oracleora19crac1:/home/oracle]$srvctl stop database -d orcl # 启动第一个实…...
今天调了个转速的小BUG
同事说转速表有个bug,转速停止后,继电器没有恢复到初始状态。若停止之前是报警,继电器吸合,则停止后继电器还是吸合。我心想不会啊,这软件都弄了好几年了,一直也没出现过状况。 经过与调试同事的沟通&#…...
RabbitMQ七种工作模式之 RPC通信模式, 发布确认模式
文章目录 六. RPC(RPC通信模式)客户端服务端 七. Publisher Confirms(发布确认模式)1. Publishing Messages Individually(单独确认)2. Publishing Messages in Batches(批量确认)3. Handling Publisher Confirms Asynchronously(异步确认) 六. RPC(RPC通信模式) 客⼾端发送消息…...
【Python教程】Python3基础篇之基础语法
博主介绍:✌全网粉丝21W+,CSDN博客专家、Java领域优质创作者,掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围:SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物联网、机器学习等设计与开发。 感兴趣的可…...
`yarn list --pattern element-ui` 是一个 Yarn 命令,用于列出项目中符合指定模式(`element-ui`)的依赖包信息
文章目录 命令解析:功能说明:示例输出:使用场景: yarn list --pattern element-ui 是一个 Yarn 命令,用于列出项目中符合指定模式( element-ui)的依赖包信息。 命令解析: yarn list…...
使用docker-compose安装Milvus向量数据库及Attu可视化连接工具
首先确保系统已经安装上了docker 然后去https://github.com/docker/compose/releases/下载安装docker-compose 跟随自己下系统和服务器情况下载 上传到服务器 mv docker-compose-linux-aarch64 docker-compose chmod x docker-compose2.dockr-compose命令 docker-compose …...
IoTDB Allocate WAL Buffer Fail Because out of memory
问题及现象 时序数据库 IoTDB 集群报错: The write is rejected because the wal directory size has reached the threshold 53687091200 bytes. You may need to adjust the flush policy of the storage storageengine or the IoTConsensus synchronization pa…...
Go支付中台方案:多平台兼容与多项目对接
一、中台的概念 中台是一种企业级的架构模式,它处于前台应用和后台资源之间,将企业核心能力进行整合、封装,形成一系列可复用的业务能力组件。这些组件就像乐高积木一样,可以被不同的前台业务快速调用,从而避免重复开…...
设计模式:23、享元模式
目录 0、定义 1、享元模式的三种角色 2、享元模式的UML类图 3、示例代码 0、定义 运营共享技术有效地支持大量细粒度的对象 1、享元模式的三种角色 享元接口(Flyweight):是一个接口,该接口定义了享元对外公开其内部数据的方…...
如何使用靜態IP代理?【詳細教程】
靜態IP地址是手動分配給設備或伺服器的固定不變的 IP。與動態 IP 地址不同,動態 IP 地址由 DHCP 伺服器自動分配,並且會隨時間而變化。 如何獲取和設置靜態IP地址 一、檢查是否需要靜態IP? 在配置靜態 IP 之前,請…...
C++day3
1、把课上类的三个练习题的构造函数写出来 #include <iostream> #include <cstring>using namespace std;class Car {string color;string brond;double speed; public:Car(string c,string b,double s):color("black"),brond("Benz"),speed(…...
ABAP开发-批量导入BAPI和BDC_1
系列文章目录 文章目录 系列文章目录[TOC](文章目录) 前言一、概念二、BDC和BAPI数据导入1、BDC数据导入(录屏)2、BAPI数据导入 三、实例1、BAPI2、BDC 总结 前言 一、概念 SAP中,对一个事务码反复操作并且达到批量处理数据的效果࿰…...
iOS 语音循环播放设置
本地文件、网络文件,区别就是URL创建方式 1、使用AVPlayerItem与AVPlayer(这个简单,只需要设置回调),而不是AVAudioPlayer(这个麻烦,需要设置代理、计时器等等) 2、设置AVPlayerIte…...
PlantUML——类图
背景 类图是UML模型中的静态视图,其主要作用包括: 描述系统的结构化设计,显示出类、接口以及它们之间的静态结构和关系。简化对系统的理解,是系统分析与设计阶段的重要产物,也是系统编码和测试的重要模型依据。 在U…...
ASP.NET Core实现鉴权授权的几个库
System.IdentityModel.Tokens.Jwt 和 Microsoft.AspNetCore.Authentication.JwtBearer 是两个常用的库,分别用于处理 JWT(JSON Web Token)相关的任务。它们在功能上有一定重叠,但侧重点和使用场景有所不同。 1. System.IdentityM…...
生成:安卓证书uniapp
地址: https://ask.dcloud.net.cn/article/35777 // 使用keytool -genkey命令生成证书: 官网: keytool -genkey -alias testalias -keyalg RSA -keysize 2048 -validity 36500 -keystore test.keystore ----------------------------------…...
探索Web3:从去中心化应用到全球数字化未来
Web3 是互联网发展的下一步,它通过去中心化的理念重新定义了数字世界。与传统的Web2相比,Web3将数据主权交还给用户,让每个人都可以在没有中介的情况下安全地交换信息和价值。本文将探索Web3的基本概念,去中心化应用(D…...
AR向左,AI向右,智能眼镜来到十字路口
从Google Glass到Vision Pro,人类对智能眼镜的探索有进展,但都不算成功,直至Ray-Ban Meta的出现,这才让行业对智能眼镜重燃信心,从去年开始,随着AI大模型应用的深入,智能眼镜又有了新的故事可说…...
CTF靶场搭建及Web赛题制作与终端docker环境部署
写在前面 ╔══════════════════════════════════════════════════════════════════════════╗ 哈喽大家好!我是Myon,趁着我的云服务器还没过期,这次给大家出一…...
Java 应用程序CPU 100%问题排查优化实战
🧑 博主简介:CSDN博客专家,历代文学网(PC端可以访问:https://literature.sinhy.com/#/literature?__c1000,移动端可微信小程序搜索“历代文学”)总架构师,15年工作经验,…...
计网(王道的总结)-数据链路层-网络层-传输层
由于时间有限,把每个王道的章节最后一节放在一起,分别看看复习知识点。 3.6.4 IEEE 802.11 无线局域网 重点: 3.7 广域网 真题考频:极低 3.8以太网交换机 4.1网络层的功能 4.2.1IPv4分组 最重要的: TTL:…...
1-4 C单向链表
目录 1.0 基本概念 2.0 初始化链表 2.0 插入数据 3.0 删除数据 4.0 获取链长度 5.0 查询链表 6.0 返回第一个节点 7.0 打印链表节点 8.0 释放内存 9.0 链表调用 1.0 基本概念 线性表的顺序存储:用一块连续的内存空间,线性表的链式存储ÿ…...
在Windows 10中使用SSH远程连接服务器(附花生壳操作方法)
SSH 在 linux 中是一种重要的系统组件,用户可以使用 SSH 来远程连接 linux 系统的计算机,或者传输文件。不过在 win10 以前,windows 并不原生支持 SSH,需要借助第三方工具来使用 SSH 功能。而实际上,微软在 2015 年就曾…...
韶音科技嵌入式面试题及参考答案
Bootloader 的启动流程是什么? Bootloader 是在操作系统内核运行之前运行的一段小程序。它的启动流程主要分为以下几个阶段。 首先是硬件初始化阶段。这个阶段会对处理器以及一些关键的硬件设备进行初始化。比如,会配置处理器的工作模式、设置堆栈指针等…...
C++ ——— 类的 6 个默认成员函数之 构造函数
目录 何为默认成员函数 一、构造函数 构造函数的概念 构造函数的特性 日期类的构造函数 栈的构造函数 编译器自动生成的构造函数 总结 何为默认成员函数 默认成员函数就是用户没有显示实现,但是编译器会自动生成的成员函数称为默认成员函数 一、构造函数 …...
【优选算法篇】:揭开二分查找算法的神秘面纱--数据海洋中的精准定位器
✨感谢您阅读本篇文章,文章内容是个人学习笔记的整理,如果哪里有误的话还请您指正噢✨ ✨ 个人主页:余辉zmh–CSDN博客 ✨ 文章所属专栏:c篇–CSDN博客 文章目录 一.二分查找算法二.算法模板模板一模板二模板三 三.例题演练1.x的平…...
【机器学习算法】——数据可视化
1. 饼图:显示基本比例关系 import matplotlib.pyplot as pltplt.rcParams[font.sans-serif] [SimHei] plt.rcParams[axes.unicode_minus] False# ——————————————————————————————————————————————————————…...
比特币与区块链原理解析:矿机挖矿与去中心化的未来
✨✨ 欢迎大家来访Srlua的博文(づ ̄3 ̄)づ╭❤~✨✨ 🌟🌟 欢迎各位亲爱的读者,感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢,在这里我会分享我的知识和经验。&am…...
SpringBoot教程(十四) SpringBoot之集成Redis
SpringBoot教程(十四) | SpringBoot之集成Redis 一、Redis集成简介二、集成步骤 2.1 添加依赖2.2 添加配置2.3 项目中使用之简单使用 (举例讲解)2.4 项目中使用之工具类封装 (正式用这个)2.5 序列化 &…...
Qt之第三方库QCustomPlot使用(二)
Qt开发 系列文章 - qcustomplot(二) 目录 前言 一、Qt开源库 二、QCustomPlot 1.qcustomplot介绍 2.qcustomplot下载 3.qcustomplot移植 4.修改项目文件.pro 5.提升QWidget类 三、技巧讲解 1.拖动缩放功能 2.等待更新 总结 前言 Qt第三方…...
机器学习决策树原理详解
一、引言 在当今蓬勃发展的人工智能与大数据领域,大模型正以前所未有的影响力改变着众多行业的格局。而决策树作为机器学习算法家族中的经典成员,以其简洁直观的特点和广泛的适用性,不仅能独立解决诸多实际问题,更是诸多先进大模…...
深入探索JavaScript循环语句:从基础到高级应用
深入探索JavaScript循环语句:从基础到高级应用 在前端开发中,JavaScript 的循环语句是构建动态和交互式网页的关键工具。本文将全面介绍 JavaScript 中的几种主要循环语句,包括 for、while、do...while 以及 for...in 和 for...of࿰…...