scanf语句执行过程:

(1)逆序取参数的偏移地址并分别入栈。

(2)根据控制字符串的格式说明符从缓冲区取数据给各变量赋值。

①若格式说明符是数值类数据:如果从缓冲区中拿出的第一个字符可以合法表示该数值类型数据(如对应%d的可以是任何数字字符、+、-;若对应%x,则除了以上还有字母a—b也可,and so forth...),然后取下一个字符,直到非合法字符,则认为该数值读取完毕并把该非法字符送回缓冲区。把之前取得的合法字符串转换成相应的数值类型并赋值。

如果从缓冲区中拿出的第一个字符对应格式说明符来说不是合法字符则直接把该非法字符送回缓冲区,在不给当前变量赋值的情况下结束该条语句。如:

 #include<stdio.h>
int main ( )
{
int a,i=;
printf("%d\n",a);
while(i<)
{scanf("%d",&a);
printf("%d\n",a);
i++;
}
return ;
}

程序执行如下图(其中第2行的a为输入回显)

aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQIAAACHCAIAAAByJ8DYAAAD6UlEQVR4nO3d23XjNhQF0NNuukopqiJpYBpIKsiHlWUOH5eXlGRTxt5LH1oQdAFCPJY9FEb569c/bm6D3/L3r3/d3Aa//RaDP2FI8xj8AeNZiUFgNGIAYgBiADkYg9vEamPx0G6dE+2zDqtP2aqzVYoR9WMwPXW27h/t/8j92UC3RfyK+RTTZkTXj8FWzWnLufmIAXdHY/Bx6vRPu7r/gzE4MZ+sJYfRLWNwW/PRefUEWu1Z9C+e0ik1a9m6X/S/LZLD6E78UrR6ms76dPp3iuzWX570nXjUozCcx/826PR5RQyOjjtLoxjw6bl/Ivdj0M/As+I3e64Y8Onx6waPtG/Vb4679WhnPjLAJ1eRQQxADCBiABEDiBhAxAAiBhAxgIgBZCMGPnHAWOp3A0lgCLvvBmLAz7e1++zjUTFgCGIAO78URRIYgX8wBTEAMYCIAUQMIGIAEQOI7zeAvMN/7L471vK0LrrVfRjU9WOwVXPacm4+YsCd7zcA328Avt8A4vsNIL7fAOL7DSCuIkPEACIGEDGAiAFEDCBiALHfAPIOH7TeHWt5Whfd6j4M6vox2Ko5bTk3HzHgzn4DsN8A7DeA2G8Asd8AYr8BxFVkiBhAxAAiBhAxgIgBRAwg9htA3uGD1rtjLU/rolvdh0FdPwZbNact5+YjBtzZbwD2G4D9BhD7DSD2G0DsN4C4igwRA4gYQMQAIgYQMYCIAcR+A8g7fNB6d6zlaV10q/swqOvHYKvmtOXcfMSAO/sNwH4DsN8AYr8BxH4DiP0GEFeRIWIAEQOIGEDEACIGEDGA2G8AeYcPWu+OtTyti251HwZ1/Rhs1Zy2nJuPGHBnvwHYbwD2G0DsN4DYbwCx3wDiKjJEDCBiABEDiBhAxAAiBpDeZ4q+e46vNchh9o24GqvvBstLUd84wy/wBcd4tTUs5jPCKz4nBnn9MV5tDa82n+/Xj8H0l4fZOnY+vNBp37La//a7Zf/l/br+1v0H698W6uNqltpt7wzamU/deXURjh7X9ytiUBz59KGt5Th6v6NZ5+gQh47lkfqdY+kUeXCd6+GaB3ti3OvafTeYuv0vi1NnatZ/q05/kqv1my9zZ6xi8rvH1a9fNJ4uUtRprs/uQEfrF+t2XSdi0GnsdGiu0YMv86EzrPnE0/WfXqSo01yf3YGO1u8cy+U8NwavWLJzdW4Tdf2tUq+o/5XrUNRfnc/qQM8d97rq6wbTnsULf/QpRalV086rL+FWqc4Qs5ks7xdFzh3CsvFokU6den1263TWue7WP67v94OvIr/6ZXinl5naz4vBq38Uvd+POnb9vBjAYWIAYgBiAMl/Hep+EfWofHkAAAAASUVORK5CYII=" alt="" />

②若格式说明符是c%则对所有输入内容都认为是合法并给变量赋值。

③若格式说明符是s%,则从第一个非空白字符开始认为合法字符直到遇到空白字符。

VC6.0反汇编结果(可以看出scanf函数取参数表中取地址的顺序与printf相同,都是倒着。)

 :    #include<stdio.h>
: int main (void)
: {
push ebp
mov ebp,esp
sub esp,50h
push ebx
push esi
push edi
lea edi,[ebp-50h]
0040101C mov ecx,14h
mov eax,0CCCCCCCCh
rep stos dword ptr [edi]
: int i=;
mov dword ptr [ebp-],
: char a,b,c;
: printf("%c\n",a);
0040102F movsx eax,byte ptr [ebp-]
push eax
push offset string "%c\n" (00425fa4)
call printf ()
0040103E add esp,
: while(i<)
cmp dword ptr [ebp-],
jge main+77h ()
: {scanf("%c%c%c",&a,&b,&c);
lea ecx,[ebp-10h];取变量c的偏移地址
0040104A push ecx
0040104B lea edx,[ebp-0Ch];取变量b的偏移地址
0040104E push edx
0040104F lea eax,[ebp-] ;取变量a的偏移地址
push eax
push offset string "%c" (0042501c)
call scanf (004010a0)
0040105D add esp,10h
: printf("%c%c%c\n",a,b,c);
movsx ecx,byte ptr [ebp-10h]
push ecx
movsx edx,byte ptr [ebp-0Ch]
push edx
0040106A movsx eax,byte ptr [ebp-]
0040106E push eax
0040106F push offset string "%c%c%c\n" ()
call printf ()
add esp,10h
: i++;
0040107C mov ecx,dword ptr [ebp-]
0040107F add ecx,
mov dword ptr [ebp-],ecx
: }
jmp main+31h ()
: return ;
xor eax,eax
: }
pop edi
0040108A pop esi
0040108B pop ebx
0040108C add esp,50h
0040108F cmp ebp,esp
call __chkesp ()
mov esp,ebp
pop ebp
ret

