C語言中可變参數的用法——va_list、va_start、va_arg、va_end参數定義 2018/7/22 C語言中可變参數的用法——va_list、va_start、va_arg、va_end参數定義 Date: 2016/11/15 Department of Computer Science and Information Engineering National Cheng Kung University, Taiwan R.O.C. CSIE CIAL Lab 1
C語言可變参數簡介 我們在C語言編程中會遇到一些参數個數可變的函數,例如printf()這個函數,它的定義是這样的: int printf( const char* format, ...); 它除了有一個参數format固定以外,後面跟的参數的個數和類型是可變的,例如我們可以有以下不同的調用方法: printf("%d",i); printf("%s",s); printf("the number is %d ,string is:%s", i, s); National Cheng Kung University CSIE Computer & Internet Architecture Lab
寫一個簡單的可變参數的C函數 void va_start( va_list arg_ptr, prev_param ); type va_arg( va_list arg_ptr, type ); void va_end( va_list arg_ptr ); va在這裏是variable-argument(可變参數)的意思.這些macro定義在stdarg.h中,所以用到可變参數的程序應該包含這個頭文件.下面我們寫一個簡單的可變参數的函數,改函數至少有一個整數参數,第二個参數也是整數,是可選的.函數只是打印這兩個参數的值. National Cheng Kung University CSIE Computer & Internet Architecture Lab
簡單CODE void simple_va_fun(int i, ...) { va_list arg_ptr; int j=0; va_start(arg_ptr, i); j=va_arg(arg_ptr, int); va_end(arg_ptr); printf("%d %d\n", i, j); return; } National Cheng Kung University CSIE Computer & Internet Architecture Lab
我們可以在上述的文件中這樣宣告我們的函數: 我們可以在上述的文件中這樣宣告我們的函數: extern void simple_va_fun(int i, ...); 我們在程序中可以這样調用: simple_va_fun(100); simple_va_fun(100,200); National Cheng Kung University CSIE Computer & Internet Architecture Lab
範例 :CODE #include "stdio.h" #include "stdarg.h" void minprintf(char *fmt, ...); void errmsg(int code, ...); int errorf(const char *format, ...); int sum(int num, ...); int sum1(int num, ...); double double_sum(double num, ...); int FILENAME=1, LINENUMBER=2, WARN=4; National Cheng Kung University CSIE Computer & Internet Architecture Lab
main(int argc, char *argv[]) { char *s = "HELLO"; int x = 10; double f = 10.0; fprintf(stdout, "\n===== Test errmsg() =====\n"); errmsg(1, "<FILE>", "cannot open %s\n", "a_file"); errmsg(3,"<FILE>",7,"cannot open %s\n","a_file"); errmsg(2, 7, "cannot open %s\n", "a_file"); errmsg(4, "<FILE> %s, x=%d", "a_file", 10); printf("\n"); fprintf(stdout, "\n===== Test minprintf() =====\n"); minprintf("x = %d, f = %f, s = %s\n", x, f, s); minprintf("s = %s, x = %d, f = %f, s = %s\n", s, x, f, s); minprintf("s = %s, x = %d, f = %f, s = %x\n", s, x, f, s); fprintf(stdout, "\n===== Test errorf() =====\n"); errorf("x = %d, f = %f, s = %s\n", x, f, s); fprintf(stdout, "\n===== Test sum, sum1, double_sum() =====\n"); printf("sum(4, 1, 2, 3, 4) = %d\n", sum(4, 1, 2, 3, 4)); printf("sum1(4, 1, 2, 3, 4, 0) = %d\n", sum1(4, 1, 2, 3, 4, 0)); printf("double_sum(4.0, 1.0, 2.0, 3.4, 0.0) = %f\n", double_sum(4.0, 1.0, 2.0, 3.4, 0.0)); } National Cheng Kung University CSIE Computer & Internet Architecture Lab
int errorf(const char *format, ...) { static int num_errors = 0; int n; va_list ap; num_errors++; fprintf(stderr, "** Error %d: ", num_errors); va_start(ap, format); n = vfprintf(stderr, format, ap); va_end(ap); fprintf(stderr, "\n"); return n; } National Cheng Kung University CSIE Computer & Internet Architecture Lab
void errmsg(int code, ...) { va_list ap; char *fmt; va_start(ap, code); //int FILENAME=1, LINENUMBER=2, WARN=4; if (code&FILENAME) (void)fprintf(stderr, "\"%s\":", va_arg(ap, char *)); if (code&LINENUMBER) (void)fprintf(stderr, "%d:", va_arg(ap, int)); if (code&WARN) (void)fputs("Warning:", stderr); fmt = va_arg(ap, char *); (void) vfprintf(stderr, fmt, ap); va_end(ap); } National Cheng Kung University CSIE Computer & Internet Architecture Lab
int sum(int num, ...) { va_list ap; int i, n = 0; va_start(ap, num); for (i=0; i<num; i++) n += va_arg(ap, int); return n; } int sum1(int num, ...) { int i=0, t, n = 0; n = num; while (1) { t = va_arg(ap, int); if (t<=0) break; n += t; //if (i<0)printf("%d,%d\n", ++i, t); National Cheng Kung University CSIE Computer & Internet Architecture Lab
double double_sum(double num, ...) { va_list ap; int cnt=0; double t, f = 0.0; va_start(ap, num); f = num; // printf("f=%f\n", f); if(num==0.0) return 0.0; cnt=1; while (1) { t = va_arg(ap, double); if (t==0.0) break; cnt++; f += t; } return f; National Cheng Kung University CSIE Computer & Internet Architecture Lab
void minprintf(char. fmt,. ) { va_list ap; char. p, void minprintf(char *fmt, ...) { va_list ap; char *p, *sval; int ival; double dval; va_start(ap, fmt); for(p=fmt; *p; p++){ if (*p != '%'){ putchar(*p); continue; } switch (*++p){ case 'd': ival = va_arg(ap, int); printf("%d", ival); break; case 'f': dval = va_arg(ap, double); printf("%f", dval); break; case 's': for (sval=va_arg(ap, char *); *sval; sval++) putchar(*sval); break; default: printf("'undefined'"); break; va_end(ap); National Cheng Kung University CSIE Computer & Internet Architecture Lab
Source http://fanli7.net/a/bianchengyuyan/C__/20130113/289956.html National Cheng Kung University CSIE Computer & Internet Architecture Lab