鱼C论坛

 找回密码
 立即注册
查看: 1906|回复: 20

[已解决]指针

[复制链接]
发表于 2020-9-3 20:44:59 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
#include <stdio.h>
int main()
{
    int i,a[]={1,2,3,4,5,6,7,8,9};
    int *p=a;
    for (i=0;i<9;i++)
    {
        printf("a[%d] 的值是%d\n",i,*p++);
    }
    return 0;
}
这个程序中*p++是怎么运算的?
最佳答案
2020-9-24 20:43:55
前面的回复,若有对你的理解造成了误解之处,请原谅! 我也不想去编辑修改前面的回复了,下午我写了一个小程序,并对其进行了探索试验,并对程序进行了注释,希望能达到你的要求。程序中由于 p 与 *p 的反复运算,若不每条都加上一个 p = a; 语句,输出的结果有可能会造成累加的效果。程序如下:
#include <stdio.h>

int main()
{
    int*p,a[zxsq-anti-bbcode-5]={11,22,33,44,55};

    p = a;
    printf("%d\n",p);             // 第1个元素的地址
    printf("%d\t",*p);            // 取得第1个元素的值,输出11
    p = a;
    printf("%d\t",*p++);       // 先取得第1个元素的值,地址再自增1,输出11
    p = a;
    printf("%d\n",*(p++));    // 先取得第1个元素的值,地址再自增1,输出11

    p = a;
    printf("%d\t",*(p+1));     // 先取p指向元素的地址,地址加1,再取其值,输出22
    p = a;
    printf("%d\n",*(++p));    // 先取p指向元素的地址,地址加1,再取其值,输出22
   
    p = a;                              // 若不加此语句,*p 值就是上一行的结果,加上此语句,*p 值就是第 1个元素的结果
    printf("%d\t",*p+1);       // 先取*p的值,使其值加1,输出12
    printf("%d\n",*p+=1);    // 先取*p的值,使其值加1,输出12
    printf("%d\n",++*p);      // 先取*p的值,使其值加1,输出13

}

本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-9-3 22:16:51 | 显示全部楼层
printf("a[%d] 的值是%d\n",i,*p++);  这条语句,你可能不好理解,我将它分解成:

printf("a[%d] 的值是%d\n",i,*p);
*p++;

能理解了不?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-9-3 22:55:26 | 显示全部楼层
风过无痕1989 发表于 2020-9-3 22:16
printf("a[%d] 的值是%d\n",i,*p++);  这条语句,你可能不好理解,我将它分解成:

