鱼C论坛

 找回密码
 立即注册
楼主: 压寨宝宝

c语言每次循环输入多个数据出错?见证基本功的时候到了各位~想挑战的来吧!~~

[复制链接]
发表于 2013-1-22 22:19:18 | 显示全部楼层
在 maill 出下断点 看反汇编代码 求采纳
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2013-1-22 22:25:05 | 显示全部楼层
int a[20],i,;
scanf("%d",&i);
scanf("%d",&a[i]); 这样的话是可以的,就是要输入两次,
在一次的情况是应该不行的!毕竟scanf("%d%d",&i,&a[i])输入的时候i 的值得还没存进去!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2013-1-22 22:43:06 | 显示全部楼层
  1. 0x004012f0 <main+0>:        push   %ebp
  2. 0x004012f1 <main+1>:        mov    %esp,%ebp
  3. 0x004012f3 <main+3>:        sub    $0x88,%esp
  4. 0x004012f9 <main+9>:        and    $0xfffffff0,%esp
  5. 0x004012fc <main+12>:        mov    $0x0,%eax
  6. 0x00401301 <main+17>:        add    $0xf,%eax
  7. 0x00401304 <main+20>:        add    $0xf,%eax
  8. 0x00401307 <main+23>:        shr    $0x4,%eax
  9. 0x0040130a <main+26>:        shl    $0x4,%eax
  10. 0x0040130d <main+29>:        mov    %eax,-0x6c(%ebp)
  11. 0x00401310 <main+32>:        mov    -0x6c(%ebp),%eax
  12. 0x00401313 <main+35>:        call   0x401858 <_alloca>
  13. 0x00401318 <main+40>:        call   0x4013d8 <__main>
  14. 0x0040131d <main+45>:        lea    -0x58(%ebp),%edx
  15. 0x00401320 <main+48>:        mov    -0x5c(%ebp),%eax
  16. 0x00401323 <main+51>:        shl    $0x2,%eax
  17. 0x00401326 <main+54>:        lea    (%edx,%eax,1),%eax
  18. 0x00401329 <main+57>:        mov    %eax,0x8(%esp)
  19. 0x0040132d <main+61>:        lea    -0x5c(%ebp),%eax
  20. 0x00401330 <main+64>:        mov    %eax,0x4(%esp)
  21. 0x00401334 <main+68>:        movl   $0x403000,(%esp)
  22. 0x0040133b <main+75>:        call   0x4018b8 <scanf>
  23. 0x00401340 <main+80>:        mov    $0x0,%eax
  24. 0x00401345 <main+85>:        leave  
  25. 0x00401346 <main+86>:        ret   
  26. End of assembler dump.
  27. (gdb)
复制代码
拜托了!~~~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2013-1-22 22:43:56 | 显示全部楼层
hy19970612 发表于 2013-1-22 22:06
你把汇编代码 反上来 我帮你解释 我没 VS
  1. #include<stdio.h>

  2. int main()
  3. {
  4.          int a[20],i;
  5.      scanf("%d,%d",&i,&a[i]);
  6.      return 0;
  7. }
复制代码
源程序是这个。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2013-1-23 11:54:39 | 显示全部楼层
C语言的程序运算顺序都是从右往左的。
这么写: scanf("%d,%d",&i,&a[i]);
是先赋a[i],而你的i在之前没有给出值,于是编译器找不到开辟的地址,所以出错了。
你这么写scanf("%d,%d",&a[i],&i);试试。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2013-1-23 15:33:18 | 显示全部楼层
季末、梨花雨落 发表于 2013-1-23 11:54
C语言的程序运算顺序都是从右往左的。
这么写: scanf("%d,%d",&i,&a);
是先赋a,而你的i在之前没有给出值 ...

刚试过了。还是不行。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2013-1-23 15:40:30 | 显示全部楼层
a是数组,所以c要求一开始就是固定的数值不能更改,除非分段隔开从新定义才行,i是int型所以可以直接赋值,但要注意i不能为数组值,这个就不能赋值,会直接报错的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2013-1-23 15:42:31 | 显示全部楼层
你说功能,我给你写代码吧,你的这个根本就不标准。。。我看得脑袋疼。。。。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2013-1-23 15:47:41 | 显示全部楼层
说真的,你如果学C先从TC学起吧,那样能养成良好的格式还有结构等,关于数组调用方面应该好好看看,没有这么用的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2013-1-23 15:48:55 | 显示全部楼层
52077643 发表于 2013-1-22 22:25
int a[20],i,;
scanf("%d",&i);
scanf("%d",&a); 这样的话是可以的,就是要输入两次,

这个用空格隔开就行了,不用分行
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2013-1-23 16:42:29 | 显示全部楼层
〢坏ヤρì滊 发表于 2013-1-23 15:48
这个用空格隔开就行了,不用分行

我写的时候也不会这么写。这是我帮同学调程序的时候发现的问题,觉得有点意思。
我就是想知道scanf里面这个是怎么扫描赋值的。
你的意见我会听取的,好好学习c的。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2013-1-23 23:33:10 | 显示全部楼层
本帖最后由 huise865 于 2013-1-23 23:43 编辑

对scanf函数来说,同时进行读入、那么前面的变量对于后面的变量来讲就是没有意义的。
比如:

  1. int i = 2,j[10];
  2. scanf("%d,%d",&i,&j[i]);      //请注意这里的i值变化,因为此时i的输入对于后面"&j[i]"是没有意义的
  3.                                //原理大概就是>首先扫描到i的地址和&j[i]的地址到缓冲区、那此时
  4.                               //&j[i]的地址是多少呢?此时的i又为多少? 由于现在i的值为2,所以
  5.                              //应该扫描&j[2]的地址到缓冲区,然后等待用户输入,原理就是这样   
