欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 八卦 > Java转C之C/C++ 的宏定义和预处理

Java转C之C/C++ 的宏定义和预处理

2025/4/19 5:28:31 来源:https://blog.csdn.net/pumpkin84514/article/details/144462036  浏览:    关键词:Java转C之C/C++ 的宏定义和预处理

C/C++ 宏定义和预处理总结

C/C++ 的宏定义和预处理器是在编译前执行的一系列文本处理操作,用于包含文件、定义常量、条件编译和控制编译器行为。以下是全面总结,涵盖各种知识点、注意事项以及示例。


表1:C/C++ 预处理指令和功能

预处理指令功能描述示例代码详细说明
#include包含头文件或其他文件#include <stdio.h>
#include "myheader.h"
<...> 表示系统路径查找,"..." 表示先在当前目录查找文件,再到系统路径查找。
#define定义宏,用于文本替换#define PI 3.14159
#define SQUARE(x) ((x) * (x))
简单宏:如 PI 替换为 3.14159
函数宏:参数替换时用括号防止优先级错误。
#undef取消宏定义#define DEBUG
#undef DEBUG
取消宏定义后,DEBUG 不再被替换。
#ifdef条件编译:检查宏是否已定义#ifdef DEBUG
printf("Debug ON\n");
#endif
如果 DEBUG 已定义,则执行代码块。
#ifndef条件编译:检查宏是否未定义#ifndef RELEASE
printf("Release mode disabled\n");
#endif
如果 RELEASE 未定义,则执行代码块。
#if / #elif / #else / #endif条件编译,支持复杂判断和多分支代码#if VALUE > 5
printf("Value > 5\n");
#else
printf("Value <= 5\n");
#endif
根据条件编译特定代码分支。
#pragma控制编译器行为#pragma once
#pragma warning(disable:4996)
#pragma once 避免重复包含头文件。
#pragma warning 控制特定警告。
#error抛出编译错误信息并终止编译#ifndef CONFIG
#error "CONFIG is not defined"
#endif
如果未定义 CONFIG,则报错并终止编译。
#line更改代码行号和文件名#line 100 "custom_file.c"用于调试,改变预处理器认为的文件名和行号。
# 操作符将宏参数转换为字符串#define STRINGIFY(x) #x
printf(STRINGIFY(Hello)); // 输出 "Hello"
参数 x 被转为字符串字面量。
## 操作符拼接宏参数,连接两个宏参数#define CONCAT(x, y) x##y
int CONCAT(var, 1) = 10; // 等效 int var1 = 10;
## 拼接参数,用于生成变量名、函数名等。
__VA_ARGS__处理可变参数宏#define LOG(fmt, ...) printf(fmt, __VA_ARGS__)可变参数宏 允许接收不定数量的参数。
预定义宏提供编译相关的文件、行号、日期、时间信息printf("File: %s, Line: %d", __FILE__, __LINE__);- __FILE__:当前文件名
- __LINE__:当前行号
- __DATE__:编译日期
- __TIME__:编译时间

表2:C/C++ 宏的分类和特点

宏类型描述示例注意事项
简单宏替换常量值#define PI 3.14无类型检查,所有出现的 PI 都直接替换为 3.14
函数宏替代简单函数的实现#define SQUARE(x) ((x) * (x))
printf("%d", SQUARE(5));
使用括号保护参数,防止运算符优先级错误。
条件宏根据宏定义值决定是否替换#if defined(WIN32)
#define OS "Windows"
#endif
多平台代码适配时非常有用。
多行宏使用 \ 将宏定义分成多行#define LOG(level, msg) \\\n printf("[%s]: %s\\n", level, msg)\\\n 必须紧跟行尾,不能有多余空格或字符。
可变参数宏接受不定数量的参数#define PRINT(fmt, ...) printf(fmt, __VA_ARGS__)必须使用 __VA_ARGS__ 捕获所有剩余参数。
递归宏宏可以嵌套引用#define X 10
#define Y X+5
printf("%d", Y);
避免循环定义,如 #define X Y#define Y X,会导致编译器报错。
预定义宏提供编译信息printf("File: %s, Line: %d, Date: %s", __FILE__, __LINE__, __DATE__);无需定义,编译器自动提供。

示例与讲解

示例1:简单宏和函数宏
#include <stdio.h>
#define PI 3.14159
#define AREA(r) (PI * (r) * (r))int main() {float radius = 5.0;printf("Circle area: %.2f\n", AREA(radius));return 0;
}

输出

Circle area: 78.54

说明

  • PI 被替换为 3.14159
  • AREA(radius) 被替换为 (3.14159 * (radius) * (radius)),括号确保运算优先级正确。

示例2:条件编译
#include <stdio.h>
#define DEBUGint main() {
#ifdef DEBUGprintf("Debug mode enabled\n");
#elseprintf("Debug mode disabled\n");
#endifreturn 0;
}

输出

Debug mode enabled

说明

  • 如果定义了 DEBUG,则执行 printf("Debug mode enabled\n");
  • 如果未定义 DEBUG,则执行 printf("Debug mode disabled\n");

示例3:多行宏
#include <stdio.h>
#define LOG(level, msg) \printf("[%s]: %s\n", level, msg)int main() {LOG("INFO", "Application started");LOG("ERROR", "An error occurred");return 0;
}

输出

[INFO]: Application started
[ERROR]: An error occurred

说明

  • 使用 \ 将宏定义分成多行,宏展开后替换为单行代码。

示例4:预定义宏
#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;
}

输出

File: example.c
Line: 5
Date: Dec 13 2024
Time: 12:00:00

说明

  • __FILE__ 提供当前文件名。
  • __LINE__ 提供当前行号。
  • __DATE____TIME__ 提供编译日期和时间。

示例5:可变参数宏
#include <stdio.h>
#define PRINT(fmt, ...) printf(fmt, __VA_ARGS__)int main() {PRINT("Name: %s, Age: %d\n", "Alice", 30);return 0;
}

输出

Name: Alice, Age: 30

说明

  • __VA_ARGS__ 捕获所有额外参数。
  • PRINT(fmt, ...) 展开为 printf(fmt, __VA_ARGS__)

注意事项

  1. 宏仅是文本替换

    • 宏在预处理阶段执行纯文本替换,没有类型检查和作用域限制。
  2. 尽量减少宏的滥用

    • 使用 inline 函数替代函数宏,避免潜在的调试困难。
    • 使用 constconstexpr 替代简单宏定义,提供更强的类型和范围控制。
  3. 防止宏替换错误

    • 在宏中使用括号保护参数,防止运算符优先级问题。
    • 避免循环宏定义,可能导致编译器报错。

通过以上表格和示例,C/C++ 的宏定义和预处理功能全面详解,确保知识点完整且代码清晰易懂,可用于快速查询和实践。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词