求高手指教,printf函数的实现原理

小蚂蚁_CrkRes 2012-09-20 10:01:42
#include<stdio.h>
int main(void){
printf("%d %lf %f\n");
}
当printf不给参数是,它到哪里去取值??
#include<stdio.h>
int main(void){
int x=5;
printf("%d %d %d \n",x++,x++,x++);
x = 5;
printf("%d %d %d \n",++x,++x,++x);
}
在Linux平台编译,为何和VC编译的结果不一样?到底编译器是怎么实现 前加加,和 后加加的?

求高手解答!!感谢了!!
...全文
305 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
lzqxs89 2012-10-26
  • 打赏
  • 举报
回复
这跟编译器有关系。所以当一个变量在同一个函数中出现多次,不要将增量或者减量运算符用在它上面!
iamnobody 2012-09-21
  • 打赏
  • 举报
回复
看顶置的帖子,不要看国内的大部分垃圾书.
xspace_time 2012-09-21
  • 打赏
  • 举报
回复
//MSDN printf.cpp

//==========================================
// LIBCTINY - Matt Pietrek 2001
// MSDN Magazine, January 2001
//==========================================
#include <windows.h>
#include <stdio.h>
#include <stdarg.h>

// Force the linker to include USER32.LIB
#pragma comment(linker, "/defaultlib:user32.lib")

extern "C" int __cdecl printf(const char * format, ...)
{
char szBuff[1024];
int retValue;
DWORD cbWritten;
va_list argptr;

va_start( argptr, format );
retValue = wvsprintf( szBuff, format, argptr );
va_end( argptr );

WriteFile( GetStdHandle(STD_OUTPUT_HANDLE), szBuff, retValue,
&cbWritten, 0 );

return retValue;
}
ouPuso 2012-09-21
  • 打赏
  • 举报
回复
这里有一个序列点的问题,在C语言标准中是未定义的,依赖于编译器的实现.在一种编译器上成功不代表在其它系列上也成功,lz可以参考《C语言参考手册 第五版》或查找序列点相关的知识.
此处我贴一个上来,lz可以参考
http://tieba.baidu.com/f?kz=673634549
www_adintr_com 2012-09-21
  • 打赏
  • 举报
回复
printf 直接到栈里去取值,它使用 va_list 等一系列的宏,根据第一个参数的地址,来计算其它的参数地址。

VC 里 printf 的实现如下:


int __cdecl printf (
const char *format,
...
)
/*
* stdout 'PRINT', 'F'ormatted
*/
{
va_list arglist;
int buffing;
int retval;

_VALIDATE_RETURN( (format != NULL), EINVAL, -1);

va_start(arglist, format);

_lock_str2(1, stdout);
__try {

buffing = _stbuf(stdout);

retval = _output_l(stdout,format,NULL,arglist);

_ftbuf(buffing, stdout);

}
__finally {
_unlock_str2(1, stdout);
}

return(retval);
}


其中的 _output_l 实现太长了,无法再这里列出,在你安装目录下的 vc\crt\src\output.c 里面
AnYidan 2012-09-21
  • 打赏
  • 举报
回复
printf 如何实现
http://topic.csdn.net/u/20070112/16/c25115de-55f3-431c-848f-7a0b1f5ce48a.html

不要写自己都不知到结果的 代码
小蚂蚁_CrkRes 2012-09-21
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 的回复:]
这里有一个序列点的问题,在C语言标准中是未定义的,依赖于编译器的实现.在一种编译器上成功不代表在其它系列上也成功,lz可以参考《C语言参考手册 第五版》或查找序列点相关的知识.
此处我贴一个上来,lz可以参考
http://tieba.baidu.com/f?kz=673634549
[/Quote]很有用,非常感谢!!
小蚂蚁_CrkRes 2012-09-21
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 的回复:]
printf 直接到栈里去取值,它使用 va_list 等一系列的宏,根据第一个参数的地址,来计算其它的参数地址。

VC 里 printf 的实现如下:


C/C++ code


int __cdecl printf (
const char *format,
...
)
/*
* stdout 'PRINT', '……
[/Quote]嗯,看看,谢谢了!!
小蚂蚁_CrkRes 2012-09-21
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 的回复:]
printf 如何实现
http://topic.csdn.net/u/20070112/16/c25115de-55f3-431c-848f-7a0b1f5ce48a.html

不要写自己都不知到结果的 代码
[/Quote]谢谢,批评;嘿嘿,不过就是好奇作祟的!!
shiter 2012-09-21
  • 打赏
  • 举报
回复
不同编译器不同的吧...
小蚂蚁_CrkRes 2012-09-20
  • 打赏
  • 举报
回复
是的呢,比较纠结!要是能够知道printf函数,怎么实现的,放在哪里?怎么去取值?前加加,后加加,怎么赋值的?值是放在buffer里面的?后面在加一条语句时;printf("%d\n",x);打印的是加加过后的值?这当中每一步的值,放在缓冲区里面?
lzqxs89 2012-09-20
  • 打赏
  • 举报
回复
我今天也看到这个问题了,这个是编译器与系统好像是有关系的! printf参数值的计算顺序也有关系,到底先计算哪个x++;

69,381

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