C语言宏参数转换为字符串

用宏定义来定义一个SQL语句, 用来指定字段的长度。那就拼接一下

#include <stdio.h>

// 定义字段长度
#define NAME_LENGTH 50

// 定义创建表的SQL语句,使用宏来指定字段长度
#define CREATE_TABLE_SQL "CREATE TABLE Users (ID INT, Name VARCHAR(" NAME_LENGTH "))"

int main() {
    // 输出创建表的SQL语句
    printf("SQL Statement: %s\n", CREATE_TABLE_SQL);
    return 0;
}
# gcc test2.c -o test2
test2.c: In function ‘main’:
test2.c:4:21: error: expected ‘)’ before numeric constant
    4 | #define NAME_LENGTH 50
      |                     ^~
test2.c:7:70: note: in expansion of macro ‘NAME_LENGTH’
    7 | #define CREATE_TABLE_SQL "CREATE TABLE Users (ID INT, Name VARCHAR(" NAME_LENGTH "))"
      |                                                                      ^~~~~~~~~~~

c的预处理器没有将数字转化为字符串。

如果将 #define NAME_LENGTH 50 改为#define NAME_LENGTH “50”后是可以的。

 

使用“#”运算符可以将宏参数转换成字符串。还是报错

# gcc test2.c -o test2
test2.c: In function ‘main’:
test2.c:7:70: error: stray ‘#’ in program
    7 | #define CREATE_TABLE_SQL "CREATE TABLE Users (ID INT, Name VARCHAR(" #NAME_LENGTH "))"

可以定义一个辅助宏将数值转化为字符串, linux内核使用的一个技巧

#define __stringify_1(x...)   #x
#define __stringify(x...)  __stringify_1(x)

稍微调整一下

#include <stdio.h>

// 定义字段长度
#define NAME_LENGTH 50

#define __stringify_1(x...) #x
#define __stringify(x...) __stringify_1(x)


// 定义创建表的SQL语句,使用宏来指定字段长度
#define CREATE_TABLE_SQL "CREATE TABLE Users (ID INT, Name VARCHAR(" __stringify(NAME_LENGTH) "))"

int main() {
    // 输出创建表的SQL语句
    printf("SQL Statement: %s\n", CREATE_TABLE_SQL);
    return 0;
}

# ./test2 SQL Statement: CREATE TABLE Users (ID INT, Name VARCHAR(50))
  • __stringify_1(x...) #x:是直接将其参数转化为字符串。注意这里使用了x...,表示这个宏可以接受多个参数

为什么用二级展开, 如果想下面这样使用获取的值是VALUE,但是输出是VALUE

#include <stdio.h>

#define VALUE 10
#define __stringify(x) #x

void main()
{
  printf(__stringify(VALUE));
}

# gcc test3.c -o test3
#./test3
#VALUE
  • __stringify(x...) __stringify_1(x):这个宏再次调用__stringify_1,但目的在于确保传递给__stringify_1的参数首先被完全展开。这是因为预处理器在处理#操作符之前不会展开宏参数中的宏。通过将参数先传递给另一个宏 (__stringify_1),我们可以确保任何在x中使用的宏都被展开了。

 

 

 

 

 

Comments are closed.