C语言进阶课程学习记录-第25课 - # 和 ## 操作符使用分析
- #运算符
- 实验-#转化字符串
- 预处理后代码
- 实验-#输出函数名
- 预处理后的代码
- ##运算符
- 实验-##定义变量
- 预处理后代码
- 实验-##定义结构体
- 预处理后的代码
- 小结
本文学习自狄泰软件学院 唐佐林老师的 C语言进阶课程,图片全部来源于课程PPT,仅用于个人学习记录
#运算符
实验-#转化字符串
#include <stdio.h>#define STRING(x) #xint main()
{printf("%s\n", STRING(Hello world!));printf("%s\n", STRING(100));printf("%s\n", STRING(while));printf("%s\n", STRING(return));return 0;
}
/*
output:
Hello world!
100
while
return
*/
预处理后代码
//gcc -E test.c -o test.i
//test.i
# 1 "test.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "test.c"int main()
{printf("%s\n", "Hello world!");printf("%s\n", "100");printf("%s\n", "while");printf("%s\n", "return");return 0;
}
实验-#输出函数名
#include <stdio.h>#define CALL(f, p) (printf("Call function %s\n", #f), f(p))int square(int n)
{return n * n;
}int func(int x)
{return x;
}int main()
{int result = 0;result = CALL(square, 4);printf("result = %d\n", result);result = CALL(func, 10);printf("result = %d\n", result);return 0;
}
/*
output:
Call function square
result = 16
Call function func
result = 10
*/
预处理后的代码
# 1 "test.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "test.c"int square(int n)
{return n * n;
}int func(int x)
{return x;
}int main()
{int result = 0;result = (printf("Call function %s\n", "square"), square(4));//逗号表达式printf("result = %d\n", result);result = (printf("Call function %s\n", "func"), func(10));printf("result = %d\n", result);return 0;
}
##运算符
实验-##定义变量
#include <stdio.h>#define NAME(n) name##nint main()
{int NAME(1);int NAME(2);NAME(1) = 1;NAME(2) = 2;printf("%d\n", NAME(1));printf("%d\n", NAME(2));return 0;
}
/*
output:
1
2*/
预处理后代码
int main()
{int name1;int name2;name1 = 1;name2 = 2;printf("%d\n", name1);printf("%d\n", name2);return 0;
}
实验-##定义结构体
#include <stdio.h>#define STRUCT(type) typedef struct _tag_##type type;\struct _tag_##typeSTRUCT(Student)
{char* name;int id;
};int main()
{Student s1;Student s2;s1.name = "s1";s1.id = 0;s2.name = "s2";s2.id = 1;printf("s1.name = %s\n", s1.name);printf("s1.id = %d\n", s1.id);printf("s2.name = %s\n", s2.name);printf("s2.id = %d\n", s2.id);return 0;
}
/*
output:
s1.name = s1
s1.id = 0
s2.name = s2
s2.id = 1*/
预处理后的代码
# 1 "test.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "test.c"typedef struct _tag_Student Student; struct _tag_Student
{char* name;int id;
};int main()
{Student s1;Student s2;s1.name = "s1";s1.id = 0;s2.name = "s2";s2.id = 1;printf("s1.name = %s\n", s1.name);printf("s1.id = %d\n", s1.id);printf("s2.name = %s\n", s2.name);printf("s2.id = %d\n", s2.id);return 0;
}
小结
#运算符用于在预处理期将宏参数转换为字符串
##运算符用于在预处理期粘连两个标识符
编译器不知道#和##运算符的存在
#和##运算符只在宏定义中有效