C预处理

本文介绍了C语言预处理的三个主要方面:文件包含、宏替换和条件编译。#include指令用于包含文件,#define用于定义宏,条件编译如#if用于控制代码块的编译。还详细讲解了宏替换的规则,包括参数替换、字符串化和连接操作。预处理在编译阶段起着关键作用,帮助简化代码并提高可维护性。
摘要由CSDN通过智能技术生成

预处理器执行宏替换、条件编译以及包含指定的文件。
#include指令:用于在编译期间把置顶文件的内容包含进当前文件中;
#define指令:用任意字符序列替换一个标记;

1、文件包含
#include指令是一个将所有声明放在一起的好方法,它保证所有的源文件都具有相同的定义与变量(函数)声明。如果某个包含文件的内容发生了变化,那么所以依赖于该包含文件的源文件都必须重新编译。

#include "file name"
#include <file name>
#include 记号序列

在源文件中,上面行将被替换为由文件名指定的文件内容。
如果文件名用引号引起来,则在源文件所在位置查找该文件;如果在该位置没有找到文件或如果文件名是尖括号括起来,则将根据相应的规则查找该文件,这个规则同具体实现有关。

2、宏替换
#define 标识符 记号序列
#define 标识符(标识符表) 记号序列
#undef 标识符

预处理器把该标识符后续出现的各个实例用给定的记号序列替换。
第二次用#define指令定义同一标识符是错误的,除非第二次定义中的标记序列与第一次相同。

通常情况下,#define指令占一行,但也可以把一个较长的宏定义分成若干行,这时需要在待续的行尾加上一个反斜杠\。 
替换只对记号进行,对括在引号中的字符串不起作用。
#define max(A, B) ((A) > (B) ? (A) : (B))

如果在替换文本中,参数名以#作为前缀则结果将被扩展为由实际参数替换该参数的带引号的字符串。
#define DPRINT(expr) printf(#expr " = %g\n", expr)
DPRINT(x/y) => printf("x/y = %g\n", x/y)
预处理运算符##为宏扩展提供一种连接实际参数的手段。如果替换文本中的参数与##相邻,则该参数将被实际参数替换,##与前后的空白符将被删除,并对替换后的结果进行重新扫描。
#define PASTE(front, back) front##back
PASTE(fight, ing) => fighting

3、条件包含
用于条件语句可以对预处理本身进行控制。
#if语句对其中的常量整形表达式进行求值,若该表达式的值不等于0,则包含其后的各行,直到遇到#endif、#elif或#else语句为止。
#if !defined(HDR)
#define HDR
...
#endif

#ifndef _CALU_H
#define _CALU_H

#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define MAX(a, b) ((a) > (b) ? (a) : (b))

extern int add(int a, int b);
extern int sub(int a, int b);
extern int mul(int a, int b);
extern int div(int a, int b);

#endif
int add(int a, int b)
{
	return a + b;
}

int sub(int a, int b)
{
	return a - b;
}

int mul(int a, int b)
{
	return a * b;
}

int div(int a, int b)
{
	if (b != 0)
	{
		return a / b;	
	}

	return 0;
}
#include "calu.h"

#define TEST_NUM 10
#define TEST_ADD

int main()
{
	int i = 0;
	int a = 3;
	int b = 7;
	int val = 0;

#if defined(TEST_ADD)
	val = add(a, b);
#elif defined(TEST_MUL)
	val = mul(a, b);
#else
	val = sub(a, b);
	val = div(a, b);
#endif

	val = MIN(a, b);
	val = MAX(a, b);

	for (i = 0; i < TEST_NUM; i++) {
		val = (val, b);
	}

	return 0;

}
# 1 "main.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "main.c"
# 1 "calu.h" 1







extern int add(int a, int b);
extern int sub(int a, int b);
extern int mul(int a, int b);
extern int div(int a, int b);
# 2 "main.c" 2




int main()
{
 int i = 0;
 int a = 3;
 int b = 7;
 int val = 0;


 val = add(a, b);







 val = ((a) < (b) ? (a) : (b));
 val = ((a) > (b) ? (a) : (b));

 for (i = 0; i < 10; i++) {
  val = (val, b);
 }

 return 0;

}

通过:gcc -E main.c -o main.i

可以看到预处理后的.i文件(包括头文件展开、宏替换及条件编译)。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值