目录

#define  标识符  常量

1.#if系列用法

2.#ifdef用法

3.#ifndef用法

4.#error用法


#define  标识符  常量

C语言中,可以用 #define 定义一个标识符来表示一个常量。其特点是:定义的标识符不占内存,只是一个临时的符号,预编译后这个符号就不存在了。

预编译又叫预处理。预编译不是编译,而是编译前的处理。这个操作是在正式编译之前由系统自动完成的。

用 #define 定义标识符的一般形式为:

#define  标识符  常量   //注意, 最后没有分号

#define 和 #include 一样,也是以“#”开头的。凡是以“#”开头的均为预处理指令,#define也不例外。

#define又称宏定义,标识符为所定义的宏名,简称宏。标识符的命名规则与前面讲的变量的命名规则是一样的。#define 的功能是将标识符定义为其后的常量。一经定义,程序中就可以直接用标识符来表示这个常量。是不是与定义变量类似?但是要区分开!变量名表示的是一个变量,但宏名表示的是一个常量。可以给变量赋值,但绝不能给常量赋值。

宏所表示的常量可以是数字、字符、字符串、表达式。其中最常用的是数字。

那么,程序中什么时候会使用宏定义呢?用宏定义有什么好处呢?我们直接写数字不行吗?为什么要用一个标识符表示数字呢?

宏定义最大的好处是“方便程序的修改”。使用宏定义可以用宏代替一个在程序中经常使用的常量。注意,是“经常”使用的。这样,当需要改变这个常量的值时,就不需要对整个程序一个一个进行修改,只需修改宏定义中的常量即可。且当常量比较长时,使用宏就可以用较短的有意义的标识符来代替它,这样编程的时候就会更方便,不容易出错。因此,宏定义的优点就是方便和易于维护。

那么程序在预编译的时候是怎么处理宏定义的呢?或者说是怎么处理预处理指令的呢?

其实预编译所执行的操作就是简单的“文本”替换。对宏定义而言,预编译的时候会将程序中所有出现“标识符”的地方全部用这个“常量”替换,称为“宏替换”或“宏展开”。替换完了之后再进行正式的编译。所以说当单击“编译”的时候实际上是执行了两个操作,即先预编译,然后才正式编译#include<stdio.h>也是这样的,即在预处理的时候先单纯地用头文件stdio.h中所有的“文本”内容替换程序中#include<stdio.h>这一行,然后再进行正式编译。

需要注意的是,预处理指令不是语句,所以后面不能加分号。这是很多新手经常犯的错误。#include 后面也没有加分号。

宏定义 #define 一般都写在函数外面,与 #include 写在一起。当然,写在函数里面也没有语法错误,但通常不那么写。#define 的作用域为自 #define 那一行起到源程序结束。如果要终止其作用域可以使用 #undef 命令,格式为:

#undef  标识符

undef 后面的标识符表示你所要终止的宏。比如前面在程序开头用 define 定义了一个宏 M,它原本的作用范围是一直到程序结束,但如果现在在程序中某个位置加了一句:

#undef M

那么这个宏的作用范围到此就结束了。#undef 用得不多,但大家要了解。

为了将标识符与变量名区别开来,习惯上标识符全部用大写字母表示。宏定义用得最多的地方是在数组中用于指定数组的长度。下面来写一个程序:

# include <stdio.h># define NUM 5int main(void){int i, j = NUM;int a[NUM] = {0};printf("请输入%d个数:", j);for (i=0; i<NUM; ++i){scanf("%d", &a[i] );}for (i=0; i<NUM; ++i){printf("%d\x20", a[i]);}printf("\n");return 0;}
输出结果是:

请输入5个数:5 4 3 2 1
5 4 3 2 1

NUM 是定义的宏,它表示的是其后的常量(而不是变量)。此外,程序中用双引号括起来的宏在预处理的时候是不会被宏替换的。因为在 C 语言中,用双引号括起来表示的是字符串。下面再写一个程序看一下:

# include <stdio.h># define PI 3.14159int main(void){double r, s;printf("请输入圆的半径:");scanf("%lf", &r); //scanf中, double只能用%lfs = PI * r * r;printf("s=PI*r^2 = %.6f\n", s); //PI不会被宏替换return 0;}

输出结果是:
请输入圆的半径:1
s=PI*r^2 = 3.141590

宏在C++或者C编程中,由于宏支持较早,使用非常广泛。下文详细分析每种宏的用法

1.#if系列用法

  常量表达式非0时,程序段参加编译;为0时,程序段不参加编译

#if 常量表达式程序段
#endif

  if后为真编译第一段,elif后为真编译第二段,都为假编译第三段

#if 常量表达式程序段1
#elif 常量表达式程序段2
#else程序段3
#endif

