请问c++宏的高级运用有哪些

wyqstc1 2008-03-06 01:43:28
看了下书,感觉宏的应用和方法没撒差别,但是既然有了这个社定肯定有他的意义.所以请高手指教下具体的实际的运用.
...全文
321 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
NKLoveRene 2008-03-06
  • 打赏
  • 举报
回复
觉得没用就不用了呗
这个也不是必须的
sheenl 2008-03-06
  • 打赏
  • 举报
回复
最高境界的用法, 手无无剑, 心中有剑。
明明c++支持宏, 但是你却不用, 就是最高境界
abupie 2008-03-06
  • 打赏
  • 举报
回复
宏定义又称为宏代换、宏替换,简称“宏”

格式:
#define 标识符 字符串

其中的标识符就是所谓的符号常量,也称为“宏名” , 预处理(预编译)工作也叫做宏展开:将宏名替换为字符串。
掌握"宏"概念的关键是“换”。一切以换为前提、做任何事情之前先要换,准确理解之前就要“换”。 即在对相关命令或语句的含义和功能作具体分析之前就要换,“不管三七二十一,先换了再说”。

常见的宏用途:
1 条件include
#ifndef MAIN_H_ 
#define MAIN_H_
其它内容
#endif

上面在看到头文件时会看到 作用就是阻止这个头文件被多次include
多次include就会出现重复的定义情况 所以需要在每个头文件中都使用这个定义
如果还不是很了解要怎样使用 可以看看 c的标准头文件 如fcntl.h

2 条件编译
#ifdef _DEBUG 
printf("this debug info\n");
#endif

如果没有定义_DEBUG宏的话 那么上面那一行是不会编译进去的
但是定义了_DEBUG后 上面那行就会编译进去 可以写个简单的程序测试

#include <stdio.h> 
int main()
{
#ifdef _DEBUG
printf("hello world\n");
#else
printf("no debug");
#endif
return 0;
}


第一次使用 gcc -D_DEBUG main.c
第二次使用 gcc main.c
运行两次的结果看

3 定义为某个值 以便后面修改这个值时不用修改其它地方代码 只要修改这个宏的定义就可以了
如一个软件的多语言版本等 如下
#include <stdio.h> 
#define PRINT_STR "你好 DD"
main(){
printf(PRINT_STR);
return 0;
}


编译时 会把PRINT_STR代替成"你好 DD" ,以后想修改时就方便了


4.定义为函数

#include <stdio.h>

#ifdef _DEBUG
#define A(x) a(x)
#else
#define A(x) b(x)
#endif

int a(int x)
{
return x+1;
}

int b(int x){
return x+100;
}

int main(){
printf ("A(10) value is %d",A(10));
return 0;
}


其实也可以定义成
#define A a

但是 定义成A(x)后 只有A后面带一个(x)类型的 编译器才会执行替换 比较安全 可以保证只替换函数而不替换变量

5.可变参数宏

有些时候定义一个宏来代替某个函数 但是这个函数是可变参数的话 那就需要考虑办法了 ,定义方法如下

#define PRINT(...) printf(__VA_ARGS__) 
#include <stdio.h>
int main(){
PRINT("%d %s %s",1,"吃饭了吗 smile MM:)","\n");
return 0;
}


6.宏组合
也就是## 和 #的用法
## 是连接符号 连接两个宏
#是把名字代替成字符串

#define s5(a) supper_ ## a 
#include <stdio.h>
void supper_printf(const char* p )
{
printf("this is supper printf:\n%s\n",a);
}

int main()
{
s5(printf)("hello owrld");
return 0;
}

//用法
#include <stdio.h>
#define s(p) #p
int main(){
printf(s(p)"\n");
return 0;
}
Treazy 2008-03-06
  • 打赏
  • 举报
回复
宏,双刃剑一把!
Chappell 2008-03-06
  • 打赏
  • 举报
回复
举个例子:
#define DECLARE_DYNAMIC(class_name) \
public: \
static CRuntimeClass class##class_name; \
virtual CRuntimeClass* GetRuntimeClass() const;
这是深入浅出MFC第三章的一个宏
假设你定义了一个类CMyClass,你希望把它申明为运行时刻类,于是你使用了上面的宏,如下:
class CMyClass{
CMyClass();
~CMyClass();

... ...

DECLARE_DYNAMIC(CMyClass)
};

它等同于如下代码:
class CMyClass{
CMyClass();
~CMyClass();

... ...

public:
static CRuntimeClass classCMyClass;
virtual CRuntimeClass* GetRuntimeClass() const;
};
  • 打赏
  • 举报
回复
这个宏还是尽量少用的好
redleaves 2008-03-06
  • 打赏
  • 举报
回复
把BOOST里那些用法都学会,你就BT了...
taodm 2008-03-06
  • 打赏
  • 举报
回复
去看<Effective C++>item1
dubiousway 2008-03-06
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 NKLoveRene 的回复:]
觉得没用就不用了呗
这个也不是必须的
[/Quote]

[Quote=引用 10 楼 uuussseeennn 的回复:]
看看MFC里是怎么用宏来实现RTTI,动态创建对象,消息映射机制的,你会对宏有一个新的认识。
[/Quote]

9楼10楼----- 这两者就是宏的最高境界了。道有千万,我取其一。
mislrb 2008-03-06
  • 打赏
  • 举报
回复
学习
dubiousway 2008-03-06
  • 打赏
  • 举报
回复
宏的应用和方法没撒差别
----- 什么意思。。。
uuussseeennn 2008-03-06
  • 打赏
  • 举报
