1、C语言中的宏定义

  #define是预处理器处理的单元实体之—

  #define定义的宏可以出现在程序的任意位置

  #define定义之后的代码都可以使用这个宏

2、定义宏常量

  #define定义的宏常量可以直接使用

  #define定义的宏常量本质为字面量

下面的宏常量定义正确吗?

 #define ERROR -1   
  
#define PATHl "D:\test\test.c"   
  
#define PATH2 D:\test\test.c   
  
#define PATH3 D:\test\   
test.c  

3、实例分析

宏定义分析     21-1.c

 #define ERROR -1  
#define PATH1 "D:\test\test.c"  
#define PATH2 D:\test\test.c  
#define PATH3 D:\test\  
test.c  
  
int main()  
{  
    int err = ERROR;  
    char* p1 = PATH1;  
    char* p2 = PATH2;  
    char* p3 = PATH3;  
}  

预处理器不会进行语法检查只是简单的文本替换,即这些宏定义都正确!!但编译器会报错!!

4、宏定义表达式

  #define表达式的使用类似函数调用

  #define表达式可以比函数更强大

  #define表达式比函数更容易出错

下面的宏表达式定义正确吗?

  

 #define _SUM_(a, b) (a) + (b)   
  
#define _MIN_(a, b) ((a) < (b) ? (a) : (b))   
  
#define _DIM_(a) sizeof(a)/sizeof(*a)  

5、实例分析

宏表达式分析     21-2.c

 #include <stdio.h>  
  
#define _SUM_(a, b) (a) + (b)  
#define _MIN_(a, b) ((a) < (b) ? (a) : (b))  
#define _DIM_(a) sizeof(a)/sizeof(*a)  
  
  
int main()  
{  
    int a = ;  
    int b = ;  
    int c[] = {};  
  
    int s1 = _SUM_(a, b);  
    int s2 = _SUM_(a, b) * _SUM_(a, b);  
    int m = _MIN_(a++, b);  
    int d = _DIM_(c);  
  
    printf("s1 = %d\n", s1);  
    printf("s2 = %d\n", s2);  
    printf("m = %d\n", m);  
    printf("d = %d\n", d);  
  
    return ;  
}  

6、宏表达式与函数的对比

  宏表达式被预处理器处理,编译器不知道宏表达式的存在

  宏表达式用“实参“完全替代形参,不进行任何运算

  宏表达式没有任何的“调用”开销

  宏表达式中不能出现递归定义

 #define _SUM_(n) ((n > 0) ? (_SUM_(n-1) + n): 0) //error

 int s = _SUM_();

7、有趣的问题

宏定义的常量或表达式是否有作用域限制?

下面的程序合法吗?

 void def()   
{  
    #define PI 3.1415926   
    #define AREA(r) r*r*PI  
}  
  
double area(double r)   
{  
    return AREA(r);  
}   

8、实例分析

宏的作用域分析     21-3.c

 #include <stdio.h>  
  
void def()  
{  
    #define PI 3.1415926  
    #define AREA(r) r * r * PI  
}  
  
double area(double r)  
{  
    return AREA(r);  
}  
  
int main()  
{  
    double r = area();  
  
    printf("PI = %f\n", PI);  
    printf("d = 5; a = %f\n", r);  
      
    return ;  
}  

9、强大的内置宏

  
  __LINE__ 表示当前行号,整型值
  __FILE__ 表示当前文件名,字符串类型
  __DATE__ 编译的日期,字符串类型
  __TIME__ 编译的时间,字符串类型
  __STDC__ 预定义的宏

10、实例分析

宏使用综合示例     21-4.c

 #include <stdio.h>  
#include <malloc.h>  
  
#define MALLOC(type, x) (type*)malloc(sizeof(type)*x)  
  
#define FREE(p) (free(p), p=NULL)  
  
#define LOG(s) printf("[%s] {%s:%d} %s \n", __DATE__, __FILE__, __LINE__, s)  
  
#define FOREACH(i, m) for(i=0; i<m; i++)  
#define BEGIN {  
#define END   }  
  
int main()  
{  
    int x = ;  
    int* p = MALLOC(int, );  
      
    LOG("Begin to run main code...");  
      
    FOREACH(x, )  
    BEGIN  
        p[x] = x;  
    END  
      
    FOREACH(x, )  
    BEGIN  
        printf("%d\n", p[x]);  
    END  
      
    FREE(p);  
      
    LOG("End");  
      
    return ;  
}  

11、小结

  预处理器直接对宏进行文本替换

  宏使用时的参数不会进行求值和运算

  预处理器不会对宏定义进行语法检查

  宏定义时出现的语法错误只能被编译器检测

  宏定义的效率高于函数调用

  宏的使用会带来—定的副作用

