C语言中二维数组的基本使用 定义 赋值读写指定元素的值 作为函数参数传递的注意点

25 篇文章 0 订阅

问题

  • 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* arrint 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
  • 4
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值