C语言预处理

预定义符号

        已经约定好了的符号

__STDC__ 如果编译器遵循 ANSIC,他的值就是 1 否则就是未定义的。

int main()
{
	printf("%s\n",__FILE__);//当前文件路径
	printf("%s\n",__DATE__);//被编译的日期
	printf("%s\n",__TIME__);//被编译的时间
	printf("%d\n",__LINE__);//当前代码的行号
	printf("%s\n",__STDC__);//当前环境是为定义的
	return 0;
}

#define 定义符号

#define 可以定义很多东西,比如 ,常量 10000、'a'

还能定义关键字 ,一段代码,一个函数,字符串,等等等。

#define 定义函数

 

//定义一个符号,内容是一个函数
#define FUNCTION int add(int x , int y)\
{\
	return x + y ;\
}
//使用这个函数
FUNCTION
int main()
{
	int a = 66;
	int b = 43;
	//对函数进行传参
	int ret = add(a, b);
	printf("%d\n", ret);

	return 0;
}

符号 与 符号的内容之间实现的是 完全替换, 符号后面有什么,那么就是什么,写的时候请注意一些符号,你替换过去是不是会多余。


#define 定义宏

        宏有点类似于函数,ADD(a , b) == (a + b); 

a 对应的是 x ,b 对应的是 y,宏的原理就是把传过去的 a and b 全部替换成相应的x 和 y

所以这里的 ADD(a,b)  == (a + b * (a - b)),

宏在书写的时候应注意多加括号,避免替换后,与你想要的优先级不一样 

类似于极限里面的等价无穷小,什么什么就是什么什么,注意优先级就行

#define ADD(x,y) (x + y*(x - y));

int main()
{
	int a = 999;
	int b = 666;
	int ret = ADD(a, b)//替换后的样子(999 + 666 * (999 - 666))
	printf("%d\n", ret);

	return 0;
}

宏的要点

不管是定义 符号 还是,都得 是先替换后运算

如果宏的参数里有其他的符号会先 进行符号替换,再进行宏替换

宏也可以宏嵌套,也就是一个宏的参数可能是另一个宏,但是宏不能递归

字符串里面,不能调用宏

宏的参数可以是某个类型

#define ALG(type) type xx 

int main()
{
	ALG(int);
	xx = 66;
	printf("%d\n",xx);


	return 0;
}

 宏与函数的对比

# and ## 运算符

   的一个参数转换为字符串表面量


#define aaa(x) #x
int main()
{
	printf(aaa(666\nljaflksd\n哈萨克开发阶段还是\n));
	//aaa(666\nljaflksd\n哈萨克开发阶段还是\n) 
	//就等于"666\nljaflksd\n哈萨克开发阶段还是\n"
	//等于printf("666\nljaflksd\n哈萨克开发阶段还是\n")
	return 0;
}

## 宏里面参数转符号连接作用,把 int 和下划线粘贴在一起就变成了一个函数名

#define AAA(A) A A##_add(A x ,A y )\
{\
	return (A)(x + y);\
}
//函数创建
AAA(int)//等于int int_add(int x int y )\
{\
	return (int)(x + y);\
}

AAA(float)//等于float float_add(float x, float y)\
{\
return (float)(x + y); \
}
int main()
{
	int ret = int_add(5, 6);
	float retone = float_add(1.1f, 2.2f);
	printf("%d\n", ret);
	printf("%f\n", retone);

	return 0;
}

条件编译

#undef 移除一个定义的符号

#ifdef 判断以一个符号是否被定义,为真执行语句为假则跳过 (判断是否有这个符号)

#define G

int main()
{
	#ifdef GHG
	printf("有定义\n");
	#endif // GHG
	printf("hehe\n");


	return 0;
}

#endif 用来结束 #if 的判断,如果没有那么 #if 下面的所以代码将会被影响根本运行不了。

分支判断:与正常的分支语句道理相同,记得末尾 #endif

#ifndef 判断一个符号没有被定义,没有为真,定义了为假

 


文件包含

两种包含方式

        #include<xxxxx.h> 直接在标准头文件夹里搜索

这是我的头文件存放地,

想查自己的文件夹存放地,可用everthing随便搜索一个头文件然后打开路径,可能会有多个,注意位置

        #include"xxxxx.h" , 先在工程文件夹里面搜索,搜不到再去标准头文件夹里搜索

        同一个工程或项目,应避免重复包含头文件,否则只会增加代码量

避免方法

        先定义一个符号,然后再在上面判断它没有被定义,因为当你第二次包含进来的时候,这个符号已经被定义,所后面都会被屏蔽掉

或者用#pragma once表示只被编译一次

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值