林鹿可爱 发表于 2019-2-11 22:55:39

关于二维数组的定义题

请问这题能不能给下详细解释

人造人 发表于 2019-2-11 23:20:25

本帖最后由 人造人 于 2019-3-16 18:00 编辑

a、c、d 编译报错
b 能通过编译

灰色的天空 发表于 2019-2-12 00:21:23

A编译时就会报错,因为第二个里面没有数字,无法分配空间;B正确。可以根据给的数字,系统会自动计算出第一个【】里面的数字。C越界了,初始化编译时就会报错。D我感觉其实也没毛病。

BngThea 发表于 2019-2-12 09:52:46

我选C

行客 发表于 2019-2-12 18:59:41

首先,为了便于下面的理解,我们首先来接受一个概念:
二维数组的初始化可以按行分段赋值,也可按行连续赋值。之所以可以这样操作,是因为:二维数组在概念上是二维的,但在内存中是连续存放的;换句话说,二维数组的各个元素是相互挨着的,彼此之间没有缝隙。那么,如何在线性内存中存放二维数组呢?在C语言中,二维数组是按行排列的。比如对于int a;也就是先存放 a 行,再存放 a 行,再存放 a 行,再存放 a 行,最后粗放a行;每行中的 3 个元素也是依次存放。数组 a 为 int 类型,每个元素占用 4 个字节,整个数组共占用 4×(5×3)=60 个字节。
具体我们来看一个例子,对于数组 a,按行分段赋值应该写作:
int a={ {1,2,3}, {4,5,6}, {7,8,9}, {10,11,12}, {13,14,15} };
而按行连续赋值可以写作:
int a={1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
这两种赋初值的结果是完全相同的。

那么好,上面我们重点说到了两个概念,一个是二维数组元素是连续存放的;另一个是二维数组是按行排列的。那么我们接下来再看三个概念:

1) 可以只对部分元素赋值,未赋值的元素自动取“零”值。例如:
int a = {{1}, {2}, {3}};
是对每一行的第一列元素赋值,未赋值的元素的值为 0。赋值后各元素的值为:
100
200
300

再如:
int a = {{0,1}, {0,0,2}, {3}};
赋值后各元素的值为:
010
002
300

2) 如果对全部元素赋值,那么第一维的长度可以不给出。例如:
int a = {1, 2, 3, 4, 5, 6, 7, 8, 9};
可以写为:
int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};

3) 二维数组可以看作是由一维数组嵌套而成的;如果一个数组的每个元素又是一个数组,那么它就是二维数组。当然,前提是各个元素的类型必须相同。根据这样的分析,一个二维数组也可以分解为多个一维数组,C语言允许这种分解。
例如,二维数组a可分解为三个一维数组,它们的数组名分别为 a、a、a。
这三个一维数组可以直接拿来使用。这三个一维数组都有 4 个元素,比如,一维数组 a 的元素为 a、a、a、a。

其实,我们从编译器的角度,对上面的规则很好理解:
我们之所以可以省略二维数组定义的一维指定(就是可以定义为int a[] ),是因为我们在初始化时,第一维的长度[]是可以直接通过初始化确定的;但是作为第二维的长度,因为有了3这个长度,所以在赋值时可以“只对部分元素赋值,未赋值的元素自动取“零”值”。

你完全可以把这个作为一种规则来记住:
二维数组第一维长度可以省略后通过初始化来确定;第二维长度需要指定,同时可以对第二维只对部分元素赋值,未赋值的元素自动取“零”。

行客 发表于 2019-2-12 19:00:37

看了上面的分析,你就会理解,为什么答案为B。
页: [1]
查看完整版本: 关于二维数组的定义题