我的编程空间,编程开发者的网络收藏夹
学习永远不晚

C语言预编译#define(预处理)

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

C语言预编译#define(预处理)

一、预定义符号

预定义符号是系统本身定义的:

  • FILE 进行编译的源文件的位置
  • LINE 文件当前的行号
  • DATE 文件被编译的日期
  • TIME 文件被编译的时间
  • STDC 如果编译器遵循 ASNSI C,其值为1,否者未定义

二、#define 定义标识符

语法:#define name stuff (用stuff替换name)

#define MAX 100   
#define STR "hehe"
int main()
{
	int max = MAX;
	printf("%d\n", max);  //输出100
	printf("%s\n",STR);   //输出 hehe
	return 0;
}

三、#define 定义宏

  • #define 机制包括了一个机制,允许把参数替换到文本中,这种实现通常称为或者宏定义
  • 宏的申明方式:#define name(parament-list) stuff 其中的parament-list是一个由逗号隔开的符号表,他们可能出现在stuff中。
  • 注意:参数列表的左括号必须与name紧邻,如果两者之间有任何空白存在,参数列表就会解释为stuff 的一部分。
#define SQUARE(X) X*X
int main()
{
	int ret = SQUARE(5);
	printf("%d\n",ret); //输出25
	return 0;
}

上面的宏定义代码存在一定的问题: 如果我们换一个参数(将5换成5+1)输出的不是36而是11为什呢?

#define SQUARE(X) X*X
int main()
{
	int ret = SQUARE(5+1);//替换之后就是(5+1*5+1 = 11)
	printf("%d\n",ret);//输出11
	return 0;
}

没加括号
因此,用于对数值表达式进行求值的宏定义都应该用这种方式加上括号,避免在使用宏时由于参数中的操作符或临近操作符之间不可预料的相互作用。

正确的代码:

#define SQUARE(X) (X)*(X))
int main()
{
	int ret = SQUARE(5+1);
	printf("%d\n",ret);//输出36
	return 0;
}

四、#define 替换规则:

  • 一, #define NAME “lisa”
    程序中有"NAME",但”“内的东西不会被宏替换。
  • 二,宏定义前面的那个必须是合法的用户标识符
  • 三,宏定义也不是说后面东西随便写,不能把字符串的两个”“拆开。
  • 四: #define NAME “lisa”
    程序中有上面的宏定义,并且,程序里有句:
    NAMELIST这样,不会被替换成"lisa"LIST
  • 五,宏不能出现递归

五、#和## 两个符号(少见)

#的作用:把参数插入到字符串中

如果我们想要实现一个代码:把参数插入到字符串中 用到“#”

这里参数a,b就插入到了字符串中了
 ##的作用:可以把位于它两边的符号合成一个符号,它允许宏定义冲从分离的文本片段创建标识符。

图中的三句代码是等价的:

printf(“%d\n”,AGE(lisa,24));
printf(“%d\n”,AGE(lisa##24));
printf(“%d\n”,AGE(lisa24));

六、宏和函数的对比

函数和宏都能实现求两个数的最大值

//函数
int Max(int x, int y)
{
	return (x > y ? x : y);
}
//宏
#define MAX(X,Y) ((X)>(Y)?(X):(Y))
int main()
{
	int a = 10;
	int b = 20;
	int max = Max(a, b); //输出20
	printf("%d\n",max);
	max = MAX(a, b);
	printf("%d\n", max); //输出20
	return 0;
}

通过分析上面的代码实现用宏比用函数会更好,有两个原因:

  • 用于调用函数和从函数返回的代码可能比实际执行的这个小型计算工作所需要的时间更多,所以宏比函数在程序的规模和速度方面更胜一筹。
  • 函数的参数必须申明为特定的类型。所以函数只能在类型合适的表达时式上使用。反之宏是与类型无关的。

当然宏相比函数也有劣势的地方:

  • 每次使用宏的时候,一份宏定义的代码将替换插入到程序中。除非宏比较短,否者可能大幅度增加程序的长度。
  • 宏没法调试
  • 宏由于类型无关,也就不够严谨
  • 宏可能会带来运算符优先级的问题,导致程序容易出错。

#define定义宏和函数的对比表格

属性#define定义宏函数
代码长度每次使用时宏代码都会被插入到程序中除了非常小的宏之外,程序的长度会大幅度增长函数的代码只出现在一个地方,每次使用这个函数时,都调用那个地方的同一份代码
执行速度更快存在函数的调用和函数的额外开销,所以速度相对慢一些
操作符优先级宏参数的求值是在所有周围表达式的上下文环境里,除非加上括号,否者邻近操作符的优先级可能产生不可预料的结果,所以建议宏在书写的时候多用括号函数参数只在函数调用的时候求值一次,它的结果值传递给函数。表达式的求值结果更容易预测。
带有副作用的参数参数可能被替换带宏中的多个位置,所以带有副作用的参数求值可能会产生不可预料的结果函数参数只在传参的时候求值一次,结果更容易控制
参数类型宏的参数与类型无关,只要对参数的操作是合法的,它就可以适用于任何参数类型函数的参数与类型有关,如果参数的类型不同,就需要不同的函数,即使他们执行任务是不同的
调试和递归宏不方便调试,不能递归函数可以逐语句调试,可以递归

命名约定:把宏名全部大写,函数名不要全部大写。

七、#undef

#undef 指令用于移除一个宏定义

当#undef 移除宏定义,再次使用报错。如图 :

到此这篇关于C语言预编译#define(预处理)的文章就介绍到这了,更多相关C语言预处理内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

C语言预编译#define(预处理)

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

C语言预编译的方法

本篇内容介绍了“C语言预编译的方法”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、预定义符号预定义符号是系统本身定义的:FILE 进行编译
2023-06-30

C语言预编译怎么使用

这篇文章主要介绍“C语言预编译怎么使用”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“C语言预编译怎么使用”文章能帮助大家解决问题。1、内置符号这些符号都可以直接使用:__FILE__
2023-06-30

C语言程序的编译与预处理实例分析

本篇内容介绍了“C语言程序的编译与预处理实例分析”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!程序的翻译环境和执行环境在ANSIC的任何一种
2023-06-30

C#的define预处理器怎么用

今天小编给大家分享一下C#的define预处理器怎么用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。#define 预处理器
2023-06-17

C语言进阶教程之预处理

C语言提供了多种预处理功能,如宏定义、文件包含、条件编译等,下面这篇文章主要给大家介绍了关于C语言进阶教程之预处理的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
2023-02-10

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录