探讨一个scanf问题
时间:2009-01-31
来源:互联网
#include <stdio.h> int main(void) { int c, rc; rc = scanf("%c", &c); int i=-1; printf("%d, %c", c , c); return 0; } |
看起来是,是scanf函数不允许(把char型,输入到int型)?但是为什么有的gcc版本可以呢?为什么 int i=-1;会干扰输出?
作者: blackwhite 发布时间: 2009-01-31
那行打印语句应为
printf("%d, %c", c&0xff , c);
作者: biinn 发布时间: 2009-01-31
就像 int a, b = 0;
a = b++ + ++b + b++;
一样
没有标准答案或者预期结果
作者: 8pm 发布时间: 2009-01-31
作者: blackwhite 发布时间: 2009-01-31
作者: 8pm
标准没有规定的行為是不确定的
就像 int a, b = 0; a = b++ + ++b + b++; 一样 没有标准答案或者预期结果 |
作者: blackwhite 发布时间: 2009-01-31
作者: blackwhite
这个仅仅是编译器依赖,对同一个编译器结果是肯定的。
|
作者: blackwhite
这个程序是从一个书上的几十行的例子来的。发现有问题,调试到最后调试的结果就是上面的例子了。我可以理解认为c有部分字节没有初始化,如果初始化了,就没有这个问题了。但是问题是为什么后的int i=-1;会对结果产生干扰?,有和没有结果不一样?
|
例如是否需要一早就预留位置
在这个例子,用 -S 编译成汇编就可以看出那里不一样,leaq -8(%rbp), %rsi,和 leaq -12(%rbp), %rsi 的区别。
但是标准没定义,GCC 也没有承诺一定会这样实现。
所以我还是那句话,标准没规定的东西,没有肯定的结果。即便是你说的所謂的“编译器依赖”,不能保证一样结果就没有深究的必要
作者: 8pm 发布时间: 2009-01-31
作者: blackwhite 发布时间: 2009-01-31
作者: Etrnls 发布时间: 2009-01-31
作者: blackwhite
谢谢指教。汇编那里没有看明白(因为不懂)。
|
leaq 指令就是 lea 指令的 64-bit 版(我用的是 x86_64)
作者: 8pm 发布时间: 2009-01-31
作者: blackwhite
这个仅仅是编译器依赖,对同一个编译器结果是肯定的。
|
违反函数对参数的要求去调用函数,并依赖其“正确”结果本来就是撞大运,测试其在不同编译器下的结果对于学习语言确实有研究价值,但在实用中根本不应当这样写程序。
作者: poet 发布时间: 2009-01-31
作者: blackwhite
这个程序是从一个书上的几十行的例子来的。发现有问题,调试到最后调试的结果就是上面的例子了。我可以理解认为c有部分字节没有初始化,如果初始化了,就没有这个问题了。但是问题是为什么后的int i=-1;会对结果产生干扰?,有和没有结果不一样?
|
作者: richardpku 发布时间: 2009-01-31
作者: blackwhite
这个仅仅是编译器依赖,对同一个编译器结果是肯定的。
|
xxx@desktop /tmp $ cat a.c #include <stdio.h> int main() { int a; scanf ("%d", &a); int b = a++ + ++a + a++ + a++; printf ("%d\n", b); return 0; } xxx@desktop /tmp $ gcc a.c xxx@desktop /tmp $ ./a.out <<< 2 11 xxx@desktop /tmp $ gcc -O a.c xxx@desktop /tmp $ ./a.out <<< 2 12 xxx@desktop /tmp $ gcc -v Using built-in specs. Target: x86_64-pc-linux-gnu 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 Thread model: posix gcc version 4.2.4 (Gentoo 4.2.4 p1.0)
作者: richardpku 发布时间: 2009-01-31
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);
}
作者: quantumfang 发布时间: 2009-01-31
把大家的帖子看懂了再说话。
作者: biinn 发布时间: 2009-01-31
这个程序是我从一个那个C programming Language的习题答案上来的简化过来有问题的code。
这个程序出问题的时候,我看了man scanf,man里边是说了前后类型要一致。它用的是must be。
在不同的机器上,不同版本的机器上,反正结果不可以预测。后边有没有其它的操作也会影响到结果。
12楼给出的例子,是个很好的例子,但是我想这个例子更可以说明的是,程序优化,也可能会让结果变化。上次gcc的那个abs bug,就是优化的结果完全错误。
作者: blackwhite 发布时间: 2009-02-01
作者: blackwhite
谢谢大家讨论。
这个程序是我从一个那个C programming Language的习题答案上来的简化过来有问题的code。 这个程序出问题的时候,我看了man scanf,man里边是说了前后类型要一致。它用的是must be。 在不同的机器上,不同版本的机器上,反正结果不可以预测。后边有没有其它的操作也会影响到结果。 12楼给出的例子,是个很好的例子,但是我想这个例子更可以说明的是,程序优化,也可能会让结果变化。上次gcc的那个abs bug,就是优化的结果完全错误。 |
作者: richardpku 发布时间: 2009-02-01
作者: biinn
拜托,楼上的。
把大家的帖子看懂了再说话。 |
当然我知道大多数砖家说的是非标准代码产生不确定结果
楼上的批评我不知所云,那我反问你别人的答复跟我的观点有关系吗?
貌似有点关系?:非标准的代码不是好的风格。
本人不是程序员,没有编过很多,很大的程序,但是有点体会:代码里面有时候陷阱重重,其实好多陷阱都是自己设的。事后恍然大悟,根本不是陷阱。那又是什么?自问吧
所以我强调的是好的风格
作者: quantumfang 发布时间: 2009-02-01
作者: quantumfang
楼上的批评我不知所云,那我反问你别人的答复跟我的观点有关系吗?
|
至于你回帖中的其他内容,我不想说什么了。
作者: biinn 发布时间: 2009-02-01
热门阅读
-
office 2019专业增强版最新2021版激活秘钥/序列号/激活码推荐 附激活工具
阅读:74
-
如何安装mysql8.0
阅读:31
-
Word快速设置标题样式步骤详解
阅读:28
-
20+道必知必会的Vue面试题(附答案解析)
阅读:37
-
HTML如何制作表单
阅读:22
-
百词斩可以改天数吗?当然可以,4个步骤轻松修改天数!
阅读:31
-
ET文件格式和XLS格式文件之间如何转化?
阅读:24
-
react和vue的区别及优缺点是什么
阅读:121
-
支付宝人脸识别如何关闭?
阅读:21
-
腾讯微云怎么修改照片或视频备份路径?
阅读:28