2016-10-28 40 views
0

我一直在尋找一種方式來的參數數目不定傳遞給一個函數,當我遇到做到這一點使用va_listva_start和STDARG.H的va_end的方式來如給出的程序here所示。

但是無法找到任何方式來訪問傳遞給函數的無限個參數的隨機方式。隨機訪問中的C函數的參數的數量不定

使用stdarg.h頭文件中的va_list的方式是按順序訪問參數。一旦讀完了一個論點,就不會有回頭。

有沒有辦法隨機訪問這些參數?

編輯:我被建議發佈代碼而不是包含它的頁面的鏈接。所以這裏是:

#include <stdarg.h> 
#include <stdio.h> 

/* this function will take the number of values to average 
followed by all of the numbers to average */ 
double average (int num, ...) 
{ 
    va_list arguments;      
    double sum = 0; 

    /* Initializing arguments to store all values after num */ 
    va_start (arguments, num);   

    for (int x = 0; x < num; x++)   
    { 
     sum += va_arg (arguments, double); 
    } 
    va_end (arguments);     // Cleans up the list 

    return sum/num;      
} 

int main() 
{ 

    printf("%f\n", average (3, 12.2, 22.3, 4.5)); 
    /* here it computes the average of the 5 values 3.3, 2.2, 1.1, 5.5 and 3.3 
    printf("%f\n", average (5, 3.3, 2.2, 1.1, 5.5, 3.3)); 
} 
+2

把每個人放在一個數組? –

+0

@WeatherVane我在想同樣的事情,只是做一個函數,讀取va_list中的參數並將它們保存在數組中?這可能不是你想要做的,但是然後添加一些精確度。 – xoxel

+1

你仍然需要知道類型和參數的數量(printf通過走格式字符串來做到這一點)BTW:對函數可以採用的參數數量也有嚴格的限制。 – joop

回答

1

有沒有便攜的方式來做到這一點。

假設您的函數被三個參數調用,即intdoublelong double。他們可能都有不同的大小。

va_arg機制故意隱藏變量參數的底層佈局,因爲它可以因實現而異。

但讓我們假設一個典型的實現可能會依次傳遞堆棧上的參數。你的函數將無法知道內存中的第三個參數是在不知道前兩個參數的大小的情況下。每個參數佔用的空間量可能與該參數的大小不匹配;例如,爲32位參數分配64位可能會更方便。

<stdarg.h>故意爲訪問可變參數提供了一個相當小的接口。它只允許你按順序訪問它們,只有當你知道每個參數的類型時。

如果你想做類似的事情,你可以編寫一個函數,它指向一個指針數組的初始元素,每一個指向某個數據結構的指針可以包含任何幾種類型(可能類似於a tagged union)。但是,調用者必須在調用該函數之前設置該結構。

幸運的是,這在實踐中並不是什麼問題。我想不出任何特定的原因,你會需要隨機訪問參數。

如果你想擁有所有相同類型的任意數量的參數,那麼這就是數組的用途。

+0

如果我們試着「退回到stdarg的後面」,請注意,在64位平臺上,參數的_some_被傳遞到寄存器中,剩下的放在堆棧中[[請參閱本問答](http: //stackoverflow.com/q/40216160/2096401))。 – TripeHound