1.1.C语言基础进阶——预处理命令

1.1.C语言基础进阶——预处理命令

因为假期实训的开始,另外也是偶然间想起来自己有个CSDN账户,便想开始试着写写博客,顺带着练习下Markdown语法
本周主要是对于C语言基础进阶,对于巩固基础来说还是很重要的

预处理命令

简单来讲就是以#开头的一行语句
主要进行了以下几种的讲解

宏定义

做简单的替换,并不会做运算

对于这句话的理解很重要,在预编译时候,宏定义会被替换为对应的字符,本身并不会进行运算。

#define N 1

其中第一个参数为宏的标识符(名字),第二个参数为替换内容,可以为空

定义符号常量

#include <stdio.h>
#define PI1 3.1415926
#define PI2 1 + 2.1415926
int main(){
	printf("PI:%.7lf, 2*PI:%.7lf\n", PI1, 2 * PI1);
	printf("PI:%.7lf, 2*PI:%.7lf", PI2, 2 * PI2);
	return 0;
}

程序运行结果如下:
在这里插入图片描述
不难看出PI2将会被替换为1 + 2.1415926,即2 * 1 + 2.1415926

定义傻瓜表达式

之所以这种叫法大概是因为一般宏定义中的表达式比较简单叭
这里面同样存在之前所说的问题,在替换中我们可能会产生与本身想法相悖的结果
参照下面的例子:

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

取两个数中较大的数字,乍一看似乎没有什么问题,但是如果运行以下代码

printf("5 + MAX(2, 3) = %d", 5 + MAX(2, 3));

期望的运行结果是8,但是实际上程序会输出2,原因在于替换后实际上程序变为

printf("5 + MAX(2, 3) = %d", 5 + 2 > 3 ? 2: 3));

因为MAX与外界数字互相之间并不独立,导致错误的产生
那我们如果把它们独立起来是不是就没有错误了呢?参考如下代码:

#define MAX(a, b) (a > b? a: b)
//省略部分代码
printf("5 + MAX(2, 3 > 4 ? 3 : 4) = %d", 5 + MAX(2, 3 > 4 ? 3 : 4));
//省略部分代码

这时候替换之后结果是:

printf("5 + MAX(2, 3 > 4 ? 3 : 4) = %d", 5 + (2 > 3 > 4 ? 3 : 4 ? 2 :3 > 4 ? 3 : 4));

可以自己运行下,实际上最后的结果是7而不是9,原因在于a,b两个数之间不互相独立,导致最终替换之后的结果错误
由此我们进一步改进为

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

但是对如下代码依然存在bug:

int a = 5;
printf("%d\n", MAX(a++, 3));
printf("%d", a);

输出结果为6和7,原因在于在替换中,a++两次出现,加了两次
使用中间量操作,最终得到的无bug的宏定义表达式为:

//__typedef(a)为内置宏,返回所给参数的数据类型
#define MAX(a, b) ({\
	__typedef(a) _a = (a), _b = (b);\
	_a > _b ? _a : _b;\
})

比开始时候要复杂很多了……

定义代码段

实际上在上面的更改中我们已经使用过类似操作,此处给出一个示例:

#define P(a){ \
	printf("%d\n", a);\
}

预定义的宏

列出部分系统中预定义的宏:

名称作用
__DATE__日期 mm dd yyyy
__TIME__时间 hh:mm:ss
__LINE__行号
__FILE__文件名
__func__函数名/非标准
__FUNC__函数名/非标准
__PRETTY_FUNCTION__更详细的函数信息/非标准

其中除了行号,均为字符串类型,行号为整型

条件式编译

宏语句解释
#ifdef DEBUG是否定义了DEBUG宏
#ifndef DEBUG是否没定义DEBUG宏
#if MAX_N == 5宏MAX_N是否等于5
#elif MAX_N == 4否则宏MAX_N是否等于4
#else类似C中else
#endif条件式编译最后要放上,表示条件结束

典型应用,用于避免编译时候对函数的多次声明,可以在头文件中加入如下类似语句

#ifdef _IS_PRINE_H
#define _IS_PRIME_H
//函数和变量的声明语句
#endif
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值