shell_shu 2015-03-20 14:33 采纳率: 50%
浏览 2638
已采纳

c语言中的printf函数问题

int main()
{
int arry[3][5]={
{1,2,4},
{4,5,6,7},
{6,5,3,8}
};
int (*p)[5];
p=arry;

    printf("%x\n",*(p+1)+3);
    printf("%x\n",*(*(p+1)+3));
    printf("%x\n",*(p+1)+3);
    printf("%x\n",*(p+1)+2);
    printf("%x\n",p);
    printf("%x\n",p+1);
    printf("%x\n",*p+1);
    printf("%x\n",p[0]+1);
    printf("%x\n",**p);
    printf("%x\n",&p);


    定义了一个二维数组arry,printf("%x\n",*(p+1)+3);为什么这样输出来的是一个地址?
    其中printf函数中的输出项表,到底是不是在计算表达式的左值还是右值,如果是的
    话,到底是哪个值? 谢谢解决问题
  • 写回答

8条回答 默认 最新

  • 王滕 2015-03-24 15:24
    关注

    再解决该问题之前,想讲一下,定义一个指针的语句,代表的含义.

    图片说明

    接下来,根据这个题来讲.

    图片说明

    int main()

    {
    int arry[3][5]={{1,2,4},{4,5,6,7},{6,5,3,8}};//数组名代表的是一块内存的首地址
    int (*p)[5];//定义一个数组指针.这个指针,指向一个一维数组的首地址.该一维数组含有5个成员.可以把这条语句理解成int5;那么指针p指向的是一个int[5] 类型,p的寻址能力是sizeof(int)*5. p+1指向的地址和p指向的地址相差20. 在二维图中,(p+1)就到下一行.
    //在一些参考书中,把*(星号)解释成降低维度(降维).本来p是指向int型数组的指针.用星号降维之后,(*p)就是一个int型的指针.那么(*p)+1,就是往后移动了sizeof(int)个字节,就是4个字节.记住,现在(*p)还依然是一块内存地址.
    p=arry;//p指向数组arry的首地址
    printf("%x\n",*(p+1)+3);//在附加的参考图中,p指向0XFFFF0002,p是一个int[5]类型的指针,所以,p+1往后移动sizeof(int)*5个字节,也就是移动到第二行,p+1就是第二行的首地址.*(p+1)就是降维,接下来如果再移动,就是移动sizeof(int)个字节.切记,这时候*(p+1)仍然是一个地址,*(p+1)并不是取(p+1)这个地址的值.因为p一开始指向的是一个数组,所以,这时候的星号只是降维.现在*(p+1)是一个地址了,也可以理解为是一个int型的指针了.如果再进行取值,那么就是一个数值.例如:*(*(p+1)+0)是第二行第一个的值, ((p+2)+4)是第三行第五个的值.
    printf("%x\n",*(*(p+1)+3));//第二行第三个的值
    printf("%x\n",*(p+1)+3);//第二行第四个的地址
    printf("%x\n",*(p+1)+2);//第二行第三个的地址
    printf("%x\n",p);//数组的首地址,也是第一行的首地址,也是第一行第一个元素的首地址.
    printf("%x\n",p+1);//第一行第二个元素的首地址.p是一个int[5]类型的指针,所以你要承认,(p+1)仍然是一个int[5]类型的指针,并不是int型的指针,所以,要先用星号对它进行降维,才是int型的指针.然后才可以使用星号取这个地址的值.
    printf("%x\n",*p+1);//第一行第二个元素的地址.
    printf("%x\n",p[0]+1);//p[0]相当于*(p+0).所以,这个是第一行第二个元素的地址.在这里再多讲一点数组方式访问和星号方式访问的转换.*(p+0)和p[0]相同,*(p+3)+2和p[3]+2相同,p[2][3]和*(*(p+2)+3)相同.
    printf("%x\n",**p);//第一行第一个元素的值.
    printf("%x\n",&p);//p是一个指针变量,p在内存中也有一个存储它的空间.这句话就是输出存放变量p的内存地址.

    }

    
    
    我猜你可以这么想:
    你如果不能理解,你可能会说:”p是一个内存地址,那么*p就该是取这块内存地址中存放的值”.那么,我们拿上面这个题为例,定义p的时候是这样定义的.int (*p)[5];然后,请你告诉我如果访问第一行第三个空间的值?是*(p+2)吗?如何访问第三行第二个空间的值?是*(p+11)吗?拜托大哥,如果你想这样访问的话,你定义指针变量p的时候,可以这样定义,int *p=arry;那么,你就可以尽情的通过*(p+11)访问到第三行第二个空间的值了.
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(7条)

报告相同问题?

悬赏问题

  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!
  • ¥15 drone 推送镜像时候 purge: true 推送完毕后没有删除对应的镜像,手动拷贝到服务器执行结果正确在样才能让指令自动执行成功删除对应镜像,如何解决?
  • ¥15 求daily translation(DT)偏差订正方法的代码