2019-02-28 计算机二级C语言程序设计之数组(下)

参考资料:
高教版《全国计算机等级考试二级教程——C语言程序设计》
《21天学通C语言》

二维数组的定义和二维数组元素的引用

二维数组的定义

当数组中的每个元素带有两个下标时,称这样的数组为二维数组

二维数组的定义语句如下:

类型名 数组名[常量表达式1][常量表达式2];

例如,有以下定义:

int a[3][4];

在这里,int是类型名,a[3][4]是一个二维数组说明符。可以认为此定义语句说明了:

  • 定义了一个名为a的二维数组
  • a数组中每个元素都是整型
  • a数组中共有3×4个元素
  • a数组的逻辑结构是一个3行4列的矩阵

二维数组中,每个元素有两个下标,第一个方括号中的下标代表行号,称行下标;第二个方括号中的下标代表列号,称列下标。行下标和列下标的下限总为0。

a数组中的元素在内存中占一系列的存储单元。数组元素在内存中的排列顺序为:先存放第0行的元素,再存放第1行的元素,以此类推。这种存放顺序称为“按行存放”。所以,在C语言中,可以把一个二维数组看成是一个一维数组,每个数组元素又是包含有若干个元素的一维数组。

二维数组元素的引用

引用二维数组时必须带有两个下标。引用形式如下:

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

例如,有以下定义:

double w[4][2];

则以下都是合法的数组元素引用形式:

w[0][1]
w[i][j]
w[i + k][j + k]

注意:每个下标表达式的值必须是整数,且不得超越数组定义中的上、下界。

二维数组的初始化

所赋初值的个数与数组元素的个数相同

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

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

全部初值括在一对花括号中,每一行的初值又分别括在一对花括号中,之间用逗号隔开。

每行所赋初值个数与数组元素的个数不同

当某行一对花括号内的初值个数少于该行中元素的个数时,例如:

int a[4][3] = {{1, 2}, {4, 5}, {7}, {10}};

系统将自动给该行后面的元素补初值0。

所赋初值行数少于数组行数

当代表给每行赋初值的行花括号对少于数组的行数时,例如:

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

系统将自动给后面各行的元素补初值0。

赋初值时省略行花括号对

在给二维数组赋初值时可以不用行花括号对,例如:

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

赋值后结果如下:

a[0][0]中储存的是1

a[0][1]中储存的是2

a[0][2]中储存的是3

a[1][0]中储存的是4

a[1][1]中储存的是5

a[1][2]中储存的是6

a[2][0]中储存的是7

a[2][1]中储存的是8

a[2][2]中储存的是9

a[3][0]中储存的是10

a[3][1]中储存的是11

a[3][2]中储存的是12

通过赋初值定义二维数组的大小

对于二维数组,只可以省略第一个方括号中的常量表达式,而不能省略第二个方括号中的常量表达式。例如:

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

在所赋初值中,第一维的大小由所赋初值的行数来决定。

当用这种形式赋初值时:

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

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

  1. 当初值个数能被第二位的常量表达式的值除尽时,所得商数就是第一维的大小。
  2. 当初值的个数不能被第二位的常量表达式的值除尽时,则第一位的大小等于所得商数加一。

二维数组和指针

二维数组元素的地址

先给出以下定义:

int *p, a[3][4];

二维数组a由若干个一维数组组成

在C语言中定义的二维数组实际上是一个一维数组,这个一维数组的每个元素又是一个一维数组。

如以上二维数组,可以将数组a看作由a[0],a[1],a[2]三个元素组成,而a[0],a[1],a[2]中每个元素又是由四个整形元素组成的一维数组。a[0],a[1],a[2]都是一维数组名,同样也代表一个不可变的地址常量,其值依次为二维数组每行第一个元素的地址,其基类型就是数组元素的类型。

二维数组名也是一个地址值变量

二维数组名同样也是一个存放地址常量的指针,其值为二维数组中第一个元素的地址。

a[0],a[1],a[2]的值分别表示a数组中第一、第二、第三行的首地址。

二维数组名应理解为一个行指针,在表达式a+1中,数值1的单位应当是4×2个字节,而不是2个字节。

对于二维数组名a,不可以进行a++,a=a+i等操作。

二维数组元素的地址

二维数组元素的地址可以由表达式&a[i][j]求得,也可以通过每行的首地址来表示。

若0≤i<3,0≤j<4,则a[i][j]的地址可以用以下五种表达式求得:

  1. &a[i][j]
  2. a[i]+j
  3. *(a+i)+j
  4. &a[0][0]+4 * i+j
  5. a[0]+4 * i+j

通过地址引用二维数组元素

若有以下定义:

int a[3][4], i, j;

并且0≤i<3,0≤j<4,则a数组元素可用以下表达式来引用:

  1. a[i][j]
  2. *(a[i]+j)
  3. *(*(a+i)+j)
  4. (*(a+i))[j]
  5. *(&a[0][0]+4 * i+j)

通过建立一个指针数组引用二维数组元素

若有以下定义:

int *p[3], a[3][2], i, j;

在这里,说明符*p[3]说明了p是一个数组名,系统将为它开辟3个连续的存储单元;*号说明了数组p是指针类型,它的每个元素都是基类型为int的指针。

若满足条件0≤i<3,则p[i]和a[i]的基类型相同,p[i]=a[i]是合法的表达式。

通过建立一个行指针引用二维数组元素

若有以下定义:

int a[3][2], (*prt)[2];

说明符(*prt)[2]说明了指针变量prt的基类型是一个包含有两个int元素的数组。

在这里,prt的基类型与a相同,因此prt = a是合法的赋值语句,prt+1等于a+1,等价于a[1]。

二维数组名和指针数组作为实参

二维数组名作为实参时实参和形参之间的数据传递

当二维数组名作为实参时,对应的形参必须是一个行指针变量。

例如,若有以下定义语句和调用语句:

#include <stdio.h>
#define M 5
#define N 3

int main (void)
{
    double s[M][N];
    //部分代码省略
    fun(s);
    //部分代码省略
}

则fun函数的首部可以是以下三种形式之一:

fun(double (*a)[N])
fun(double a[][N])
fun(double a[M][N])

注意:列下标不可缺。

指针数组作为实参时实参和形参之间的数据传递

当指针数组名作为实参时,对应的形参应当是一个指向指针的指针。

例如,若有以下定义语句和调用语句:

#include <stdio.h>
#define M 5
#define N 3

int main (void)
{
    double s[M][N], *ps[M];
    //部分代码省略
    fun(ps);
    //部分代码省略
}

则fun函数的首部可以是以下三种形式之一:

fun(double *a[M])
fun(double *a[])
fun(double **a)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,084评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,623评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,450评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,322评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,370评论 6 390
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,274评论 1 300
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,126评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,980评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,414评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,599评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,773评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,470评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,080评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,713评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,852评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,865评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,689评论 2 354