Application of Variable parameters in macro definition in C Language
In the C standard library, input and output functions of printf, scanf, sscanf, sprintf, and sscanf are variable parameters. When debugging a program, we may want to define a variable parameter output function to record logs. Using a variable parameter macro is a good choice.
InC99A macro can also contain variable parameters like a function, such:
#define LOG(format, ...) fprintf(stdout, format, __VA_ARGS__)
Where,
...Variable Parameter List, __va_args _ in preprocessing, will be
Parameter Set (real parameter list).
At the same time, gcc also supports variable parameter names (
Note: VC does not support):
#define LOG(format, args...) fprintf(stdout, format, args)
Similarly, args will be replaced by the actual parameter set during preprocessing. The method is the same as the method above, but the parameter symbol is changed.
Note that the variable parameters in the preceding two methods cannot be omitted, although an empty parameter can be passed in. Speaking of this, it is necessary to mention the usage of the "#" Connection Symbol. The "#" function is to connect token. In the above example, format, args, __va_args can be considered as a token. If the token is empty, "#" is not connected, so variable parameters can be omitted. Transformation of the above two examples:
#define LOG(format, ...) fprintf(stdout, format, ##__VA_ARGS__)#define LOG(format, args...) fprintf(stdout, format, ##args)
If the parameter can be omitted, you can define a switch using a macro to implement a function that outputs logs:
#ifdef DEBUG#define LOG(format, ...) fprintf(stdout, ">>>>>" format "<<<<", ##__VA_ARGS__)#else#define LOG(format, ...)#endif
In the development phase, add a DEBUG macro to the compilation options to output logs where the LOG macro is used in the program. Otherwise, only an empty LOG macro is called, no output. Assume that the source file is test. c. When gcc is compiled, add-DDEBUG (-D indicates the preset macro, which is defined by the compiler during pre-compilation) to determine the condition when the DEBUG macro is determined, so as to output logs:
gcc -o test test.c -DDEBUG
Example: In Android NDK development, print the log macro:
You need to load the Log Module in the android. mk file and add the DEBUG option:
LOCAL_LDLIBS: =-llog # Add the Log Module LOCAL_CFLAGS + =-DDEBUG
NDKTest. cpp
#include
#include #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)#endifJNIEXPORT 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;}