文章教程

全国计算机等级考试二级C语言7.2二维数组的定义和引用

8/22/2020 10:24:52 PM 人评论 次浏览

7.2 二维数组的定义和引用

考点3 二维数组的定义及其元素的引用

1.二维数组的定义

在C语言中,二维数组中元素排列的顺序是:按行存放,即在内存中先按顺序存放第一行的元素,再存放第二行的元素。因此,二维数组元素的存储与一维数组元素存储相类似,总是占用一块连续的内存单元。

二维数组的一般形式为:

类型说明符 数组名[常量表达式][常量表达式];

例如:intc[3][4];

定义c为3 ×4(3行4列)的数组。注意:不能写成c[3,4]。C语言对二维数组采用这样的定义方式:可以把二维数组当作是一种特殊的一维数组。

例如,可以把c看成是一个一维数组,它有3个元素c[0]、c[1]、c[2],每个元素又是一个包含4个元素的一维数组。可以把c[0]、c[1]、c[2]看做是3个一维数组的名字。

真考链接

考点3偏难,属于重点理解重点掌握知识点。在选择题中的考核概率为90%。在操作题中,主要出现在编程题中,一般用于处理数据比较多的实际问题,考核概率为20%。

2.二维数组元素的引用

二维数组的表示形式为:

数组名[下标表达式1][下标表达式2]

数组的下标可以是整型表达式,如 c[3-1][3 ×2-2]。

数组元素可以出现在表达式中,也可以被赋值,如a[1][3] =b[3][2]/2。

小提示

定义数组时用的c[3][4]和引用元素时的c[3][4]的区别:前者用来定义数组的维数和各维的大小,共有3行4列;后者中的3和4是下标值,c[3][4]代表该数组中的一个元素。如果a[3][4]是二维数组中最后一个元素,那么该数组共有4行5列。

真题精选

【例1】有以下程序,最后输出的值为(  )。

main()

{ int a[4][4] = {{1,4,3,2},{8,6,5,7},{3,7,2,5},{4,8,6,1}},i,j,k,t;

for(i = 0;i <4;i++)

for(j = 0;j < 3;j++)

for(k = j+1;k <4;k++)

if(a[j][i] > a[k][i])

{t=a[j][i];a[j][i] =a[k][i];a[k][i] =t;}

for(i=0;i<4;i++)printf("% d,",a[i][i]);

A.1,6,5,7    B.8,7,3,1    C.4,7,5,2    D.1,6,2,1

【答案】A

【解析】本题用多重for循环的嵌套来实现对二维数组的按列排序。利用最外层循环来实现对列的控制。内部循环利用选择法对数组元素按照从小到大的顺序进行排列,最后输出对角线上的元素值。

【例2】若二维数组a有m列,则在a[i][j]之前的元素个数为(  )。

A.j*m+i    B.i*m+j    C.i*m+j-1    D.i*m+j+1

【答案】B

【解析】在C语言中,由于二维数组在内存中是按照行优先的顺序存储的(即先顺序存储第0行元素,再存第1行元素,依次类推),且下标的起始值为0,因此在a[i][j]之前的元素有i*m+j个。

【例3】以下程序的输出结果是(  )

#include <stdio.h>

main()

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

for(i=0;i<3;i++)

printf("% d,",x[i][2-i]);

}B.1,4,7,

A.1,5,9, C.3,5,7, D.3,6,9,

【答案】C

【解析】本题考查了二维数组的初始化赋值问题,读者需要清楚地了解在二维数组中逻辑存放结构的情况

【例4】以下不能正确定义二维数组的选项是(  )。

A.inta[2][2] ={{1},{2}};    B.inta[][2] ={1,2,3,4};

C.inta[2][2] ={{1},2,3};    D.inta[2][] ={{l,2},{3,4}};

【答案】D

【解析】C语言中明确规定,在定义二维数组时,后一个下标值不能省略,否则将无法判定数组中某一行的元素个数

【例5】请编写函数fun(),其功能是:找出2*M整型二维数组中最大元素的值,并将此值返回调用函数。

注意:部分源程序给出如下。

