1. 程式人生 > >軟體素材---C語言函式不確定個數的入參的處理

軟體素材---C語言函式不確定個數的入參的處理

1 :  #用來把引數轉換成字串

#define P(A) printf("%s:%d\n",#A,A);
int main(int argc, char **argv)
{
        int a = 1, b = 2;
        P(a);
        P(b);
        P(a+b);
        system("pause");
}


輸出為:

2: ## 運算子可以用於巨集函式的替換部分

#define XNAME(n) x ## n

如果這樣使用巨集:XNAME(8) ,則會被展開成這樣:x8

##就是個粘合劑,將前後兩部分粘合起來,也就是有“字元化”的意思。但是“##”不能隨意粘合任意字元,必須是合法的C語言標示符。在單一的巨集定義中,最多可以出現一次“#”或“##”預處理操作符。如果沒有指定與“#”或“##”預處理操作符相關的計算次序,則會產生問題。為避免該問題,在單一的巨集定義中只能使用其中一種操作符(即,一份“#”或一個“##”,或都不用)。除非非常有必要,否則儘量不要使用“#”和“##”。

3: __VA_ARGS__ 是一個可變引數的巨集,這個可變引數的巨集是新的C99規範中新增的,目前似乎只有gcc支援(VC6.0的編譯器不支援)。實現思想就是巨集定義中引數列表的最後一個引數為省略號(也就是三個點)。

4、##__VA_ARGS__ 巨集前面加上##的作用在於,當可變引數的個數為0時,這裡的##起到把前面多餘的","去掉的作用,否則會編譯出錯

5、va_list 是在C語言中解決變參問題的一組巨集,所在標頭檔案:#include <stdarg.h>,用於獲取不確定個數的引數。

Example:

#include <stdarg.h>

typedef enum{
    ERR= 0,
    WARING,
}LogType;//用於指示不同的log型別,例如ERR型別單獨存在一種檔案中。

#define  LOG(format, ...)  LogFile(ERR, format, ##__VA_ARGS__)

void LogToFile(LogType typed, const char *format, ...)
{
    char* str = NULL;

    va_list ptr;
    va_start(ptr, format);//獲取可變引數列表的第一個引數的地址
    vsnprintf(buf, sizeof(buf), format, ptr);//inux環境下是:vsnprintf,VC6環境下是:_vsnprintf
    va_end(ptr);//清空va_list可變引數列表
    str = buf;

}

函式: int vsnprintf(char* str, size_t size, const char* format, va_list ap);

函式功能:將可變引數格式化輸出到一個字元陣列。

params:

  1. char *str 把生成的格式化的字串存放在這裡對應的地址.

  2. size_t size , str可接受的最大字元數.

  3. const char *format , 指定輸出格式的字串,它決定了你需要提供的可變引數的型別、個數和順序。

  4. va_list ap 可變引數