scanf()接受不同类型的参数的一个例子

avatar 2017年07月27日08:54:00 1 2904 views
博主分享免费Java教学视频,B站账号:Java刘哥 ,长期提供技术问题解决、项目定制:本站商品点此
在《C陷阱与缺陷》连接(第四章)那一章中,有这样一个程序:
  1. #include <stdio.h>
  2. main()
  3. {
  4.     int i;
  5.     char c;
  6.     for(i = 0; i < 5; ++i)
  7.     {
  8.         scanf("%d", &c);
  9.         printf("%d ", i);
  10.     }
  11.     printf("\n");
  12. }

这是一个关于printf()与scanf()在不同情形下可以接受不同类型的参数的一个例子。
       如果我们输入0 1 2 3 4, 并不一定能够得到0 1 2 3 4。在有些编译器上,可能得到0 0 0 0 0 1 2 3 4。
为什么呢?原因就像书上所说的一样,问题的关键在于c被声明为char类型,而不是int类型。当程序要求scanf()读入一个整数,应该给它传递一个指向整数的指针。而程序中scanf()得到的却是一个指向字符的指针,scanf()并不能分辨这种情况。它只是将这个指向字符的指针作为指向整数的指针而接受,并在指针指向的位置存储一个整数。因为整数所占的存储空间要大于字符所占的存储空间,所以字符c附近的内存将被覆盖。
    下面,我将详细说明一下上面所说的这一种情况,注意,只有某些编译器会有上面的结果,并不是所有的都会这样,我自己的就不是这样的

1. 这是我们假设的在内存中变量的存储情况:



2. 我们现在从循环开始,i = 0, 输入c=0,得到如下结果:



3. 现在i++, i = 1, 输入1,由于输入时会把char当作int来处理,红色框为char的内存加上覆盖到的其他部分内存空间,蓝色框为i的内存空间,如下图:



4. i不断的++,我们输入2, 3, 4,都像上面的情况一样,2, 3, 4都在0x00000000地址的位置存储着,而从0x00000004开始到0x00000010,始终都为0,下面看一下输入4的情况:



如果我们是从终端输入的话,那么这个程序在某些机器上始终让你输入,是个死循环,因为i的值根本就没有发生改变,每次被重新设置为0,循环将一直进行。
    但是假设我们是从文件读入的,当读入到4时,就已经是文件末尾了。那么当循环在此执行时,scanf函数不再试图读入新的数值到c,这时,i才可以正常地递增,于是执行printf(),打印出1,如此下去,将打印2, 3, 4。然后程序结束,最终打印的结果就为书上所描述的那种情况:0 0 0 0 0 1 2 3 4。
    特别注意,上面所说的都是某些机器上运行的结果,算是一个特例。并不是每个机器上都会运行出那样的结果的



原文地址:http://blog.chinaunix.NET/uid-24807808-id-3335656.html

  • 微信
  • 交流学习,资料分享
  • weinxin
  • 个人淘宝
  • 店铺名:言曌博客咨询部

  • (部分商品未及时上架淘宝)
avatar

发表评论

avatar 登录者:匿名
匿名评论,评论回复后会有邮件通知

  

已通过评论:0   待审核评论数:0