问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

请教C语言二级指针“(void **)&”的问题?

发布网友 发布时间:2022-04-21 15:43

我来回答

3个回答

热心网友 时间:2023-11-14 23:34

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

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

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

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

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

热心网友 时间:2023-11-14 23:35

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

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

#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;
}

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

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

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

热心网友 时间:2023-11-14 23:35

倘若此时有一个二级指针文件中可以编译通过,但会给出警告。若是在.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;是将一个一维数组(等价于一级指针)赋给一个二级指针(要通过“&”赋一级指针的地址才行),地球人都知道这是行不通的!虽然乍听起来还蛮合理的,其实此般理解无异于穿凿附会。刚才解释过,两者的语义迥异!不过,这样理解似乎更能深刻且方便地知道那样做错在哪里了,呵呵。
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
福如东海终身寿险(A款)(分红型)能退多少钱 我买的新华人寿保险福如东海A型,但是想退了。 杭州樱花日语学校的学习效果如何得到管理与跟踪? 枣子不能与什么一起吃 枣子和什么食物相克 枣子和什么相克 枣子跟什么不能一起吃 电风扇带不动风叶拿掉风叶能转是怎么回事 嵌入式学习首先要学什么基础 学习嵌入式的基础是什么 404 Not Found C语言指针**p是什么意思 c语言中如何通过二级指针来操作二维数组 C语言中的结构体二级指针问题 C语言中*t(t为二级指针)是什么意思 老母鸡怎么炖最补 C语言关于二级指针的问题 怎么炖老母鸡?辅料用哪些才补? c语言的二级指针如何初始化了? 清炖老母鸡需要哪些食材? C语言 二级指针的问题 炖的读音 c语言关于二级指针 炖老母鸡汤里面需要加什么材料才能养气补血 c语言 二级指针 如何清炖老母鸡 如何清炖母鸡汤好吃 老母鸡炖汤加什么补肾 老母鸡汤怎么炖最补气血 清炖老母鸡怎么做最好吃 关于c语言二级指针的一个问题 c语言指针二级指针和二级地址的解释和平常地址与指针的区别 C语言二级指针题 C语言 传递二级指针 C语言二级指针问题 关于c语言二级指针的问题 C语言二级指针的问题 c语言中二级指针怎么转换的 电脑管家 路由器管家 怎么把禁止的设备给解除掉 雅琪变装系列小说全部有木有 濂怎么读 演员雅琪资料! 人妖雅琪系列能发给我吗,跪谢了大哥 北京卫视的美女主持人雅淇,她究竟是何来历? 急求人妖雅琦的全部txt小说!!!! 赵雅琪多少岁了 雅琪系列小说合集!求! 林雅琪是做什么的? 404 Not Found 雅琪诺质量好吗?听说是什么中国十大墙纸品牌,是吗?