不使用stdarg.h的可变长度参数

Mor*_*rki 3 c printf

我试图通过检查堆栈来理解并实现一种处理可变长度参数函数的方法,但我不知道在哪里以及如何启动.我发现以下链接很有帮助,但我仍然不太明白我是如何能够在c中找到像打印功能这样的东西.

http://www.swig.org/Doc1.3/Varargs.html

C++中函数参数列表中的尾随点(...)

Ale*_*nze 6

看看之前存在C Reference Manual by Dennis M. Ritchieprintf()那个实现,...并且<stdarg.h>:

printf ( fmt, args )
  char fmt [ ] ;
{
  ...
  int *ap, x, c ;
  ap = &args ; /* argument pointer */
  ...
  for ( ; ; ) {
    while ( ( c = *fmt++ ) != ´%´ ) {
      ...
      switch ( c = *fmt++) {
      /* decimal */
      case ´d ´:
        x = *ap++ ;
        if(x < 0) {
          x = -x;
          if ( x<0 ) { /* is - infinity */
            printf ( "-32768" ) ;
            continue ;
          }
          putchar ( ´-´);
        }
        printd(x);
        continue ;
      ...
      }
      ...
    }
    ...
  }
}

printd(n)
{
  int a ;
  if ( a=n/10 )
    printd(a);
  putchar ( n%10 + ´0´ ) ;
}
Run Code Online (Sandbox Code Playgroud)

您可以忽略函数和参数声明的旧(AKA K&R)语法:

printf ( fmt, args )
  char fmt [ ] ;
Run Code Online (Sandbox Code Playgroud)

甚至用更现代的代替它:

int printf ( char fmt[], int args )
Run Code Online (Sandbox Code Playgroud)

但是想法是一样的,你直接得到一个指向第一个可选参数(args)的指针,就像在上面的代码中所做的那样ap = &args;,然后继续递增它以获得对更多参数的访问.

或者你可以使用最后一个非可选参数作为起点间接地做到这一点:

int printf ( char fmt[], ... )
{
  ...
  int *ap, x, c ;
  ap = &fmt ; /* argument pointer */
  ap++; /* ap now points to first optional argument */
  ...
}
Run Code Online (Sandbox Code Playgroud)

这说明了这种机制.

请注意,如果您编写这样的代码,它将无法移植,甚至可能无法使用您的编译器.