zoukankan      html  css  js  c++  java
  • 第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 }

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

    运行结果如下:

    小结:

  • 相关阅读:
    pipelinewise 学习二 创建一个简单的pipeline
    pipelinewise 学习一 docker方式安装
    Supercharging your ETL with Airflow and Singer
    ubuntu中使用 alien安装rpm包
    PipelineWise illustrates the power of Singer
    pipelinewise 基于singer 指南的的数据pipeline 工具
    关于singer elt 的几篇很不错的文章
    npkill 一个方便的npm 包清理工具
    kuma docker-compose 环境试用
    kuma 学习四 策略
  • 原文地址:https://www.cnblogs.com/wanmeishenghuo/p/9536628.html
Copyright © 2011-2022 走看看