根据前面的某一篇的文章,可以清楚的看到:对于每一个函数,通过这个函数的[ebp+x]就可以直接访问到它调用的时候传进来的形参的值,通过[ebp-x]就可以直接访问它的局部变量。

所以printf这个函数不定参数的实现是通过栈机制实现的,在传入实参的时候,从右向左一次把各个参数压入栈,但是这些压入栈的数据是没有类型区分的,就是把相应的数据依次放到栈中排好。最后压入栈的那个参数“%d%d%d”等类似的参数,才是决定printf参数类型的东西。等到程序的执行控制权到达printf中以后,printf就从传入的实参的起始位置,按照“%d%d%d”等类似的字符串来控制类型依次输出。这个字符串控制输出的个数和类型。同时这个字符串没有越界检测。

int a = 10;
printf("%d %d %d\n", a);

  这种打印的越界是不会检测的,函数调用前实参压栈a,然后压栈"%d %d %d\n"类型控制字符串。最后在printf中函数调用的时候,从之前压入的实参中依次打印出三个int,虽然压入栈的实参只有一个int,但是没有越界检测,所以还是会打印三个int。

来分析一个实际的问题:

char s[] = "123", *p;
p = s;
printf("%c%c%c\n", *p++, *p++, *p++);

  这个问题要注意printf和*p++这两个知识点,printf的参数压栈是从右向左的,并且注意*p++的执行顺序。所以第一个压栈的参数是1然后压栈2,然后压栈3。打印的时候一次打印321。

printf参数的问题的更多相关文章

  1. 汇编中call printf参数压栈时错误理解

    EAX, ECX,EDX,EBX均可以32bit,16bit,8bit访问,如下所示: <-------------------EAX------------------------>|& ...

  2. C: printf参数执行顺序与前置后置自增自减的影响

    起源: 今天在了解副作用side-effect的过程中,看到了下面的网页,把我带到了由printf引起的一系列问题,纠结了一整天,勉强弄懂. 第一个代码没什么好解释的.而第二个printf(" ...

  3. printf()参数的处理

    下面程序的输出为? #include <stdio.h> int main(void) { ,b=,c=; printf(),(c = c*)); ; } 答案是110..40..60 这 ...

  4. 5-2-2 printf参数从右往左压栈

    5-2-2 C中printf计算参数时是从右到左压栈的 #include <stdio.h> int main (int argc, char **argv) { ; ,,,,}; int ...

  5. printf 参数检查 __attribute__((format(printf, 1, 2)))

    With GCC, I can specify __attribute__((format(printf, 1, 2))) , telling the compiler that this funct ...

  6. getopt函数的使用——分析命令行参数

    getopt(分析命令行参数) getopt(分析命令行参数) 短参数的定义 返回值 范例 getopt_long 相关函数表头文件#include<unistd.h> 函数声明int g ...

  7. Printf()输出格式控制(转)

    int printf(const char *format,[argument]); format 参数输出的格式,定义格式为: %[flags][width][.perc] [F|N|h|l]typ ...

  8. C语言的本质(18)——函数的可变参数

    一般而言,在设计函数时会遇到许多数学和逻辑操作,是需要一些可变功能.例如,计算数字串的总和.字符串的联接或其它操作过程. 实现一个函数,要求在函数中计算传入的所有参数之和,并输出到屏幕上.这个函数实现 ...

  9. 如何使用getopt()函数解析参数

    最近在写程序的过程中,把一部分时间都花费在程序对参数的处理上.今天听了学长说到getopt函数,才发现原来c里面还有一个专门解决参数处理的函数,查询了相关资料,这里简单总结一下. 使用int main ...

随机推荐

  1. HDU 4664 Triangulation【博弈论】

    一个平面上有n个点(一个凸多边形的顶点),每次可以连接一个平面上的两个点(不能和已经连接的边相交),如果平面上已经出现了一个三角形,则不能在这个平面上继续连接边了. 现在总共有N个平面,每个平面上都有 ...

  2. js的replace的用法;

    obj.replace("需要替换的字符串","替换后的字符串")

  3. python手记(36)

    #!/usr/bin/env python #-*- coding: utf-8 -*- #code:myhaspl@qq.com import cv2 import numpy as np fn=& ...

  4. Android Gson深入分析

    眼下解析json有三种工具:org.json(Java经常使用的解析),fastjson(阿里巴巴project师开发的).Gson(Google官网出的).解析速度最快的是Gson,下载地址:htt ...

  5. SlidingMenu的编译及使用

    1. 在github上有一个效果不错的开源库,SlidingMenu 最新的代码下载下来后,ExampleListActivity项目会报错:      No resource found that ...

  6. JavaScript之面向对象学习四原型对象的动态性

    1.由于在原型中查找值的过程是一次搜索,因此我们对原型对象所做的任何修改都能够立即从实例上反映出来---即便是先创建了实例后修改原型也是如此.代码如下: function Person(){ } va ...

  7. 基于Nodejs开发的web即时聊天工具

    由于公司需要开发web即时聊天的功能,开始时我们主要的实施方法是用jquery的ajax定时(10秒)轮询向服务器请求,由于是轮询请求,对 服务器的压力比较大.我们网站上线的时间不长,访问量不是很大, ...

  8. BHO启动IE调试

    如下图选择Web Browser Debugger, 输入启动网址

  9. BZOJ 2300: [HAOI2011]防线修建( 动态凸包 )

    离线然后倒着做就变成了支持加点的动态凸包...用平衡树维护上凸壳...时间复杂度O(NlogN) --------------------------------------------------- ...

  10. 根据用户的ID查用户的名字

    awk -F: '{if($3==0){print $1}}'  /etc/passwd