printf如何处理其参数?

时间:2010-03-12 14:21:20

标签: c arguments printf

printf如何处理其参数?我知道在C#中我可以使用params关键字来做类似的事情,但我无法在C中完成它?

6 个答案:

答案 0 :(得分:18)

这样的功能称为variadic function。您可以使用...在C中声明一个,如下所示:

int f(int, ... );

然后,您可以使用va_startva_argva_end来处理参数列表。这是一个例子:

#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>

void f(void);

main(){
        f();
}

int maxof(int n_args, ...){
        register int i;
        int max, a;
        va_list ap;

        va_start(ap, n_args);
        max = va_arg(ap, int);
        for(i = 2; i <= n_args; i++) {
            if((a = va_arg(ap, int)) > max)
                max = a;
        }

        va_end(ap);
        return max;
}

void f(void) {
        int i = 5;
        int j[256];
        j[42] = 24;
        printf("%d\n",maxof(3, i, j[42], 0));
}

有关详细信息,请参阅The C Bookstdarg.h

答案 1 :(得分:9)

此功能称为函数中可变数量的参数。您必须包含 stdarg.h 头文件;然后在函数体内使用 va_list 类型和 va_start va_arg va_end 函数:

void print_arguments(int number_of_arguments, ...)
{
  va_list list;
  va_start(list, number_of_arguments);
  printf("I am first element of the list: %d \n", va_arg(list, int));
  printf("I am second element of the list: %d \n", va_arg(list, int));
  printf("I am third element of the list: %d \n", va_arg(list, int));
  va_end(list);
}

然后像这样调用你的函数:

print_arguments(3,1,2,3);

将打印出以下内容:

    I am first element of the list: 1
    I am second element of the list: 2
    I am third element of the list: 3

答案 2 :(得分:8)

在C中完成此操作的方式称为“varargs”。这里有一个教程:http://c-faq.com/~scs/cclass/int/sx11b.html

答案 3 :(得分:7)

就像其他人所说的那样,printf使用va_args来运行。编写自己的printf版本是一个非常酷的练习,如果没有其他方法来验证printf,不像Pascal的writeln不是编译魔术。在你这样做之后,你应该离开它。这是blog article我写的详细说明原因(简短的回答是你可以创建可能长时间未被发现的错误)。

答案 4 :(得分:5)

只是为了完成故事gcc(不确定其他编译器)支持

#define FUNC(X,Y,...) wiz(X,Y, ##__VA_ARGS__)

允许可变参数宏

答案 5 :(得分:0)

与C中的printf有关的答案完整性附件:

printf <stdio.h> source code为方便起见:

  20 #include <libioP.h>
  21 #include <stdarg.h>
  22 #include <stdio.h>
  23 
  24 #undef printf
  25 
  26 /* Write formatted output to stdout from the format string FORMAT.  */
  27 /* VARARGS1 */
  28 int
  29 __printf (const char *format, ...)
  30 {
  31   va_list arg;
  32   int done;
  33 
  34   va_start (arg, format);
  35   done = vfprintf (stdout, format, arg);
  36   va_end (arg);
  37 
  38   return done;
  39 }
  40 
  41 #undef _IO_printf
  42 ldbl_strong_alias (__printf, printf);
  43 /* This is for libg++.  */
  44 ldbl_strong_alias (__printf, _IO_printf);

我们可以看到上面答案中描述的模板已满足:

  1. 函数声明:...符号强调多个参数作为输入。
  2. va_list变量创建,可自动提取“额外”输入参数。
  3. va_start呼叫将我们设置为起始地址。
  4. va_arg调用可实际使用每个参数。每个调用都会递增到下一个参数。将在vfprintf内部使用。
  5. va_end宏来清理并结束该过程。在概念上类似于“免费”的内存分配。