回复
看看MFC里是怎么用宏来实现RTTI,动态创建对象,消息映射机制的,你会对宏有一个新的认识。
chm格式的 VC++高级编程。一本很好的学习教程。本书目录: 目录 一 走进Visual C++ 1 理解VC工程 2 MFC编程特点 3使用Wizard 二 MFC程序结构分析 1 WINDOWS程序工作原理 2 建立应用程序 3 程序结构剖析 3.1 类CMYAPP 3.2 类CMAINFRAME 3.3类CMyView与CMyDoc 三 深入MFC类库 1 处理用户输入 1.1 定义对话框资源 1.2 定义对话框类 2 有关屏幕输出 2.1 设备上下文工作原理 2.2 实例绘图原理剖析 2.3 绘图操作实现 2.4 有关屏幕映射方式 3 文件处理 3.1 对象持续化简述 3.2 实例分析 3.3 与文件处理关系密切的类CFile 4 DAO技术 4.1 DAO与ODBC 4.2 使用MFC实现DAO技术 5 打印 5.1打印和显示 5.2打印分页 5.3打印工作的开始和结束 5.4打印程序实例 四 VC程序调试 1 VC调试工具 1.1 调试环境的建立 1.2调试的一般过程 1.3 如何设置断点 1.4 控制程序的运行 1.5 查看工具的使用 2 高级调试技术 2.1 TRACE 的利用 2.2 ASSERT的利用 2.3 ASSERT_VALID的利用以及类的AssertValid()成员函的重载 2.4对象的DUMP函数的利用 3 内存漏洞的检查 五Visual C++与多媒体 1 对声音的处理 1.1媒体控制接口 1.2波形混音器 2 多媒体文件I/O 3多媒体图形图像技术 4图像合成 5 FLC动画 6热点 后记 如果下载后打不开,点击一下右键选择属性,在弹出的对话框中选择 “常规”->“解除锁定” 即可。
1. C 语言中的指针和内存泄漏 5 2. C语言难点分析整理 10 3. C语言难点 18 4. C/C++实现冒泡排序算法 32 5. C++中指针和引用的区别 35 6. const char*, char const*, char*const的区别 36 7. C中可变参数函数实现 38 8. C程序内存中组成部分 41 9. C编程拾粹 42 10. C语言中实现数组的动态增长 44 11. C语言中的位运算 46 12. 浮点数的存储格式: 50 13. 位域 58 14. C语言函数二维数组传递方法 64 15. C语言复杂表达式的执行步骤 66 16. C语言字符串函数大全 68 17. C语言定义技巧 89 18. C语言实现动态数组 100 19. C语言笔试-运算符和表达式 104 20. C语言编程准则之稳定篇 107 21. C语言编程常见问题分析 108 22. C语言编程易犯毛病集合 112 23. C语言缺陷与陷阱(笔记) 119 24. C语言防止缓冲区溢出方法 126 25. C语言高效编程秘籍 128 26. C运算符优先级口诀 133 27. do/while(0)的妙用 134 28. exit()和return()的区别 140 29. exit子程序终止函数与return的差别 141 30. extern与static存储空间矛盾 145 31. PC-Lint与C\C++代码质量 147 32. spirntf函数使用大全 158 33. 二叉树的数据结构 167 34. 位运算应用口诀和实例 170 35. 内存对齐与ANSI C中struct内存布局 173 36. 冒泡和选择排序实现 180 37. 函数指针数组与返回数组指针的函数 186 38. 右左法则- 复杂指针解析 189 39. 回车和换行的区别 192 40. 堆和堆栈的区别 194 41. 堆和堆栈的区别 198 42. 如何写出专业的C头文件 202 43. 打造最快的Hash表 207 44. 指针与数组学习笔记 222 45. 数组不是指针 224 46. 标准C中字符串分割的方法 228 47. 汉诺塔源码 231 48. 洗牌算法 234 49. 深入理解C语言指针的奥秘 236 50. 游戏外挂的编写原理 254 51. 程序实例分析-为什么会陷入死循环 258 52. 空指针究竟指向了内存的哪个地方 260 53. 算术表达式的计算 265 54. 结构体对齐的具体含义 269 55. 连连看AI算法 274 56. 连连看寻路算法的思路 283 57. 重新认识:指向函数的指针 288 58. 链表的源码 291 59. 高质量的子程序 295 60. 高级C语言程序员测试必过的十六道最佳题目+答案详解 297 61. C语言常见错误 320 62. 超强的指针学习笔记 325 63. 程序员之路──关于代码风格 343 64. 指针、结构体、联合体的安全规范 346 65. C指针讲解 352 66. 关于指向指针的指针 368 67. C/C++ 误区一:void main() 373 68. C/C++ 误区二:fflush(stdin) 376 69. C/C++ 误区三:强制转换 malloc() 的返回值 380 70. C/C++ 误区四:char c = getchar(); 381 71. C/C++ 误区五:检查 new 的返回值 383 72. C 是 C++ 的子集吗? 384 73. C和C++的区别是什么? 387 74. 无条件循环 388 75. 产生随机数的方法 389 76. 顺序表及其操作 390 77. 单链表的实现及其操作 391 78. 双向链表 395 79. 程序员数据结构笔记 399 80. Hashtable和HashMap的区别 408 81. hash 表学习笔记 410 82. C程序设计常用算法源代码 412 83. C语言有头结点链表的经典实现 419 84. C语言惠通面试题 428 85. C语言常用定义 450

64,649

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