c语言编程学习之二维数组
二维数组
c语言按照行主序存储二维数组。也就是说,二维数组元素在内存中的位置是连续的,每行末尾元素(若不是最后一行)的下一个元素就是下一行的首元素。
如下图所示
接下来我们来分析一下如何将二维数组所有元素初始化零。
假设数组的声明如下:
int a[NUM_ROWS][NUM_COLS];
普通的写法是利用两层for循环
int row, col;
for (row = 0; row < NUM_ROWS; row++)
for (col = 0; col < NUM_COLS; col++)
a[row][col] = 0;
我们可以利用指针操作,将二维数组看成一个一维的大数组,其元素数量为NUM_ROWS*NUM_COLS,利用一个for循环完成操作
int *p;
for (p = &a[0][0]; p <= &a[NUM_ROWS-1][NUM_COLS-1]; p++)
*p = 0;
不过虽然代码量减少了,但实际上程序运行的次数和前者两层for循环操作运行次数是一样的。(这类方法明显破坏了程序的可读性,但是至少对一些老的编译器来说这种方法在效率方面进行了补偿。不过,对许多现代的编译器来说,这样所获得的速度优势往往极少甚至完全没有。)
接下来我们再看一个例子:将二维数组第i行的元素置0
为了访问到第i行的元素,让p指向数组a中第i行的第一个元素:
p=&a[i][0];
实际上,我们还可以将这句代码简写为
p=a[i];
对于任意一维数组a[]来说,其首元素地址为a。而二维数组可以看成是多个一维数组,行数就是一维数组的个数,列数就是数组中元素的个数。由此第i行的首元素地址就为a[i]。
如果要正经推导的话:对于任意数组a来说,表达式a[i]等价于(a + i)。因此&a[i][0]等同于&((a[i] + 0)),而后者等价于&a[i];又因为&和运算符可以抵消,也就等同于a[i]。
那么代码为:
int a[NUM_ROWS][NUM_COLS], *p, i;
for (p = a[i]; p < a[i] + NUM_COLS; p++)
*p = 0;
接下来我们再来思考一下怎么将数组a的第i列的元素置零呢?
我们可以利用数组指针(指向数组的指针)来实现这点。如声明一个数组指针:int (*p)[NUM_COLS]
。
我们知道,c语言指针每次自增1时,内存地址增加的量即为指针指向类型的所占内存单元数。在这里,p指向一个元素个数为NUM_COLS的int型数组,那么p++将会导致p指向地址增加NUM_COLS*(int型所占地址单元个数),这就实现了p从这一行指向了下一行。
代码如下
for(p = &a[0]; p < &a[NUM_ROWS]; p++){
(*p)[i] = 0;
}
最后,如果我们想遍历整个数组的话,也可以将整个二维数组看成一整个一维数组,利用指针进行遍历。
int *t;
for(t = a[0]; t <= &a[NUM_ROWS-1][NUM_COLS-1]; t++)
printf("%d ",*t);
c语言编程学习之二维数组的更多相关文章
- C语言中如何将二维数组作为函数的参数传递
今天写程序的时候要用到二维数组作参数传给一个函数,我发现将二维数组作参数进行传递还不是想象得那么简单里,但是最后我也解决了遇到的问题,所以这篇文章主要介绍如何处理二维数组当作参数传递的情况,希望大家不 ...
- 以杨辉三角为例,从内存角度简单分析C语言中的动态二维数组
学C语言,一定绕不过指针这一大难关,而指针最让人头疼的就是各种指向关系,一阶的指针还比较容易掌握,但一旦阶数一高,就很容易理不清楚其中的指向关系,现在我将通过杨辉三角为例,我会用四种方法从内存的角度简 ...
- 程序员之--C语言细节13(二维数组和指针,&*a[i][0]的理解,数组1[e]和e[1]非常可能你没见过)
主要内容:二维数组和指针.&*a[i][0]的理解.数组1[e]和e[1] #include <stdio.h> #define NUM_ROWS 10 #define NUM_C ...
- 剑指Offer编程题1——二维数组中的查找
剑指Offer编程题1---------------二维数组中的查找 题目描述 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完 ...
- java学习之二维数组
java当中的二维数组,存储一组比较特殊的对象.他存储一个数组,同时存储的数组当中又存储着元素. java二维数组的声明方式一: class Arr2Demo { public static void ...
- 基于visual Studio2013解决C语言竞赛题之0604二维数组置换
题目
- Java学习之二维数组定义与内存分配详解
二维数组:就是元素为一维数组的一个数组. 格式1: 数据类型[][] 数组名 = new 数据类型[m][n]; m:表示这个二维数组有多少个一维数组. n:表示每一个一维数组的元素有多少个. 注意: ...
- 剑指Offer_编程题之二维数组中的查找
题目描述 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数.
- Java 学习笔记 二维数组和对象数组
定义二维数组 int[][] a = new int[4][5]; 可以不指定列数 int[][] a = new int[4][]; 获取行 int i = a.length(); 如果使用第一个例 ...
随机推荐
- 14、MyBatis教程之全部(包括所有章节)
MyBatis 3.5.5 教程 1.环境准备 jdk 8 + MySQL 5.7.19 maven-3.6.1 IDEA 学习前需要掌握: JDBC MySQL Java 基础 Maven Juni ...
- 8、Spring教程之静态代理/动态代理
为什么要学习代理模式,因为AOP的底层机制就是动态代理! 代理模式: 静态代理 动态代理 学习aop之前 , 我们要先了解一下代理模式! 静态代理 静态代理角色分析 抽象角色 : 一般使用接口或者抽象 ...
- 2021华为软件精英挑战赛(C/C++实现)-苦行僧的实现过程
下面给出2021华为软件精英挑战赛参与的整个过程,虽然成绩不是很好,但是也是花了一些时间的,希望后面多多学习,多多进步. 代码已经上传到了Github上:https://github.com/myFr ...
- docker使用常见问题解决方案:错误号码2058,docker WARNING :IPv4,容器间的通讯
1.错误号码2058 1,错误解决: 解决方法:docker下mysql容器 登录 mysql -u root -p 登录你的 mysql 数据库,然后 执行这条SQL: ALTER USER 'ro ...
- B. 【例题2】雷达装置
B . [ 例 题 2 ] 雷 达 装 置 B. [例题2]雷达装置 B.[例题2]雷达装置 题目解析 求最少所需的雷达数,考虑贪心算法. 以这张图为例.以一个城市为中心,作一个半径为 d d d的圆 ...
- PhpStorm/WebStorm实用技巧
我常用的IDE设置和功能 1) 使用IDE管理远程主机 Tools -> Deployment -> Browse Remote Host 其中功能十分强大 自己去探索 关键提示: 手动/ ...
- OGG-Oracle 集成模式抽取进程,REGISTER DATABASE都做了什么?
一.学习目标 有同事问OGG技术问题,OGG软件,在oracle数据库中,集成模式抽取进程REGISTER DATABASE,都做了什么操作? 有什么风险? 并且提到了一个抽取进程注册,在瞬时间并发占 ...
- 它来了,它来了,HarmonyOS应用开发在线体验来了
接下来是我们的两分钟科普,一分钟玩转HarmonyOS应用开发在线体验,一分钟简单了解"一次开发.多设备部署"的原理.萌新的开发者也能第一时间掌握,往下看吧~ 一分钟玩转Harmo ...
- Sentinel上生产环境只差一步,监控数据持久化
之前介绍了Sentinel相关的文章,小伙伴在生产实践中不知道有没有这个疑问?我们的Sentinel控制台监控的数据只能看最近5分钟的,如图 那么就导致历史数据是查看不了的,那肯定是不行的,在生产环境 ...
- VirtualBox虚拟机读取U盘
1 概述 使用VirtualBox虚拟机(系统Win10)读取宿主机(系统Manjaro)中的U盘. 2 安装扩展 戳这里下载对应版本的一个叫Oracle_VM_VirtualBox_Extensio ...