20.预处理详解

一.预定义符号

cpp 复制代码
"add.c"

#include <stdio.h>

void test()
{
	printf("test():%s\n", __FILE__);
}
cpp 复制代码
extern void test();

int main()
{
	printf("%s\n", __FILE__);
	printf("%s\n", __DATE__);
	printf("%s\n", __TIME__);
	printf("%d\n", __LINE__);
	//printf("%d\n", __STDC__);//说明VS不支持ANSIC
	test();
	return 0;
}

当前被定义的文件的路径

二.#define定义常量

这里不进行任何计算,只进行替换

三.#define定义宏

cpp 复制代码
#define SQUARE(X) X*X
int main()
{
    int a = 5;
    printf("%d\n", SQUARE(a));
    return 0;
}

这样看着没啥问题

cpp 复制代码
#define SQUARE(X) X*X
int main()
{
    int a = 5;
    printf("%d\n", SQUARE(a+1));
    return 0;
}

替换成这样就肯定算不对了

cpp 复制代码
#define SQUARE(X) (X)*(X)
int main()
{
    int a = 5;
    printf("%d\n", SQUARE(a+1));
    return 0;
}

我们可以尝试写一个宏,是参数的2倍

四.带有副作用的宏参数

cpp 复制代码
//写一个宏,求2个整数的较大值
#define MAX(x,y) ((x)>(y)?(x):(y))
int main()
{
    int a = 0;
    int b = 0;
    scanf("%d %d", &a, &b);// 3 5
    int m = MAX(a++, b++);
    printf("m = %d\n", m);
    printf("a = %d\n", a);
    printf("b = %d\n", b);
    return 0;
}

五.宏替换的规则

六.宏函数的对比

cpp 复制代码
#define MALLOC(n, type) (type*)malloc(n*sizeof(type))

int main()
{
	int *p = (int*)malloc(10*sizeof(int));
	int* p = MALLOC(10, int);
	
	return 0;
}

七.# 和

1.#运算符

cpp 复制代码
int main()
{
	printf("hello world\n");
	printf("hello ""world\n");

	return 0;
}

这两个字符串打印都是一样的

cpp 复制代码
#define PRINT(val, format)  printf("the value of "#val" is " format"\n", val)
int main()
{
	int a = 10;
	//printf("the value of a is %d\n", a);
	PRINT(a, "%d");
	printf("the value of ""a"" is ""%d""\n", a);

	int b = 20;
	//printf("the value of b is %d\n", b);
	PRINT(b, "%d");

	float f = 3.5f;
	//printf("the value of f is %f\n", f);
	PRINT(f, "%f");

	return 0;
}

#val的意思就是不要解析成值,而是将其转化成为字符串

2.##运算符

八.命名约定

九.#undef

cpp 复制代码
#define MAX 100

int main()
{
	printf("%d\n", MAX);
#undef MAX
	//printf("%d\n", MAX);

#define MAX 1000
	printf("%d\n", MAX);

	return 0;
}

十.命令行定义

cpp 复制代码
int main()
{
    int arr[SZ];
    int i = 0;
    for(i=0; i<SZ; i++)
    {
        arr[i] = i;
    }
    for(i=0; i<SZ; i++)
    {
        printf("%d ", arr[i]);
    }
    return 0;
}

这样就能进行编译了

十一.条件编译

cpp 复制代码
#include <stdio.h>
#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;
}

放开__DEBUG__,就能进行printf

十二.头文件的包含

1.本地文件包含

先去库里面找,找不到再到自己的安装路径下找

2.库文件包含

" "是兼容<>的,但是" "效率会变低

3.嵌套文件包含

再.h文件中加上这个,那么我们就能定义__TEST_H__,这样就只拿到一次了

十三. 其他预处理指令

相关推荐
雪落漂泊4 分钟前
C++11(上)
开发语言·c++
青山木19 分钟前
Hot 100 --- 最长递增子序列
java·数据结构·算法·leetcode·动态规划
春涧草茶26 分钟前
慢就是快12-2三种访问权限|getter与setter|魔法方法
开发语言·python
無限進步D39 分钟前
Java Web 前端 简介
java·开发语言·前端·css·html·css3·web
土司大王1 小时前
LeetCode hot100——33.搜索旋转排序数组:Java 二分模板与 O(log n) 实现
数据结构·算法·leetcode
不穿鞋的懒羊羊1 小时前
STL容器
算法
huang5791471 小时前
多线程环境下的共享数据结构安全问题分析4
算法
qq_401700411 小时前
Qt QUrl 详解与代码示例
开发语言·数据库·qt
zh路西法1 小时前
【玩转VLA具身智能机械臂】(四):点云分割与 OBB 夹取——从 PCA 失效到主动扫描
c++·机械臂·pca·vla·planner·obb·moveit2
小灰灰搞电子1 小时前
Rust Attribute(属性标记)完整整理
开发语言·后端·rust