跃2.0 2017-11-10 12:31 采纳率: 40%
浏览 1032
已采纳

为什么这个变量不能控制循环,变量作用域

#include
int main()
{
int N;
int i = 0;
scanf("%d",&N);
while(i<N)
{
unsigned short a,g,d;
printf("请输入a\n");
scanf("%u",&a);
printf("我是a=%u\n",a);
i++;
printf("我是i=%d\n",i);
printf("我是N=%d",N);
}

return 0;

}//如题,N不能控制循环,我怀疑是因为变量作用域问题,可是为什么呢,我把N改成static int N,把i改成static int i就又可以了,有没有办法可以不改,求解答,

  • 写回答

7条回答

  • 造轮使者 2017-11-10 15:07
    关注

    楼上说的可能没在点子上,本程序真正出问题的原因应该是:读入a的值的时候由于格式化字符串中的%u溢出将N的值破坏了,因为N和a均在栈中管理,N的首地址比a的首地址高2个字节,当向a的首地址放入4个字节的数据时,N的低2字节将被覆盖
    改成static int N以后,N将不再在栈中管理,因此就不会和栈中的a冲突,因此改为static后就正常了。
    下面看一下N和a均在栈中时的汇编代码:
    跟踪到scanf("%d",&N);时:

       0x00401566 <+70>:    lea    0x58(%esp),%eax
       0x0040156a <+74>:    mov    %eax,0x4(%esp)
       0x0040156e <+78>:    movl   $0x41b000,(%esp)
       0x00401575 <+85>:    movl   $0x1,0x20(%esp)
       0x0040157d <+93>:    call   0x40b558 <scanf>
    

    可见,N的地址为0x58(%esp)
    跟踪到scanf("%u",&a);时:

       0x00401598 <+120>:   lea    0x56(%esp),%eax
       0x0040159c <+124>:   mov    %eax,0x4(%esp)
       0x004015a0 <+128>:   movl   $0x41b00b,(%esp)
       0x004015a7 <+135>:   call   0x40b558 <scanf>
    

    可见,a的地址为0x56(%esp)
    在执行本次scanf之前,我先扫一下0x56(%esp)的地址(此时ESP的值为0x28fe50):

    (gdb) x/10bx ($esp+0x56)
    0x28fea6:   0x00    0x00    0x0a    0x00    0x00    0x00    0x00    0x00
    

    可见N位于$esp+0x58处,确实是10(0x0000000a)
    下面我们给a读入一个127(0x007f),看看0x56(%esp)的地址变化的情况:

    (gdb) x/10bx ($esp+0x56)
    0x28fea6:   0x7f    0x00    0x00    0x00    0x00    0x00    0x00    0x00
    

    看到了吗?之前的0x0a被覆盖掉了,因为%u使得scanf函数&a处写入了**4**个字节,假如我们输入一个对于unsigned short会溢出的数,比如4294967295(0xffffffff),你将在屏幕上看到以下输出:

    10
    请输入a
    4294967295
    我是a=65535
    我是i=1
    我是N=65535请输入a
    (后面的输出省略)
    

    看吧!N怎么会等于65535(0xffff)!原来就是因为写入的0xffffffff覆盖掉了N的低16位!此时去扫一下内存,一定会发现N所在的0x58(%esp)变为了0xff 0xff

    改成static int N以后,N将不再在栈中管理,因此就不会和栈中的a冲突,因此改为static后就正常了。

    个人的一点探讨,如尚未解决您的问题,可追问;若解决了您的问题,请采纳。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(6条)

报告相同问题?

悬赏问题

  • ¥15 fpga自动售货机数码管(相关搜索:数字时钟)
  • ¥20 Python安装cvxpy库出问题
  • ¥15 用前端向数据库插入数据,通过debug发现数据能走到后端,但是放行之后就会提示错误
  • ¥15 python天天向上类似问题,但没有清零
  • ¥30 3天&7天&&15天&销量如何统计同一行
  • ¥30 帮我写一段可以读取LD2450数据并计算距离的Arduino代码
  • ¥15 C#调用python代码(python带有库)
  • ¥15 活动选择题。最多可以参加几个项目?
  • ¥15 飞机曲面部件如机翼,壁板等具体的孔位模型
  • ¥15 vs2019中数据导出问题