目录

  • 关于C语言中printf函数“输出歧视”的问题

    • 问题描述
    • 探索问题原因
    • 另一种研究方法
    • 问题结论

关于C语言中printf函数“输出歧视”的问题

问题描述

昨天晚上被问到一个问题,为什么在同一个printf函数中两次输出一个double型变量会得不到正确的结果。具体代码大致如下:

#include <stdio.h>int main()
{int a;double b;double result;printf("Please input a: ");scanf("%d", &a);printf("Please input b: ");scanf("%lf", &b);printf("\n");result = a * b;printf("result_int: %d\nresult_double: %f\n", result, result);return 0;
}

看主函数的第18行语句,其中result作为一个double型变量,被以整型浮点型分别输出了一次,按照正常思路,输出应该是下面这样:

Please input a: 12
Please input b: 12.3result_int: 858993460
result_double: 147.600000

即前一个按整型输出时,会按照double型低32位的数据,输出一个不期望的整数。

但是第二次输出时,则会按照其正确的形式(64位8字节double类型)输出一个预期中的浮点数:147.600000

结果却大出意料,实际输出是下面这样:

Please input a: 12
Please input b: 12.3result_int: 858993460
result_double: 0.000000

探索问题原因

这样的结果让人很意外,第一时间就想到了是否是因为result本身出了问题,所以在原程序后加入了一句printf("\n%f\n", result);来确认result是否发生了意料之外的变化。

但是很显然,并不是result出了问题,因为单独输出的result依然是正常的147.600000

那么接下来,既然result本身没有问题,就应当想到是否在输出上出了问题。比如很显然地,%d格式是标准的Int型输出格式,正常来讲应该是32位数据,而double则是64位数据,是否是这里出了问题呢?

比如在同一句输出里面,对同一个变量多次不完整输出,导致了其地址的递进式输出。

当然,到此时,这只是我的一种猜测。

要验证这个想法,最简单的莫过于直接查看内存内容。

如图

转换为4字节整数显示结果为
与输出

result_lower_32 = 858993459
result_higher_32 = 1080193843
resule_now = 147.600000

相符。

到此,产生这一问题的原因已经弄清楚了,并且最终问题应该是出在printf函数的定义中,看来还是C语言基础不牢,今天开始有必要重新学习,认真研究其每个细节。

另一种研究方法

实际上一开始因为不太熟悉VS的调试操作,并没能很快地在调试界面找到方法查看具体变量的内存地址及其内容,原因一则是很久没有用C语言了,二则当初学的时候也没有认真,所以验证这个问题的过程十分艰辛,

中间还自己写了个函数想要输出数据的二进制格式,但是这个函数针对整型时工作正常,换成double型之后,由于没想到办法对double型和unsigned long long型直接进行位运算,所以迫不得已对double型数据进行了强制类型转换,最终发现强制类型转换会导致数据变化,无法保持其原型,所以这一思路作废。就此略过不表。

后来想起来C语言中可以对数据直接按16进制格式输出,故设计了如下程序进行尝试。

#include <stdio.h>int main()
{//该系统中,double为64位8字节,int和long为32位4字节。//且为小端系统,即低位数据存储在内存的低位地址中。double b;printf("Please input the values of b:\n");scanf("%lf", &b);printf("\n");printf("These are two parts of b:\n");printf("\tlower byte = \t%#x\n\thigher byte = \t%#x\n\n", b, b);printf("This is the whole b:\n");printf("\t%#llx\n", b);return 0;
}

输出如下(输入为12.3)

Please input the values of b:
12.3These are two parts of b:lower byte =    0x9999999ahigher byte =   0x40289999This is the whole b:0x402899999999999a

问题结论

从上述两种研究方法的结果,我们可以明显看到,在同一个输出格式字符串中,倘若针对某一个待输出量的转换说明不足以对应其所有的数据位,则printf函数仅仅按照转换说明对应的数据位数,从低到高,依次输出。

所以对于介于初学和中级之间的学习者而言,研究stdio.h头文件的源码函数很有必要的。

转载于:https://www.cnblogs.com/lierchao/p/10003639.html