2.#ifdef用法

  标识符已经是一个定义过的宏名,则程序段参加编译,否则调用另外一段,#else段可选。

#ifdef 标识符程序段
#else程序段
#endif

3.#ifndef用法

  标识符没定义过,则程序段参加编译,否则调用另外一段,#else段可选。

#ifndef 标识符程序段
#else程序段
#endif

4.#error用法

  用于发现错误,在错误的那一行会跳出编译过程。
  #error后面只是一个人为提示的字符串,请自行定义。
————————————————
版权声明:本文为CSDN博主「插件开发」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/m0_67316550/article/details/124358636

c语言 宏定义 宏用法相关推荐

  1. C语言中#、##宏定义的用法

    一.#的用法 #用于编译器编译过程进行预处理. 1.宏定义 #define ON 1#ifndef _PARA_ #define _PARA_ #enddef#ifdef _PARB_ #define ...

  2. c语言中定义宏的利与弊

    在编写c文件时,我们都喜欢用宏来定义一些常量或者函数,这样增加了程序的可读性!但是我们有没有想过使用宏定义时可能出现问题呢?下面就简单举几例来说明宏定义的弊端! 例1: #define jia(m,n ...

  3. systemverilog 宏定义 `define 用法。

    #将宏定义转化成字符串 `define stringfy(x) `"x`" string s; s = `stringfy(`macro);#此时宏`macor不可以有输入,否则报 ...

  4. java中宏定义,宏定义的使用

    C中的宏分为两类,对象宏(object-like macro)和函数宏(function-like macro). 预定义宏: 1.预定义宏的行为是由编译器指定的. 2.前后双下杠的一般都是预定义. ...

  5. C语言中宏定义宏编译的使用#if,#ifdef,#ifndef,#elif,#else,#endif,defined使用详解,可以实现和if else一样的效果

    #define            定义一个预处理宏 #undef            取消宏的定义 #if                   编译预处理中的条件命令,相当于C语法中的if语句 ...

  6. java define 宏_宏定义宏函数(日志输出)define

    最常见的就是 #indef __cplusplus 这表示支持C++语法 再如可以定义常量 #define MAX 100 这跟JAVA全局变量有什么区别呢? JAVA的变量是有类型的,这没有类型,这 ...

  7. C语言——数组定义及用法

    目录: 一:定义 二:声明数组 三:初始化数组 数组赋值的区别 四:二维数组 五:多维数组 六:传递数组给函数 1.方式 一 2.方式 二 3.方式 三 七:从函数返回数组 八:指向数组的指针 来自: ...

  8. 宏定义宏函数 if else语句报错:error: ‘else’ without a previous ‘if’(看似解决实际上没解决)

    代码 #include <stdio.h> #include <stdlib.h>#define ALOGE(...) { printf(__VA_ARGS__); print ...

  9. C语言-宏定义#define的用法

    目录 1 不带参宏定义 2 带参宏定义 3 与字符串有关的用法 3.1 字符串转换 3.2 字符转换 3.3 字符连接 1 不带参宏定义 这种用法是最简单最常见的一种方式,如下: #define PA ...

最新文章

  1. CodeForces - 600E Lomsat gelral(树上启发式合并)
  2. getchar()和EOF
  3. 数据结构与算法入门---数据结构类型
  4. 关于java的集合类,以及HashMap中Set的用法!
  5. hdu_5761_Rower Bo(xjb猜公式)
  6. Druid的Segment Balance及其代价计算函数分析
  7. 罕有数据库系统之比拟 - Oracle数据库
  8. 打开终端报错:bash: /某路径/bashrc: No such file or directory
  9. Android模拟器 使用 Fiddler抓包
  10. 微信公众号迁移及公证书快速办理流程
  11. java 图片 加边框_给图片加图片边框 图片边框要求为PNG格式
  12. 正则表达式Regix
  13. Android中获取手机内所有应用信息
  14. Teamcenter RAC 调用查询
  15. Odoo开发需要注意些什么?
  16. 全球与中国聚合支付平台市场深度研究分析报告
  17. 分割速度最快的视频分割器
  18. vue图片img加载失败显示自定义默认图片(缺省图)
  19. 以三字游戏为例的模拟项目工程的实现与布局
  20. linux更换包管理工具,linux 软件包管理

热门文章

  1. KMSAuto Net 2016 1.4.9 Portable
  2. 入门 Python 数据分析教程指南(学习路线 + Python 资料),轻轻松松月入过万
  3. VS2012属性管理器哪里找?
  4. Linux 命令行的艺术
  5. 物联网之窄带物联网(NB-IOT)
  6. 电机拖动笔记-变压器初始:电动机惯例和发电机惯例
  7. 【Matlab绘图】
  8. 光耦驱动达林顿管从而驱动继电器工作
  9. 如何在两个月之内掌握C++入门?
  10. Access时间转换