C语言-宏定义

2023-11-14

1. 宏定义是什么?

宏是用来表示一段代码的标识符。

宏也是标识符,也要满足标识符的规则。但通常习惯使用大写字母下划线命名。

2. 宏定义怎么用?

宏定义通常有三种用法:

  • 当作常量使用。
  • 当作函数使用。
  • 编译预处理。

2.1 宏定义常量

2.1.1 预定义宏

ANSI C标准定义有些定义好的宏定义,称为预定义宏。这些宏定义以双下划线__开头结尾。

No. 预定义宏 作用
1 __LINE__ 当前所在文件的行号
2 __FILE__ 表示当前源文件
3 __DATE__ 文件被编译的日期
4 __TIME__ 文件被编译的时间
  • 示例
printf("%s:%d\n",__FILE__,__LINE__);
printf("%s:%s\n",__DATE__,__TIME__);

在这里插入图片描述**注:**显示的时间为编译完成的时间,之后再运行程序,编译时间是不会改变的

2.1.2 自定义宏

除了使用标准定义的宏,可以使用#define指令用来定义一个宏。

  • 语法
#define 标识符 值
  • 示例
#define PI 3.1415926
  • 说明
  1. 注意没有结尾的分号,因为不是C的语句。
  2. 名字必须是一个单词,值可以是各种东西。
  3. 在C语言的编译器开始之前,编译预处理程序会把程序中的名字换成值。是完全的文本替换。
  4. 如果一个宏的值有其他宏的名字,也会被替换。
#define PI_2 2*PI

在这里插入图片描述

  1. 如果一个宏的值超过一行,最后一行之前行末需要加\。
//#define PI_2 2*PI
#define PI_2 2 \
             * \
             PI
  1. 宏的值后面出现的注释不会被当做宏的值的一部分。

2.2 带参数的宏

宏可以带参数,使用上有些像函数。这种宏称为带参数的宏。

  • 语法
#define 标识符(参数...) 代码
  • 示例
#define square(x) ((x)*(x))
#define cube(x) ((x)*(x)*(x))

是否可以不带括号?答案是否定的,参考如下代码
在这里插入图片描述

  • 说明
    上面因为缺少括号导致错误,称为宏定义边际效应,所以带参数的宏需要在一下两个位置加上括号:
  1. 参数出现的每个地方都要加括号。

  2. 整个值要加括号。

参数的宏也可以有多个参数

#define MIN(a,b) ((a)<(b)?(a):(b))

小例:

  1. 变量值交换SWAP(a,b)
#define SWAP(a,b) {int t=a;a=b;b=t;}
  1. 最大值MAX(a,b),最小值MIN()
#define MAX(a,b) ((a)>(b)?(a):(b))
#define MIN(a,b) ((a)<(b)?(a):(b))

在写代码的时候,应尽量避免使用宏定义。

2.3 编译预处理

有时我们会使用没有值的宏,这种宏用于条件编译的,#ifdef #ifndef用于检查宏是否被定义过。控制代码的编译。

#define _DEBUG
  • 示例
#ifdef TEST
    printf("Test\n");
#else
    printf("No Test\n");
#endif

3. 宏展开

宏的本质是指编译前(编译预处理阶段),用定义中的值或者代码完全替换宏的标识符。
在这里插入图片描述在Linux下gcc中可以使用-E或者–save-temps,查看替换后的结果。

4. 编译预处理指令

#开头的都是编译预处理指令。除了宏定义,还有文件包含#include和条件编译指令#if#ifdef #ifndef#else#elif

  • 文件包含#include 把文件内容包含到代码中
  • 条件编译指令#if#ifdef #ifndef#else#elif

根据编译条件,选择编译或者编译某段代码。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C语言-宏定义 的相关文章

