难题请教

pipilang 2003-11-05 09:17:54
谁能详细解释一下printf函数的工作过程,比如在stdio.h中怎样定义,为什么要这样定义?它工作的原理是什么?
...全文
49 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
wshcdr 2003-11-21
  • 打赏
  • 举报
回复
: daizh() 大哥
可不可以给一能编译运行的例子给我

要求
win2k+VC6
zhouqingyuan 2003-11-18
  • 打赏
  • 举报
回复
学习
royalty 2003-11-18
  • 打赏
  • 举报
回复
gz
leyt 2003-11-18
  • 打赏
  • 举报
回复
不错
ftp123 2003-11-17
  • 打赏
  • 举报
回复
good!先收
orjava 2003-11-08
  • 打赏
  • 举报
回复
很好。up!
wangwubian 2003-11-07
  • 打赏
  • 举报
回复
Great
shenke410 2003-11-06
  • 打赏
  • 举报
回复
同意,朋友!
up!
limd 2003-11-06
  • 打赏
  • 举报
回复
上面不错呀
daizh 2003-11-05
  • 打赏
  • 举报
回复
原型:_CRTIMP int __cdecl printf(const char *, ...);
作用:将给定的字符串按规定的格式输出到stdout。
原理:它如何实现变参数的,请参看下面的文章。




用C语言实现参数个数可变的函数
      作者:张文亮


  采用C语言编程的时候,函数中形式参数的数目通常是确定的,在调用时要依次给出与形式参数对应的所有实际参数。但在某些情况下希望函数的参数个数可以根据需要确定。典型的例子有大家熟悉的函数printf()、scanf()和系统调用execl()等。那么它们是怎样实现的呢?

  C编译器通常提供了一系列处理这种情况的宏,以屏蔽不同的硬件平台造成的差异,增加程序的可移植性。这些宏包括va—start、va—arg和va—end等。

  使用这些宏有两种不同的形式,二者在程序中包括的头文件不同,宏的定义也存在一些差别。这两种方式对应的头文件和宏的声明见表1。

  采用ANSI标准形式时,参数个数可变的函数的原型声明是:

  type funcname(type para1, type para2, ...)

  这种形式至少需要一个普通的形式参数,后面的省略号不表示省略,而是函数原型的一部分,type是函数返回值和形式参数的类型。

  采用与UNIX System V兼容的声明方式时,参数个数可变的函数原型是:

  type funcname(va—alist)

  va—dcl

  这种形式不需要提供任何普通的形式参数,type是函数返回值的类型。va—dcl是对函数原型声明中参数va—alist的详细声明,实际是一个宏定义,对不同的硬件平台采用不同的类型来定义,但在最后都包括了一个分号,因此va—dcl后不再需要加上分号了。va—dcl在代码中必须原样给出,va—alist在VC中可以原样给出,也可以略去,但在UNIX上的CC或Linux上的GCC中都要省略掉。此外,采用头文件stdarg.h编写的程序是符合ANSI标准的,可以在各种操作系统和硬件上运行,而采用头文件varargs.h的方式仅仅是为了与以前的程序兼容。所以建议大家使用前者。两种方式的基本原理是一致的,只是在语法形式上有一些细微的区别。以下主要就前一种方式对参数的处理做出说明。

  va—start使argp指向第一个可选参数。va—arg返回参数列表中的当前参数并使argp指向参数列表中的下一个参数。va—end把argp指针清为NULL。函数体内可以多次遍历这些参数,但是都必须以va—start开始,并以va—end结尾。

  调用者在实际调用参数个数可变的函数时,要通过一定的方法指明实际参数的个数,例如把最后一个参数置为空字符串(系统调用execl()就是这样的)、-1或其他的方式。

  下面给出一个具体的例子,前一部分是采用了符合ANSI标准形式的代码,后一部分是采用了与UNIX System V兼容方式的代码。代码中加了一些注释,这里就不再解释了。该例子已经在VC/Windows NT4.0、CC/AIX4.3.2.0、GCC/Redhat Linux 6.0环境下编译并正常运行。

  1.演示如何使用参数个数可变的函数,采用ANSI标准形式

  #include 〈stdio.h〉

  #include 〈string.h〉

  #include 〈stdarg.h〉

  / 函数原型声明,至少需要一个确定的参数,注意括号内的省略号 /

  int demo( char , ... );

  void main( void )

  {

   demo(″DEMO″, ″This″, ″is″, ″a″, ″demo!″, ″\0″);

  }

  / ANSI标准形式的声明方式,括号内的省略号表示可选参数 /

  int demo( char msg, ... )

  {

  va—list argp;

  / 定义保存函数参数的结构 /

  int argno = 0; / 纪录参数个数 /

  char para;

  / 存放取出的字符串参数 /

  / argp指向传入的第一个可选参数,msg是最后一个确定的参数 /

  va—start( argp, msg );

  while (1) {

  para = va—arg( argp, char );

  / 取出当前的参数,类型为char . /

   if ( strcmp( para, ″\0″) == 0 )

  / 采用空串指示参数输入结束 /

  break;

  printf(″Parameter #%d is: %s\n″, argno, para);

   argno++;

  }

   va_end( argp );

   / 将argp置为NULL /

    return 0;

  }

  2.演示如何使用参数个数可变的函数,采用与UNIX System V兼容的方式

  #include 〈stdio.h〉

  #include 〈string.h〉

  #include 〈varargs.h〉

  / 函数原型声明,括号内的类型va—list在VC/Windows NT4.0可以保留,但在AIX和Linux下需要去掉,即改成int demo( ) /

  int demo( va—list );

  void main( void )

  {

   demo(″This″, ″is″, ″a″, ″demo!″, ″\0″);

  }

  / UNIX System V采用的声明方式,括号内是va—alist,不是va—list,而且va—dcl后面不需要分号 /

  int demo( va—alist )

  va—dcl  

  {

  va—list argp;

   / 定义保存函数参数的结构 /

     int argno = 0; / 纪录参数个数 /

     char para;

  / 存放取出的字符串参数 /

  va—start( argp );

  / argp指向第一个可选参数 /

  while (1) {

  para = va—arg( argp, char );

  / 取出当前的参数,类型为char /

     if ( strcmp( para, ″\0″) == 0 )

  / 采用空串指示参数输入结束 /

     break;

     printf(″Parameter #%d is: %s\n″, argno, para);

     argno++;

     }

  va_end( argp ); / 将argp置为NULL /

  return 0;

  }

表1   ANSI标准形式 UNIX SystemⅤ兼容方式
头文件 #include 〈stdarg.h〉 #include 〈varargs.h〉
va_start void va_start(argp, paran) va_list argp; void va_start(argp) va_list argp;
va_arg type va_arg(argp, type) va_list argp; type va_arg(argp, type) va_list argp;
va_end void va_end(argp) va_list argp; void va_end(argp) va_list argp;
fierygnu 2003-11-05
  • 打赏
  • 举报
回复
printf解析format串,按照format串中的定义解释后边的可变参数列表,格式化后输出。
pxwzd123 2003-11-05
  • 打赏
  • 举报
回复
int printf( const char *format [, argument]... );

The printf function formats and prints a series of characters and values to the standard output stream, stdout.

The format argument consists of ordinary characters, escape sequences, and (if arguments follow format) format specifications. The ordinary characters and escape sequences are copied to stdout in order of their appearance.

24,855

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 工具平台和程序库
社区管理员
  • 工具平台和程序库社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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