nonocast / me

记录和分享技术的博客
http://nonocast.cn
MIT License
20 stars 0 forks source link

学习 C/C++ (Part 16: variadic function) #281

Open nonocast opened 2 years ago

nonocast commented 2 years ago

假设我们需要对n个数进行求和,设计函数: sum(int, ...);, 虽然C支持可变函数, 但是在sum函数中无法获取可变参数的数量,它只是往栈上去压参数,所以必须人为设定数量,就有了如下实现:

int sum(int n, ...) {
  va_list args;
  int sum = 0;

  va_start(args, n);

  for (int i = 0; i < n; ++i) {
    sum += va_arg(args, int);
  }

  va_end(args);

  return sum;
}

那么问题来了,为什么printf不需要设置数量,也能获取所有的可变参数呢?

void mockprintf(const char *fmt, ...) {
    va_list ap;
    va_start(ap, fmt);
    for (const char *s = fmt; *s; ++s) {
        switch(*s) {
            case 'd':
                printf("meet d\n");
                int d = va_arg(ap, int);
                printf("%d\n", d);
                break;
            case 's':
                printf("meet s\n");
                const char *str = va_arg(ap, char*);
                printf("%s\n", str);
                break;
            case 'c':
                printf("meet c\n");
                char c = va_arg(ap, int);
                printf("%c\n", c);
                break;
            default:
                printf("unknown format specifier\n");
        }
    }
    va_end(ap);
}

int main() {
    mockprintf("cdfs", 'A', 0x45, "string");
    return 0;
}

这是参考阅读中uxff的blog中的一个mock printf, printf依靠第一个format中的%来提取可变参数,阴险。。。

printf() family

常规的printf family:

简单来说,

参考阅读