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. Android:MVC模式(下)

    在上一篇文章中,我们将 View 类单独出来并完成了设计和编写.这次我们将完成 Model 类,并通过 Controller 将两者连接起来,完成这个计算器程序. 模型(Model)就是程序中封装了数 ...

  2. Android-->状态栏高度,导航栏高度,Window高度,DecorView高度,heightPixels

    1:DecorView的高度 DecorView的高度代表的是: 整个装饰窗口的高度, 这个高度包括:状态烂的高度和导航栏的高度.(状态栏和导航栏通常叫做装饰窗口, 而ActionBar不属于装饰窗口 ...

  3. Python爬虫之路——简单网页抓图升级版(添加多线程支持)

    转载自我的博客:http://www.mylonly.com/archives/1418.html 经过两个晚上的奋斗.将上一篇文章介绍的爬虫略微改进了下(Python爬虫之路--简单网页抓图),主要 ...

  4. 微信小程序日期定位弹出框遮挡问题

    只需要用bindtap绑定一个点击后的操作(隐藏键盘): wx.hideKeyboard()

  5. maximum-depth-of-binary-tree——找出数的最大深度

    Given a binary tree, find its maximum depth. The maximum depth is the number of nodes along the long ...

  6. 建立第一个Sencha Touch应用

    准备 开始开发前,请先到下面的地址下载Sencha Touch 2的包:http://www.sencha.com/products/touch/download/ .下载完解压后你会发现包里有很多文 ...

  7. PHP中的$_SERVER['PATH_INFO']

    PHP中的全局变量$_SERVER['PATH_INFO']是一个很有用的参数,众多的CMS系统在美化自己的URL的时候,都用到了这个参数. 对于下面这个网址: http://www.test.com ...

  8. POJ 1753 (枚举+DFS)

    Flip Game Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 40632   Accepted: 17647 Descr ...

  9. idea安装plugin

    ---恢复内容开始--- ---恢复内容结束---

  10. Java泛型 类型变量的限定

    有时候,类和方法须要对类型变量加以约束.比方你有一个方法,你仅仅希望它接收某个特定类型及其子类型作为參数. 以下就举一个方法限定接收參数的类型的样例来说明怎样限定类型变量. 首先有几个简单的辅助类: ...