C语言:预处理

1.#运算符

当预处理器搜索#define定义的符号的时候,字符串常量的内容并不被搜索。

复制代码
#include <stdio.h>
#define PRINT(n) printf("the value of n is %d", n);
int main()
{
	int a = 10;
	PRINT(a);
	return 0;
}

就像这段代码中,printf中的第一个n是不会被宏代替的,但我们想说明的是a的值(也就是第一个n被替换后的结果)。那我们就可以使用#运算符。

接下来要说的#运算符所执⾏的操作可以理解为"字符串化"。

复制代码
#include <stdio.h>
#define PRINT(n) printf("the value of "#n " is %d", n);
int main()
{
	int a = 10;
	PRINT(a);
	return 0;
}

在这段代码中,a被带入到#n和n,因为#n的预处理(字符串化)使得语句变成了printf("the value of ""a" " is %d", a);几个字符串会自动连接在一起,所以就能将a打印出来了。

2.## 运算符

可以把位于它两边的符号合成⼀个符号,它允许宏定义从分离的⽂本⽚段创建标识符。 ## 被称

为记号粘合。这样的连接必须产⽣⼀个合法的标识符。否则其结果就是未定义的。这⾥我们想想,写⼀个函数求2个数的较⼤值的时候,不同的数据类型就得写不同的函数。

复制代码
int int_max(int x, int y)
{
 return x>y?x:y;
}
float float_max(float x, float y)
{
 return x>yx:y;
}

其实在c++中可以使用函数重载来解决,其实在c语言中也有不错的方法来实现。

复制代码
#define GENERIC_MAX(type) \
type type_max(type x, type y)\
{ \
 return (x>y?x:y); \
}

学了基本的预处理,有人可以会想使用以上方式去定义函数,但我们会发现每次定义出来的函数名都是type_max,这是因为编译器将这个看成一个整体,并不会将其中的type代入。

解决就需要用到## 运算符。

复制代码
type type##_max(type x, type y)\
{ \
 return (x>y?x:y); \
}

这样编译器就会先将type代入,再将这两段文本连接在一起。这样处理后我们就可以通过这个宏定义去定义很多类似的函数了。

3.命名约定
⼀般来讲函数的宏的使⽤语法很相似。所以语⾔本⾝没法帮我们区分⼆者。
那我们平时的⼀个习惯是:
(1)把宏名全部⼤写
(2)函数名不要全部⼤写
4.#undef
这条指令⽤于移除⼀个宏定义。
5.#if,#elif,#else
同条件语句中的用法,多出来一条使用的预编译命令(#endif)。#endif表示这个if的条件编译的结束。
6.#ifdef,#ifndef
#ifdef判断的是是否定义,是为真,否为假,而#ifndef正好相反。#endif和前面一样表示条件编译的结束。在头文件中使用这些判断是否定义的预处理命令可以防止我们重复包含头文件,当然#pragma once也可以实现这个功能。
7.头⽂件的包含
双引号包含头文件一般用于用户头文件,会先在当前文件夹中寻找,再去标准路径中查找。而三角包含头文件一般用于库文件,会直接去标准路径中查找,库函数基于性能的考虑会选择这种包含方式。

相关推荐
Aurorar0rua1 小时前
CS50 x 2024 Notes Data structures - 08
c语言·开发语言·学习方法
小米里的大麦1 小时前
19 C、C++ 操作 MySQL
c语言·c++·mysql
Logic1012 小时前
C语言/数据结构位运算题解:异或XOR找出套碗游戏中的“幸运碗“——只出现一次的数字
c语言·数据结构·算法·数组·位运算·时间复杂度·空间复杂度
番茄灭世神2 小时前
PN学堂GD32教程第12篇——SPI与Nor Flash
c语言·stm32·单片机·嵌入式·gd32·总线协议
苏辰澈2 小时前
C++独属于自己的变身:多态
c语言·开发语言·c++·visualstudio·编辑器
水饺编程3 小时前
第1章,[Win32 章节]:在 VS2019 里面安装 MSDN
c语言·c++·windows·visual studio
水饺编程3 小时前
第1章,[Win32 章节]:编程环境与 MSDN
c语言·c++·windows·visual studio
wuminyu14 小时前
ForkJoinPool窃取线程在扫描其他WorkQueue时的随机采样算法与Phase线程挂起唤醒机制解析
java·linux·c语言·jvm·c++
Logic10114 小时前
C语言/数据结构欧几里得算法题解:长方形切割最大正方形——贪心划分计数
c语言·数据结构·算法·贪心算法·时间复杂度·空间复杂度·欧几里得算法
老王爱玩车16 小时前
文件操作从打开到缓冲区
c语言·开发语言·学习