上节讲解的数组可以看作是一行连续的数据,只有一个下标,称为一维数组。在实际问题中有很多数据是二维的或多维的,因此C语言允许构造多维数组。多维数组元素有多个下标,以确定它在数组中的位置。本节只介绍二维数组,多维数组可由二维数组类推而得到。

二维数组的定义

二维数组定义的一般形式是:

dataType arrayName[length1][length2];

其中,dataType 为数据类型,arrayName 为数组名,length1 为第一维下标的长度,length2 为第二维下标的长度。例如:

int a[3][4];

定义了一个3行4列的数组,共有3×4=12个元素,数组名为a,即:
a[0][0], a[0][1], a[0][2], a[0][3]
a[1][0], a[1][1], a[1][2], a[1][3]
a[2][0], a[2][1], a[2][2], a[2][3]

在二维数组中,要定位一个元素,必须给出一维下标和二维下标,就像在一个平面中确定一个点,要知道x坐标和y坐标。例如,a[3][4] 表示a数组第3行第4列的元素。

二维数组在概念上是二维的,但在内存中地址是连续的,也就是说各个元素是相互挨着的。那么,如何在线性内存中存放二维数组呢?有两种方式:一种是按行排列, 即放完一行之后再放入第二行。另一种是按列排列, 即放完一列之后再放入第二列。

在C语言中,二维数组是按行排列的。也就是先存放a[0]行,再存放a[1]行,最后存放a[2]行;每行中的四个元素也是依次存放。数组a为int类型,每个元素占用4个字节,整个数组共占用4×(3×4)=48个字节。

【示例】一个学习小组有5个人,每个人有三门课的考试成绩。求全组分科的平均成绩和各科总平均成绩。

-- Math C English
80 75 92
61 65 71
59 63 70
85 87 90
76 77 85

可设一个二维数组a[5][3]存放五个人三门课的成绩。再设一个一维数组v[3]存放所求得各分科平均成绩,设变量average 为全组各科总平均成绩。编程如下:

  1. #include <stdio.h>
  2. int main(){
  3. int i, j; //二维数组下标
  4. int sum=0; //当前科目的总成绩
  5. int average; //总平均分
  6. int v[3]; //各科平均分
  7. int a[5][3]; //用来保存每个同学各科成绩的二维数组
  8. printf("Input score:\n");
  9. for(i=0; i<3; i++){
  10. for(j=0; j<5; j++){
  11. scanf("%d", &a[j][i]); //输入每个同学的各科成绩
  12. sum+=a[j][i]; //计算当前科目的总成绩
  13. }
  14. v[i]=sum/5; // 当前科目的平均分
  15. sum=0;
  16. }
  17. average =(v[0]+v[1]+v[2])/3;
  18. printf("Math: %d\nC Languag: %d\nEnglish: %d\n", v[0], v[1], v[2]);
  19. printf("Total:%d\n", average);
  20. return 0;
  21. }

运行结果:
Input score:
80 61 59 85 76 75 65 63 87 77 92 71 70 90 85↙
Math: 72
C Languag: 73
English: 81
Total:75

程序使用了一个嵌套循环。在内循环中依次读入某一门课程的各个学生的成绩,并把这些成绩累加起来,退出内循环后再把该累加成绩除以5送入v[i]之中,这就是该门课程的平均成绩。外循环共循环三次,分别求出三门课各自的平均成绩并存放在v数组之中。退出外循环之后,把v[0]、v[1]、v[2]相加除以3即得到各科总平均成绩。最后按题意输出各个成绩。

二维数组的初始化

二维数组的初始化可以按行分段赋值,也可按行连续赋值。

例如对数组a[5][3],按行分段赋值可写为:

int a[5][3]={ {80,75,92}, {61,65,71}, {59,63,70}, {85,87,90}, {76,77,85} };

按行连续赋值可写为:

int a[5][3]={80, 75, 92, 61, 65, 71, 59, 63, 70, 85, 87, 90, 76, 77, 85};

这两种赋初值的结果是完全相同的。

【示例】求各科平均分和总成绩平均分。

  1. #include <stdio.h>
  2. int main(){
  3. int i, j; //二维数组下标
  4. int sum=0; //当前科目的总成绩
  5. int average; //总平均分
  6. int v[3]; //各科平均分
  7. int a[5][3]={ {80,75,92}, {61,65,71}, {59,63,70}, {85,87,90}, {76,77,85} };
  8. for(i=0; i<3; i++){
  9. for(j=0; j<5; j++){
  10. sum+=a[j][i]; //计算当前科目的总成绩
  11. }
  12. v[i]=sum/5; // 当前科目的平均分
  13. sum=0;
  14. }
  15. average =(v[0]+v[1]+v[2])/3;
  16. printf("Math: %d\nC Languag: %d\nEnglish: %d\n", v[0], v[1], v[2]);
  17. printf("Total:%d\n", average);
  18. return 0;
  19. }

运行结果:
Math: 72
C Languag: 73
English: 81
Total:75

对于二维数组初始化赋值还有以下说明

1) 可以只对部分元素赋初值,未赋初值的元素自动取0值。例如:

int a[3][3]={{1},{2},{3}};

是对每一行的第一列元素赋值,未赋值的元素取0值。 赋值后各元素的值为:
1  0  0
2  0  0
3  0  0

