标题:scanf和printf函数家族用于格式化输入和输出
只看楼主
ghsagdh
Rank: 1
等 级:新手上路
帖 子:2
专家分:0
注 册:2011-7-5
 问题点数:0 回复次数:0 
scanf和printf函数家族用于格式化输入和输出
scanf和printf函数家族用于格式化输入和输出,功能非常强大,但是也非常容易出错。尤其是scanf后果更为严重,动不动就是内存访问错误。

  由 于在C中,整型默认为int,浮点型默认为double。所以用scanf读入short和long需要分别用%hd和%ld,而浮点数又有些特别,%f 对应的是float,而不是%hf,相反double对应的%lf,而long double对应的是%Lf。其实我觉得,如果采用%hf-- float,%f--double, %lf--long double更为合理,与整型处理更一致,真不知道scanf的设计和实现者是如何考虑的。

  由 于编译器不扫描scanf和printf的格式字符串,所以无从知晓是否对应正确。scanf应该不会对参数进行任何处理,short指针就 是 short指针,float指针就是float指针。而printf就不一样了,精度低于int的参数如short会提升为int,精度低于 double 的类型如float会提升为double。

  scanf不管传入的指针具体类型,只是根据格式字符串的指示,把特定参数 当作某种类型指针使用,比如%d对应的是一个4字节的整型指针,如果传入的是一个short指针,那么scanf还是会把它当作整型指针使用,结果多修改 了两个字节。此外还有%d、%hd等对应到char *,%f、%lf或%Lf对应到int *等都会导致严重后果。%n对应的是一个整型指针,返回已经 扫描过的字符数。%hn对应short *,%ld对应long *,这和%d是一致的。%n不会扫描输入流,这是它别的格式码最大的区别。

  printf相对来说要稍微安全一点,因为大部分情况下它只对参数读,%n是一个例外。但是对应错误会导致输出结果不正确。比如比较经典的是:

  printf( "%d\n", 3.14 );

  输 出结果不是3而是令人奇怪的1374389535,原因其实很简单,3.14是一个8字节的double值,但printf把它的低4字节当作int处 理,于是得到这么奇怪的结果。printf不知道如何处理3.14,只知道它是一个double值,于是就当double处理。如果放一个字符变量,那么 会导致多读取堆栈上额外的三个字节,也可能导致内存访问错误。
搜索更多相关主题的帖子: 编译器 double 字符串 short 
2011-08-06 10:24



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-346915-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.301415 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved