LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
12
返回列表 发新帖
楼主: blackwhite

探讨一个scanf问题

[复制链接]
发表于 2009-1-31 13:49:11 | 显示全部楼层
Post by blackwhite;1942487
这个程序是从一个书上的几十行的例子来的。发现有问题,调试到最后调试的结果就是上面的例子了。我可以理解认为c有部分字节没有初始化,如果初始化了,就没有这个问题了。[color="Red"]但是问题是为什么后的int i=-1;会对结果产生干扰?,有和没有结果不一样?


初始化了照样有问题,scanf的类型必须严格一致。你把程序放到大端的架构上运行就挂了
回复 支持 反对

使用道具 举报

发表于 2009-1-31 13:51:45 | 显示全部楼层
Post by blackwhite;1942488
这个仅仅是编译器依赖,对同一个编译器结果是肯定的。

那可未必。这个是 undefined behavior,你说的情况那叫 implementation-defined behavior。
  1. xxx@desktop /tmp $ cat a.c
  2. #include <stdio.h>
  3. int main()
  4. {
  5.     int a;
  6.     scanf ("%d", &a);
  7.     int b = a++ + ++a + a++ + a++;
  8.     printf ("%d\n", b);
  9.     return 0;
  10. }
  11. xxx@desktop /tmp $ gcc a.c
  12. xxx@desktop /tmp $ ./a.out <<< 2
  13. 11
  14. xxx@desktop /tmp $ gcc -O a.c
  15. xxx@desktop /tmp $ ./a.out <<< 2
  16. 12
  17. xxx@desktop /tmp $ gcc -v
  18. Using built-in specs.
  19. Target: x86_64-pc-linux-gnu
  20. Configured with: /var/tmp/portage/sys-devel/gcc-4.2.4/work/gcc-4.2.4/configure --prefix=/usr --bindir=/usr/x86_64-pc-linux-gnu/gcc-bin/4.2.4 --includedir=/usr/lib/gcc/x86_64-pc-linux-gnu/4.2.4/include --datadir=/usr/share/gcc-data/x86_64-pc-linux-gnu/4.2.4 --mandir=/usr/share/gcc-data/x86_64-pc-linux-gnu/4.2.4/man --infodir=/usr/share/gcc-data/x86_64-pc-linux-gnu/4.2.4/info --with-gxx-include-dir=/usr/lib/gcc/x86_64-pc-linux-gnu/4.2.4/include/g++-v4 --host=x86_64-pc-linux-gnu --build=x86_64-pc-linux-gnu --disable-altivec --disable-nls --with-system-zlib --disable-checking --disable-werror --enable-secureplt --enable-multilib --disable-libmudflap --disable-libssp --disable-libgcj --enable-languages=c,c++,treelang,fortran --enable-shared --enable-threads=posix --enable-__cxa_atexit --enable-clocale=gnu
  21. Thread model: posix
  22. gcc version 4.2.4 (Gentoo 4.2.4 p1.0)
复制代码
回复 支持 反对

使用道具 举报

发表于 2009-1-31 14:55:21 | 显示全部楼层
楼主说的太诡异了!
int i=-1;会有影响?这一句完全可以删掉的,难道真的会有影响?!

楼主预期的结果的什么,不妨也写出来,便于对比。
你的程序我编译了,输入同一个参数,每次结果都不同。(icc,gcc)

yf@qv ~ $ ./a.out
128
-1081859279, 1
yf@qv ~ $ ./a.out
128
-1082095055, 1
yf@qv ~ $ ./a.out
3
-1081318605, 3
yf@qv ~ $ ./a.out
3
-1075771341, 3
yf@qv ~ $ ./a.out
3
-1080130509, 3
yf@qv ~ $ ./a.out
AA
-1076881599, A
yf@qv ~ $ ./a.out
A
-1080507327, A
yf@qv ~ $ ./a.out
A
-1081625791, A


应该说是你的编程风格不好,里面包含陷阱。

int i=-1;注释掉和不注释都试了。

#include <stdio.h>
#include<stdlib.h>
int main(void)
{
        int c, rc;
        rc = scanf("%c", &c);
        //int i=-1;
        printf("%d, %c\n", c , c);
        //return 0;
        exit(0);
}
回复 支持 反对

使用道具 举报

发表于 2009-1-31 15:49:56 | 显示全部楼层
拜托,楼上的。
把大家的帖子看懂了再说话。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-1-31 23:46:13 | 显示全部楼层
谢谢大家讨论。
[color="Red"]这个程序是我从一个那个C programming Language的习题答案上来的简化过来有问题的code。
这个程序出问题的时候,我看了man scanf,man里边是说了前后类型要一致。它用的是must be。
在不同的机器上,不同版本的机器上,[color="Red"]反正结果不可以预测。后边有没有其它的操作也会影响到结果。
12楼给出的例子,是个很好的例子,但是我想这个例子更可以说明的是,程序优化,也可能会让结果变化。上次gcc的那个abs bug,就是优化的结果完全错误。
回复 支持 反对

使用道具 举报

发表于 2009-2-1 02:59:08 | 显示全部楼层
Post by blackwhite;1942700
谢谢大家讨论。
[color="Red"]这个程序是我从一个那个C programming Language的习题答案上来的简化过来有问题的code。
这个程序出问题的时候,我看了man scanf,man里边是说了前后类型要一致。它用的是must be。
在不同的机器上,不同版本的机器上,[color="Red"]反正结果不可以预测。后边有没有其它的操作也会影响到结果。
12楼给出的例子,是个很好的例子,但是我想这个例子更可以说明的是,程序优化,也可能会让结果变化。上次gcc的那个abs bug,就是优化的结果完全错误。


abs那个是gcc bug。 这里是undefined behavior,根本不是一回事……
回复 支持 反对

使用道具 举报

发表于 2009-2-1 03:17:56 | 显示全部楼层
Post by biinn;1942577
拜托,楼上的。
把大家的帖子看懂了再说话。


我说的是楼主说的其中一点:int i=-1;是否有影响?

当然我知道大多数砖家说的是非标准代码产生不确定结果

楼上的批评我不知所云,那我反问你别人的答复跟我的观点有关系吗?

貌似有点关系?:非标准的代码不是好的风格。

本人不是程序员,没有编过很多,很大的程序,但是有点体会:代码里面有时候陷阱重重,其实好多陷阱都是自己设的。事后恍然大悟,根本不是陷阱。那又是什么?自问吧

所以我强调的是好的风格
回复 支持 反对

使用道具 举报

发表于 2009-2-1 11:54:48 | 显示全部楼层
Post by quantumfang;1942742

楼上的批评我不知所云,那我反问你别人的答复跟我的观点有关系吗?

你至少连 lz 的帖子都没仔细看。lz 的代码是从书中看到的,可你却说 lz 的编程风格不好。那代码根本不是他写的。

至于你回帖中的其他内容,我不想说什么了。
回复 支持 反对

使用道具 举报

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

本版积分规则

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