关于C语言中printf函数“输出歧视”的问题相关推荐

  1. c语言输出的时候让字符占五位,C语言中printf的规范输出

    1.调用格式为  printf("", ); 其中格式化字符串包括两部分内容: 一部分是正常字符, 这些字符将按原样输出; 另一部分是格式化规定字符, 以"%" ...

  2. exit在c语言里的作用,C语言中exit函数的使用

    exit() 结束当前进程/当前程序/,在整个程序中,只要调用 exit ,就结束 return() 是当前函数返回,当然如果是在主函数main, 自然也就结束当前进程了,如果不是,那就是退回上一层调 ...

  3. C语言程序设计中用printf函数输出数据

    文章目录 前言 一.创建C语言项目 二.printf函数介绍 总结 前言 记录暑假期间自学C语言的小问题和总结 一.创建C语言项目 这里使用的是Visual Studio 2019 首先新建一个C++ ...

  4. c语言中printf格式大全,printf()输出格式大全

    学习了<C语言printf()和puts()的简单使用>,大家应该能够使用 printf() 输出简单格式的数据了,%d.%f.%c 和 %s 只是 printf( ) 的格式控制字符串中 ...

  5. c语言printf函数的作用,c语言中printf用法及其函数定义

    c语言中printf用法及其函数定义 发布时间:2020-04-09 10:51:14 来源:亿速云 阅读:354 作者:小新 今天小编给大家分享的是c语言中printf用法及其函数定义,很多人都不太 ...

  6. 利用c语言中printf输出图形

    c语言中利用printf输出图形 通过对c语言中printf的使用,我根据自己对*符号的排版利用dev c++编译出了一个菱形的图案.感受到了通过高级程序语言输出自己构建的内容的乐趣.在这个过程中,计 ...

  7. python语言中ch_已知在Python语言中 upper() 函数可以将英文小写字母转化为大写字母,例如: 'cpda'.upper() CPDA 则下列语句的输出结果为 CHINACPD...

    已知在Python语言中 upper() 函数可以将英文小写字母转化为大写字母,例如: >>> 'cpda'.upper() CPDA 则下列语句的输出结果为 CHINACPDA a ...

  8. c程序设计语言中printf,编程序 用getchar函数读入两个字符c1和c2,然后分别用putchar和printf函数输出这两个字符。请问...

    编程序,用getchar函数读入两个字符给c1和c2,然后分别用putchar和printf函数输出这两个字符.请问: 1. 变量C1,C2应定义为字符型或整型?或二者皆可? 答:在这个题目里,变量C ...

  9. c语言中gets函数可以输入空格吗_C语言中printf和gets函数的实用技巧

    Printf函数输出的格式与方法: 想要一起学习交流,或者系统学习c++的可以加553014383,邀请码:悟空,裙内有众多资源及解答老师. 1.输出数字的时候存在宽度和精度,那对于数字而言,输出数字 ...

最新文章

  1. [Zend PHP5 Cerification] Lectures -- 4. XML Web Service
  2. OpenGL入门学习(十二) 【转】
  3. 在Python中使用LDA处理文本
  4. 小米用户画像_鹅智库发布手机品牌用户画像 一二线城市最爱小米 5G领域或占先机...
  5. 【已解决】ReferenceError: $ is not defined
  6. INTEROP tile cache
  7. windows系统-汇编语言与机器码的关系
  8. 可持久化3--可持久化01Trie
  9. [存档]获取通讯录信息并写到SD卡上
  10. R语言实现46种距离算法
  11. 固态硬盘测试软件有哪些,手把手教你测试固态硬盘!硬盘测试软件大汇总
  12. C语言冒泡排序(升序)
  13. [数理统计-逐步回归]国内旅游收入回归
  14. STM32F205VCT6主控PLC控制器板,已批量生产
  15. Opencv实战四 图像匹配
  16. Python|从PDF中批量提取图片
  17. (基于matlab)蒙特卡罗法 之 布丰投针实验 (1/10)
  18. 笔记本卡顿不流畅是什么原因_电脑卡顿不流畅是什么原因?
  19. 指纹支付 java lang6_支付宝;超6成人使用指纹、刷脸支付,网友;喜欢用密码!...
  20. 阿姨,我真不是修电脑的!

热门文章

  1. 【Kaggle Learn】Python 5-8
  2. 使用 alpine 打包镜像注意事项
  3. Linux shell 学习笔记(12)— linux 信号、后台运行脚本、作业控制、定时运行任务
  4. 提高班第三周周记(中秋第三天)
  5. 《attention is all you need》解读
  6. 一起读Bert文本分类代码 (pytorch篇 五)
  7. The bean 'xxxx.FeignClientSpecification', defined in null, could not be registered. A bean with that
  8. LeetCode简单题之按键持续时间最长的键
  9. 自定义算子高性能开发
  10. Jittor 的Op, Var算子