3

我试图通过检查堆栈来理解和实现一种处理可变长度参数函数的方法,但我不知道从哪里开始以及如何开始。我发现以下链接很有帮助,但我仍然不太明白如何在 c 中实现类似打印功能的功能。

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

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

4

1 回答 1

6

查看很久以前存在C Reference Manual by Dennis M. Ritchie的实现,并且:printf()...<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´ ) ;
}

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

printf ( fmt, args )
  char fmt [ ] ;

甚至用更现代的替换它:

int printf ( char fmt[], int args )

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

或者您可以使用最后一个非可选参数作为起点来间接执行此操作:

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

这说明了机制。

请注意,如果您这样编写代码,它将无法移植,甚至可能无法与您的编译器一起工作。

于 2013-03-05T07:05:42.863 回答