随机推荐

  • 华为云 弹性文件服务器,华为云centos7 配置弹性云服务器实现多网卡多IP访问(转载华为云官网)...

    配置弹性云服务器实现多网卡多IP访问 当弹性云服务器配置了多张网卡时 需要在弹性云服务器内部配置策略路由来实现非主网卡的通信 具体操作步骤如下 可能原因 未设置路由规则 导致扩展网卡的IP无法访问 Linux操作系统 执行以下命令 在 et
  • 模拟电路设计(38)---基于LT1173的负压产生电路

    今天来介绍下LT1173在buck step down 模式的工作电路 在介绍PWM电路结构时 有一种形式成为buck型 如下所示 晶体管开关变换器 buck 电路 LT1173提供了内置开关管的集电极和发射极管脚 因此根据上图连接电感 电
  • 基于cuda的ffmpeg源码安装

    文章目录 1 安装nvcodec 2 安装ffmpeg 本次安装系统是ubuntu20 04 本文将GPU 加速的视频处理集成到最流行的开源多媒体工具中 FFmpeg 是最受欢迎的开源多媒体操作工具之一 其插件库可应用于音频和视频处理管道的
  • mysql io_MySQL占用IO过高解决方案

    IO过高是指输入输出过高了这个有许多原因都会导致mysqlIO过高了 小编见过apache处理数据缓存导致mysqlIO过高问题当然也有其它关于mysql本身问题导致mysqlIO过高的问题了 下面给各位整理总结一下关于mysqlIO过高处
  • 深度学习中超参数介绍,过拟合、欠拟合、梯度消失及梯度爆炸的理解

    超参数的设置对训练的影响 1 学习率 learning rate 学习率 learning rate 是指在优化算法中更新网络权重的幅度大小 学习率可以是恒定的 逐渐降低的 基于动量的或者是自适应的 不同的优化算法决定不同的学习率 为了能够
  • jquery的$.extend和$.fn.extend作用及区别

    jquery的 extend和 fn extend作用及区别 jQuery为开发插件提拱了两个方法 分别是 jQuery fn extend jQuery extend 虽然 javascript 没有明确的类的概念 但是用类来理解它 会更
  • {"error":{"root_cause":[{"type":"security_exception","reason":"missing authentication token for REST

    错误如下 error root cause type security exception reason missing authentication token for REST request idx header WWW Authen
  • cpustat:在 Linux 下根据运行的进程监控 CPU 使用率

    转自 https linux cn article 8466 1 html pr cpustat 是 Linux 下一个强大的系统性能测量程序 它用 Go 编程语言 1 编写 它通过使用 用于分析任意系统的性能的方法 USE 2 以有效的方
  • Redis学习笔记

    Redis学习笔记 什么是Redis 安装Rides 启动Redis 连接Redis Redis基础知识 五大数据类型 1 String 2 List 3 Set 4 Hash 5 Zset 三种特殊数据类型 1 geospatial 地理
  • 以太坊的MPT树,以及编码,leveldb存储

    声明 此为使用网上多处资料整理而成 由于很多地方内容相同 已经分不清哪里是原创 一 MPT树 1 Trie树 Trie 又称为字典树或者前缀树 prefix tree 属于查找树的一种 它与平衡二叉树的主要不同点包括 每个节点数据所携带的
  • IPP图像处理函数命名格式

    IPP图像处理函数命名格式 专栏目录 说明 一 函数格式 二 data domain 三 Name 1 无修饰符的名称 2 有修饰符的名称 四 数据类型 五 描述符 六 参数 七 拓展 八 函数原型 专栏目录 一 IPP简介及windows
  • Android 初级到高级 进阶

    高级Android学习 Android学习路线指南 singwhatiwanna的博客 CSDN博客
  • ads原理图生成layout_ADS原理图和版图协同优化仿真方法总结

    1 概述 在用ADS进行射频电路仿真时 在原理图层面仿真完毕后 通常还要考虑实际的射频版图布局中传输线的耦合 印制板介质损耗等效应的影响 此时就要在ADS的版图仿真中来实现 在学习ADS时 需要版图仿真时 通常是先原理建模 然后通过生成版图
  • SpringCloud 微服务服务治理注册中心

    一 什么是服务治理 在传统rpc远程调用中 服务与服务依赖关系 管理比较复杂 所以需要使用服务治理 在这里插入图片描述管理服务与服务之间依赖关系 可以实现服务调用 负载均衡 容错等 实现服务发现与注册 二 服务注册与发现 在服务注册与发现中
  • Unity脚本实现——触摸屏3D模型,随单根手指,无死角旋转(Input的GetTouch方法和touchCount属性)

    Unity脚本实现模型360度旋转 参考别人随手指绕Y轴转动 添加了绕X轴转动 using System Collections using System Collections Generic using UnityEngine publ
  • document 使用方法介绍

    document节点是文档的根节点 每张网页都有自己的document节点 属性 1 document doctype 它是一个对象 包含了当前文档类型 Document Type Declaration 简写DTD 信息 2 docume
  • Tessy — 嵌入式软件单元测试/ 集成测试工具

    Tessy 源自戴姆勒 奔驰公司的软件技术实验室 由德国Hitex 公司负责全球销售及技术支持服务 是一款针对嵌入式软件进行单元 集成测试的工具 它可以对C C 代码进行单元 集成测试 可以自动化搭建测试环境 执行测试 评估测试结果并生成测
  • SpringBoot 线程池的使用

    前言 最近在做订单模块 用户购买服务类产品之后 需要进行预约 预约成功之后分别给商家和用户发送提醒短信 考虑发短信耗时的情况所以我想用异步的方法去执行 于是就在网上看见了Spring的 Async了 但是遇到了许多问题 使得 Async无效
  • flutter Flex Wrap Stack Align布局

    1 flex布局 Flex direction Axis horizontal 水平反向 direction不能为空 direction Axis vertical 垂直反向 Expanded flex 1 实现代码如下 child Con
  • C语言-宏定义

    C语言 宏定义 1 宏定义是什么 2 宏定义怎么用 2 1 宏定义常量 2 1 1 预定义宏 2 1 2 自定义宏 2 2 带参数的宏 2 3 编译预处理 3 宏展开 4 编译预处理指令 1 宏定义是什么 宏是用来表示一段代码的标识符 宏也