C语言-宏定义与使用分析的更多相关文章

  1. C 语言宏定义

    C 语言宏定义1.例子如下: #define PRINT_STR(s) printf("%s",s.c_str()) string str = "abcd"; ...

  2. 将C语言宏定义数值转换成字符串!

    将C语言宏定义转换成字符串! 摘自:https://blog.csdn.net/happen23/article/details/50602667 2016年01月28日 19:15:47 六个九十度 ...

  3. C语言 宏定义之可变参数

    可变参数宏定义 C99编译器标准允许你可以定义可变参数宏(variadic macros),这样你就可以使用拥有可以变化的参数表的宏.可变参数宏就像下面这个样子: #define dbgprint(. ...

  4. c语言宏定义

    一. #define是C语言中提供的宏定义命令,其主要目的是为程序员在编程时提供一定的方便,并能在一定程度上提高程序的运行效率,但学生在学习时往往不能理解该命令的本质,总是在此处产生一些困惑,在编程时 ...

  5. C语言宏定义#define用法

    #define是C语言中提供的宏定义命令,其主要目的是为程序员在编程时提供一定的方便,并能在一定程度上提高程序的运行效率,但学生在学习时往往不能 理解该命令的本质,总是在此处产生一些困惑,在编程时误用 ...

  6. C 语言宏定义函数编写时 do-while 的妙用和一些注意事项

    在 C 语言中,我们都知道可以用宏定义来编写函数,一般称为宏函数.如果一个宏函数比较复杂,那么在编写这样的宏函数是有一定技巧和注意事项的.文章给出一些我认为值得关注的地方,以及一些注意事项(个人建议) ...

  7. C语言宏定义时#(井号)和##(双井号)的用法1

    #在英语里面叫做 pound 在C语言的宏定义中,一个#表示字符串化:两个#代表concatenate 举例如下: #include <iostream> void quit_comman ...

  8. C语言宏定义时#(井号)和##(双井号)的用法

    C语言中如何使用宏C(和C++)中的宏(Macro)属于编译器预处理的范畴,属于编译期概念(而非运行期概念).下面对常遇到的宏的使用问题做了简单总结. 关于#和## 在C语言的宏中,#的功能是将其后面 ...

  9. C语言宏定义相关

    写好C语言,漂亮的宏定义很重要,使用宏定义可以防止出错,提高可移植性,可读性,方便性 等等.下面列举一些成熟软件中常用得宏定义......1,防止一个头文件被重复包含#ifndef COMDEF_H# ...

随机推荐

  1. 通过shell模拟redis-trib.rb info的输出

    需求:模拟redis-trib.rb info ip:port输出的结果 如: [redis@lxd-vm3 ~]$ redis-trib.rb info 5.5.5.101:29001 /usr/l ...

  2. php环境配置 wampserver 数据库无法连接

    开始接触php编程,最初级的选择了wampserver+phpstorm+notepad++.值得注意的有一下几点. 1.使用跳过不输入数据库密码登录数据库之后请及时修改数据库密码以及相关文件.否则在 ...

  3. springboot打成jar包并携带第三方jar

    1.修改打包方式为jar <packaging>jar</packaging> 2.添加第三方依赖到pom文件 我的第三方依赖包在resources目录下的lib目录下(地址可 ...

  4. SVN使用经验

    转载于:Svn发布项目 个人使用体验: 关于svn的相关命令 从服务器检出创建的项目文件夹,向项目中添加文件,右键tortoiseSvn->add 然后右键SVN Commit,选择文件并输入提 ...

  5. python + excel工资条自动生成

    年终绩效分配结果出来了,领导要求每人要清楚地知道自己的情况.要求:总绩效和各分类都要清楚.这就表示我们要给每人六个纸条,一个总的,五个分的.打出来,裁开,分发给每个人!累死人.所以,我就想能否每人生成 ...

  6. codechef Chef at the River

    难度 \(hard\) 题意 官方中文题意 做法 设\(G=(V,E)\) 定义1:\(M(G)\)为\(G\)的最小点覆盖 定义2:\(ans(G)\)为\(G\)的题意答案,不考虑船夫 结论1:\ ...

  7. 【Pyecharts可视化分享】杭州步行热门路线等~

    前言 本文包括内容如下: 杭州步行热门路线 渐变效果散点图 均是Echarts官方提供等示例,本文将会通过Pyecharts来进行实现. 杭州步行热门路线 因为代码中需要调用百度地图,所以开始之前你需 ...

  8. centos7 下 安装GeoIP2,在nginx中根据ip地址对应的国家转发请求

    最近有个需求是根据用户的地理位置,访问不同的服务器,比如国外用户访问国外的服务器,国内的用户访问国内的服务器,实现的思路主要两种: 智能dns,这个需要在阿里云中注册为企业版才有提供 nginx中使用 ...

  9. wfuzz的使用

    用于模糊测试,测试过滤字符 转载:https://www.secpulse.com/archives/81560.html https://www.freebuf.com/sectool/173746 ...

  10. C++中c_str()的用法

    这个函数经常用到,总是记不住,记下来,方便翻阅 c_str()函数返回一个指向正规C字符串的指针,内容与string串相同. C++中c_str()主要用法就是为了与C语言兼容,在C语言中没有stri ...