printf("a[%d] 的值是 ...

我不理解的是,*p++不应该是根据右结合性先算++再算*的吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-9-3 23:13:19 | 显示全部楼层
本帖最后由 4goodworld 于 2020-9-3 23:22 编辑

我翻看了一些资料,和查看了反汇编代码
微信截图_20200903231442.png
情况是设置了一个变量a,先执行   a=*p,然后p++,返回a的值
就算你是 *(p++)
你看看编译器运算的规则
1.png
和上图一样
理论的东西我不是很强,无法解释得清楚,我建议你去csdn上去搜搜看
我只能说,编译器的规则在同时出现* ++的时候,就是先解引用,再++
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-9-4 00:32:47 | 显示全部楼层
雨天Zz 发表于 2020-9-3 22:55
我不理解的是,*p++不应该是根据右结合性先算++再算*的吗?

*p = *p + 1 及 *p += 1 与 *p++ 是等价的,*p 它就是一个变量,i++、j++ 能理解吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 0 反对 1

使用道具 举报

发表于 2020-9-4 15:31:01 | 显示全部楼层
雨天Zz 发表于 2020-9-3 22:55
我不理解的是,*p++不应该是根据右结合性先算++再算*的吗?

      设 p 指向数组 a 的首元素即 p = a:

      p++; 此时 *р;得到的下一个元素a[1]的值。

      *p++;由于 ++ 和 * 同优先级,结合方向为自右而左,因此它等价于 *(p++),先引用 p 的值,实现 *p 的运算,然后再使 p 自增1。如果 p 当前指向 a 数组中第 i 个元素a[ i ],则:*(p--)相当于a[ i-- ],先对 p 进行“*”运算(求 p 所指向的元素的值),再使 p 自减。

      *(p++)与*(++p)作用不相同! 前者是先取 *p 值,然后使 p 加1。后者是先使 p 加1,再取 *p。若 p 初值为a(即&a[0]),若输出*(p++),得到a[0]的值,而输出*(++p),得到a[1]的值。

      ++(*p)表示 p 所指向的元素值加1,--(*p)表示 p 所指向的元素值减1。如果p = a,则++(*p)相当于++a[0],若a[0]的值为3,则在执行++(*p)(即++a[0])后a[0]的值为4,注意:是元素a[0]的值加减1,而不是指针p的值加减1。

      *(++p)相当于a[++i ],先使 p 自加,再进行“*"运算。*(--p)相当于a[--i ],先使 p 自减,再进行“*"运算。

      上面是我学习笔记的一小段,希望能对你有所帮助。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

发表于 2020-9-21 08:45:26 | 显示全部楼层
问题还没解决,帮你顶上去
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-9-21 22:35:43 | 显示全部楼层
乐乐学编程 发表于 2020-9-21 08:45
问题还没解决,帮你顶上去

算了,没有用的,半个月了,只能是下次看到他的帖子,不回复就是了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-9-22 06:35:31 | 显示全部楼层
*p++, 先使用*p的值,再p++
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-9-22 06:36:59 | 显示全部楼层
风过无痕1989 发表于 2020-9-21 22:35
算了,没有用的,半个月了,只能是下次看到他的帖子,不回复就是了

看了下你上面的回复,这就是入门指针了?
*p++ 和 *p += 1或 *p = *p + 1居然等价,推荐自己写个程序去看看吧
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

发表于 2020-9-22 10:05:15 | 显示全部楼层
雨天Zz 发表于 2020-9-3 22:55
我不理解的是,*p++不应该是根据右结合性先算++再算*的吗?

你的理解没错,你可以在你的代码上加一句,这样就可以看到地址和值的关系了。p++每加一下地址是在+4的。
#include <stdio.h>
int main()
{
    int i,a[]={1,2,3,4,5,6,7,8,9};
    int *p=a;
    for (i=0;i<9;i++)
    {
        printf("a[%d] 的值是%d\n",i,*p++);
        printf("地址是是%p\n",p);
    }
    return 0;
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-9-22 13:28:42 | 显示全部楼层
baige 发表于 2020-9-22 06:36
看了下你上面的回复,这就是入门指针了?
*p++ 和 *p += 1或 *p = *p + 1居然等价,推荐自己写个程序去 ...


我不知道怎么说了,抄一段书给你看:

例如:
int main()
{
int*p,a[5]={1,3,5,7,9};
p=a;
printf("%d",*p++)

有的人认为 “*p++” 的作用是先使 p 加 1,即指向第1个元素 a[1] 处,然后输出第 1 个元素 a[1] 的值 3,其实不然,由于 ++ 的优先级高于 *,因此先执行 p++,而 p++ 的作用是先用 p 的原值进行运算(进行 *p 的运算),然后再使 p 加 1.p 原来指向数组 a 的第 0 个元素 a[0],因此 *p 就是第 0 个元素 a[0] 的值 1,结论是先输出 a[0] 的值,然后再使 p 加 1。如果是 *(++p),则先使p指向 a[1],然后输出 a[1] 的值。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-9-22 16:10:48 | 显示全部楼层
雨天Zz 发表于 2020-9-3 22:55
我不理解的是,*p++不应该是根据右结合性先算++再算*的吗?

指针先移动到下一个指针,然后再解引用
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-9-22 20:05:46 | 显示全部楼层
++--运算符很特殊。小甲鱼可能没讲,++--在前,则先运算,再赋值。若++--在后,则先赋值再运算。
比如a=8++,b=++8。那么a的值是8,b的值是9。额,我举个例子,简单的形象,能不能这么写代码我可不知道。

还是写完整点吧。比如。i=j=8.而后,a=i++;b=++j。那么,a的值是8,b的值是9。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

发表于 2020-9-23 22:04:47 | 显示全部楼层
baige 发表于 2020-9-22 06:35
*p++, 先使用*p的值,再p++

我的老师也是告诉我们 “ ++ 的优先级高于 * ”,能否说详细一点?谢谢 !
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-9-23 23:05:05 | 显示全部楼层
本帖最后由 baige 于 2020-9-23 23:07 编辑
乐乐学编程 发表于 2020-9-23 22:04
我的老师也是告诉我们 “ ++ 的优先级高于 * ”,能否说详细一点?谢谢 !

#include <stdio.h>

int main(){
        int a[] = {1,2,3,4};
        int *p = a;
        for(int i = 0; i < 4; ++i){
                printf("%d\n",*p++);
                
        }
        return 0;
} 
#include <stdio.h>

int main(){
        int a[] = {1,2,3,4};
        int *p = a;
        for(int i = 0; i < 4; ++i){
                printf("%d\n",*p);
                p++;
                
        }
        return 0;
} 
#include <stdio.h>

int main(){
        int a[] = {1,2,3,4};
        int *p = a;
        for(int i = 0; i < 4; ++i){
                printf("%d\n",*p+=1);
                
        }
        return 0;
} 
#include <stdio.h>

int main(){
        int a[] = {1,2,3,4};
        int *p = a;
        for(int i = 0; i < 4; ++i){
                printf("%d\n",*p = *p + 1);
                
        }
        return 0;
} 
自己看程序运行结果
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-9-23 23:27:49 | 显示全部楼层
本帖最后由 乐乐学编程 于 2020-9-24 14:24 编辑
baige 发表于 2020-9-23 23:05
自己看程序运行结果


第1个程序,输出的结果是:1、2、3、4,第2个程序,输出的结果是:1、1、1、1,第3个程序,输出:2、3、4、5,第4个输出:2、2、2、2

昨天喝多了,没有运行程序,瞎说了,抱歉,抱歉!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-9-24 08:34:20 | 显示全部楼层
本帖最后由 gy1768532 于 2020-9-24 08:45 编辑
风过无痕1989 发表于 2020-9-4 00:32
*p = *p + 1 及 *p += 1 与 *p++ 是等价的,*p 它就是一个变量,i++、j++ 能理解吗?


*p = *p + 1和*p+=1是等价的,不过其代表的意思是先*p,取值,然后取出来的值+1,而*p++和*(p++)是等价的,指向下一个元素地址,这个和普通变量有所不同,除此之外,还要注意(*p)++,这里代表的是取出来的值自增,而不是地址了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-9-24 08:45:19 | 显示全部楼层
我一开始也遇到这个问题,后来自己琢磨了一下,虽然说优先级不一样,但是理解应该差不多的,就像j = i++,是先把i的值赋值给j,然后在自增1(等价于{j = i;i = i+1;),这里*p++和*(p++)等价,p++是先把p拿出来,然后对p进行运算之后,再自增1,所以*p++就是,先运算p++(这里则是先把p拿出来),发现前面有取值运算,所以对p进行取值运算之后,在执行p+1(也就是指向下一个元素地址)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-9-24 14:28:01 | 显示全部楼层
baige 发表于 2020-9-23 23:05
自己看程序运行结果

昨晚喝多了,眼花,将*P+=1,看成了*p+=i;将*p+1,看成了*p+i 了,抱歉,抱歉! 我已经修改上面的回复了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-1-12 23:34

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表