1.#define 的作用

  在C或C++语言源程序中允许用一个标识符来表示一个字符串,称为“宏”。被定义为“宏”的标识符称为“宏名”。在编译预处理时,对程序中所有出现的“宏名”,都用宏定义中的字符串去代换,这称为“宏代换”或“宏展开”。宏定义是由源程序中的宏定义命令完成的。宏代换是由预处理程序自动完成的。

  在C或C++语言中,“宏”分为有参数和无参数两种。

2. 无参宏定义

  无参宏的宏名后不带参数。

  其定义的一般形式为:

  #define 标识符 字符串

  其中的“#表示这是一条预处理命令。凡是以“#”开头的均为预处理命令。“define”为宏定义命令。“标识符”为所定义的宏名。“字符串”可以是常数、表达式、格式串等。

  例如:

  #define M (a+b)

  它的作用是指定标识符M来代替表达式(a+b)。在编写源程序时,所有的(a+b)都可由M代替,而对源程序作编译时,将先由预处理程序进行宏代换,即用(a+b)表达式去置换所有的宏名M,然后再进行编译。

  程序1:

#define M (a+b)

  main(){

  int s,y;

  printf("input a number: ");

  scanf("%d",&y);

  s=M*M;

  printf("s=%d\n",s);
}

  上例程序中首先进行宏定义,定义M来替代表达式(a+b),在 s= M * M 中作了宏调用。在预处理时经宏展开后该语句变为: S=(a+b)*(a+b)

  但要注意的是,在宏定义中表达式(a+b)两边的括号不能少。否则会发生错误。

  如当作以下定义后:#difine M (a)+(b)

  在宏展开时将得到下述语句:S= (a)+(b)*(a)+(b)

  对于宏定义还要说明以下几点:

  1. 宏定义是用宏名来表示一个字符串,在宏展开时又以该字符串取代宏名,这只是一种简单的代换,字符串中可以含任何字符,可以是常数,也可以是表达式,预处理程序对它不作任何检查。如有错误,只能在编译已被宏展开后的源程序时发现。

  2. 宏定义不是说明或语句,在行末不必加分号,如加上分号则连分号也一起置换。

  3. 宏定义必须写在函数之外,其作用域为宏定义命令起到源程序结束。如要终止其作用域可使用#undef命令。

3. 带参宏定义

  c语言允许宏带有参数。在宏定义中的参数称为形式参数,在宏调用中的参数称为实际参数。对带参数的宏,在调用中,不仅要宏展开,而且要用实参去代换形参。

  带参宏定义的一般形式为:

  #define 宏名(形参表字符串

  在字符串中含有各个形参。

  带参宏调用的一般形式为:

  宏名(形参表)

  例如:

  #define M(y) ((y)*(y)+3*(y)) /*宏定义*/

  ....

  k=M(5); /*宏调用*/

  ....

  在宏调用时,用实参5去代替形参y,经预处理宏展开后的语句为:

  k=5*5+3*5

  程序2:

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

  main(){

  int x,y,max;

  printf("input two numbers: ");

  scanf("%d%d",&x,&y);

  max=MAX(x,y);

  printf("max=%d\n",max);

  }

  上例程序的第一行进行带参宏定义,用宏名MAX表示条件表达式(a>b)?a:b,形参a,b均出现在条件表达式中。程序第七行max=MAX(x,y)为宏调用,实参x,y,将代换形参a,b。宏展开后该语句为:

  max=(x>y)?x:y;

  用于计算x,y中的大数。

4.防止重复定义

#define 条件编译

  头文件(.h)可以被头文件或C文件包含;

  重复包含(重复定义)

  由于头文件包含可以嵌套,那么C文件就有可能包含多次同一个头文件,就可能出现重复定义的问题的。

  通过条件编译开关来避免重复包含(重复定义)

  例如

  #ifndef __headerfileXXX__

  #define __headerfileXXX__

  …

  文件内容

  …

  #endif

