Variable Length Arguments
當輸入的引數長度不確定時,我們可以使用 Variable Length Arguments 來實作。
其來自於 <stdarg.h>
標準函式庫中
意義
va_list
為 variable argument lists
無論輸入的參數個數為何,皆可處理
實作原理
typedef char *va_list;
#define va_start(ap, param) (ap = (((va_list)¶m) + sizeof(param)))
#define va_end(ap) (void)((ap) = 0)
#define va_arg(ap, type) (*(type *)((ap += sizeof(type)) - sizeof(type)))
用法
- 宣告 資料型態為 va_list 的 ap (為 pointer)
va_list ap;
Macro 之 prototype
void va_start(va_list ap, last_arg);
type va_arg(va_list ap, type);
void va_end(va_list ap);
void va_copy(va_list dest, va_list src);
- va_start:將 ap (pointer)設定成第一個參數的位址
- va_arg: 將 ap 設定成下一個參數之位址
- va_end: 表示走訪結束,ap 設定成 NULL
- va_copy: 複製一份 va_list到 dest
例子
#include <stdarg.h>
#include <stdio.h>
int sum(int, ...);
void print_name(const char *, ...);
int main() {
int count = 3;
printf("Sum of 1, 2, 3 = %d\n", sum(count, 1, 2, 3));
count = 4;
printf("Sum of 14, 2, 25, 30 = %d\n\n", sum(count, 14, 2, 25, 30));
print_name("Sophie", "Meg", "Kenny", "Smith", "John");
return 0;
}
int sum(int multi_nums, ...) {
int total = 0;
va_list ap;
va_start(ap, multi_nums);
for(int i = 0; i < multi_nums; i++) {
total += va_arg(ap, int);
}
va_end(ap);
return total;
}
void print_name(const char *firstStr, ...){
va_list ap;
va_start(ap, firstStr);
int num = 0;
const char* str = firstStr;
while(str != NULL){
printf("%d. %s\n", num+1, str);
str = va_arg(ap, const char *);
num++;
}
va_end(ap);
printf("Total: %d people\n", num);
}
編譯
gcc test.c -o0 -o test
執行
./test
Sum of 1, 2, 3 = 6
Sum of 14, 2, 25, 30 = 71
1. Sophie
2. Meg
3. Kenny
4. Smith
5. John
Total: 5 people