前言:在本文中,我将系统的整理一下C语言关于预处理部分的语法,便于整理与回归。
1.预定义符号
在C语言中,C标准提供里一些C预定义符号,在预处理期间完成,可以直接使用。
有如下几个符号:
2.#define
在这个define情况下,该语句是在预处理期间处理完成的。有下面几种不同的分类:
2.1#define 常量定义
注:在使用这个常量定义时候,尽量不要在后面带上“;"这个分号(有需要除外)。
2.2#define 宏定义
#define机制包括了⼀个规定,允许把参数替换到⽂本中,这种实现通常称为宏(macro)或定义宏(definemacro)
注:
1.参数列表的左括号必须与name紧邻,如果两者之间有任何空⽩存在,参数列表就会被解释为stuff的⼀部分。
2.要带上小括号
3.不要使用带有改变参数本身性质的语法
宏在替换过程中,遵循以下规律:
- 在调⽤宏时,⾸先对参数进⾏检查,看看是否包含任何由#define定义的符号。如果是,它们⾸先被替换。
- 替换⽂本随后被插⼊到程序中原来⽂本的位置。对于宏,参数名被他们的值所替换。
- 最后,再次对结果⽂件进⾏扫描,看看它是否包含任何由#define定义的符号。如果是,就重复上述处理过程。
注:1.define可以出现其他define符号 2.在define中不能使用递归
2.3 宏与函数区别
3.4#undef 移除定义
3.5define与函数的命名约定
在通常情况下,宏一般全部大写命名,函数一般不全大写命名。
3.#与##操作符
#作用:将参数字符串化
##作用:参数字符串化并粘合其右边符号作为一个变量名称
3.1#的代码示例:
把字符串中的参数字符串化
#include<stdio.h>#define my_printf(val,name) printf("the num of " #name " is %d",val);int main()
{int a = 6;my_printf(a, a);return 0;
}
3.2##的代码示例
造一个贴切返回类型的函数名
#define my_max(type) \
type type##_max(type x,type y)\
{\
return x>y?x:y;\
}\
my_max(int)int main()
{int max = int_max(1, 2);printf("max = %d\n", max);return 0;
}
4.命名行定义
许多C的编译器提供了⼀种能⼒,允许在命令⾏中定义符号。⽤于启动编译过程。例如:当我们根据同⼀个源⽂件要编译出⼀个程序的不同版本的时候,这个特性有点⽤处。(假定某个程序中声明了⼀个某个⻓度的数组,如果机器内存有限,我们需要⼀个很⼩的数组,但是另外⼀个机器内存⼤些,我们需要⼀个数组能够⼤些。)
5.条件编译
在编译⼀个程序的时候我们如果要将⼀条语句(⼀组语句)编译或者放弃是很⽅便的。
条件编译用来处理调试性的代码,删除可惜,保留⼜碍事,所以我们可以选择性的编译或者是一些不同版本的代码。
5.1#if
这个跟if基本是一样的,如果if后面结果为真,那么下面这些代码(直到#end)就执行编译,为假就不参与编译。
下面是示例:
int main()
{
#if 1printf("hello world\n");
#endifreturn 0;
}
这里有个很坑的写法:
#include<stdio.h>
#include<windows.h>#define A 1
int main()
{int a = 1;#if A == aprintf("hello world\n");
#endifsystem("pause");return 0;
}
明明相等为啥printf不参与编译啊?因为变量a是在预处理之后形成的。
5.2#ifdef
如果后面的参量名称被定义了,那么ifdef下面(直到#endif)就参与编译。如果没有被定义,ifdef下面(直到#endif)就不参与编译。
#include<stdio.h>
#include<windows.h>#define PAUSEint main()
{#ifdef PAUSEprintf("pause\n");
#endifreturn 0;
}
5.3#ifndef
如果后面的参量名称没有被定义,那么ifndef下面(直到#endif)就参与编译。如果被定义,ifndef下面(直到#endif)就不参与编译。
#include<stdio.h>
#include<windows.h>#define PAUSEint main()
{#ifndef PAUSEprintf("pause\n");
#endifreturn 0;
}
所以这里有个很重要的常见用法:就是避免头文件重复包含的问题(参见下面方法2)。
//1.方式1:
#pragma once//2.方式2:
#ifndef ONCE
#define ONCE//...#endif
5.4多个分支条件编译#if #elif #else
与if、else if、else同理
#include<stdio.h>
#include<windows.h>#define A 2int main()
{#if A==1printf("1\n");
#elif A==2printf("2\n");
#elif A==3printf("3\n");
#endifsystem("pause");return 0;
}
5.5上面所说的可以嵌套使用
#include<stdio.h>
#include<windows.h>#define A 2int main()
{#if A==2
#ifdef Aprintf("ok\n");
#endif
#endifreturn 0;
}
6.头文件包含
#include”“先搜索本地头文件,找不到再去找库头文件。
#include<>直接去找库头文件.
完。