#define的3种用法详解的更多相关文章

  1. Java for循环的几种用法详解

    本文非常适合初学Java的程序员,主要是来了解一下Java中的几种for循环用法,分析得十分详细,一起来看看. J2SE 1.5提供了另一种形式的for循环.借助这种形式的for循环,可以用更简单地方 ...

  2. PHP字符串替换str_replace()函数4种用法详解

    mixed str_replace ( mixed $search , mixed $replace , mixed $subject [, int &$count ] )该函数返回一个字符串 ...

  3. 【转】 #define用法详解

    #define用法详解   1.#define 的作用 在C或C++语言源程序中允许用一个标识符来表示一个字符串,称为“宏”.被定义为“宏”的标识符称为“宏名”.在编译预处理时,对程序中所有出现的“宏 ...

  4. Extjs Window用法详解 3 打印具体应用,是否关掉打印预览的界面

    Extjs Window用法详解 3 打印具体应用,是否关掉打印预览的界面   Extjs 中的按钮元素 {xtype: 'buttongroup',title: '打印',items: [me.ts ...

  5. C语言对文件的操作函数用法详解2

    fopen(打开文件) 相关函数 open,fclose 表头文件 #include<stdio.h> 定义函数 FILE * fopen(const char * path,const  ...

  6. C#中string.format用法详解

    C#中string.format用法详解 本文实例总结了C#中string.format用法.分享给大家供大家参考.具体分析如下: String.Format 方法的几种定义: String.Form ...

  7. linux管道命令grep命令参数及用法详解---附使用案例|grep

    功能说明:查找文件里符合条件的字符串. 语 法:grep [-abcEFGhHilLnqrsvVwxy][-A<显示列数>][-B<显示列数>][-C<显示列数>] ...

  8. mysql中event的用法详解

    一.基本概念mysql5.1版本开始引进event概念.event既“时间触发器”,与triggers的事件触发不同,event类似与linux crontab计划任务,用于时间触发.通过单独或调用存 ...

  9. CSS中伪类及伪元素用法详解

    CSS中伪类及伪元素用法详解   伪类的分类及作用: 注:该表引自W3School教程 伪元素的分类及作用: 接下来让博主通过一些生动的实例(之前的作业或小作品)来说明几种常用伪类的用法和效果,其他的 ...

随机推荐

  1. Jenkins——为什么使用持续集成?

    一.开发模型 1.瀑布开发模型:过程线性不可逆的开发模型 优势: 1)简单易懂 2)当前阶段完成后只需要关注后续阶段 3)为项目提供了按阶段划分的检查节点 劣势: 1)各个阶段的划分完全固定,阶段之间 ...

  2. 虚拟地址和物理地址(MMU)以及cache

    最近非常忙,博客很乱也没有更新,这里随便记录点东西,周末有空整理下. cache是一个与CPU很近的高速存储器, 作用:提高内存的访问读写速度 cache属性是指对这部分虚拟地址的读写是使用cache ...

  3. 为游戏编写boss剧情

    教程目录: 1. 小游戏展示 2. 下载游戏引擎 3. 创作一个移动的背景 4. 让阿菌煽动翅膀 5. 让阿菌模拟重力下坠 6. 让阿菌可以摸鱼 7. 编写游戏开始与结束 8. 编写 boss 剧情 ...

  4. BBS项目(一)

    目录 BBS项目(一) 项目开发流程 BBS项目 BBS表分析 自关联 表关系图示 BBS项目(一) 项目开发流程 项目分类 针对互联网用户:抖音,淘宝····· 针对公司内部:后台管理系统··· 针 ...

  5. 手把手教你使用 Java 在线生成 pdf 文档

    一.介绍 在实际的业务开发的时候,研发人员往往会碰到很多这样的一些场景,需要提供相关的电子凭证信息给用户,例如网银/支付宝/微信购物支付的电子发票.订单的库存打印单.各种电子签署合同等等,以方便用户查 ...

  6. 微信小程序 LIn UL的使用

    网址:https://doc.mini.talelin.com/component/form/rate.html 1:将文件解压拉至小程序项目下: 2:网站复制样式代码: 3:复制至需要展示的页面 4 ...

  7. ASP.NET Core 6框架揭秘实例演示[26]:跟踪应用接收的每一次请求

    很多人可能对ASP.NET Core框架自身记录的诊断日志并不关心,其实这些日志对纠错排错和性能监控提供了很有用的信息.如果需要创建一个APM(Application Performance Mana ...

  8. Android 12(S) 图形显示系统 - BufferQueue的工作流程(十一)

    题外话 我竟然已经写了这个系列的十一篇文章了,虽然内容很浅显,虽然内容很枯燥,虽然内容也许没营养,但我为自己的坚持点赞! 一.前言 前面的两篇文章,分别讲解了Producer的处理逻辑和queue b ...

  9. python神器 Jupyter Notbook

    python神器 Jupyter Notbook 简介 Jupyter Notebook是基于网页的用于交互计算的应用程序.其可被应用于全过程计算:开发.文档编写.运行代码和展示结果. Jupyter ...

  10. SMB共享配置

                                                                   SMB 使用命令挂载和卸载SMB文件系统 自动挂载SMB文件系统 红帽企业 ...