1. 程式人生 > >可變引數應用

可變引數應用

利用可變引數列表:可變引數列表是通過巨集來實現的,這些巨集定義在stdarg.h中。

值得注意的是:可變引數列表傳參時,第一個傳的引數的個數。

步驟:

1.定義一個va_list型別的變數 arg

2.巨集va_start(arg,num)---這個巨集有兩個引數,第一個引數為va_list型別的變數,第二個引數為可變引數列表之前的引數。作用就是使得 va_list 的變數指向可變引數列表的首地址。這才是一般意義上的對 va_list的初始化。

3.巨集va_arg(arg,int) ---第一個引數為va_list型別的變數第二個為引數的型別。

4.巨集va_end(arg)---結束標誌


使用可變引數,實現函式,求函式引數的平均值

程式碼如下:

  1. #include<stdio.h>  
  2. #include<stdlib.h>  
  3. #include <stdarg.h>   
  4. int average(int num, ...)//第一個引數傳的是引數的個數,後面三個點代表可變引數列表  
  5. {  
  6.     int sum = 0;  
  7.     va_list arg;  //定義一個va_list型別的變數  
  8.     va_start(arg, num); //巨集 va_start  
  9.     for (int i = 0; i < num; i++)  
  10.     {  
  11.         sum += va_arg(arg, int
    );  //巨集 va_arg  
  12.     }  
  13.     va_end(arg); //巨集 va_end  
  14.     return sum / num;  
  15. }  
  16. int main()  
  17. {  
  18.     int aver = 0;  
  19.     aver = average(5,2,4,6,8,10); //第一引數為個數,之後的數為被平均的數  
  20.     printf("%d\n", aver);  
  21.     system("pause");  
  22.     return 0;  
  23. }  
使用可變引數,實現函式,求函式引數的最大值

程式碼如下:

  1. #include <stdio.h>
  2. #include <stdarg.h>
  3. #include <windows.h>
  4. int Max(int n, ...)  
  5. {  
  6.     int i = 0;  
  7.     int max = 0;  
  8.     va_list arg;  
  9.     va_start(arg, n);  
  10.     for (i = 0; i < n; i++)  
  11.     {  
  12.         int val = va_arg(arg, int);  
  13.         if (val > max)  
  14.         {  
  15.             max = val;  
  16.         }  
  17.     }  
  18.     va_end(arg);  
  19.     return max;  
  20. }  
  21. int main()  
  22. {  
  23.     int ret = Max(10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);  
  24.     printf("%d\n", ret);  
  25.     system("pause");  
  26.     return 0;  
  1. }  

 在C語言中常用printf函式輸出各種型別的數值,而且輸出的引數可多可少,這就涉及到了可變引數函式的定義。

    在此模擬實現printf函式,可完成下面的功能,能完成下面函式的呼叫。 print("s ccc d.\n","hello",'b','i','t',100); 函式原型: print(char *format, ...) 

     程式碼如下:

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>

#include <stdlib.h>

#include<stdarg.h>

void print(char *tmp, ...)   //實現可變形參

{

va_list arg;     //宣告va_list型別的變數arg,用於訪問引數列表的未確定部分

va_start(arg, tmp);    //呼叫va_start來初始化。它的第一個引數是va_list的變數名,第2個引數是省略號前最後一個有名字的引數。初始化過程把arg變數設定為指向可變引數部分的第一個引數。

while (*tmp != '\0')

{

if (*tmp == 'c')

{

putchar(va_arg(arg, char ));  //定義va_arg來訪問引數,這個巨集接受兩個引數:va_list變數和引數列表中下一個引數的型別。

}

else if (*tmp == 's')

{

puts(va_arg(arg, char *));

}

else if (*tmp == 'd')

{

int d = va_arg(arg, int);

printf("%d", d);

}

tmp++;

}

va_end(arg);     //最後,當訪問完最後一個可變引數之後,我們需要呼叫va_end。

}

int main()

{

int a = 1;

int b = 2;

int c = 3;

print("sccc d\n""hello"'b''i''t',100);

getchar();

system("pause");

    return 0;  

}  

但是,可變引數會有一些限制,例如:

  1.可變引數必須從頭到尾逐個訪問。如果你在訪問幾個引數之後想要終止,這是可以的,但是,如果你要訪問中間的引數,那是不行的。

  2.可變引數中至少有一個命名引數。如果連一個命名引數都沒有,就無法使用va_start。

  3.這些巨集無法判斷每個引數的型別。

  4.這些巨集無法直接判斷實際存在引數的數量。

  5.如果在va_arg中指定了錯誤的型別,那麼後果是不可預測的。

希望這些對大家有所幫助。