MST

星途 面试题库

面试题:C语言##和#运算符在复杂宏定义场景的应用

假设有一个项目,需要通过宏定义实现一个日志记录系统,要求能够根据不同的日志级别(如DEBUG、INFO、WARN、ERROR)记录不同格式的日志信息。请利用##和#运算符设计宏,使得日志记录函数可以接受不同数量和类型的参数,并根据日志级别输出格式化的日志内容到控制台,例如:`LOG(DEBUG, "Variable %s has value %d", var_name, var_value);`。详细说明宏的设计思路和实现代码。
32.4万 热度难度
编程语言C

知识考点

AI 面试

面试题答案

一键面试

宏的设计思路

  1. 定义日志级别:通过宏定义不同的日志级别,例如 DEBUGINFOWARNERROR
  2. 使用 ### 运算符# 运算符用于将参数转换为字符串,## 运算符用于连接两个标记。
  3. 可变参数宏:C99 标准支持可变参数宏,利用这一特性来实现接受不同数量和类型的参数。
  4. 格式化输出:使用 printf 函数进行格式化输出到控制台。

实现代码

#include <stdio.h>

// 定义日志级别
#define DEBUG 0
#define INFO 1
#define WARN 2
#define ERROR 3

// 当前日志级别
#define CURRENT_LOG_LEVEL DEBUG

// 日志记录宏
#define LOG(level, ...) \
    do { \
        if (level <= CURRENT_LOG_LEVEL) { \
            const char* level_str; \
            switch (level) { \
                case DEBUG: level_str = "DEBUG"; break; \
                case INFO: level_str = "INFO"; break; \
                case WARN: level_str = "WARN"; break; \
                case ERROR: level_str = "ERROR"; break; \
                default: level_str = "UNKNOWN"; break; \
            } \
            printf("[%s] ", level_str); \
            printf(__VA_ARGS__); \
            printf("\n"); \
        } \
    } while (0)

你可以这样使用这个宏:

int main() {
    const char* var_name = "count";
    int var_value = 10;
    LOG(DEBUG, "Variable %s has value %d", var_name, var_value);
    LOG(INFO, "This is an info message");
    LOG(WARN, "This is a warning");
    LOG(ERROR, "This is an error");
    return 0;
}

在上述代码中:

  1. 首先定义了不同的日志级别 DEBUGINFOWARNERROR,并设置了当前日志级别 CURRENT_LOG_LEVEL
  2. LOG 宏接受一个日志级别参数 level 和可变参数 ...
  3. 在宏内部,首先判断当前日志级别是否满足输出条件。如果满足,根据 level 值确定日志级别的字符串表示。
  4. 使用 printf 函数输出日志级别字符串和格式化后的日志内容。__VA_ARGS__ 是可变参数宏的占位符,它会被实际传入的可变参数替换。
  5. main 函数中展示了不同日志级别的使用示例。