当前位置:网站首页>[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;
}
本章完
边栏推荐
- SQL injection Less54 (limited number of SQL injection + union injection)
- TCP详解(一)
- 11、Redis实现关注、取消关注以及关注和粉丝列表
- Mycat's master-slave relationship, vertical sub-database, horizontal sub-table, and detailed configuration of mycat fragmented table query (mysql5.7 series)
- 【异常】The field file exceeds its maximum permitted size of 1048576 bytes.
- 15、网站统计数据
- 10. Redis implements likes (Set) and obtains the total number of likes
- What is SQALE
- Map.Entry理解和应用
- return in try-catch
猜你喜欢

MP使用时的几个常见报错

接口测试关键技术

8、统一处理异常(控制器通知@ControllerAdvice全局配置类、@ExceptionHandler统一处理异常)

CentOS7下mysql5.7.37的安装【完美方案】

什么是系统?

STM32 problem collection

TCP详解(一)

8. Unified exception handling (controller notifies @ControllerAdvice global configuration class, @ExceptionHandler handles exceptions uniformly)

Recursive query single table - single table tree structure - (self-use)

The use of font compression artifact font-spider
随机推荐
解析小结—自用
TCP详解(二)
10、Redis实现点赞(Set)和获取总点赞数
TCP详解(三)
CloudCompare & PCL calculate the degree of overlap between two point clouds
Installation of mysql5.7.37 under CentOS7 [perfect solution]
【Cocos Creator 3.5】缓动系统停止所有动画
Uninstallation of mysql5.7.37 under CentOS7 [perfect solution]
遗留系统的自动化策略
15、网站统计数据
IIR滤波器和FIR滤波器
STM32 problem collection
测试中的误报和漏报同样的值得反复修正
LeetCode简单题之两个数组间的距离值
字体压缩神器font-spider的使用
7年经验,功能测试工程师该如何一步步提升自己的能力呢?
【C语言】预处理操作
【HCIP】ISIS
SQL injection Less46 (injection after order by + rand() Boolean blind injection)
选好冒烟测试用例,为进入QA的制品包把好第一道关