关于printf()与scanf()在不同情形下可以接受不同类型的参数的一个例子。

引用地址:http://blog.chinaunix.net/uid-24807808-id-3335656.html

在《C陷阱与缺陷》连接(第四章)那一章中,有这样一个程序:

#include <stdio.h>

main()
{
    int i;
    char c;
    
    for(i = 0; i < 5; ++i)
    {
        scanf("%d", &c);
        printf("%d ", i);
    }

    printf("\n");
}

这是一个关于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。

    特别注意,上面所说的都是某些机器上运行的结果,算是一个特例。并不是每个机器上都会运行出那样的结果的


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值