宏定义 使用分析
来源:互联网 发布:c 的sms源码 编辑:程序博客网 时间:2024/04/29 21:21
宏定义:
在程序中,以#开头的都是预处理指令。
#define定义宏常量可以出现在代码的任何地方。
如下图所示:
判断宏定义是否正确,要把宏定义的内容代到真正的程序中,根据实际的程序来看。
#define从本行开始,之后的代码都可以使用这个宏常量。这里的之后是指文本的排列顺序的之后,不是程序代码运行的顺序。
使用#undef来结束一个宏定义。 以此限制宏定义的作用范围。
例如:
int f1(int a, int b){ #define _MIN_(a,b) ((a)<(b) ? a : b) return _MIN_(a, b); #undef _MIN_}
可以在一个函数里定义一个宏定义。
定义宏表达式:
#define表达式给有函数调用的假象,却不是函数
#define表达式可以比函数更强大
#define表达式比函数更容易出错
举例说明,宏表达式的优点:
#define DIM(array) (sizeof(array)/sizeof(*array))...int a[] = {1, 2, 3, 4};printf("%d\n", DIM(a));
这段程序会输出数组的元素个数4,但是如果使用函数来表示的话,输出的结果为1。因为,函数有弱点,他的参数传入的只是一个指针,sizeof(array)计算的是地址的长度,地址是32位4个字节,计算结果为1,但是宏表达式中sizeof(array)是计算整个数组的字节数。
举例说明,宏表达式的副作用:
#define SUM(a, b) (a)+(b)...printf("%d\n", SUM(1,2) * SUM(1,2));
预期程序会输出9,但是不对,程序输出5,因为宏定义是文本替换,替换结果为:1+2*1+2=5。因此宏定义表达式也有很大的副作用。
宏表达式与函数的对比:
宏表达式在预编译期被处理,编译器不知道宏表达式的存在。
宏表达式用“实参”完全替代形参,不进行任何运算。
宏表达式没有任何的“调用”开销。节省时间空间。
宏表达式中不能出现递归定义。
这样的递归写法是错误的,会把define中第二个FAC当作函数来看,会报错。
举例程来表明宏定义的优点:
#include <stdio.h>#include <malloc.h>#define MALLOC(type, x) (type*)malloc(sizeof(type)*x)#define FOREVER() while(1)#define BEGIN {#define END }#define FOREACH(i, m) for(i=0; i<m; i++)int main(){ int array[] = {1, 2, 3, 4, 5}; int x = 0; int*p = MALLOC(int, 5); FOREACH(x, 5) BEGIN p[x] = array[x]; END FOREACH(x, 5) BEGIN printf("%d\n", p[x]); END FOREVER(); free(p); printf("Last printf...\n"); return 0;}
上面的程序看起来已经不像C语言了。
内置宏定义
有的编译器没有 _ STDC _
利用内置宏来定义日志宏,即打印相关的操作内容。
#include <stdio.h>#define LOG(s) printf("%s,%d,%s,%s\n",__FILE__,__LINE__,__DATE__,s)void f(){ LOG("Enter f()"); LOG("Exit f()");}int main(){ LOG("Enter main()"); f(); LOG("Exit main()"); return 0;}
函数与宏的详细对比:
宏是由预处理直接替换展开的,编译器不知道宏的存在
函数是由编译器直接编译的实体,调用行为由编译器决定
多次使用宏会导致程序代码量增加
函数是跳转执行的,因此代码量不会增加
宏的效率比函数要高,因为是直接展开,无调用开销
函数调用时会创建活动记录,效率不如宏
宏的效率比函数稍高,但是其副作用巨大,容易出错。
函数存在实参到形参的传递,因此无任何副作用,但是函数需要建立活动对象,效率受影响
宏的参数可以是类型名
函数的参数必须是固定类型,效率稍低,不易出错
宏可以实现函数不能实现的功能,如计算数组的元素个数
- 宏定义 使用分析
- 宏定义与使用分析
- 宏定义及使用分析
- 宏定义与使用分析
- 宏定义与宏使用分析
- 3.1、宏定义和使用分析
- 宏定义#ifndef和#define,#endif的使用分析
- UNSTUFF_BITS宏定义分析
- __range_ok 宏定义分析
- container_of宏定义分析
- offsetof宏定义分析
- SYSCALL_DEFINE3宏定义的分析
- C宏定义使用
- 宏定义使用学习
- 宏定义的使用
- 宏定义使用
- 使用宏定义DEFINE
- 宏定义的使用
- 浅谈CSRF攻击方式
- c语言用尾递归实现单向链表的逆向排列
- 任志强:2017年房价更高,跟货币毫无关系
- JavaWeb项目导入MyEclipse后变为JAVA项目项目【解决方法】
- CANNOT LINK EXECUTABLE DEPENDENCIES: cannot locate symbol解决
- 宏定义 使用分析
- android——8点控制裁剪框
- C++ string assign()赋值常用方法
- Linux strace命令
- SpringMVC:生成Excel和PDF
- 盒模型
- PHP防止sql语句注入终极解决方案
- 解决listview中checkbox复用的问题
- cocos creator学习笔记2017.2.9