菜鸟在线C编译器:1)或2)1. http://www.compileonline.com/compile_c_online.php
2.http://www.runoob.com/try/runcode.php?filename=helloworld&type=c
摘要:
注意:如果想要使用stdarg.h中的宏定义和类型对象,必须显示定义头文件#include <stdarg.h>
- va_start 和 va_end一对;
- va_copy 和va_end一对;
- va_start 表示 是从哪一个参数,作为不定数组的起始位置;
- va_arg 是个游标,逐个向下一个指定;
- va_end 变量 valist 将重置为空,并释放内存;
由于可变参数函数的参数数量不定,
C语言定义了省略号来表示之后的参数列表,但最少要有一个确定类型的参数(C++中可以忽略)
常用0:
#include <stdio.h>
#include<string.h>
#include<stdarg.h>
void f1(const char*pre,int num_args,...){
char buffer[100];
memset(buffer,'\0',sizeof(char)*100);
sprintf(buffer,"%s:pre=%s",buffer,pre);
va_list _pvalist;
va_start(_pvalist,num_args);
for(int i=0;i<num_args;i++){
const char*temp=va_arg(_pvalist,const char*);
sprintf(buffer,"%s;index=%d,value = %s",buffer,i,temp);
}
va_end(_pvalist);
printf("ret = [%s];\n",buffer);
puts(buffer);
}
void main(){
f1("前缀",3,"第一个","di-2-ge","num-3rd");
}
方式一:
void printargs(int arg1, ...){
va_list valist;
va_start(valist,arg1); 从arg1 开始;
for (i = arg1; i != -1; ){
printf("%d ", i);
i = va_arg(valist, int);// 是个游标,逐个向下一个指定;
}
va_end(valist);
}
int main(void)
{
printargs(5, 2, 14, 84, 97, 15, 24, 48, -1);
printargs(84, 51, -1);
printargs(-1);
printargs(1, -1);
return 0;
}
方式二:
va_list temp;
va_copy(temp,valist);
va_arg(temp,type)
va_end(temp);
注意:va_start/va_arg/va_end函数符合C89标准。而va_copy是C99定义的
自定义printf
#include <stdio.h>
#include <stdarg.h>
void my_printf(const char* fmt, ...){
va_list ap;
va_start(ap, fmt);
int i=0;
while (fmt[i] != '\0'){
if (fmt[i] != '%'){
printf("%c", fmt[i]);
i ++;
continue;
}
fmt ++; // 跳过%
switch(fmt[i]){
case 'c': // 得到一个字符
char cc;
cc = (char)va_arg(ap, int);// 是个游标,逐个向下一个指定;
printf("%c", cc);
break;
case 'd': // 得到一个整数
int dd;
dd = (int)va_arg(ap, int);// 是个游标,逐个向下一个指定;
printf("%d", dd);
break;
case 's': // 得到一个字符串
char *ss;
ss = va_arg(ap, char*);// 是个游标,逐个向下一个指定;
printf("%s", ss);
break;
}
va_end(ap);
}
}
int main(int argc, char* argv){
my_printf("Hello World\n");
printf("%d Hi %s 2233 %c\n", 2, "adfa", 'a');
}