实现变参传递的关键是:

传入参数在内存中是连续分布的。

#define va_list void*
#define va_arg(arg, type) *(type*)arg; arg = (char*)arg + sizeof(type);
#define va_start(arg, start) arg = (va_list)(((char*)&(start)) + sizeof(start))
#define va_end(arg) arg = (void*)0 这四个宏其实是c语言定义好的在stdarg.h中。
通过va_start(arg, start)传入第一个参数以确定后面参数的地址。
va_arg(arg, type)取出arg的值,并将地址指向下一个
#include <stdio.h>

#define va_list void*
#define va_arg(arg, type) *(type*)arg; arg = (char*)arg + sizeof(type);
#define va_start(arg, start) arg = (va_list)(((char*)&(start)) + sizeof(start))
#define va_end(arg) arg = (void*)0
int sum(int nr, ...)
{
int i = ;
int result = ;
va_list arg = NULL;///不定类型指针
va_start(arg, nr);//让指针指向第二个参数地址 for(i = ; i < nr; i++)
{
result += va_arg(arg, int);
}
va_end(arg);
return result;
} int main(int argc, char* argv[])
{
printf("%d\n", sum(, ,,,));
printf("%d\n", sum(, , , )); return ;
}
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
/* #define va_list void*
#define va_arg(arg, type) *(type*)arg; arg = (char*)arg + sizeof(type);
#define va_start(arg, start) arg = (va_list)(((char*)&(start)) + sizeof(start)) 这些在stdarg.h中定义过
*/
void printf_diy(char *fmt,...) {
va_list arg; //定义一个不定类型指针
char c; va_start(arg, fmt); //arg指向下一个参数 do {
c = *fmt;
if(c != '%'){
putchar(c); //输出
}
else {
fmt++;
switch(*fmt) {
case 'd':
printf("%d", *((int*)arg));
break;
case 'x':
printf("%#x", *((int*)arg));
break;
case 'f':
printf("%f", *((float*)arg));
default:
break;
} va_arg(arg,int);
} ++fmt; } while (*fmt != '\0'); va_end(arg);
return;
} int main(int argc, char **argv) {
int i = ;
int j = ;
float f = 13.9; printf_diy("i = %d\n", i);
printf_diy("j = %d\n", j);
printf_diy("f = %f\n", f);
return ;
}
05-11 11:30