文章目录
- 问题
- 依次解决
- C语言中二维数组如何定义、如何一次性赋值?
- 如何使用 sizeof() 计算二维数组的行数、列数?【与定义数组的地方,在同一作用域内可用】
- 如何读写指定位置的元素?【不同作用域,有两种方式】
- 不同作用域内,如何遍历数组元素?
- 二维数组作为函数参数时,函数如何声明(参数列表如何写)?
- Code & Output
- Screenshot
- Code
- Output
问题
- C语言中二维数组如何定义、如何一次性赋值?
- 如何使用 sizeof 计算二维数组的行数、列数?【与定义数组的地方,在同一作用域内可用】
- 如何读写指定位置的元素?【不同作用域,有两种方式】
- 不同作用域内,如何遍历数组元素?
- 二维数组作为函数参数时,函数如何声明(参数列表如何写)?
依次解决
以下只给出最关键的几行代码。具体代码上下文可以在最后贴上的的代码全文中查看。
C语言中二维数组如何定义、如何一次性赋值?
int arr[3][4] = {
[0] = {1,2,3,4}, // “[1] = ”部分可以省略,省略则按代码书写顺序排序。
[1] = {5,6,7,8},
[2] = {9,10,11,12}
};
还有其他好几种赋值方式,但等你完全需要的时候再花时间去查找how to……。
如何使用 sizeof() 计算二维数组的行数、列数?【与定义数组的地方,在同一作用域内可用】
int row = sizeof(arr) / sizeof(arr[0]);
printf("row count: %lu / %lu = %d\n", sizeof(arr), sizeof(arr[0]), row);
int column = sizeof(arr[0]) / sizeof(arr[0][0]);
printf("column count: %lu / %lu = %d\n", sizeof(arr[0]), sizeof(arr[0][0]), column);
// row count: 48 / 16 = 3
// column count: 16 / 4 = 4
如何读写指定位置的元素?【不同作用域,有两种方式】
比如说,我在 main 函数内定义了数组,然后在 main 函数内 有以下代码:
// 同一作用域内,可以用 array[二维数组的行数][二维数组的列数] 读取/改写指定的元素值。
arr[1][2] = 555;
printf("%d\n", arr[1][2]); // 555
// 同一作用域内,不可以用 array[二维数组的第几行 * 每行数组的列数 + 当前列数] 方式读写指定元素
// arr[6] = 666; // Error: Array type 'int[4]' is not assignable
// printf("%d\n", arr[6]); // Warning: Array index 6 is past the end of the array (which contains 3 elements)
可如果我把二维数组作为函数参数传到另一个函数里,在该函数中该如何读区指定位置的元素呢?
反过来了:
在 main 函数/定义数组处,与数组定义在同一作用域内 | 在被调用函数内(拿到的数组名其实是一个指针变量) | |
---|---|---|
array[ 二维数组的行数][ 二维数组的列数] | 可用 | 不可用 |
array[ 二维数组的第几行 * 每行数组的列数 + 当前列数] | 不可用 | 可用 |
为什么二维数组中元素的定位除了 [行][列]
的定位方式,还可以用一个下标[index]
就定位?
再回到二维数组的定义写法,以下三种方式等效:
int arr[3][4] = { [0]={1,2,3,4}, [1]={5,6,7,8}, [2]={9,10,11,12} };
int arr[3][4] = { {1,2,3,4}, {5,6,7,8}, {9,10,11,12} };
int arr[3][4] = { 1,2,3,4, 5,6,7,8, 9,10,11,12 };
前两行也就是省略了[行号]=
。
而第三行是直接把嵌套的大括号{}省略
了,直接一层大括号按顺序赋值。
第三行的赋值方法可行,那我们拿array[通过行列号计算得出的下标]
读写二维数组可行不可行? 部分场景是可行的。
不同作用域内,如何遍历数组元素?
两种定位方式描述见上一条。
for (int i = 0; i < row; i++) {
for (int j = 0; j < column; j++) {
int value = arr[i][j];
printf("array[%d][%d] = %d\t\t", i, j, value);
}
printf("\n");
}
for (int i = 0; i < row; i++) {
for (int j = 0; j < column; j++) {
// int value = arr[i][j]; // Error: Subscripted value is not an array, pointer, or vector
int index = i * column + j;
int value = arr[index];
printf("arr[%d][%d]不可用,对应的arr[%d]= %d\t\t", i, j, index, value);
}
printf("\n");
}
二维数组作为函数参数时,函数如何声明(参数列表如何写)?
首先排除第一种int arr[][]
传递数组可以用int* arr
或int arr[]
两种方式。
因为是传递数组作为参数到另一个函数,在这个新函数内无法用 sizeof() 求出数组size及元素个数,所以函数参数列表中还需要调用方计算出行数、列数并传递
。
// void traversePrint(int arr[][]); // 方法声明直接报错: Array has incomplete element type 'int[]'
// void traversePrint(int* arr[]); // 方法声明倒是不直接报错,但是在方法内部没有办法读写指定元素。 arr[i][j] 报错: Thread 1: EXC_BAD_ACCESS (code=1, address=0x400000003)
void traversePrint(int* arr, int row, int column);
void traversePrint(int arr[], int row, int column);
Code & Output
Screenshot
Code
//
// main.c
// 012911am-二维数组
//
// Created by wuyujin1997 on 2023/1/29.
//
#include <stdio.h>
/// 接收二维数组变量,遍历该数组并依次打印各个元素
/// - Parameters:
/// - arr: 数组变量(本质上也是一个指向了自己的指针变量)
/// - row: 二维数组的行数(需要调用者传至本函数)
/// - column: 二维数组的列数
//void traversePrint(int arr[][]) { // Error: Array has incomplete element type 'int[]'
//void traversePrint(int* arr, int row, int column) {
void traversePrint(int arr[], int row, int column) {
// 在本函数作用域内,无法通过 arr 求出其 size 和长度。
for (int i = 0; i < row; i++) {
for (int j = 0; j < column; j++) {
// int value = arr[i][j]; // Error: Subscripted value is not an array, pointer, or vector
int index = i * column + j;
int value = arr[index];
printf("arr[%d][%d]不可用,对应的arr[%d]= %d\t\t", i, j, index, value);
}
printf("\n");
}
// 试一下能否用 array[二维数组的第几行 * 每行数组的列数 + 当前列数] 直接读写指定的元素
arr[6] = 123456;
printf("%d\n", arr[6]);
}
int main(int argc, const char * argv[]) {
// 定义二维数组
int arr[3][4] = {
[0] = {1,2,3,4}, // “[1] = ”部分可以省略,省略则按代码书写顺序排序。
[1] = {5,6,7,8},
[2] = {9,10,11,12}
};
// 同一作用域内,可以用 array[二维数组的行数][二维数组的列数] 读取/改写指定的元素值。
arr[1][2] = 555;
printf("通过 array[行号][列号]直接读写某个元素的值: %d\n", arr[1][2]);
// 同一作用域内,不可以用 array[二维数组的第几行 * 每行数组的列数 + 当前列数] 方式读写指定元素
// arr[6] = 666; // Error: Array type 'int[4]' is not assignable
// printf("%d\n", arr[6]); // Warning: Array index 6 is past the end of the array (which contains 3 elements)
// 计算二维数组的行数、列数
int row = sizeof(arr) / sizeof(arr[0]);
printf("row count: %lu / %lu = %d\n", sizeof(arr), sizeof(arr[0]), row);
int column = sizeof(arr[0]) / sizeof(arr[0][0]);
printf("column count: %lu / %lu = %d\n", sizeof(arr[0]), sizeof(arr[0][0]), column);
// 遍历二维数组
for (int i = 0; i < row; i++) {
for (int j = 0; j < column; j++) {
int value = arr[i][j];
printf("array[%d][%d] = %d\t\t", i, j, value);
}
printf("\n");
}
traversePrint(arr, row, column);
return 0;
}
Output
通过 array[行号][列号]直接读写某个元素的值: 555
row count: 48 / 16 = 3
column count: 16 / 4 = 4
array[0][0] = 1 array[0][1] = 2 array[0][2] = 3 array[0][3] = 4
array[1][0] = 5 array[1][1] = 6 array[1][2] = 555 array[1][3] = 8
array[2][0] = 9 array[2][1] = 10 array[2][2] = 11 array[2][3] = 12
arr[0][0]不可用,对应的arr[0]= 1 arr[0][1]不可用,对应的arr[1]= 2 arr[0][2]不可用,对应的arr[2]= 3 arr[0][3]不可用,对应的arr[3]= 4
arr[1][0]不可用,对应的arr[4]= 5 arr[1][1]不可用,对应的arr[5]= 6 arr[1][2]不可用,对应的arr[6]= 555 arr[1][3]不可用,对应的arr[7]= 8
arr[2][0]不可用,对应的arr[8]= 9 arr[2][1]不可用,对应的arr[9]= 10 arr[2][2]不可用,对应的arr[10]= 11 arr[2][3]不可用,对应的arr[11]= 12
123456
Program ended with exit code: 0