#define定义宏(宏定义)
文章目录
- 前言
- 一、预定义符号
- 二、#define详解
- 1.#define定义标识符
- 2.#define宏定义
- 小结
- 3.define 替换规则
前言
提示:本文将介绍一些预定义符号和#define宏定义,宏与函数的优缺点对比等。
一、预定义符号
__FILE__ //进行编译的源文件
__LINE__ //文件当前的行号
__DATE__ //文件被编译的日期
__TIME__ //文件被编译的时间
__STDC__ //如果编译器遵循ANSI C,其值为1,否则未定义
这些预定义符号都是语言内置的。
举个栗子:
#define _CRT_SECURE_NO_WARNINGS 1#include<stdio.h>int main()
{printf("file:%s line:%d\n", __FILE__, __LINE__);return 0;
}
打印结果:
二、#define详解
1.#define定义标识符
#define name stuff //#define的一般使用形式
举个栗子:
#define MAX 1000 //将1000赋值给MAX
#define reg register //为register这个关键字,创建一个更简短的名字
#define do_forever for(;;) //用更形象的符号来替换一种实现
#define CASE break; case //在写case自动把break打上
#define DEBUG_PRINT printf("file:%s\tline:%d\t \data:%s\ttime:%s\n",\_FILE_,LINE_, \_DATA_,_TIME_)
//如果定义的stuff过长,可以分成几行写,除了最后一行,每行的后面都加上一个反斜杠(续航符)
2.#define宏定义
#define机制包括一个规定,允许把参数替换到文本中,这种实现通常称为宏或者定义和宏
#define name(parament-list) stuff //其中的parament—list是一个由逗号隔开的符号表,它们可能出现在stuff中
注意:参数列表的左括号必须与name紧邻;如果两者之间有任何空白,参数列表就会被解释为stuff的一部分。
举个例子:
#define SQUARE(x) x*xint main()
{printf("%d\n", SQUARE(5));return 0;
}
运行结果:
修改一下代码:
#define SQUARE(x) x*xint main()
{printf("%d\n", SQUARE(5+1));return 0;
}
打印结果:
观察这段代码,乍一看你可能觉得这个代码将打印36这个值,但是打印出来的却是11,为什么呢?
替换文本时,参数x被替换成x+1,所有这条语句实际上变成了: printf (“%d\n”,a + 1 * a + 1 );
如何解决呢?
只需在宏定义上加上两个括号,即:#define SQUARE(x) (x) * (x)等价于printf (“%d\n”,(a + 1) * (a + 1) );
我们再看另外一个宏定义栗子:
#define DOUBLE(x) (x)+(x)int main()
{int x = 5;printf("%d\n", 10 * DOUBLE(x));return 0;
}
这将打印什么值呢?
看上去好像打印100,实际上打印的是55。
我们发现替换之后:
printf (“%d\n”,10 * (5) + (5));乘法运算优先于定义的加法,所以得出55.
解决办法就是在宏定义表达式两边加上一对括号就可以了:
#define DOUBLE( x) ( ( x ) + ( x ) )
小结
所以用于对数值表达式进行求值的宏定义都应该用这种方式加上括号,避免在使用宏时由于参数中的操作符或邻近操作符之间不可预料的相互作用。
3.define 替换规则
在程序中扩展#define定义符号和宏时,需要涉及几个步骤:
- 在调用宏时,首先对参数进行检查,看看是否包含任何由#define定义的符号。如果是,它们首先被替换。
- 替换文本随后被插入到程序中原来文本的位置。对于宏,参数名被他们的值所替换。
- 最后,再次对结果文件进行扫描,看看它是否包含任何由#define定义的符号。如果是,就重复上述处理过程。
1.宏参数和#define 定义中可以出现其他#define定义的符号。但是对于宏,不能出现递归。
2. 当预处理器搜索#define定义的符号的时候,字符串常量的内容并不被搜索。
#define定义宏(宏定义)相关推荐
- ACMNO.35 C语言-宏润年 给年份year,定义一个宏,以判别该年份是否闰年。提示:宏名可以定义为LEAP_YEAR,形参为y,既定义宏的形式为 #define LEAP_YEAR(y)
题目描述: 给年份year,定义一个宏,以判别该年份是否闰年. 提示:宏名可以定义为LEAP_YEAR,形参为y, 既定义宏的形式为 #define LEAP_YEAR(y) (读者设计的字符串) 输 ...
- define宏定义和const定义之间的区别
define部分: 宏不仅可以用来代替常数值,还可以用来代替表达式,甚至是代码段.(宏的功能很强大,但也容易出错,所以其利弊大小颇有争议.) 宏的语法为: #define 宏名称 宏值 注意,宏定义不 ...
- 给年份year,定义一个宏,以判别该年份是否闰年。提示:宏名可以定义为LEAP_YEAR,形参为y,既定义宏的形式为 #define LEAP_YEAR(y) (读者设计的字符串)
题目描述 给年份year,定义一个宏,以判别该年份是否闰年.提示:宏名可以定义为LEAP_YEAR,形参为y,既定义宏的形式为 #define LEAP_YEAR(y) (读者设计的字符串) 输入 一 ...
- 预处理那些事(定义表示符,定义宏,#define)
介绍预处理之前 先铺垫一小端程序运行的小知识方便我们理解预处理 当我们一个程序运行的时候是通过很多步的 当然所有文件执行时都会有编译环境和运行环境 编译环境 编译也分为几部分 预编译 处理预定义内容 ...
- 伪指令-宏定义:使用#define定义一个宏,宏体中包含命名空间信息导致vs大量报红,但编译和运行却正常
宏定义:使用#define伪指令定义一个宏 宏体中包含命名空间信息导致vs大量报红,但编译和运行却正常 宏分为不带参数的宏和带参数的宏. 在带参数的宏中,关键字#define后面出现的第一个连续字符序 ...
- 编写一个头文件,头文件中定义一个宏cube(x)用于求一个数的平方
<程序设计基础实训指导教程-c语言> ISBN 978-7-03-032846-5 p145 7.1.2 上级实训内容 [实现内容17]编写一个头文件,头文件中定义一个宏cube(x)用于 ...
- C语言宏定义、宏替换
1.宏替换的格式 #define 名字 替换文本 后续所有出现名字的地方都将被替换为替换文本. 替换文本可以是任意的,例如 #define forever for(;;) //无限循环 该语句为无限循 ...
- c语言 宏定义 去除宏定义_如何检查是否在C中定义了宏?
c语言 宏定义 去除宏定义 To check whether a Macro is defined or not in C language – we use #ifdef preprocessor ...
- C++中宏的定义与用法(现已被内联函数所代替)
在noip中,宏还是被经常采用,所以这里讲一下,C++中宏的定义与用法 第一种用法--配合条件编译:#define DEBUG 定义一个叫DEBUG的标识符.它应该与#ifdef或#ifndef配合使 ...
最新文章
- 如何在一年内拥有十年的工作经验(值得你反复读5遍以上)
- Linux网络模式及远程连接出错排障
- ajax跨域问题(php)
- Sublime Text 3 初试牛刀
- 个人学习进度条------第二周
- 惊喜不止小米9!小米又一4800万新机确认:不给友商机会?
- 用eclipice抓取JS代码
- 你有进一步深入理解二分查找吗?
- 如何快速学习Java? 1
- 华为交换机基本配置命令
- adb模拟按键home_ADB——模拟手机按键输入
- 常见错误——给定编码中的字符无效。(xml)
- LINUX下载编译libx264
- Linux下使用nmap扫描端口
- 微信小程序开发(十七)模板消息
- 手机安装W ndows7镜像,Windows7ISO镜像安装系统教程
- Liberal Arts:志存高远
- 利用msf 对靶机metasploittable2 进行信息收集
- Android DNK安装笔记
- 推荐STM32F030K6T6国产兼容替换芯马XM1008K6T6