加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

指向C多维数组的指针的地址

发布时间:2020-12-16 09:44:03 所属栏目:百科 来源:网络整理
导读:以下代码提问: #include stdio.hint main(int argc,char *arg[]){ if (argc2){ int m=atoi(arg[1]); int n=atoi(arg[2]); int a[m][n]; int (*p)[m][n]=a; printf("p : %p,*p : %p,**p : %pn",p,*p,**p); } return 0;} 主要环境:gcc版本4.6.3(Ubuntu / Li
以下代码提问:

#include <stdio.h>

int main(int argc,char *arg[]){

    if (argc>2){
      int m=atoi(arg[1]);
      int n=atoi(arg[2]);

      int a[m][n];
      int (*p)[m][n]=&a;

      printf("p : %p,*p : %p,**p : %pn",p,*p,**p);
    }

    return 0;
}

主要环境:gcc版本4.6.3(Ubuntu / Linaro 4.6.3-1ubuntu5)x86-64

gcc main.c
./a.out 2 4

输出:

p : 0xbfea7ef0,*p : 0xbfea7ef0,**p : 0xbfea7ef0

问题是为什么p == * p == ** p.我想这可能是因为a是一个数组,一种常量指针,其地址是特定的,这涉及gcc的一些实现细节.

解决方法

对于固定大小的数组和可变修改的数组,观察到的行为是相同的:

#include <stdio.h>

int main(void)
{
    enum { m = 3,n = 4 };
    int a[m][n];
    int (*p)[m][n] = &a;

    printf("p : %p,**p);
    return(0);
}

在我的机器上,这产生了:

p : 0x7fff6c542520,*p : 0x7fff6c542520,**p : 0x7fff6c542520

当然,p是两个程序中指向2D数组的指针(我不会再次添加’在两个程序中的’限定符,即使它适用).当你打印p时,你得到分配给它的数组的地址,这是a的地址.因为p是指向2D数组的指针,所以* p’是’2D数组,但是在大多数情况下数组引用变成指向其第一个元素的指针,因此* p是指向[0]的指针,它是相同的内存位置作为参考.类似地,** p’是’1D数组,但类似地,** p是指向[0] [0]的指针,它也是与引用相同的存储器位置.因此,这三个值应该是相同的,并且编译器正确.

这并不容易阅读,但是,它正试图解释的C也不是.

这是原始程序的一个小变化,它说明了p,* p和** p指向的不同对象的大小:

#include <stdio.h>

int main(void)
{
    enum { m = 3,n = 4 };

    int a[m][n];
    int (*p)[m][n]=&a;

    printf("p+0 : %p,(*p)+0 : %p,(**p) + 0 : %pn",(void *)(p+0),(void *)((*p)+0),(void *)((**p)+0));
    printf("p+1 : %p,(*p)+1 : %p,(**p) + 1 : %pn",(void *)(p+1),(void *)((*p)+1),(void *)((**p)+1));
    return(0);
}

严格地说,%p转换规范应该给出一个void *;这里的演员强制执行.官方的原始代码有点草率,尽管很少有机器可以解决这个问题.

这个输出是:

p+0 : 0x7fff63453520,(*p)+0 : 0x7fff63453520,(**p) + 0 : 0x7fff63453520
p+1 : 0x7fff63453550,(*p)+1 : 0x7fff63453530,(**p) + 1 : 0x7fff63453524

注意指向的对象的大小是如何不同的,如1版本所示:

sizeof(*p)   = 0x30
sizeof(**p)  = 0x10
sizeof(***p) = 0x04

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读