二维数组做形参写法

传递二维数组

固定行列,直接传递地址

#include <stdio.h>
#include <stdlib.h>



void Print(int array[3][3])
{
    printf("\n");

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

    printf("\n");
}





int main()
{
    int a[3][3]={0};


    for(int i=0; i<3; i++)
        for(int j=0; j<3; j++)
        {
            scanf("%d",&a[i][j]);
        }

    Print(a);
    return 0;
}

在这里插入图片描述



定义指针数组

#include <stdio.h>
#include <stdlib.h>



void Print(int** array, int n, int m)
{
    printf("\n");

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

    printf("\n");
}




int main()
{
    int rows = 3;
    int cols = 3;
    int** numbers = new int*[rows];

    for(int i=0; i<rows; i++)
    {
	numbers[i] = new int[cols];
	for(int j=0; j<3; j++)
	{
	    numbers[i][j] = i*cols+j+1;
	}
    }
    Print(numbers, 3, 3);
    return 0;
}




传递首地址,给出行、列

#include <stdio.h>
#include <stdlib.h>



void Print(int* array, int n, int m)
{
    printf("\n");

    for(int i=0;i<n;i++)
    {
        for(int j=0; j<m; j++)
        {
            printf("%d ",*(array+i*m+j));
        }
        printf("\n");
    }

    printf("\n");
}




int main()
{
    int a[3][3]={0};


    for(int i=0; i<3; i++)
    {
        for(int j=0; j<3; j++)
        {
            scanf("%d",&a[i][j]);
        }
	}
    Print(*a, 3, 3);
    return 0;
}

在这里插入图片描述



注意:当定义一个[100]100]的二维数组,但是只用了其中的左上角[10][10],将二维数组地址作为参数传递给函数的时候,在函数形参中,定义参数列表的时候(比如以上两种方法),一定要已[100][100]定义,不能以[10][10]定义,由于地址的连续性([100][100]中存了的数据是不连续的)会导致访问数据错误。

<think>好的,我现在需要帮助用户解决如何在C语言中通过形参传递二维数组的问题。用户之前遇到了关于数组类型不完整的错误,现在转向二维数组作为函数参数的问题。我需要结合用户提供的引用资料和之前的回答来给出准确的解决方案。 首先,用户提供的引用中提到了几种方法:传递数组指针、指针数组,以及关于二维数组形参退化的内容。之前的回答中,用户已经了解了FILE指针数组的错误,可能现在需要扩展到更一般的二维数组传递问题。 我需要确定用户的问题核心:如何在函数声明中正确接收二维数组作为参数,并避免类型不匹配的错误。根据引用资料,C语言中二维数组作为形参传递有几种方式,包括使用数组指针、指定列数,或者使用二级指针动态分配的情况。 用户可能混淆了二维数组和二级指针,因为引用3提到二维数组与二级指针无关,特别是在栈分配的情况下。因此,需要明确区分栈分配的二维数组和堆分配的情况,因为它们的传递方式不同。 根据引用2和引用5,当传递栈上的二维数组时,必须指定列数,否则编译器无法计算元素地址。这应该作为重点之一。同时,动态分配的二维数组(比如使用malloc)可以使用二级指针传递,但需要正确分配内存。 另外,用户之前的回答中提到了数组声明不规范的问题,这里也可能相关。比如,声明函数参数时,如果使用int**,而实际传递的是int[][n],会导致类型不匹配,如引用1中的例子。 因此,我需要整理出几种方法,并给出示例代码,说明每种方法的适用场景和注意事项。需要强调栈分配和堆分配二维数组的不同处理方式,避免用户混淆。 可能还需要解释为什么二维数组作为参数传递时需要指定列数,涉及数组在内存中的布局和地址计算,如引用5提到的COLNUM的必要性。 最后,用户可能需要知道如何选择合适的方法,比如固定列数时用数组指针,动态分配时用二级指针,或者使用一维数组模拟二维数组,以增加灵活性。 需要确保回答结构清晰,步骤明确,并包含代码示例,帮助用户理解和应用。同时,相关问题可以引导用户进一步学习相关主题,如动态内存分配、数组与指针的关系等。</think>### 在C语言中通过形参传递二维数组的完整指南 #### 一、核心原理 二维数组在内存中按行优先顺序存储,传递时需要明确**列维度信息**以便计算元素地址[^5]。形参传递的本质是通过指针访问连续内存空间,根据数组分配方式(栈/堆)选择不同传递方式[^3]。 --- #### 二、栈分配的二维数组(静态数组) 需显式指定列维度,三种等价声明方式: ```c // 方式1:完整维度声明 void func(int arr[3][5]) { printf("%d", arr[2][4]); } // 方式2:省略行维度 void func(int arr[][5]) { printf("%d", arr[1][3]); } // 方式3:数组指针形式(推荐) void func(int (*arr)[5]) { printf("%d", arr[0][2]); } ``` **调用示例**: ```c int main() { int a[3][5] = {{1,2,3,4,5}, {6,7,8,9,10}}; func(a); // 正确传递二维数组首地址 return 0; } ``` **关键限制**:必须已知列维度(第二维长度) --- #### 三、堆分配的二维数组(动态数组) 使用二级指针+单独分配每行内存: ```c // 参数使用int**接收 void dynamic_func(int **arr, int rows, int cols) { for(int i=0; i<rows; i++) { for(int j=0; j<cols; j++) { printf("%d ", arr[i][j]); } } } int main() { // 动态分配示例 int rows = 3, cols = 4; int **arr = malloc(rows * sizeof(int*)); for(int i=0; i<rows; i++) { arr[i] = malloc(cols * sizeof(int)); } dynamic_func(arr, rows, cols); // 正确传递动态数组 return 0; } ``` --- #### 四、特殊技巧:一维数组模拟 通过行优先展开成一维数组: ```c void flat_array_func(int *arr, int rows, int cols) { for(int i=0; i<rows; i++) { for(int j=0; j<cols; j++) { printf("%d ", arr[i*cols + j]); // 手动计算二维索引 } } } int main() { int a[3][5] = {{1,2,3,4,5}}; flat_array_func(&a[0][0], 3, 5); // 取首元素地址传递 return 0; } ``` --- #### 五、常见错误对照表 | 错误写法 | 正确写法 | 错误原因 | |---------|----------|---------| | `void func(int **arr)` | `void func(int (*arr)[5])` | 类型不匹配[^1] | | `int arr[][]` | `int arr[][5]` | 缺少列维度信息[^5] | | `arr[i][j]`(动态数组) | `*((int*)arr + i*cols +j)` | 动态数组行不连续 | --- #### 六、选择依据流程图 ```mermaid graph TD A[需要传递二维数组] --> B{数组分配方式?} B -->|栈分配| C[必须指定列维度] B -->|堆分配| D[使用二级指针] C --> E[选择固定列维度写法] D --> F[需配合行列参数传递] ``` --- #### 七、典型应用场景 1. **图像处理**:传递`unsigned char img[HEIGHT][WIDTH]` 2. **矩阵运算**:动态分配`double **matrix` 3. **游戏地图**:使用一维数组模拟`int map[ROWS*COLS]` ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值