You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言2D数组指针函数传参原理及代码疑问求助

二维数组传入函数的访问逻辑解析

原代码第7行的工作原理

你的代码里,print函数的参数arr被声明为int *类型——这相当于把二维数组当成连续的一维内存块来处理。C语言中,二维数组在内存里是按行连续存储的,比如你的arr在内存中的布局是:1,2,3,4,5,6,7,8,9,没有间隙。

第7行的*((arr+i*n) + j)可以拆成两步理解:

  1. arr+i*n:计算第i行的起始地址。因为每行有n个int元素,所以跳过前i行的i*n个int,得到第i行第一个元素的指针。
  2. +j:在第i行的基础上,再往后移动j个int,指向第i行第j列的元素。
  3. 外层的*解引用这个指针,拿到对应位置的数值。

这种写法本质是手动模拟了二维数组的内存寻址,把二维结构转换成一维指针来操作。

*( *(p + i) + j)失效的原因

*( *(p + i) + j)是**针对二维数组指针(指向一维数组的指针)**的标准访问写法,但你的print函数参数是int *,不是这种类型,所以会出错:

  1. 当p是int *类型时,p+i的含义是:指针向后移动i个int的位置(偏移量为i*sizeof(int)),而不是移动i行。
  2. 此时*(p+i)得到的是一个int值(不是指向一维数组的指针),你再对这个int值做+j的指针运算,属于非法操作——C语言不允许把普通整数当成指针来使用,编译器会报错或者运行时崩溃。

如果想使用*( *(p + i) + j)的写法,需要把函数参数改成指向一维数组的指针,示例如下:

#include <stdio.h>
// 参数是指向包含3个int的数组的指针
void print(int (*arr)[3], int m)
{
    int i, j;
    for (i = 0; i < m; i++)
      for (j = 0; j < 3; j++)
        printf("%d ", *(*(arr + i) + j));
}
 
int main()
{
    int arr[][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
    int m = 3;
 
    print(arr, m); // 无需强制类型转换
    return 0;
}

这里arr作为参数传入时,会自动转换成int (*)[3]类型(指向3个int的数组的指针),arr+i会移动i*sizeof(int[3])的字节数(即跳过一整行),*(arr+i)得到第i行的数组名(再转成指向该行第一个元素的指针),最后+j就能定位到目标元素。

内容的提问来源于stack exchange,提问作者Draisen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 08:11:27