二维数组

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语言编程学习之二维数组的更多相关文章

  1. C语言中如何将二维数组作为函数的参数传递

    今天写程序的时候要用到二维数组作参数传给一个函数,我发现将二维数组作参数进行传递还不是想象得那么简单里,但是最后我也解决了遇到的问题,所以这篇文章主要介绍如何处理二维数组当作参数传递的情况,希望大家不 ...

  2. 以杨辉三角为例,从内存角度简单分析C语言中的动态二维数组

    学C语言,一定绕不过指针这一大难关,而指针最让人头疼的就是各种指向关系,一阶的指针还比较容易掌握,但一旦阶数一高,就很容易理不清楚其中的指向关系,现在我将通过杨辉三角为例,我会用四种方法从内存的角度简 ...

  3. 程序员之--C语言细节13(二维数组和指针,&amp;*a[i][0]的理解,数组1[e]和e[1]非常可能你没见过)

    主要内容:二维数组和指针.&*a[i][0]的理解.数组1[e]和e[1] #include <stdio.h> #define NUM_ROWS 10 #define NUM_C ...

  4. 剑指Offer编程题1——二维数组中的查找

    剑指Offer编程题1---------------二维数组中的查找 题目描述 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完 ...

  5. java学习之二维数组

    java当中的二维数组,存储一组比较特殊的对象.他存储一个数组,同时存储的数组当中又存储着元素. java二维数组的声明方式一: class Arr2Demo { public static void ...

  6. 基于visual Studio2013解决C语言竞赛题之0604二维数组置换

     题目

  7. Java学习之二维数组定义与内存分配详解

    二维数组:就是元素为一维数组的一个数组. 格式1: 数据类型[][] 数组名 = new 数据类型[m][n]; m:表示这个二维数组有多少个一维数组. n:表示每一个一维数组的元素有多少个. 注意: ...

  8. 剑指Offer_编程题之二维数组中的查找

    题目描述 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数.

  9. Java 学习笔记 二维数组和对象数组

    定义二维数组 int[][] a = new int[4][5]; 可以不指定列数 int[][] a = new int[4][]; 获取行 int i = a.length(); 如果使用第一个例 ...

随机推荐

  1. Python3中变量作用域nonlocal的总结

    最近,在工作中踩到了一个关于Python3中nonlocal语句指定的变量作用域的坑.今天趁周六休息总结记录一下. 众所周知,Python中最常见的作用域定义如下:   但是,为了更加方便地在闭包函数 ...

  2. python中类的魔法方法

    __xx__这种方法,在Python中均称为魔法方法 1.__init__(self) 该方法的作用是初始化对象 在创建对象时被默认调用,不需要手动调节 self参数不需要开发者传递,解释器会自动将创 ...

  3. 从键盘读入学生成绩,找出最高分, 并输出学生成绩等级(Java)

    从键盘读入学生成绩,找出最高分, 并输出学生成绩等级 一.题目 从键盘读入学生成绩,找出最高分,并输出学生成绩等级. 成绩>=最高分-10 等级为'A' 成绩>=最高分-20 等级为'B' ...

  4. [Azure Devops] 使用 Azure Boards 管理工作

    1. 什么是 Azure Boards 通过 Azure Boards 网络服务,团队可以管理其软件项目.它提供了丰富的功能,包括 Scrum 和看板的本地支持.可定制的仪表板和集成报告.这些工具可以 ...

  5. Windows下解析命令行参数

    linux通常使用GNU C提供的函数getopt.getopt_long.getopt_long_only函数来解析命令行参数. 移植到Windows下 getopt.h #ifndef _GETO ...

  6. PTA 输出数组元素

    7-3 输出数组元素 (15 分)   本题要求编写程序,对顺序读入的n个整数,顺次计算后项减前项之差,并按每行三个元素的格式输出结果. 输入格式: 输入的第一行给出正整数n(1).随后一行给出n个整 ...

  7. 你说,怎么把Bean塞到Spring容器?

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 小傅哥,你是怎么学习的? 有很多初学编程或者码了几年CRUD砖的小伙伴问我,该怎么学 ...

  8. java例题_21 求 1+2!+3!+...+20!的和

    1 /*21 [程序 21 求阶乘] 2 题目:求 1+2!+3!+...+20!的和 3 程序分析:此程序只是把累加变成了累乘. 4 */ 5 6 /*分析 7 * 1.汲取上一题的教训,这么大的数 ...

  9. Sqlmap的基础用法(禁止用于非法用途,测试请自己搭建靶机)

    禁止用于非法用途,测试与学习请自己搭建靶机 sqlmap -r http.txt  #http.txt是我们抓取的http的请求包 sqlmap -r http.txt -p username  #指 ...

  10. upload-labs通关历程

    使用靶场前,先配置php版本为5.2,和下列对应配置. php.ini magic_quotes_gpc  Off php<5.3.4 httpd.conf AddType applicatio ...