int a [3][3]={{0,1},{0,0,2},{3}};

赋值后的元素值为:
0  1  0
0  0  2
3  0  0

2) 如对全部元素赋初值,则第一维的长度可以不给出。例如:

int a[3][3]={1,2,3,4,5,6,7,8,9};

可以写为:

int a[][3]={1,2,3,4,5,6,7,8,9};

3) 二维数组可以看作是由一维数组嵌套而成的,把一维数组的每个元素看作一个数组,就组成了二维数组。当然,前提是各元素类型必须相同。根据这样的分析,一个二维数组也可以分解为多个一维数组,C语言允许这种分解。

如二维数组a[3][4],可分解为三个一维数组,其数组名分别为:a[0]、a[1]、a[2]。

对这三个一维数组不需另作说明即可使用。这三个一维数组都有4个元素,例如:一维数组a[0]的元素为a[0][0], a[0][1], a[0][2], a[0][3]。必须强调的是,a[0], a[1], a[2]不能当作下标变量使用,它们是数组名,不是一个单纯的下标变量。

C语言二维数组的更多相关文章

  1. c语言二维数组传递

    c语言二维数组传递,目前我总结三种方法,以及纠正一个不能使用的方法 /********************************* * 方法1: 第一维的长度可以不指定 * * 但必须指定第二维 ...

  2. 关于c语言二维数组与指针的个人理解及处理办法。

    相信大家在学习C语言时,对一维数组和指针的理解应该是自信的,但是,我在学习过程中,看到网上一些博文,发现即便是参加工作的一些专业编程人员,突然碰到二维数组和指针的问题时,也可能会遇到难以处理的诡异问题 ...

  3. C语言 二维数组复制、清零及打印显示

    #include <stdlib.h> #include <stdio.h> #include <string.h> //二维整型数组打印显示 ],int row, ...

  4. C语言二维数组作业

    一.PTA实验作业 题目1:7-3 出生年 1. 本题PTA提交列表 2. 设计思路 1.声明一个函数different()用来计算一个年份的不同数字个数 2.定义y(y是来计算符合要求的年份的量), ...

  5. C语言 二维数组(指针)动态分配和释放(转)

    C 二维数组(指针)动态分配和释放 先明确下概念: 所谓32位处理器就是一次只能处理32位,也就是4个字节的数据,而64位处理器一次就能处理64位,即8个字节的数据.如果我们将总长128位的指令分别按 ...

  6. C语言二维数组作为函数参数

    设有整型二维数组a[3][4]如下:0   1   2   34   5   6   78   9  10  11 它的定义为:    int a[3][4]={{0,1,2,3},{4,5,6,7} ...

  7. C语言二维数组作为函数的参数

    前言:今天在实现装配线调度程序时候,用到了二维数组,并将其作为函数的参数.在写程序的时候,遇到一些问题,即二维数组做函数的参数应该如何正确表示.我写程序的错误如下程序所示: #include < ...

  8. C语言二维数组实现扫雷游戏

    #include<stdio.h> //使用二维数组实现 扫雷 int main() { char ui[8][8]={ '+','+','+','+','+','+','+','+', ...

  9. c语言二维数组与指针

    问题,以下输出的结果是什么,区别在于哪? void main() { ][] = { ,,,,,,,,,,, }; //输出的3个地址都一样,差别在哪? printf("\n%x" ...

随机推荐

  1. 【LeetCode】33. Search in Rotated Sorted Array (4 solutions)

    Search in Rotated Sorted Array Suppose a sorted array is rotated at some pivot unknown to you before ...

  2. 乱码字符引起的JSON转换失败

        这种问题有两个解决办法,使用后不管你是什么特殊字符还是什么西欧字体还是什么稀奇古怪的内容都可以完美解决!   1.要把即将转换为json的内容先转换为unicode编码,json转换无误后,使 ...

  3. 常见URL字符及URL编码值

    大家上网的时候一定会看到很多这类情况有的网页地址都是%22%32%11%23%21等这种机器语言恐怕只有机器能马上辨认吧现在我把大概知道的总结一下 字符                         ...

  4. s:if 标签用法总结和举例

    http://www.360doc.com/content/11/1108/18/6161903_162838014.shtml

  5. cordova添加Splash

    最新版本的cordova添加Splash只需要改写config.xml 官方文档地址为:http://cordova.apache.org/docs/en/4.0.0/config_ref_image ...

  6. PHP垃圾回收机制引用计数器概念

    参考: http://www.phpddt.com/php/gc-refcounting-basics.html

  7. ios界面跳转

    import Foundationimport UIKit class MyViewController: UIViewController{ // var window: UIWindow? ove ...

  8. 插入节点appendChild()

    http://www.imooc.com/code/1698 插入节点appendChild() 在指定节点的最后一个子节点列表之后添加一个新的子节点. 语法: appendChild(newnode ...

  9. CSS——div居中,window.open(0

    margin:0 auto 表示什么意思?? margin后面如果只有两个参数的话,第一个表示top和bottom,第二个表示left和right因为0 auto,表示上下边界为0,左右则根据宽度自适 ...

  10. JavaScript中的闭包详解

    闭包是JavaScript的重要特性,非常强大,可用于执行复杂的计算,可并不容易理解,尤其是对之前从事面向对象编程的人来说,对 JavaScript 认识和编程显得更难.特别是在看一些开源的JavaS ...