用宏定义来定义一个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.