求c语言指针方式引用二维数组问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了求c语言指针方式引用二维数组问题相关的知识,希望对你有一定的参考价值。

如图所示
先说明,这个方法我们没学过,从开始就不知道原理了
为什么a和*a都是地址啊,能详细说明原理吗,说一四五就可以,谢谢

就按照你举的例子来说:
a[2][3]=0,1,2,3,4,5
这时形成一个二维数组,元素是:
a[0][0]=0,物理地址&a[0][0]
a[0][1]=1,地址&a[0][0]+1
a[0][2]=2,地址&a[0][0]+2
a[1][0]=3,地址&a[0][0]+3
a[1][1]=4,地址&a[0][0]+4
a[1][2]=5,地址&a[0][0]+5
分配存储空间时,系统把每3个数据作为一组,组名记a[0]、a[1],这两个值分别是每组第一个元素的地址,即a[0]=&a[0][0],a[1]=&a[1][0]。
所以:
a指向数组首元素的地址,a=&a[0][0];
a[0]代表第一组首元素地址,当然,a[0]也指向数组首元素的地址,a[0]=&a[0][0];
*a是对a取值,它取出的是a[0],当然=&a[0][0];
&a[0]指a[0]的地址,还是它自己,所以&a[0]=&a[0][0]。
所以,第一行个打印语句输出的5个内容都是一样的,所以,输出5个19ff0c。是a[0][0](元素0)的储存位置。
第二个打印语句输出的5个内容也是相同的,都是19ff18。它们是a[1][0](元素3)的存放位置,19ff0C+3×4=19ff0c+12=19ff0c+c=19ff18。
后面也是类似解释。
具体p1、p2、p3的使用,是前面定义了三个字符串,此处拿来使用。你可以直接把p1的内容"%x,%x,%x,%x,%x\n"拿来替换掉p1,就好理解了。
有什么问题请留言。追问

这个程序将指针p1放入输出里,是指针p1依次指向a,*a,a[0]还是有别的意思

*a是对a的取值,但a指向的数组首元素地址,那*a不应该取出地址的值0吗

追答

p1只是一个字符数组,它的值是“%x,%x,%x,%x,%x\n”,没有任何其他意义。

如果不用p1,第一个输出语句你可以写成:

printf(“%x,%x,%x,%x,%x\n”,a,*a,a[0],&a[0],&a[0][0]);

p1的作用仅此而已。

p1永远也不会指向a,a[0]等等,也不需要p1执行它们。

另外,a是二维数组,相当于二级指针。a相当于二维数组的首地址(等于a[0][0]的地址)。*a是取得一维数组a[0]的首地址(也等于a[0][0]的地址)。

*a才是一级指针,对它取值**a才能得到a[0][0]的元素值0。

参考技术A

我是这样理解的:

a是一个二维数组,也就是一个二级指针,那么a代表指向数组头的二级指针,*a代表指向数组头的一级指针,**a代表第一个数组元素。因为二维数组只是一维数组在内存地址上的连续表示,所以a和*a的区别在于它们的有效范围不同,分别是数组的两个维度的维数。

所以a和*a都是指向数组头的指针,它们都指向第一个元素,所以输出的地址相同。

证实:

#include <stdio.h>


int main()

    int a[2][2] = 1,2,3,4;

    printf("%x, %x, %d\\n", a, *a, **a);


    return 0;

输出结果:

参考技术B 这个方法我们没学过,从开始就不知道原理了

C语言:定义指向二维数组的指针变量

C语言:定义指向二维数组的指针变量

标签: C语言 二维数组 指针

by 小威威


1.引入

我们知道,要在函数中处理数组,一般要给函数传递指针。那么,对于一维int数组a[10],我们可以定义一个int *类型的指针变量p指向该数组。为什么这样定义?(按照我下面的理解方式有利于理解二维数组指针的定义)

首先我们可以把这个一维数组中的10个元素当作10个数组,每个数组都只有一个元素,即指针在每一次移动,都只需指向一个int类型的变量(通过指针对数组进行操作),故定义指向一个int变量的指针。

那么对于二维数组a[3][2],我们要定义一个 int (*p) [2]的指针。首先我们来分析一下这个指针的类型。它也等价于这种形式:int [2] *p。意思是定义一个指向两个int类型变量的指针。当你学了结构体,你就对这种数据类型的定义方式不陌生了。但没有学过结构体,就有点抽象了。我先举个简单的例子:例如我定义一个数组int a[10],其实它也可以表示成另一种形式:int [10] a。意思是定义一个变量a,它是int [10]类型的,即它是一个拥有10个int变量长度的变量,即是数组。那对于二维数组a[3][2],为什么要定义一个指向两个int变量的指针呢?

按照前面对一维数组的分析,我们可以把这个二维数组看作是三个数组,每个数组有两个元素。指向该二维数组的指针在进行移动时,它指向的是一整个数组,即两个int类型,所以需要定义int [2] 类型的指针变量。

由此我们可以总结规律,指向二维数组a[i][j]的指针类型必然是 int [j] *类型。

2.实例

# include <stdio.h>
int main(void) 
    int a[4][3] = 
        1, 2, 12,
        3, 4, 34,
        5, 6, 56,
        7, 8, 78
    ;
    int (*pArr) [3];  //一定要加上括号,因为[]的优先级高于*
    pArr = a;
    for (int i = 0; i < 4; i++)
        for (int j = 0; j < 3; j++)
            printf("%d ", pArr[i][j]);
    return 0;

3.提醒

有人会说难道不能定义一个int**的指针类型吗?那你可能是被动态数组影响到了。其实我前面讲的都是针对于静态数组。对于静态数组,它在内存中所占的空间是连续的,只需要用到地址,所以只要一颗;而动态数组是先建立一个一维数组,然后分别在一维数组的元素内再开辟一段连续的空间,它就需要地址的地址,所以需要两个*。这很重要很重要噢!!!


以上内容皆为本人观点,欢迎大家提出批评和指导,我们一起探讨!


以上是关于求c语言指针方式引用二维数组问题的主要内容,如果未能解决你的问题,请参考以下文章

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

c 语言用指针表示二维数组的列 怎样表示

如何在c语言二维数组中使用指针

C语言中的二维数组名是一个二重指针吗?

C语言通过指针 将一个二维数组赋值给另一个二维数组

C 语言二级指针作为输入 ( 二维数组 | 二维数组内存大小计算 | 指针跳转步长问题 )