📜  数组练习题

📅  最后修改于: 2021-09-27 06:21:22             🧑  作者: Mango

在本文中,我们将讨论与数组相关的一些重要概念以及基于此的问题。在理解这一点之前,您应该对数组有基本的了解。

类型 1. 基于数组声明 –
这些是数组声明的几个关键点:

  • 一维数组可以声明为 int a[10] 或 int a[] = {1, 2, 3, 4}。这意味着在一维数组中指定元素的数量是可选的。
  • 二维数组可以声明为 int a[2][4] 或 int a[][4] = {1, 2, 3, 4, 5, 6, 7, 8}。这意味着指定行数是可选的,但列数是强制性的。
  • 如果打印, int a[4] 的声明会将值作为垃圾提供。但是, int a[4] = {1,1} 会将剩余的两个元素初始化为 0。

Que – 1.预测以下程序的输出

int main()
{
    int i;
    int arr[5] = {1};
    for (i = 0; i < 5; i++)
        printf("%d ", arr[i]);
    return 0;
}

(A) 1 后跟四个垃圾值:
(乙) 1 0 0 0 0
(C) 1 1 1 1 1
(D) 0 0 0 0 0

解决方案:如前所述,如果数组用很少的元素初始化,剩余的元素将被初始化为 0。因此,将打印 1 后跟 0, 0, 0, 0。

Que – 2.预测以下程序的输出:

int main()
{
    int a[][] = {{1,2},{3,4}};
    int i, j;
    for (i = 0; i < 2; i++)
        for (j = 0; j < 2; j++)
            printf("%d ", a[i][j]);
    return 0;
}

(一) 1 2 3 4
(B) 编译器错误“int a[][] = {{1,2},{3,4}};”
(C) 4个垃圾值
(四) 4 3 2 1

解决方案:如前所述,指定二维数组中的列数是强制性的,因此,它会给出编译时错误。

类型 2. 查找具有给定基地址的元素的地址 –
声明数组时,会为其分配一个连续的内存块,这有助于从基址查找元素的地址。

对于一维数组a[100],可以找到第i个元素的地址为:

addr(a[i]) =  BA+ i*SIZE

其中 BA 表示基地址(第 0 个元素的地址),SIZE 表示数组中每个元素的大小。

对于二维数组 x[3][3],元素可以表示为:

55

由于二维数组在 C 语言中是按行主顺序存储的,因此将首先存储第 0 行,然后是第 1 行和第 2 行。为了找到 x[2][2] 的地址,我们需要转到第 2 行(每行有 3 个元素)。到达第 2 行后,它可以作为一维数组访问。因此,我们需要转到数组的第二个元素。假设 BA 为 0,大小为 1,x[2][2] 的地址将为 0 + (2 * 3 + 2) * 1 = 8。

对于具有 m 行和 n 列的给定数组,地址可以计算为:

add(a[i][j]) = BA + (i*n + j) * SIZE

其中 BA 表示基地址(第 0 个元素的地址),n 表示二维数组中的列数,SIZE 表示数组中每个元素的大小。

Que – 3.考虑以下 C 中“二维数组”的声明:

char a[100][100];

假设主内存是字节寻址的,并且数组从内存地址 0 开始存储,a[40][50] 的地址是:(GATE CS 2002)
(一) 4040
(乙) 4050
(三) 5040
(三) 5050

解决方案:使用所讨论的公式,

addr[40][50] = 0 + (40*100 + 50) * 1 = 4050

Que – 4.对于访问 X[i][j][k] 的 C 程序,以下中间代码由编译器生成。假设整数的大小为 32 位,字符的大小为 8 位。 (GATE-CS-2014)

t0 = i * 1024
t1= j * 32
t2 = k * 4
t3 =t1 + t0
t4 = t3 + t2
t5 = X[t4]

下列关于 C 程序源代码的说法中哪一项是正确的?
(A) X 被声明为“int X[32][32][8]”
(B) X 被声明为“int X[4][1024][32]”
(C) X 被声明为“char X[4][32][8]”
(D) X 被声明为“char X[32][16][2]”

解:对于一个三维数组 X[10][20][30],我们有 10 个大小为 [20]*[30] 的二维矩阵。因此,对于一个 3D 数组 X[M][N][O],X[i][j][k] 的地址可以计算为:

BA + (i*N*O+j*O+k)*SIZE

给定不同的表达式,t5 的最终值可以计算为:

t5 = X[t4] = X[t3+t2] = X[t1+t0+t2] = X[i*1024+j*32+k*4]

通过等同地址,

(i*N*O+j*O+k)SIZE = i*1024+j*32+k*4 = (i*256+j*8+k)4

比较 i、j 和 SIZE 的值,我们得到

SIZE = 4, N*O = 256 and O = 8, hence, N = 32

由于大小为 4,因此数组将为整数。将 N 和 O 的值与数组匹配为整数的选项是 (A)。

类型 3. 使用指针访问数组元素 –

  • 在一维数组 a[100] 中,元素 a[i] 可以作为 a[i] 或 *(a+i) 或 *(i+a) 访问
  • a[i] 的地址可以作为 &a[i] 或 (a+i) 或 (i+a) 访问
  • 在二维数组 a[100][100] 中,元素 a[i][j] 可以作为 a[i][j] 或 *(*(a+i)+j) 或 *(a[i] ]+j)
  • a[i][j] 的地址可以作为 &a[i][j] 或 a[i]+j 或 *(a+i)+j 访问
  • 在二维数组中,第 i 行的地址可以作为 a[i] 或 *(a+i) 访问

Que – 5.假设以下 C 变量声明

int *A [10], B[10][10];  

以下表达式中

I. A[2]
II. A[2][3]
III. B[1]
IV. B[2][3]

如果在 C 程序 (GATE CS 2003) 中用作赋值语句的左侧,它不会产生编译时错误?
(A) 仅 I、II 和 IV
(B) 仅限 II、III 和 IV
(C) 仅 II 和 IV
(D) 仅 IV

解决方案:正如问题中给出的,A 是一个包含 10 个指针的数组,B 是一个二维数组。考虑到这一点,我们举一个例子:

int *A[10], B[10][10];
int C[] ={1, 2, 3, 4, 5};

由于 A[2] 代表一个整数指针,所以它可以存储整数数组的地址为: A[2] = C;因此,我是有效的。

由于 A[2] 表示 C 的基地址,因此 A[2][3] 可以修改为: A[2][3] = *(C +3) = 0;它会将 C[3] 的值更改为 0。因此,II 也是有效的。

由于B是二维数组,B[2][3]可以修改为:B[2][3] = 5;它会将 B[2][3] 的值更改为 5。因此,IV 也是有效的。

由于 B 是二维数组,B[2] 表示第 2 行的地址,不能在语句的 LHS 处使用,因为修改地址无效。因此III无效。