以上。

【C】貌似不友好的scanf()的更多相关文章

  1. ASP.NET Core 2.1 : 十四.静态文件与访问授权、防盗链

    我的网站的图片不想被公开浏览.下载.盗链怎么办?本文主要通过解读一下ASP.NET Core对于静态文件的处理方式的相关源码,来看一下为什么是wwwroot文件夹,如何修改或新增一个静态文件夹,为什么 ...

  2. <转>程序员的心理疾病

    注:本文转自大神王垠的博客 原文出处 http://www.yinwang.org/blog-cn/2014/02/09/programmer-mental/ 说实话,虽然似乎为之奋斗了十多年,在真正 ...

  3. poj1477(水)

    犯了一个错误,贡献了一次CE: G++里面没有头文件,用scanf会CE:然而C++就可以. 两大cow解释: 最好不要c 的输入和c++的一起用 (特别是关同步的时候) 然而好像他们也不是很了解.. ...

  4. ## ucore Lab0 一些杂记

    ucore Lab0 一些杂记 前一阵子开始做 MIT 6.828,做了两三个实验才发现清华的 ucore 貌似更友好一些,再加上前几个实验也与6.828 有所重叠,于是决定迁移阵地. 文章计划分两类 ...

  5. uva 6757 Cup of Cowards(中途相遇法,貌似)

    uva 6757 Cup of CowardsCup of Cowards (CoC) is a role playing game that has 5 different characters (M ...

  6. scanf和cin的差异

    scanf和cin的差异 引例:http://www.cnblogs.com/shenben/p/5516996.html 大家都知道,在C++中有两种输入.输出方式—scanf和cin,但是,它们之 ...

  7. 站点维护使用app_offline.htm页面提供友好的更新提示

    进行站点维护时为了以一个友好的方式提示给用户,比如什么“本网站正在更新”等等的信息可以建立一个叫app_offline.htm 的静态HTM页面文件,其中修改成你要临时显示的内容,将其放在你的应用的根 ...

  8. [WC 2005]友好的生物

    Description $W$ 星球是一个和地球一样气候适宜.物种聚集的星球.经过多年的研究,外星生物学家们已经发现了数万种生物,而且这个数字还在不断增大. $W$ 星球上的生物很有趣,有些生物之间很 ...

  9. ALGO-117_蓝桥杯_算法训练_友好数

    问题描述 有两个整数,如果每个整数的约数和(除了它本身以外)等于对方,我们就称这对数是友好的.例如: 9的约数和有:+= 4的约数和有:+= 所以9和4不是友好的. 220的约数和有: = 284的约 ...

随机推荐

  1. DevExpress.XtraGrid 【转】

    http://www.cnblogs.com/zeroone/p/4574539.html DevExpress.XtraGrid控件使用 该控件类是一个表格控件,但是其具有很多方便而使用的功能,例如 ...

  2. display:flex不兼容Android、Safari低版本的解决方案 【flex布局】

    引自 http://www.cnblogs.com/shimily/articles/7943370.html <!DOCTYPE html> <html lang="en ...

  3. Android Design Support Library概览

    尊重劳动成果.转载请注明出处:http://blog.csdn.net/growth58/article/details/47972467 关注新浪微博:@于卫国 邮箱:yuweiguocn@gmai ...

  4. angular 图片加载失败 情况处理? 如何在ionic中加载本地图片 ?

    1.angular 图片加载失败 情况处理 在directive中定义组件,在ng-src错误时,调用err-src app.directive('errSrc',function(){ return ...

  5. 理解MySql事务隔离机制、锁以及各种锁协议

    一直以来对数据库的事务隔离机制的理解总是停留在表面,其内容也是看一遍忘一边.这两天决定从原理上理解它,整理成自己的知识.查阅资料的过程中发现好多零碎的概念假设串起来足够写一本书,所以在这里给自己梳理一 ...

  6. Solaris之单用户模式

    1.TERM 表示终端 vt100 是简单的终端模式 export TERM=vt100 在此模式下,方向键无效,用字母键 有很多环境变量,PATH .PS1 .TERM 一般在屏幕上写的都是暂时的, ...

  7. caffe搭建--caffe- win10 vs2015 编译(支持GPU)--注意在cmake的时候需要根据情况仔细修改配置

    --http://blog.csdn.net/longji/article/details/60964998 注意: 在cmake的时候需要根据情况仔细修改配置,比如,如果gpu的能力不足3.0的话, ...

  8. 关于erlang的向上取整和向下取整

    在erlang的API中,erlang:trunc/1 是就近取整,erlang:round/1是四舍五入的, 整理下:对于正数的向上和向下取整, %% 向上取整 ceil(N) -> T = ...

  9. Eclipse-----Eclipse断点调试

  10. Mvc创建并注册防盗链

    创建CustomHandler.JpgHandler public class JpgHandler : IHttpHandler { public void ProcessRequest(HttpC ...