C語言可變參數在宏定義中的應用__C語言

來源:互聯網
上載者:User
C語言可變參數在宏定義中的應用

        http://www.cnblogs.com/xyang0917/p/4172493.html

在C語言的標準庫中,printf、scanf、sscanf、sprintf、sscanf這些標準庫的輸入輸出函數,參數都是可變的。在偵錯工具時,我們可能希望定義一個參數可變的輸出函數來記錄日誌,那麼用可變參數的宏是一個不錯的選擇。

在C99中規定宏也可以像函數一樣帶可變的參數,如:

#define LOG(format, ...) fprintf(stdout, format, __VA_ARGS__)   其中,...表示可變參數列表,__VA_ARGS__在預先處理中,會被實際的參數集(實參列表)所替換。
同時gcc還支援帶可以變參數名的方式( 注意:VC不支援 ):

#define LOG(format, args...) fprintf(stdout, format, args)   同樣,args在預先處理過程中,會被實際的參數集所替換。其用法和上面的方式一樣,只是參數的符號有變。

需要注意的是,上述兩種方式的可變參數不能省略,儘管可以傳一個空參數進去。說到這裡,有必要提一下“##”串連符號的用法,“##”的作用是對token進行串連,上例中format,args,__VA_ARGS都可以看作是token,如果token為空白,“##”則不進行串連,所以允許省略可變參數。對上述2個樣本的改造:
#define LOG(format, ...) fprintf(stdout, format, ##__VA_ARGS__)   #define LOG(format, args...) fprintf(stdout, format, ##args)   即然參數可以省略,那麼用宏定義一個開關,實現一個輸出日誌的函數就簡單了:

#ifdef DEBUG   #define LOG(format, ...) fprintf(stdout, ">>>>>" format "<<<<", ##__VA_ARGS__)   #else   #define LOG(format, ...)   #endif   在開發階段時,在編譯選項中加入一個DEBUG宏,即會在程式中使用了LOG宏的地方輸出日誌,否則只是調用了一個空的LOG宏而已,不會有任何輸出。假設源檔案為test.c,gcc編譯時間加上-DDEBUG(-D表示預定宏,在先行編譯的時候由編譯器定義)即在判斷DEBUG宏時條件成立,從而達到輸出日誌的目的:

gcc -o test test.c -DDEBUG  
樣本:在Android的NDK開發中,列印log的宏:

需要在android.mk檔案中載入日誌模組,並添加DEBUG選項:

LOCAL_LDLIBS    := -llog    #添加日誌模組   LOCAL_CFLAGS    += -DDEBUG  

NDKTest.cpp

#include <jni.h>   #include <android/log.h>      #define LOG_TAG "HelloNDK"   #ifdef DEBUG   #define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)   #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)   #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)   #else   #define LOGI(...) do{} while(0)   #define LOGD(...) do{} while(0)   #define LOGE(...) do{} while(0)   #endif      JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved)   {       JNIEnv *env;       jclass cls;       if (vm->GetEnv((void**)&env, JNI_VERSION_1_4) != JNI_OK)       {           LOGE("init javavm failed!");           return JNI_ERR;       }       cls = env->FindClass("com/learn/ndk/SampleModel");       if (cls == NULL)       {           LOGE("can't find com.learn.ndk.SampleModel.");           return JNI_ERR;       }       class_com_learn_ndk_MainActivity = (jclass)env->NewWeakGlobalRef(cls);       env->DeleteLocalRef(cls);       return JNI_VERSION_1_4;  

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.