printf函数

printf函数遵守C调用规范,即参数 从右至左 压栈,堆栈由调用者平衡。(这种从右至左的方式不会随着编译器,机器的不同而不同) )。

 

[code]

printf("%d,%d", i, i++ );   产生的汇编码大致像下面这样:

 

mov         eax,dword ptr [i]             

push        eax                               //最右边那个i的值被压入栈中

inc           eax                               //i++

mov         dword ptr[ i ], eax

mov         edx,dword ptr [i] 

push        edx                               //第二个i的值被压入栈中

push        offset string "%d,%d"     //字符串 "%d,%d"的地址被压入栈中

call           printf                            //跳转到函数print

add          esp, 12                         //平衡堆栈

[/code]

 

有几个小题帮助分析:

 

1.

 

#include <stdio.h>

 

int main()

{

    char * p = "abcdefg";

    printf("%c%c", *p,*(p++));

    return 0;

}

 

输出结果:ba

 

2.

 

#include <stdio.h>

 

int main()

{

    char * p = "abcdefg";

    printf("%c%c%c", *p,*(p++), *(++p));

    return 0;

}

 

输出结果:cbb

 

3.

 

#include <stdio.h>

 

int main()

{

    char * p = "abcdefg";

    printf("%c%c", *p,*(p+3));

    return 0;

}

 

输出结果:ad

 

int printf( const char *format , ... );

最后一个(在这个函数中是第二个)参数写成“...”意思是该函数能接收不定数量的参数,或者更普遍的说法是变长参数。

 

以printf为例:

printf("This is a %s and a %s", s1, s2);

在这次调用中,除去第一个字符常指针,有两个实际参数s1和s2的地址。

printf("I wanna to print %d.", num);

在这次调用中,除去第一个字符常指针,有一个实际参数num。

 

C语言允许变长参数的具体实现,因编译器而异。多数仍然是通过栈来实现,因为参数的使用和记录都是由编译器维护

 

 

这里是printf的源代码

C/C++ code

#include <libioP.h>

#include <stdarg.h>

#include <stdio.h>

 

#undef printf

 

/* Write formatted output to stdout from the format string FORMAT.  */

/* VARARGS1 */

int

__printf (const char *format, ...)

{

  va_list arg;

  int done;

 

  va_start (arg, format);

  done = vfprintf (stdout, format, arg);

  va_end (arg);

 

  return done;

}

 

#undef _IO_printf

 

 

typedef   char   *     va_list; 

#define   _INTSIZEOF(n)       (   (sizeof(n)   +   sizeof(int)   -   1)   &   ~(sizeof(int)   -   1)   ) 

#define   va_start(ap,v)     (   ap   =   (va_list)&v   +   _INTSIZEOF(v)   ) 

#define   va_arg(ap,t)         (   *(t   *)((ap   +=   _INTSIZEOF(t))   -   _INTSIZEOF(t))   ) 

#define   va_end(ap)             (   ap   =   (va_list)0   ) 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值