C语言二维数组知识点详解与练习

回顾一维数组

在C语言中,声明1维数组需要指定数组的类型、名称、和长度。

int arr[3];

问题来了:我们如果需要动态开辟数组的内存单元如何做?







请在上面填空。

声明二维数组

在C语言中,声明二维数组需要指定数组的类型、名称、行数和列数。

int arr[3][4];

在声明数组时,也可以对数组进行初始化:

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

二维数组在内存中是按行优先顺序存储的,这意味着第一行的元素存储在连续的内存位置,然后是第二行,依此类推。

访问二维数组元素

可以使用两个下标运算符[]来访问二维数组中的元素。第一个下标表示行数,第二个下标表示列数。

例如,要访问二维数组arr中的第2行第3列的元素,可以写成:

int element = arr[1][2];

需要注意的是,数组下标是从0开始计数的,所以:

  • 第一行下标为0
  • 第二行下标为1
  • 第三行下标为2
  • 以此类推...

同样地,列下标也是从0开始计数。

遍历二维数组

可以使用嵌套的循环来遍历二维数组中的所有元素。外层循环用于遍历行,内层循环用于遍历列。

例如,下面的代码遍历二维数组arr并打印每个元素:

for(int i = 0; i < 3; i++) {
  for(int j = 0; j < 4; j++) {
    printf("%d ", arr[i][j]);
  }
  printf("\n");
}

这段代码将输出:

1 2 3 4
5 6 7 8
9 10 11 12

数组作为函数参数

可以将二维数组作为函数的参数传递。在函数中访问二维数组元素时,可以使用和普通数组一样的方式。

例如,下面的代码定义了一个函数,用于计算二维数组中所有元素的和:

int sum(int arr[][4], int rows, int cols) {
  int s = 0;
  for(int i = 0; i < rows; i++) {
    for(int j = 0; j < cols; j++) {
      s += arr[i][j];
    }
  }
  return s;
}

在调用函数时,可以直接传递二维数组名、行数和列数:

int total = sum(arr, 3, 4);

注意事项

在使用二维数组时需要注意以下几点:

  1. 确保不越界,否则会出现意料之外的结果或程序崩溃。
  2. C语言中的二维数组是定长的,一旦声明后大小就固定了,无法动态改变。
  3. 如果需要动态大小的二维数组,可以使用动态内存分配来创建和管理。
  4. 二维数组作为函数返回值时,要声明一个返回二维数组的函数,需要使用双重指针。

例如,下面的代码定义了一个函数,返回包含3行4列的二维数组:

int** createMatrix(int rows, int cols) {
  int** matrix = (int**)malloc(rows * sizeof(int*));
  for(int i = 0; i < rows; i++) {
    matrix[i] = (int*)malloc(cols * sizeof(int));
  }
  return matrix;
}

练习题

1. 以下程序中调用scanf函数给变量a输入数值的方法是错误的,其错误原因是:
int main() {
    int *p, *q, a, b;
    p = &a;
    printf("input a:");
    scanf("%d", *p);
    ......
}
  • A. *p表示的是变量a的值,而不是变量a的地址
  • B. *p表示的是指针变量p的地址
  • C. *p表示的是指针变量p的值
  • D. *p只能用来说明p是一个指针变量
2. 若有定义"int a[4][5]",则下列选项中能正确引用二维数组a的是:
  • A. a[2+3]
  • B. a[4][1]
  • C. a(2)(3)
  • D. a[2][3]