2012-03-30 58 views
4

我使用va_list的是這樣的:va_list的和在va_arg

void foo(const char* firstArg, ...) { 
    va_list args; 
    va_start (args, firstArg); 
    for (const char* arg = firstArg; arg != NULL; arg = va_arg(arg, const char*)) { 
     // do something with arg 
    } 

    va_end(args); 
} 

FOO( 「123」, 「234」, 「345」)

前三個參數傳遞給正確富,但其中「 345" 完成後,

arg = va_arg(arg, const char*) 

設置一些其它反常值ARG

所以問題出在哪裏。我使用llvm3.0作爲我的編譯器。

+0

OK,我這樣做'foo(「123」,「234」,「345」,NULL)'。我會測試它是否工作。 – holsety 2012-03-30 02:38:49

+1

你真的應該傳遞'(char *)NULL',因爲'NULL'可能被定義爲一個普通的0,編譯器無法隱式知道它是一個沒有強制轉換的指針值。如果'sizeof(int)!= sizeof(char *)'對於64位實現來說並不少見,這一點尤其重要。 – FatalError 2012-03-30 03:30:32

+2

其實不然。在C11中,§7.19''聲明_宏是 NULL NULL ,它擴展爲一個實現定義的空指針常量;因此只有一個破壞的實現可以以不等於空指針的方式定義NULL 。在§7.17''中的C99中的措詞是相同的,我相信C89也基本相同。 – 2012-03-30 03:50:50

回答

4

我覺得迴路應如下:

for (const char* arg = firstArg; arg != NULL; arg = va_arg(args, const char*)) 

的變化是va_arg(args, const char*)而不是va_arg(arg/*<<==*/, const char*)

10

C不會自動將NULL置於...參數列表的末尾。如果你想用NULL來檢測參數的結尾,你必須明確地傳遞它。某些函數(如printf)使用較早的參數來確定它們何時到達參數的末尾。

編輯:而實際上,如果你想要把一個NULL末,你需要讓它得到正確類型的空指針傳遞給它轉換爲適當的類型。)

+0

請您提供額外的信息或鏈接,以瞭解printf()在到達參數結尾時如何計算出來。 「printf()」的工作方式與任何其他具有可變數量參數的函數的工作方式完全相同嗎? – barnes 2015-01-20 02:36:59

+1

它計數百分號的數量。 – 2015-01-20 04:10:02

+0

我只是假設'printf()'使用了2個類型爲'va_list()'的指針。一個用於跟蹤'%'的參數和其他參數。是對的嗎? – barnes 2015-01-20 04:33:02