【C语言】预处理(C语言深度了解)

预处理分为以下几部分

* 宏定义

* 条件编译

* 头文件包含

* #运算符

* ##预算符

请添加图片描述

宏定义

**宏定义常量**
#include<stdio.h>
#define num 3.1415926
int main()
{
	printf("%.7f",num);
}

宏定义字符串
在宏定义字符串中,字符串要用双引号括起来,也可以用’\‘来续行字符串,如果想输入’\‘的话需要用两个’\’

#include<stdio.h>
#define str "c\\输入字符串\
宏定义字符串\
续行"
int main()
{
	printf("%s", str);
}

在这里插入图片描述
用宏定义充当注释符号
在这之前我们先了解一下程序翻译的过程

  • 预处理 -E :头文件展开,去注释,宏替换,条件编译
  • 编译 -S :将干净的C语言,编译成汇编语言
  • 汇编 -c :将汇编翻译成为目标二进制文件(可被链接的)
  • 链接 :将目标二进制文件与相关库链接,形成可执行文件
    (库的优点:1、高效性2、健壮性or鲁棒性)
#define BSC //
int main()
{
	BSC printf("hello");//BSC表示空
}

#define BMC /*
#define EMC */
int main()
{
	BMC printf("hello"); EMC
}

两段代码均不能将代码注释,在程序编译中也说明了是先去注释,在宏替换

用define宏定义表达式

#define sum(x) (x)+(x)
int main()
{
	printf("%d\n",sum(10));
	printf("sum(20)");
}

在这里插入图片描述


#define INIT_VAL(a,b) \
a=0; \
b=0;
int main()
{
	int x = 10;
	int y = 20;
	printf("before:%d %d\n",x,y);
	INIT_VAL(x, y);
	printf("after:%d %d", x, y);

}

在这里插入图片描述
如果想要定义多条宏语句可以去使用do{}while语句

#define INIT_VAL(a,b) \
   do{\
       a=0;\
       b=0;\
   }while(0);
int main()
{
	int flag = 0;
	scanf_s("%d",&flag);
	int x = 10;
	int y = 20;
	printf("before:%d %d\n",x,y);
	if (flag) {
		INIT_VAL(x,y);//宏定义
	}
	else
	{
		printf("error!\n");
	}
	printf("after:%d %d\n",x,y);
}

在这里插入图片描述
#undef(取消宏定义,也可以叫为限定宏的有效范围)
首先我们先了解一下宏定义的范围
源文件的任何地方,宏都是可以定义,无论是在函数内外,无关
宏的定义范围:从定义开始,往后都是有效的

void show()
{
#define M 100
	printf("1%d\n",M);//ture
}
int main()
{
	show();
	printf("2%d\n", M);//ture
}
void show()
{
	printf("1%d\n",M);//error未定义
}
int main()
{
#define M 100
	show();
	printf("2%d\n", M);//ture
}
int main()
{
#define M 10
	printf("%d", M);//ture
#undef M  //取消宏定义
	printf("%d", M);//显示未定义
}
int main()
{
#define X 3
#define Y X*2
#undef X   //取消宏定义
#define X 2//从新定义X
	int z = Y;
	printf("%d",z);//最后打印的是4
}

#define和#undef最好别在代码块中使用,容易以为是由作用域的

#define M 10
void show()
{
	printf("%d",M);//可以输出
}
int main()
{
#undef M
	show();
}

原因是宏替换在函数调用之前

条件编译

格式:#ifdef 标识符 (是用来判断标识符是否被定义) 本质就是一个代码裁剪的工具 条件编译的作用:通过裁剪代码,快速实现某种目的(版本维护(免费,收费),功能裁剪,跨平台性)
#define INIT 
int main()
{
#ifdef INIT
	{
		printf("ture");
	}
#else
	{
		printf("error");
	}
#endif
}
#ifndef//(没有被定义)的用法是和#ifdef一样的,

#if和#ifdef的区别在于#if是来判断宏定义的真假,而#ifdef是判断是否定义的

#define INIT 1
int main()
{
#if INIT
	printf("ture");
#else
	printf("error");
#endif
	return 0;
}

请添加图片描述
请添加图片描述
也可以在#if 后面定义加上条件,多分支用法


#define INIT 1
int main()
{
#if INIT<1
	printf("1");
#elif INIT<2
	printf("2");
#elif INIT<3
	printf("3");
#else
	printf("0");
#endif
	return 0;
}

用#if 代替#ifdef

#define INIT 
int main()
{
#if defined(INIT)
	printf("ture");
#else
	printf("error");
#endif
	return 0;
}

用#if 代替#ifndef

#define INIT 
int main()
{
#if !defined(INIT)
	printf("ture");
#else
	printf("error");
#endif
	return 0;
}
#if 还有以下用法:#if defined()&&defined()    #if defined()||defined()

条件编译也是支持嵌套的

#define INIT 
#define C
int main()
{
#if defined(INIT)
	printf("ture");
#if defined(C)
	printf("hello");
#endif
	printf("hi");
#else
	printf("error");
#endif
	return 0;
}

条件编译所用的地方
在这里插入图片描述

头文件包含

防止头文件被重复定义,也可以选择用#pragma once
#ifndef INIT
#define INIT 
#include<stdio.h>
#endif

重复包含不一定会报错,会引起多次拷贝,主要会影响编译效率,同时也可能引起一些未定义的错误,但是特别少
头文件展开就是把头文件的内容拷贝到目标文件中

#运算符

#include<stdio.h>
int main()
{
	printf("hello world\n");
	printf("hello""world\n");
	const char* str = "hello world";
	printf(str);
	return 0;
}

在这里插入图片描述
相邻的字符串(" ")具有自动连接特性

printf(str);//是成立的

在这里插入图片描述
|
|

#define STR(s) #s
int main()
{
	printf("PI:"STR(3.1415926)"\n");
	return 0;
}

在这里插入图片描述
由上面可知相邻字符串具有自动连接性,因为能打印出来,也就说明了,#s将3.1415926变为字符串了
再次证明#将内容转换为字符串

#pragma warning(disable:4996)
#define STR(s) #s
int main()
{
	char str[64] = {0};
	strcpy(str, STR(abc));
	printf("%s",str);
	return 0;
}

##预算符

在这里插入图片描述
例子:

在这里插入图片描述

最后:文章有什么不对的地方或者有什么更好的写法欢迎大家在评论区指出来。
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值