复制代码

评分

参与人数 1鱼币 +3 收起 理由
压寨宝宝 + 3 感谢!!~~~~

查看全部评分

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

使用道具 举报

发表于 2013-1-24 08:59:23 | 显示全部楼层
本帖最后由 〢坏ヤρì滊 于 2013-1-24 09:00 编辑
压寨宝宝 发表于 2013-1-23 16:42
我写的时候也不会这么写。这是我帮同学调程序的时候发现的问题,觉得有点意思。
我就是想知道scanf里面这 ...


简单举个例子吧
比如:scanf("%d",&a);
首先scanf是输入一个值,把这个值赋予给a,
而%d是取整数但是是小于单精数的一个数值,也就是小于25000的值,d是取整的格式,&是赋值,这个是固定格式,就是这么简单的,如果格式如你输入的不正确,会出现报错,如何让他不报错,那么简单做个if语句判断返回一下就行,当然如果定义数组时,你没定义,或者是一个变量,当执行到那步仍然是变量时就会报错,如果你在前段用指针指向过去,而后段调用那就没问题了,记得第二段定义一下就可以了,使用的数值仍是前段的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2013-1-24 09:23:28 | 显示全部楼层
我想问下你,你的scanf("%d",&a[i])有什么特殊意义么?为什么不写成scanf("%d",&a)?你是想把值赋给指定的内存空间地址呢还是要做什么?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2013-1-24 10:15:58 | 显示全部楼层
huise865 发表于 2013-1-23 23:33
对scanf函数来说,同时进行读入、那么前面的变量对于后面的变量来讲就是没有意义的。
比如:

恩!按照你解释的原理的话,我的疑问就解释的通了。
但是,我依旧有点点不确定的是,它的客观的原理是不是就是这样的。。
这位热心的大师,你是从何处了解到scanf是这个运行原理的呢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2013-1-24 10:48:11 | 显示全部楼层
〢坏ヤρì滊 发表于 2013-1-24 08:59
简单举个例子吧
比如:scanf("%d",&a);
首先scanf是输入一个值,把这个值赋予给a,

额。总感觉不是我想要知道的东西。
这样吧。我跟你叙述下我的理解,你看下哪里有问题。
1.取出scanf中要赋予值的变量的地址。比如本例中的i,a,入栈。
2,扫描用户输入的暂存在输入缓冲区的数值,
3,按顺序将扫描的数值依次赋予到对应的变量当中。比如本例中的i,a.
接着本例中的问题出现在第一步,变量a中i值不定,由系统随机给予垃圾值,造成访问地址的段异常,于是呼程序崩溃停止。
上面三步我是按照“huise865”热心的朋友的解释来理解的过程。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2013-1-24 11:30:57 | 显示全部楼层
我的理解是   “int a[20],i;”
                  这行代码是叫系统分配给数组a[]一定的内存空间,a[0]到a[19],然后给i分配内存空间.

                  "scanf("%d,%d",&i,&a[i]);"
                   这行代码的意思是找到i的地址,把输入的值放进i,然后找a[i]的地址,把值放进去,但是因为一开始i只是定义了,并没有初始化(赋值),所以执行这个语句的时候,a[i]中的i是超出a[0]到a[19]的值的垃圾值

#include <stdio.h>

int main(void)
{
        int i;
        int a[20];
       
        i = 5;
        //scanf("%d %d", &i, &a[i]);  errer  &a[i]中i在使用的时候没有先初始化,是个垃圾值
       
        scanf("%d", &a[i]); //正确,因为在这之前,i已经初始化,是有意义的值
        printf("i = %d   a[%d] = %d\n", i, i, a[i]);
       
        return 0;
}

评分

参与人数 1鱼币 +2 收起 理由
压寨宝宝 + 2 thank you!!~

查看全部评分

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

使用道具 举报

 楼主| 发表于 2013-1-24 12:25:50 | 显示全部楼层
翠竹 发表于 2013-1-24 11:31
既然你问了,我就反汇编解释一下
程序段初始化不说了,直接看这句:
4:        int a[20],i;

很详细!!很好。非常感谢,理解啦!~~~
恩!!正在努力学习汇编中!~~~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2013-1-24 12:28:22 | 显示全部楼层
L]V[G 发表于 2013-1-24 11:30
我的理解是   “int a[20],i;”
                  这行代码是叫系统分配给数组a[]一定的内存空间,a[0]到 ...

恩恩,同意!!~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2013-1-25 08:56:13 | 显示全部楼层
本帖最后由 〢坏ヤρì滊 于 2013-1-25 08:58 编辑
压寨宝宝 发表于 2013-1-24 10:48
额。总感觉不是我想要知道的东西。
这样吧。我跟你叙述下我的理解,你看下哪里有问题。
1.取出 ...


这么跟你解释把,数组要求的是提前声明变量值,才能调用,也就是说int a[20] ,i;下面调用时可以直接使用a这样就行了,就是c要求数组必须腾出部分固定内存空间来存入你放入数组的数值的地方,这样明白吗?
但是规定了不能够后期调用进i这个值,否则声明数组时就是存在问题了,关键在于你编写的程序是先使用使用数组后定义数组大小,问题就是这个,如果你想自定义数组,那么就分段控制, 内外结构就可以了,内部定义后返回外部继续使用这个数组就行。。。。这回明白了。。。。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-6 08:10

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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