c语言中如何通过二级指针来操作二维数组

如题所述

1、首先我们打开电脑里的C语言软件,新建一个工程和.c文件,输入头文件和主函数。

2、然后我们输入图示代码初始化数组,定义变量类型。

3、然后我们输入图示代码用for语句实现数组的访问。

4、然后我们输入图示代码进行输出。

5、然后我们输入图示代码编译、运行,即可通过二级指针来操作二维数组

温馨提示:答案为网友推荐,仅供参考
第1个回答  推荐于2017-10-15

通过二级指针去访问二维数组需要先给二级指针分配等同于二维数组行数的一维数组指针,然后把二维数组的每行首地址赋值给对应位置的一维指针上。之后就可以通过二维指针直接访问了。

参考代码如下,可以看具体注释辅助理解。

#include <stdio.h>//输入输出头文件。
#include <stdlib.h>//本程序需要用到malloc/free函数,引用该头文件。
int main()
{
    int a[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12}; //定义二维数组a,并赋值从1-12.
    int ** p = NULL;//定义二维指针。
    int i, j;
    
    p = (int **)malloc(sizeof(int *) *3);//要访问的数组有三行,所以申请三个一维指针变量。
    for(i = 0; i < 3; i ++)
    {
        p[i] = a[i];//将二维数组行地址赋值到对应的一维指针上。
    }
    
    for(i = 0; i < 3; i ++)
    {
        for(j = 0; j < 4; j ++)
            printf("%d ", p[i][j]); //用指针输出元素。p[i][j]这里也可以写作*(*(p+i) + j)。
        printf("\n"); //每行输出后加一个换行
    }
    
    free(p);//释放申请的内存。
    
    return 0;
}

用二维指针访问二维数组多用于函数调用。

对于一维数组,如果函数参数为一维指针可以直接用数组名当做函数参数。但是如果函数参数为二维指针,直接用二维数组名做参数会出现访问出错,是因为二维指针和二维数组的访问方式不同造成的,需要如示例代码中做转换。

另外一种常用的方法是利用二维数组的内存连续性将二维数组转为一维数组处理,与本题无关,不做更多描述。

第2个回答  推荐于2017-10-02
倘若此时有一个二级指针文件中可以编译通过,但会给出警告。若是在.CPP文件中则不会编译通过!我相信很多人的第一反应是加上强制类型转换:q=(int**)a;如此以来,程序编译、链接畅通无阻,连警告也没有!但一运行就会出问题:这是当然的!下面进行详细分析。。。。。。根据我上面讲述的:q可视为int**类型,且是int*变量的地址类型变量!对q (指针变量)的引用,得到是的其(即q)内存单元的数据,即int*变量的地址,*q则是获取q所指向的int*变量类型地址的内容,相当于int* Q变量Q的直接引用,得到是int类型变量的地址。q所占的内存为4BYTE,*q所占的内存也为4BYTE。一切都清楚了。现在来分析二维数组a的数据类型。我们知道指针与数组的联系的常见具体应用有两种:一种是“数组指针”:形如(*ptr)[];另外一种是“指针数组”:形如*ptr[]。两者之间的区别想必大家都清楚。如果我定义一个:“数组指针”并初始化:int (*pp)[3]=a;那么通过pp完全可以操作a[2][3]。来分析一下“数组指针”(*ptr)[SIZE],ptr所指的对象是有SIZE个某种数据类型值的数组。而ptr本身又是一级指针,一级指针又等价于一维数组。a[2][3]的低维是一个维度为3的一维数组。高维是一个维度为2的一维数组,不难理解,正如前面所述:二维数组的每个元素是一个一维数组,相当于一维数组的两次嵌套。比如变量a[0]是一个维度为3的一维数组,a[1]亦是一样。这样一来,高维的那一部分可视为一个指针!一个胆大的设想出来了:二维数组本质上就等同于“数组指针”!<typeinfo)cout<<typeid(a).name()<<endl;cout<<typeid(pp).name()<<endl;输出结果为:int (*)[3](换行)int (*)[3]两者完全相同,与设想一致!现在回到问题上来,q=(int**)a;强制转换成功,但却不可能正确运行!原因已浮出水面:q这个地址单元存放的是int*类型的“指针变量”的地址,而二维数组a骨子里却是一个“数组指针”。两者完全是“八竿子打不着”!想一想它们的内存分布情况,前者(地址)所指向的内存大小恒为4BYTE,后者(地址)所指向的内存大小是随着你定义的数组维数而不断变化的!即使通过强制类型转换成功,q的内存值就是a所代表的地址,但这个地址仅仅是一个地址,而q的内存值不仅要求是一个地址,而且还必须是一个“指针变量”的地址!只有这样通过*q(前面说过:*q则是获取q所指向的int*变量类型地址的内容,即一个int变量的地址)才能操作一个普通变量的地址,否则就是用“*”来操作普通变量,想一下int x=250;*x又是“数组指针”?这里有必要强调一下:我是从它们的存储映象上来讲的,但编译器的语义实现上两者是绝不能划等号的!你能够将一个二维数组赋值给一个一维数组吗?显然是不行的!因此我们这样想:语句q=(int**)a;是将一个一维数组(等价于一级指针)赋给一个二级指针(要通过“&”赋一级指针的地址才行),地球人都知道这是行不通的!虽然乍听起来还蛮合理的,其实此般理解无异于穿凿附会。刚才解释过,两者的语义迥异!不过,这样理解似乎更能深刻且方便地知道那样做错在哪里了,呵呵。本回答被提问者采纳
相似回答