当前位置:网站首页>[C language] Preprocessing operation
[C language] Preprocessing operation
2022-07-31 03:10:00 【Ahao_te】
在编译一个CLanguage involves many steps.The first step is the preprocessing stage.
1、预处理详解
1.1、预定义符号
The table below summarizes the reasons预处理器定义的符号.Their values are either string constants,Or a decimal numeric constant.__ FILE __ 和 __ LINE __ Used to view the file's disk address and source file code line number, respectively,__ DATE __ 和 __ TIME represent the date and time, respectively, STDC __ Identify if the compiler followsANSI C.
具体展示:
#include<stdio.h>
int main()
{
int i = 0;
FILE* pf = fopen("log.txt", "w");
if (pf == NULL)
{
perror("fopen");
return -1;
}
for (i = 0; i < 10; i++)
{
fprintf(pf, "file:%s line=%d date:%s time:%s i=%d\n", __FILE__, __LINE__, __DATE__, __TIME__, i);
}
fclose(pf);
pf = NULL;
return 0;
}
1.2、#define
1.2.1 #define 定义标识符
#define name stuff
比如
#define MAX 1000
//如果是 #define MAX 1000;
//max = 1000;; 不太合适
if(condition)
max = MAX;
else
max = 0;
1.2.2 #define 定义宏
#define The mechanism has a rule,Run replaces the arguments into the text,This implementation is called a macro or definition macro.
下面是宏的声明方式:
#define name( parament-list ) stuff
其中parament-list is a comma-separated list of symbols,它们可能出现在stuff中.
注意:
参数列表的左括号必须与name紧贴.
如果两者之间有任何空白存在,参数列表就会被解释为stuff的一部分.
See below for macro substitution
比如有一个
#define SQUARE( x ) x*x
SQUARE(5);将会等于55,那么如果是SQUARE(5 + 1),就会等于5 + 1 * 5 +1.
This reminds us more clearly,when defining a macro,It is best to leave out the parentheses.
比如x * x写成 ((x)(x)),This allows us to get the expected results more accurately.
1.2.3 #define 替换规则
- 在调用宏时,首先对参数进行检查,看看是否包含任何由#define定义的符号.如果是,它们首先被替换.
- 替换文本随后被插入到程序中原来文本的位置.对于宏,参数名被他们的值所替换.
- Finally see if there are more#define定义的符号.Repeat if so1,2步骤.
注意:
- 宏参数和#define 定义中可以出现其它#define 定义的符号.但是对于宏,不能出现递归.
- 当预处理器搜索#define定义的符号的时候,字符串常量的内容并不被搜索.
1.2.4 #和##
如何把参数插入到字符串中?
char* p ="hello ""world\n";
printf("hello," world\n);
printf("%s",p);
这里输出的是不是
hello world?
是,我们发现字符串是有自动连接的特点的.
When a string is used as a macro parameter, I want to put it into a string as a string.
用# ,Turns a macro argument into a string for .
That is the case below
将i+3作为参数传给VALUE,并且通过#Puts the original content of the parameter into a string as a string.
int i = 10;
#define PRINT(FORMAT, VALUE)\ printf("the value of " #VALUE " is "FORMAT "\n", VALUE);
...
PRINT("%d", i+3); //产生什么效果?
##的作用
##The symbols on both sides can be combined into one symbol
注意:
这样的连接必须产生一个合法的标识符.否则结果就是未定义的.
#define CAT(str, Num) str##Num
int main()
{
char* str1 = "hello world";
printf("%s\n", CAT(str, 1)); //"hello world"
printf("%s\n", str1); //"hello world"
return 0;
}
1.2.4 with side effects宏参数
x+1; without side effects
x++; with side effects
#define MAX(a, b) ( (a) > (b) ? (a) : (b) )
...
x = 5;
y = 8;
z = MAX(x++, y++);
printf("x=%d y=%d z=%d\n", x, y, z);
输出结果:6,10,9.
1.2.4 宏和函数对比
Macros are usually used to perform simple operations.
For example, when you need some simple addition, subtraction, multiplication and division operations,The excellence of macros is more prominent.
因为:
- 宏比函数在程序的规模和速度方面更胜一筹
- 宏与类型无关
But macros also have drawbacks
- 每次使用宏的时候,The code defined by the macro needs to be inserted into the program.除非宏比较短,否则可能大幅度增加程序的长度.
- 宏是无法调试的.
- Macros are type-independent,所以不够严谨
- Macros can introduce priority issues,It is easy to make program errors.
1.2.4 命名约定
宏名全部大写
函数名不要全部大写
1.3 #undef
#undef NAME
用于移除一个宏定义
1.4 条件编译指令
When some debug code,删除可以,保留又碍事,所以我们可以选择性的编译.
比如:
#define __DEBUG__
int main()
{
int i = 0;
int arr[10] = {
0 };
for (i = 0; i < 10; i++)
{
arr[i] = i;
#ifdef __DEBUG__
printf("%d\n", arr[i]);
#endif //__DEBUG__
}
return 0;
}
There are other common conditional compilation directives:
#define M 6
int main()
{
#if M<5
printf("haha\n");
#elif M==5
printf("heihei\n");
#else
printf("hey!\n");
#endif
return 0;
}
ifndef == if not define
ifdef == if define
#define MAX 100
int main()
{
#ifndef MAX //#indef MAX
printf("max\n");
#endif
return 0;
}
1.5 实现OFFSETOF
宏定义offsetofIt is used to observe the offset address of the structure member.
offsetof(type, m_name)
比如
#include <stddef.h>
struct S
{
char c1;
int a;
short c2;
char c3;
};
int main()
{
struct S s = {
0 };
printf("%d\n", offsetof(struct S, c1));
printf("%d\n", offsetof(struct S, a));
printf("%d\n", offsetof(struct S, c2));
printf("%d\n", offsetof(struct S, c3));
}
从地址为0to access structure members,You can get the corresponding address and the equivalent offset.
struct S
{
char c1;
int a;
short c2;
char c3;
};
#define OFFSETOF(type,name) (int)&(((type*)0)->name)
int main()
{
struct S s = {
0 };
printf("%d %d %d %d",OFFSETOF(struct S, c1), OFFSETOF(struct S, a),
OFFSETOF(struct S, c2), OFFSETOF(struct S, c3));
return 0;
}
本章完
边栏推荐
- Multilingual settings of php website (IP address distinguishes domestic and foreign)
- 解析小结—自用
- 16、热帖排行
- 【Exception】The field file exceeds its maximum permitted size of 1048576 bytes.
- JetPack组件Databinding
- Uninstallation of mysql5.7.37 under CentOS7 [perfect solution]
- 2022 Nioke Multi-School League Game 4 Solution
- YOLOV5 study notes (3) - detailed explanation of network module
- 8. Unified exception handling (controller notifies @ControllerAdvice global configuration class, @ExceptionHandler handles exceptions uniformly)
- 11. Redis implements follow, unfollow, and follow and follower lists
猜你喜欢
YOLOV5学习笔记(三)——网络模块详解
11. Redis implements follow, unfollow, and follow and follower lists
一份高质量的测试用例如何养成?
Chapter 9 SVM Practice
STM32问题合集
Graphical lower_bound & upper_bound
The whole process scheduling, MySQL and Sqoop
10、Redis实现点赞(Set)和获取总点赞数
共模电感的仿真应用来了,满满的干货送给大家
Office automation case: how to automatically generate period data?
随机推荐
StringJoiner in detail
【HCIP】ISIS
选好冒烟测试用例,为进入QA的制品包把好第一道关
7年经验,功能测试工程师该如何一步步提升自己的能力呢?
JetPack component Databinding
TCP/IP四层模型
Discourse Custom Header Links
冒泡排序、选择排序、直接插入排序、二分法查找
【CocosCreator 3.5】CocosCreator 获取网络状态
Uninstallation of mysql5.7.37 under CentOS7 [perfect solution]
Unity3D Button mouse hover enter and mouse hover exit button events
点云DBSCAN聚类(MATLAB,非内置函数)
10. Redis implements likes (Set) and obtains the total number of likes
学习DAVID数据库(1)
mycat的主从关系 垂直分库 水平分表 以及mycat分片联表查询的配置详解(mysql5.7系列)
False positives and false negatives in testing are equally worthy of repeated corrections
Chapter 9 SVM实践
【C语言】三子棋(经典解法+一览图)
MP使用时的几个常见报错
QML的使用