请勿改动主函数main()和其他函数中的任何内容,仅在函数fun()的花括号中填入你编写的若干语句。

试题程序

#define M 4

#include <stdio.h>

int fun(int a[][M])

void main()

{ int arr[2][M] ={5,8,3,45,76,-4,12,82};

printf("max=% d\n",fun(arr));

【答案】int fun(int a[ ][M])

{ int i,j,max=a[0][0];

for(i=0;i<2;i++)

for(j=0;j<M;j++)

if(max<a[i][j])

max=a[i][j];

return max;

【解析】本题要求数组的最大值,需要运用循环语句,因为数组是二维数值,所以应使用两层加for循环嵌套。使用for循环语句时需要注意循环变量的取值范围。

对于此类求最大值或最小值的问题,可以采用逐个比较的方式,要求对数组中所有元素遍历一遍,并且从中找出数组最大值或最小值。首先定义变量max存放在数组中的第一个元素的值,然后利用for循环逐个找出数组中的元素,并与max比较,如果元素值大于max,则将该值赋予max,循环结束后max的值即为数组最大值,最后将该值返回。

考点4 二维数组的初始化

真考链接

考点4 属于重点掌握知识点。尤其要注意数组下标是从0开始的,这一点在引用数组里的元素时要注意。对此知识点的考查主要以选择题的形式出现,考核概率为40%。

可以在定义二维数组的同时给二维数组的各元素赋初值。例如:

float m[2][2] ={{1.5,3.2},{0.8}};

全部初值放在一对花括号中,每一行的初值又分别括在一对花括号中,之间用逗号隔开。当某行一对花括号内的初值个数少于该行中元素的个数时,系统将自动地给后面的元素补初值0。同样,不能跳过每行前面的元素而给后面的元素赋初值。

数组是一种构造类型的数据。二维数组可以看做是由一维数组的嵌套而构成的。如果一维数组的每个元素又都是一个数组,就组成了二维数组(前提是各元素类型必须相同)。

由此也可以这样分析,一个二维数组也可以分解为多个一维数组。C语言允许这样分解二维数组,如a[3][4]可分解为3个一维数组,其数组名分别为a[0],a[1],a[2]。对这3个一维数组不需另做说明即可使用。这3个一维数组都有4个元素,一维数组a[0]的元素为a[0][0],a[0][1],a[0][2],a[0][3]。必须强调的是,a[0],a[1],a[2]不能当作下标变量使用,它们是数组名,不是一个单纯的下标变量。

对于一维数组,可以在数组定义语句中省略方括号中的常量表达式,通过所赋初值的个数来确定数组的大小;对于二维数组,只可以省略第一个方括号中的常量表达式,而不能省略第二个方括号中的常量表达式。例如:

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

a数组的第一维方括号中的常量表达式省略,在所赋初值中,含有4个花括号,则第一维的大小由花括号的个数来决定。因此,该数组其实是与a[4][3]等价的。当用以下形式赋初值时:

int c[][3] ={1,2,3,4,5};

第一维的大小按以下规则决定:

(1)当初值的个数能被第二维的常量表达式的值除尽时,所得商数就是第一维的大小。

(2)当初值的个数不能被第二维的常量表达式的值除尽时,则:

第一维的大小 =所得商数+1

因此,按此规则,以上c数组第一维的大小应该是2,也就是说语句等同于intc[2][3] ={1,2,3,4,5};。

小提示

如果一个二维数组的最后一个元素的下标是a[5][5],则说明此二维数组有6行6列。即要注意,数组的下标是从0开始的。

常见问题

在程序中定义一个数组用来存储数据,通常会给其所有元素赋初值为0,为什么?

如果定义了一个数据而未给其赋初值,系统会自动给其赋随机值,为了避免在运算中造成不必要的麻烦,通常给其赋初值,这也是一个良好的编程习惯。

真题精选

【例1】下面程序输出的结果是(  )。

main()

{ int i;

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

for(i=0;i<3;i++)

printf("% d ",a[2-i][i]);

A.159    B.753    C.357    D.591

【答案】B

【解析】本题用循环的方法考查对数组概念的掌握。首先,当i=0时,数组中的位置是a[2][0] =7,当然,如果用排除法,就不用考虑后面的循环,因为在4个选项中,第1个数为7的选项只有B。本题执行第2次循环时,i的值为1,则printf函数中的数组指向为a[1][1] =5,依次循环,可求出答案。

【例2】以下数组定义错误的是( )

A.intx[][3] ={0};    B.intx[2][3] ={{1,2}, {3,4}, {5,6}};

C.intx[][3] ={{1,2,3}, {4, ,5 6}};   D.intx[][3] ={1,2,3,4,5,6};

【答案】B

【例3】以下能正确定义数组并正确赋初值的选项是(  )

【解析】二维数组的初始化有以下几种形式:①分行进行初始化;②不分行的初始化;③部分数组元素初始化;④省略第一维的定义,不省略第二维的定义。选项B等号右边分了3行,大于等号左边数组的行数。

A.intN=5,b[N][N];    B.inta[1][2] ={{1},{3}};

C.intc[2][] ={{1,2},{3,4}};    D.intd[3][2] ={{1,2},{3,4}};

【答案】D

【解析】选项A中,数组的下标应为整型变量;选项B的行下标应为2;选项C的列下标不能省略

【例4】以下能对二维数组a进行正确初始化的选项是(  )

A.inta[2][] ={{1,0,1},{5,2,3}};    B.inta[][3] ={{1,2,3},{4,5,6}};

C.inta[2][4] ={{1,2,3},{4,5},{6}};    D.inta[][3] ={{1,0,1},{},{1,1}};

【答案】B

【解析】本题考查了对二维数组初始化的基本语法问题,读者需要清楚地了解初始化二维数组的基本格式

【例5】已知int类型的变量占4个字节有下面的程序段:

main()

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

printf("% d",sizeof(a));

则程序段的输出结果是( )。

A.12    B.24    C.48    D.64

【答案】C

【解析】程序通过赋初值的方式定义了4行3列的数组,则大小为12,而一个int变量占4个字节,所以程序输出48。

【例6】有以下程序:

main()

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

int i,j,k=2;

for(i=0;i<3;i++)

{printf("% d ",m[k][i]);}

执行后输出的结果是( )。

A.456    B.258    C.369    D.789

【答案】C

【解析】本题的功能是输出m[2][0],m[2][1]和m[2][2]。

【例7】下列给定程序中,函数fun()的功能是:求ss所指字符串数组中长度最短的字符串所在的行下标,作为函数值返回,并把其串长放在形参n所指的变量中。ss所指字符串数组中共有M个字符串,且串长小于N。请在标号处填入正确的内容,使程序得出正确的结果。

注意:部分源程序给出如下。不得增行或删行,也不得更改程序的结构。

试题程序

#include <stdio.h>

#include <string.h>

#define M 5

#define N 20

int fun(char(*ss)[N],int *n)

{ int i,k=0,len= N;

for(i=0;i<【1】;i++)

{ len=strlen(ss[i]);

if(i==0)*n=len;

if(len【2】*n){

*n=len;

k=i;

return(【3】);

main()

{ charss[M][N] ={"shanghai","guangzhou "," beijing "," tianjing ","chongqing"};

int n,k,i;

printf("\nThe original strings are:\n");

for(i=0;i<M;i++)puts(ss[i]);

k=fun(ss,&n);

printf(" \nThe length of shortest string is:% d\n",n);

printf("\nThe shortest string is:% s\n",ss[k]);

【答案】【1】M 【2】 < 【3】k

【解析】本题考查:for循环语句的循环条件;if语句条件表达式;return语句完成函数值的返回

标号【1】:题目指出ss所指字符串数组中共有M个字符串,所以for循环语句的循环条件是i<M。

标号【2】:要求长度最短的字符串,*n中存放的是已知字符串中长度最短的字符串的长度,这里将当前字符串长度与*n比较,若小于*n,则将该长度值赋给*n,因此,if语句的条件表达式为len<*n。

标号【3】:将最短字符串的行下标作为函数值返回,变量k存储行下标的值。

教程类别