VaeSummerTime 发表于 2021-11-25 16:42:25

【指针】对以下程序语句分析输出语句的输出,并对错误的语句分析其错误原因。

如题:对以下程序语句分析输出语句的输出,并对错误的语句分析其错误原因。
#include <stdio.h>
void main ()
{
        int x = 12,a= {1,5,8},*p1=&x,**p2=&p1,*p3={&x,a,a+1};
        float y = 9.9,*p4=&y;
        char s [] = "fighting!",*ps =&s;
        printf("%d,%d,%d,%d\n",x,*p1,**p3,**p2);
        printf("%d,%d,%d\n",*a*p3,*(*(p3+1)));
        printf("%d,%d,%d\n",*(a+1),*p3,**(p3+2));
        printf("%.1f,%.1f,%.1f\n",y,*p4,*&y);
        ++ps;
        printf("%c,%c\n",*s,*ps++);
        printf("%d,%d\n",ps-s,ps==s+2);
        printf("%c",*s++);
        printf("%x",p1+p2);

}
刚学指针有点晕,求助

番杰 发表于 2021-11-26 22:57:25

本帖最后由 番杰 于 2021-11-30 17:25 编辑

那咱们就一个一个的看:
1.
printf("%d,%d,%d,%d\n",x,*p1,**p3,**p2);
(1)x好说,就是把x打印出来,也就是12;
(2)*p1:含义既是对p进行解引用;从定义*p1=&x中可以看出,p是一个指向x的指针,意思就是p中存储的是x的地址;那么对p1进行解引用,也就是取出p中的存储的地址上的数值,刚才也说了p中存储的是x的地址;所以取出的值就是x,也就是12.
(3)**p3:首先你需要知道p3是一个指针数组;指针数组,顾名思义;它是一个数组,并且数组中的每一项都是指针;然后再接着看:**p3相当于*(*p3),先看括号中的*p3,p3是一个数组名同时也是这个数组的起始地址;所以*p3就是对这个数组的起始地址进行解引用,也就是说取出该地址上的数值:也就是&x;所以,*(*p3)就变成了*(&x);对x的地址进行解引用,那取出的数值也就可想而知了,必然是x,就是12.
(4)**p2:这个就是进行了两次解引用;那咱们就一层一层的来看,定义中**p2=&p1可以看出:p2是一个指向指针(p1)的指针;**p2 = *(*p2);先看小括号中的*p2,这个就是对p2进行解引用;取出p2中存储的地址上的数值;前面也说了p2是一个指向指针(p1)的指针;所以p2中存储的是p1的地址;所以*p2得出的结果就是p1的地址中的数值,只不过p1地址上的数值也是个地址;所以**p2可以看成*p1,前也说了*p1的值为x,也就是12,所以结果就是12;


先写这么多,你先看看能不能看看懂,能看懂的话,我继续给你往下解释。

VaeSummerTime 发表于 2021-11-30 16:48:57

番杰 发表于 2021-11-26 22:57
那咱们就一个一个的看:
1.



能看懂!!太详细了,谢谢大佬
想要后面的解释

番杰 发表于 2021-11-30 17:22:24

VaeSummerTime 发表于 2021-11-30 16:48
能看懂!!太详细了,谢谢大佬
想要后面的解释

行,有点多,我慢慢给你写哈{:10_254:}

番杰 发表于 2021-12-2 18:08:21

接着看
2.
printf("%d,%d,%d\n",*a,*p3,*(*(p3+1)));//问题里是不是在*a和*p3少打了一个,号
(1)*a好说,就是对a进行解引用,而a本身是一个数组,对于数组而言,数组名就代表着数组的起始地址,所以对a进行解引用,就相当于对数组a的起始地址进行解引用,而数组a的起始地址与a的地址是同一个,进而就得到:对a进行解引用就相当于对“a的地址”进行解引用,所以结果也就是a的数值,也就是1.
(2)*p3,这种写法是一种“语法糖”,可以参考:什么是语法糖
它就相当于:*(*(p3 +1));所以我们先看括号里的:p3+1(稍等,一会给你补,我先吃个饭)
页: [1]
查看完整版本: 【指针】对以下程序语句分析输出语句的输出,并对错误的语句分析其错误原因。