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__,这样就只拿到一次了

十三. 其他预处理指令

相关推荐
ly7689几秒前
Python 全面入门:从核心语法到工程实践
开发语言·python
艾伦_耶格宇1 小时前
【AI】-4 OpenCode Go 接入 Obsidian 完整指南
运维·开发语言·人工智能·agent·opencode
码匠许师傅1 小时前
【C++ 面试真题】30. 聊聊 C++ 的互斥锁与读写锁
java·c++·面试
旋生万物2 小时前
【终极实战】用Python从零“生成“一个宇宙:螺旋干涉模型的代码实现
开发语言·前端·人工智能·react.js·php·wpf
ShineWinsu2 小时前
对于 C++:C++14中从变量模板、泛型 Lambda 到并发与字面量的解析
c++·算法
土司大王2 小时前
LeetCode hot100——合并两个有序链表
算法·leetcode·链表
码行山野赴时序归途2 小时前
算法效率的度量(上):时间复杂度中的对数思维
c语言·数据结构·算法
16月6日-晴2 小时前
Java面向对象进阶—多态
java·开发语言
冯汉栩3 小时前
Swift Control RollingCountdownView(动画倒计时)
开发语言·ios·swift