首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

C 宏定義中 # 號運算符 (字符串化) 詳解:#hdlr 將參數轉為字符串字面量

     編輯:程式設計綜合問答

代碼片段


#define QMI_SVC_HDLR(cmdval, hdlr) {cmdval, #hdlr, hdlr}

核心結論

# 是 C 預處理器的 **字符串化運算符 (Stringizing Operator)**。

  • **作用**:將宏參數的**實際參數名** (或參數文本) 轉換為**雙引號包圍的字符串字面量**。
  • **位置**:只能用於**帶參數的宏定義**中,且必須置於參數名**之前**。
  • **結果**:`#hdlr` → `"hdlr"` (若調用時傳入 `myFunc`,則變為 `"myFunc"`)。

展開示例


// 宏調用
QMI_SVC_HDLR(5, myHandler)

// 預處理後展開為
{5, "myHandler", myHandler}

結構體初始化包含三個字段:數值、處理器名稱字符串、處理器函數指針。

完整演示程序


#include 

#define QMI_SVC_HDLR(cmdval, hdlr) {cmdval, #hdlr, hdlr}

typedef void (*HandlerFunc)(void);

typedef struct {
    int cmd;
    const char* name;
    HandlerFunc func;
} ServiceHandler;

void handleLogin() { printf("Login handler\n"); }
void handleLogout() { printf("Logout handler\n"); }

int main() {
    ServiceHandler handlers[] = {
        QMI_SVC_HDLR(100, handleLogin),
        QMI_SVC_HDLR(200, handleLogout)
    };
    
    for (int i = 0; i < 2; i++) {
        printf("Cmd: %d, Name: %s, Func: %p\n", 
               handlers[i].cmd, handlers[i].name, handlers[i].func);
        handlers[i].func();
    }
    return 0;
}

輸出:


Cmd: 100, Name: handleLogin, Func: 0x...
Login handler
Cmd: 200, Name: handleLogout, Func: 0x...
Logout handler

進階:## 連接運算符 (Token Pasting)

常與 `#` 配合使用:


#define DECLARE_HANDLER(name) \
    void handle_##name() { printf(#name " called\n"); }

DECLARE_HANDLER(Login)   // 展開為 void handle_Login() { printf("Login" " called\n"); }
DECLARE_HANDLER(Logout)  // 展開為 void handle_Logout() { printf("Logout" " called\n"); }

實際應用場景

  • 命令表/分發表註冊:自動生成命令字符串名稱,避免手寫字符串與函數名不同步。
  • 日誌/調試宏:`#define LOG_VAR(x) printf(#x " = %d\n", x)` → `LOG_VAR(count)` → `printf("count = %d\n", count)`。
  • 序列化/反射模擬:結構體字段名自動字符串化。

注意事項

  1. 參數宏展開後再字符串化:`#define STR(x) #x` / `STR(VALUE)` → `"VALUE"` (若 VALUE 是宏,先展開再字符串化需雙層宏)。
  2. 字符串化結果為**字符串字面量**,存儲在只讀數據段,生命周期全程。
  3. 不支持字符串化表達式:`#(a+b)` 非法,只能字符串化單個參數標識符。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved