c語言不定引數與printf函式的實現
阿新 • • 發佈:2019-02-07
今天學習了C語言不定引數,C語言中的不定引數主要靠<strarg.h>這個標頭檔案實現,這個標頭檔案包含了va_list()、va_start()、va_end()三個巨集,其用法為先宣告一個va_list型別的變數,它用於訪問引數列表未確定的部分。這個變數是由va_start來初始化的。它的第一個引數是va_list的變數名,第二個引數是省略號前最後一個有名字的引數。初始化過程把va_list的變數設定為指向可變引數的第一個引數。
為了訪問引數,需要使用va_arg,這個巨集接受兩個引數(va_list變數和引數列表中下一個引數的型別)訪問完最後一個引數,需要呼叫va_end(),其格式如下:
void fun(int a,...)
{
va_list parameter;
va_start(parameter, a);
va_arg(parameter, int );
}
舉個例子,如果要實現求多個數的平均值,因為C中不允許預設引數,所以只能用上述方法進行求平均數,程式碼如下
int average(int val, ...) { va_list arg; int sum = 0; int i = 0; va_start(arg, val); //va_arg(); for (i = 0; i < val; i++) { sum += va_arg(arg, int);//每呼叫一次向下取一個 } va_end(arg); return sum / val; }
如果要求多個數的最大值可以寫為
int average(int val, ...)
{
va_list arg;
int max;
int sum = 0;
int i = 0;
va_start(arg, val);
for (i = 0; i < val; i++)
{
sum = va_arg(arg, int);
if (sum>max)
max = sum;
}
va_end(arg);
return max;
}
由此我們還可以用stdarg這個巨集來模擬printf函式的實現,這裡我只是做了模擬了字串輸出,整形與字元型輸出程式碼如下:
#include<stdio.h> #include<stdarg.h> void printd(int n)//把整形按字元型輸出 { if (n < 0) { putchar('-'); } if (n) { printd(n /10); putchar(n % 10 + '0'); } } void my_printf(char* val,...) { int ch; va_list arg; va_start(arg, val); while (*val != '\0') { switch (*val) { case '%': //遇到%執行switch case語句 { if (*(val + 1) == 'c')//輸出字元 { ch = va_arg(arg, char); putchar(ch); val++; //指標變數向下偏移一個單位 } else if (*(val + 1) == 'd') { ch = va_arg(arg, char);//輸出整形 printd(ch); val++; } else if (*(val + 1) == 's')//輸出字串 { char*p = va_arg(arg, char*); while (*p != '\0') { putchar(*p); p++; } val++; //指向頭一變數的下一個字元 } else putchar('%'); break; } default: { putchar(*val); break; } } val++; } va_end(arg); } int main() //程式除錯 { int c =100 ; char*p = "laomasb"; char a = 'c'; my_printf("%s\n%d\n%c\n", p, c,a); system("pause"); return 0; }
這裡寫得還差很多,比如說%後面加數字的話是沒辦法識別並且寇衝輸出空間的,而且這程式碼自己看著就比較low。希望大神給出些建議。