当前位置: 首页 > news >正文

C++ - 宏基础(简单常量替换宏、函数样式的宏、多行宏、预定义宏、字符串化宏、连接宏、可变参数日志宏)

宏概述

  1. 在编程中,宏(Macro)是一种预处理器指令

  2. 宏可以让程序员在源代码中定义一段值或代码的别名,在编译程序之前,预处理器会查找这些宏,并将其替换为相应的值或代码


C++ 宏

  1. 在 C++ 中,宏可以通过预处理器指令 #define 来定义

  2. 宏可以是简单的常量替换,也可以函数样式的宏(函数样式的宏并不是真正的函数)

  3. 宏通常全大写以区别于变量

  4. 可以使用反斜杠(\)实现多行宏


一、简单常量替换宏

#include <iostream>

using namespace std;

#define PI 3.14159

int main() {
    
	cout << PI << endl;

	double radius = 5.0;
    double area = PI * radius * radius;
	cout << area << endl;

	return 0;
}
  • 输出结果
3.14159
78.5397

二、函数样式的宏

#include <iostream>

using namespace std;

// 使用反斜杠(\)实现多行宏
#define CALCULATE_MAXIMUM_1(firstNumber, secondNumber) \
    ((firstNumber > secondNumber) ? firstNumber : secondNumber)

#define CALCULATE_MAXIMUM_2(firstNumber, secondNumber) ((firstNumber > secondNumber) ? firstNumber : secondNumber)

int main() {

	int a = 5, b = 10;
	int result1 = CALCULATE_MAXIMUM_1(a, b);
	int result2 = CALCULATE_MAXIMUM_2(a, b);
	cout << result1 << endl;
	cout << result2 << endl;

	return 0;
}
  • 输出结果
10
10

三、多行宏

#include <stdio.h>

// 使用反斜杠(\)实现多行宏
#define PRINT_SUM(a, b) \
    printf("%d + %d = ", (a), (b)); \
    printf("%d\n", (a)+(b))

int main() {

    PRINT_SUM(3, 5);

    return 0;
}

四、预定义宏

#include <stdio.h>

int main() {

    printf("File: %s\n", __FILE__); // 当前文件名
    printf("Line: %d\n", __LINE__); // 当前行号
    printf("Date: %s\n", __DATE__); // 编译日期
    printf("Time: %s\n", __TIME__); // 编译时间

    return 0;
}

五、宏的特殊用法

1、字符串化宏
(1)基本介绍
#define STRINGIFY(x) #x
  • 将宏参数 x 直接转换为字符串常量(在编译期展开)
(2)演示
#include <iostream>

using namespace std;

#define STRINGIFY(x) #x

int main() {

    // 将变量名转为字符串
    int someVar = 42;
    cout << "变量名: " << STRINGIFY(someVar) << endl;

    // 将表达式转为字符串
    cout << "表达式: " << STRINGIFY(3 + 5 * 2) << endl;

    return 0;
}
  • 输出结果
变量名: someVar
表达式: 3 + 5 * 2
2、连接宏
(1)基本介绍
#define STRINGIFY(x) #x
  • 将两个宏参数 a 和 b 直接拼接成一个符号(在编译期展开)
(2)演示
#include <iostream>

using namespace std;

#define CONCAT(a, b) a##b

void print_hello()
{
    cout << "Hello World" << endl;
}

int main() {

    // 拼接变量名

    int xy = 100;
    cout << CONCAT(x, y) << endl;


    // 拼接函数名
    CONCAT(print_, hello)();

    return 0;
}
  • 输出结果
100
Hello World
3、可变参数日志宏
(1)基本介绍
#define LOG(fmt, ...) printf("[LOG] " fmt "\n", ##__VA_ARGS__)
  • 可变参数日志输出,支持格式化字符串
(2)关键语法解析
  1. 字符串字面量的自动拼接
"[LOG] " fmt "\n"

// 等价于
"[LOG] " "your_format" "\n"

// 合并后
"[LOG] your_format\n"
  1. ##__VA_ARGS__ 是传入的可变参数,## 前缀用于当可变参数为空时,自动删除前面的逗号
LOG("No args");

// 展开为
printf("[LOG] " "No args" "\n",);

// 使用 ## 前缀后
printf("[LOG] " "No args" "\n");
(3)演示
#include <cstdio>

#define LOG(fmt, ...) printf("[LOG] " fmt "\n", ##__VA_ARGS__)

int main() {
    int error_code = 404;
    const char* path = "/index.html";

    LOG("程序启动");

    LOG("文件 %s 未找到,错误码: %d", path, error_code);

    return 0;
}
  • 输出结果
[LOG] 程序启动
[LOG] 文件 /index.html 未找到,错误码: 404
http://www.dtcms.com/a/111469.html

相关文章:

  • 深入理解C++引用:从基础到现代编程实践
  • 【设计模式】代理模式
  • 如何计算财富自由所需要的价格?
  • mapbox进阶,使用本地dem数据,加载hillshade山体阴影图层
  • 什么是缓存穿透、缓存雪崩、缓存击穿?
  • 使用VS2022远程调试Linux项目问题
  • Linux / Windows 下 Mamba / Vim / Vmamba 安装教程及安装包索引
  • 程序化广告行业(54/89):人群标签、用户标签与Look Alike原理详解
  • 鸿蒙NEXT开发随机工具类(ArkTs)
  • 【大模型基础_毛玉仁】6.5 实践与应用--RAG、Agent、LangChain
  • FPGA--HDLBits网站练习
  • 思维链、思维树、思维图与思维森林在医疗AI编程中的应用蓝图
  • ARXML文件解析-1
  • 14.流程自动化工具:n8n和家庭自动化工具:node-red
  • 解决LeetCode“使括号有效的最少添加”问题
  • Android Hilt 教程
  • 马斯克 AI 超算
  • 蓝桥云客---九宫幻方
  • ngx_ssl_init
  • 【2-7】脉码调制
  • Apache httpclient okhttp(2)
  • 【winodws】夜神模拟器虚拟机启动失败,请进行修复。关闭hyper-v
  • CSS Id 和 Class 选择器学习笔记
  • 【嵌入式-stm32电位器控制LED亮灭以及编码器控制LED亮灭】
  • 标准库文档
  • 基于时间卷积网络TCN实现电力负荷多变量时序预测(PyTorch版)
  • 如何确保MQ消息队列不丢失:Java实现与流程分析
  • ubuntu20.04升级成ubuntu22.04
  • JavaScript BOM核心对象、本地存储
  • Linux学习笔记7:关于i.MX6ULL主频与时钟配置原理详解