• 第21课 宏定义与使用分析


    C语言中的宏定义:

    定义宏常量:

     就宏定义来说,这是正确的,预处理器可以编译过。 但是就真正的编译来说,这是错误的,真正的编译会有语法错误。

    示例程序:

     1 #define ERROR -1
     2 #define PATH1 "D:	est	est.c"
     3 #define PATH2 D:	est	est.c
     4 #define PATH3 D:	est
     5 test.c
     6 
     7 int main()
     8 {
     9     int err = ERROR;
    10     char* p1 = PATH1;
    11     char* p2 = PATH2;
    12     char* p3 = PATH3;
    13 }

    执行预处理,gcc -E test.c -o test.i,预处理器处理之后结果如下:

    预处理器进行直接的文本替换,是不会进行语法检查的。第4行最后一个会被认为是接续符,将第5行接到第4行。

    再继续执行编译的话,16,17行会报错。

    宏常量和const常量是不同的,const常量本质是变量,要占用内存空间,而define出来的宏是个字面量,不会占用内存空间。

    宏定义表达式:

    在C语言中,我们无法定义一个函数来求数组的大小,但是可以定义一个宏函数,来做这件事。

    示例程序:

     1 // #include <stdio.h>
     2 
     3 #define _SUM_(a, b) (a) + (b)
     4 #define _MIN_(a, b) ((a) < (b) ? (a) : (b))
     5 #define _DIM_(a) sizeof(a)/sizeof(*a)
     6 
     7 
     8 int main()
     9 {
    10     int a = 1;
    11     int b = 2;
    12     int c[4] = {0};
    13 
    14     int s1 = _SUM_(a, b);
    15     int s2 = _SUM_(a, b) * _SUM_(a, b);
    16     int m = _MIN_(a++, b);
    17     int d = _DIM_(c);
    18 
    19     // printf("s1 = %d
    ", s1);
    20     // printf("s2 = %d
    ", s2);
    21     // printf("m = %d
    ", m);
    22     // printf("d = %d
    ", d);
    23 
    24     return 0;
    25 }

    预处理结果如下:

    打开printf打印行,运行结果如下:

    程序的输出并不是我们的预期,可见宏代码块的副作用出来了。

    第17行真正求得了数组的大小。

    宏表达式与函数对比:

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

    示例程序:

     1 // #include <stdio.h>
     2 
     3 void def()
     4 {
     5     #define PI 3.1415926
     6     #define AREA(r) r * r * PI
     7 }
     8 
     9 double area(double r)
    10 {
    11     return AREA(r);
    12 }
    13 
    14 int main()
    15 {
    16     double r = area(5);
    17 
    18     // printf("PI = %f
    ", PI);
    19     // printf("d = 5; a = %f
    ", r);
    20     
    21     return 0;
    22 }

    编译结果如下:

    预处理没有报错,这说明对于宏而言是没有作用域限制的。

    作用域的概念是针对C语言里面的变量和函数的,它不针对宏,因为宏是被预处理器处理的。编译器不知道宏的存在。

    强大的内置宏:

    综合示例:

     1 #include <stdio.h>
     2 #include <malloc.h>
     3 
     4 #define MALLOC(type, x) (type*)malloc(sizeof(type)*x)
     5 
     6 #define FREE(p) (free(p), p=NULL)
     7 
     8 #define LOG(s) printf("[%s] {%s:%d} %s 
    ", __DATE__, __FILE__, __LINE__, s)
     9 
    10 #define FOREACH(i, m) for(i=0; i<m; i++)
    11 #define BEGIN {
    12 #define END   }
    13 
    14 int main()
    15 {
    16     int x = 0;
    17     int* p = MALLOC(int, 5);
    18     
    19     LOG("Begin to run main code...");
    20     
    21     FOREACH(x, 5)
    22     BEGIN
    23         p[x] = x;
    24     END
    25     
    26     FOREACH(x, 5)
    27     BEGIN
    28         printf("%d
    ", p[x]);
    29     END
    30     
    31     FREE(p);
    32     
    33     LOG("End");
    34     
    35     return 0;
    36 }

    上述程序中定义的宏是无法用函数来取代的。

    运行结果如下:

    小结:

  • 相关阅读:
    kbmMW 5.07.00试用笔记
    在 Andriod/IOS 程序中使用自定义字体
    【转】Delphi 10.3关于相机该注意的细节
    Delphi 10.3终于来了
    REST easy with kbmMW #17 – Database 6 – Existing databases
    【go】1环境搭建go语言介绍
    【ESSD技术解读02】企业级利器,阿里云 NVMe 盘和共享存储
    项目实战总结以及接入UAPM
    RocketMQ 5.0 POP 消费模式探秘
    Cube 技术解读 | 详解「支付宝」全新的卡片技术栈
  • 原文地址:https://www.cnblogs.com/wanmeishenghuo/p/9536628.html
Copyright © 2020-2023  润新知