主题:[讨论]关于printf函数的一个问题
CompileError
[专家分:0] 发布于 2011-02-07 19:06:00
#include <stdio.h>
int main()
{
unsigned short int a , b ;
scanf("%d%d" , &a , &b ) ;
printf("%d,%d",a,b) ;
return 0 ;
}
这个代码当输入1 2 时输出0,2而不是输出1,2
当交换a,b的位置 即
#include <stdio.h>
int main()
{
unsigned short int a , b ;
scanf("%d%d" , &b , &a ) ;
printf("%d,%d",b,a) ;
return 0 ;
}
时,输入1,2时能正确输出1,2
这是为什么?
p.s用的eclipse编译器,可以看看poj3718这个问题.很明显
求解 谢谢~
回复列表 (共2个回复)
沙发
CompileError [专家分:0] 发布于 2011-02-07 19:30:00
纠结了很久也没想出个所以然来。。求指点
读入unsigned short类型的数据是%d吧....
为什么交换a , b位置之后就能正确读入数据呢...太纠结了..
板凳
windy0will [专家分:2300] 发布于 2011-02-07 22:21:00
首先lz 您的代码能够很好的编译,没有什么警告?比如
[quote]
[color=800000]C:\Documents and Settings\Administrator\桌面\test>gcc -Wall -std=c99 noname.c
noname.c: In function `main':
noname.c:5: warning: int format, different type arg (arg 2)
noname.c:5: warning: int format, different type arg (arg 3)[/color][/quote]
对于scanf函数一定要注意格式要正确。
一般的情况,%d %u是int类型。%hd %hu是short类型。%hhd %hhu是char类型。
建议:把scanf("%d%d" , &a , &b )改为scanf ("%hd%hd", &a, &b).
如果改为 scanf ("%hu%hu", &a, &b)更好,毕竟有unsigned short int a , b;
如果要完完全全把 当交换a,b的位置输出看似是正确的1,2 是很麻烦的。
无论交不交换a,b的位置,都会出现溢出:某个变量会覆盖其他内存的值。下面我给一段代码,结合注释应该容易懂的:
[code=c]
#include <stdio.h>
#include <stdlib.h>
/* 我用的这台电脑是小尾端的,故下面代码只考虑小尾端 */
int main(void)
{
/* before_a的地址 > a的地址 > b的地址 > after_b的地址 */
unsigned short int before_a, a, b, after_b;
before_a = after_b = -1, a=0xaaaa, b=0xbbbb;
printf ("(%04hx) %04hx, %04hx (%04hx)\n\n",
before_a, a, b, after_b);
/* 输入1,将其保存到变量a中,由于类型长度不一致,0x000000001将分成2部分,低位
的0x0001保存到变量a中,高位的0x0000保存到before_a中,故将原来存在于before_a中的值覆盖了 */
before_a = after_b = -1, a=0xaaaa, b=0xbbbb;
scanf ("%d", &a); /* 这里输入 1 */
printf ("(%04hx) %04hx, %04hx (%04hx)\n\n",
before_a, a, b, after_b);
/* 输入2,过程和上面的一样,0x000000002(2)的高位0x0000将覆盖变量a原来值0xaaaa,低位0x2存于b中 */
before_a = after_b = -1, a=0xaaaa, b=0xbbbb;
scanf ("%d", &b); /* 这里输入 2 */
printf ("(%04hx) %04hx, %04hx (%04hx)\n\n",
before_a, a, b, after_b);
/* 输入 1 2:过程和上面的一样,
只是先把0x00000001覆盖a和before_a,此后a覆盖为(0x1),before_a覆盖为(0x0)
然后再把0x00000002覆盖b和a, 此后b覆盖为(0x0), b覆盖为(0x2) */
before_a = after_b = -1, a=0xaaaa, b=0xbbbb;
scanf ("%d%d", &a, &b); /* 这里输入 1 2 */
printf ("(%04hx) %04hx, %04hx (%04hx)\n\n",
before_a, a, b, after_b);
/* 输入 2 1:过程和上面的一样,
只是先把0x00000002覆盖a和 b,此后a覆盖为(0x0), b覆盖为(0x2)
然后再把0x00000002覆盖a和before_a,此后a覆盖为(0x1),before_a覆盖为(0x0) */
/* 由于楼主原来代码并没有before_a这个变量,输出的结果看似正确而已 */
before_a = after_b = -1, a=0xaaaa, b=0xbbbb;
scanf ("%d%d", &b, &a); /* 这里输入 2 1 */
printf ("(%04hx) %04hx, %04hx (%04hx)\n\n",
before_a, a, b, after_b);
system ("pause");
return 0 ;
}[/code]
我来回复