鱼C论坛

 找回密码
 立即注册
查看: 2825|回复: 8

[已解决]指针,一个不容易发现的错误

[复制链接]
发表于 2017-10-1 19:49:15 | 显示全部楼层 |阅读模式

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

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

x
本帖最后由 boot 于 2017-10-1 19:52 编辑

小甲鱼老师讲过,下面这个是错误的,许多人的答案是在第二个for语句进行指针*p的初始化。
#include "stdio.h"

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

        for(i = 0; i < 10; i++)
        {
                p = &a[i];
                p++;
        }

        for(i = 0; i < 10; i++, p++)
        {
                printf("a[%d] = %d\n", i, *p);
        }

        return 0;
}
但我又发现这个:我在第二个//for(i = 0; i < 10; i++)//这里我把p++去掉了,结果最后正常输出了数组里的元素
#include "stdio.h"

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

        for(i = 0; i < 10; i++)
        {
                p = &a[i];
                p++;
        }

        for(i = 0; i < 10; i++)//这里我把p++去掉了,结果最后正常输出了数组里的元素
        {
                printf("a[%d] = %d\n", i, *p);
        }

        return 0;
}
最佳答案
2017-10-3 06:57:47
本帖最后由 ravenhu13 于 2017-10-3 07:06 编辑

楼主代码可以运行0至9??不明觉厉,第一眼看代码就觉得有问题,因为P的值是固定的,无论怎么打印*P都必须是同一个值,也就是你的循环打印*P这里不可能打印出不同的值,楼主你确定你没剪切错代码??
#include "stdio.h"

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

        for(i = 0; i < 10; i++)
        {
                p = &a[i];
                p++;
        }
/////////////////下面的这个P就没变过,怎么可能打印出不同的值??///////////////
        for(i = 0; i < 10; i++)//这里我把p++去掉了,结果最后正常输出了数组里的元素
        {
                printf("a[%d] = %d\n", i, *p);
        }

        return 0;
}

正确的代码应该如下:
int *p, i, a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
//下面是个没有意义的循环,最终*P等于a[10](题目里的数组下标最多只到a[9]),这就是经典的数组越界,这个时候引用*p将会产生不可预计后果。
                for (i = 0; i < 10; i++)
                {
                        p = &a[i];
                        p++;
                }
                //重新纠正p的地址。
                p = &a[0];

                for (i = 0; i < 10; i++,p++)
                {
                        printf("a[%d] = %d\n", i, *p);
                }

如图所示,正常输出

如图所示,正常输出
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2017-10-1 19:50:07 | 显示全部楼层
求解,这是为什么???
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-10-1 20:02:41 | 显示全部楼层
2017-10-01_195625.png

2017-10-01_200148.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 2 反对 0

使用道具 举报

 楼主| 发表于 2017-10-1 21:57:19 | 显示全部楼层

嗯,谢谢你。
但我还想知道,就是为什么我那个会输出从0到9的数呢???
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-10-1 22:38:12 | 显示全部楼层
boot 发表于 2017-10-1 21:57
嗯,谢谢你。
但我还想知道,就是为什么我那个会输出从0到9的数呢???

拿下面代码运行分析下。至于什么问题,我只能说是编译器问题
#include "stdio.h"

int main()
{
        int *p, i, a[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
                printf("%p\n\n", p);

        for(i = 0; i < 10; i++)
        {
                p = &a[i];
                
                                printf("%p\n", p);

                                p++;
        }

                printf("\n");

                 printf("%p\n", p);

        for(i = 0; i < 10; i++)//这里我把p++去掉了,结果最后正常输出了数组里的元素
        {
                printf("a[%d] = %d\n", i, *p);
                                printf("%p\n", p);
        }

        return 0;
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-10-3 06:57:47 | 显示全部楼层    本楼为最佳答案   
本帖最后由 ravenhu13 于 2017-10-3 07:06 编辑

楼主代码可以运行0至9??不明觉厉,第一眼看代码就觉得有问题,因为P的值是固定的,无论怎么打印*P都必须是同一个值,也就是你的循环打印*P这里不可能打印出不同的值,楼主你确定你没剪切错代码??
#include "stdio.h"

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

        for(i = 0; i < 10; i++)
        {
                p = &a[i];
                p++;
        }
/////////////////下面的这个P就没变过,怎么可能打印出不同的值??///////////////
        for(i = 0; i < 10; i++)//这里我把p++去掉了,结果最后正常输出了数组里的元素
        {
                printf("a[%d] = %d\n", i, *p);
        }

        return 0;
}

正确的代码应该如下:
int *p, i, a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
//下面是个没有意义的循环,最终*P等于a[10](题目里的数组下标最多只到a[9]),这就是经典的数组越界,这个时候引用*p将会产生不可预计后果。
                for (i = 0; i < 10; i++)
                {
                        p = &a[i];
                        p++;
                }
                //重新纠正p的地址。
                p = &a[0];

                for (i = 0; i < 10; i++,p++)
                {
                        printf("a[%d] = %d\n", i, *p);
                }
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 2 反对 0

使用道具 举报

 楼主| 发表于 2017-10-3 16:17:02 From FishC Mobile | 显示全部楼层
ravenhu13 发表于 2017-10-3 06:57
楼主代码可以运行0至9??不明觉厉,第一眼看代码就觉得有问题,因为P的值是固定的,无论怎么打印*P都必须 ...

谢谢了,我之前那个代码运行之后就是那样的,可能是编译器的问题吧。我当时也是这么想的已经越界了,没想到会是这个样子呢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-3-29 19:01:34 | 显示全部楼层
对啊,为什么啊,当i等于不同值的时候p不都时会有对应的地址么,为什么第一个循环结束后p的地址一定是&a[9]+4
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-3-31 12:09:14 | 显示全部楼层
林01 发表于 2020-3-29 19:01
对啊,为什么啊,当i等于不同值的时候p不都时会有对应的地址么,为什么第一个循环结束后p的地址一定是&a[9] ...

因为越界了啊。因为你a[10]实际上从a[0]开始只到a[9]啊,他第一个for循环,直接给干到a[10]了,最多是a[9],那a[10]自然是最大位数a[9]往后4个字节啊。而且应该不出意外是一串奇怪的数字。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-9-21 22:13

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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