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处理。如果放一个字符变量,那么会导致多读取堆栈上额外的三个字节,也可能导致内存访问错误。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值