鱼C论坛

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

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

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

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

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

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

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

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

  5.         for(i = 0; i < 10; i++)
  6.         {
  7.                 p = &a[i];
  8.                 p++;
  9.         }

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

  14.         return 0;
  15. }
复制代码

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

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

  5.         for(i = 0; i < 10; i++)
  6.         {
  7.                 p = &a[i];
  8.                 p++;
  9.         }

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

  14.         return 0;
  15. }
复制代码

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

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

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

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

  15.         return 0;
  16. }
复制代码


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

  10.                 for (i = 0; i < 10; i++,p++)
  11.                 {
  12.                         printf("a[%d] = %d\n", i, *p);
  13.                 }
复制代码

如图所示,正常输出

如图所示,正常输出
想知道小甲鱼最近在做啥?请访问 -> 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的数呢???

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

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

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

  11.                                 p++;
  12.         }

  13.                 printf("\n");

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

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

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

使用道具 举报

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

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

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

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

  15.         return 0;
  16. }
复制代码


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

  10.                 for (i = 0; i < 10; i++,p++)
  11.                 {
  12.                         printf("a[%d] = %d\n", i, *p);
  13.                 }
复制代码
想知道小甲鱼最近在做啥?请访问 -> 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-4-28 01:12

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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