• 14 宏


    1 C语言中的宏定义

    • #define预处理器处理的单元实体之一
    • #define 定义的宏可以出现在程序的任意位置
    • #define 定义之后的代码都可以使用这个宏

    2 定义宏常量

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

    • #define 定义的宏常量本质为字面量 => 宏常量(本质是字面量)不是变量,不占用内存,这是与 const 常量(本质是只读变量)的本质区别

    • 示例1:分析下面定义的宏常量

      #define ERROR -1
      #define PATH1 "D:	est	est.c"
      #define PATH2 D:	est	est.c
      #define PATH3 D:	est
      test.c
      
      int main()
      {
          int err = ERROR;
          char* p1 = PATH1;
          char* p2 = PATH2;
          char* p3 = PATH3;
      }
      
      • 利用预处理器分析:单步编译:gcc -E test.c -o test.i

        结果:编译正确,说明预处理器不进行语法检查,只进行宏替换

      • 宏替换后,可以看到 p2p3 语法错误:

        int err = -1;
        char* p1 = "D:	est	est.c";
        char* p2 = D:	est	est.c;
        char* p3 = D:	esttest.c;
        

    3 宏定义表达式

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

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

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

    • 示例2:分析下面定义的宏表达式

      #include <stdio.h>
      
      #define _SUM_(a, b) (a) + (b)
      #define _MIN_(a, b) ((a) < (b) ? (a) : (b))
      // 得到一个数组的大小:C语言中无法通过一个函数得到一个数组的大小,只能通过宏
      #define _DIM_(a) sizeof(a)/sizeof(*a)
      
      
      int main()
      {
          int a = 1;
          int b = 2;
          int c[4] = {0};
      
          int s1 = _SUM_(a, b);                 // <=> int s1 = (a) + (b);
          int s2 = _SUM_(a, b) * _SUM_(a, b);   // <=> int s2 = (a) + (b) * (a) + (b);
          int m = _MIN_(a++, b);                // <=> int m = ((a++) < (b) ? (a++) : (b));
          int d = _DIM_(c);                     // <=> int d = sizeof(c)/sizeof(*c);
      
          printf("s1 = %d
      ", s1);  // s1 = 3
          printf("s2 = %d
      ", s2);  // s2 = 5
          printf("m = %d
      ", m);  // m = 2
          printf("d = %d
      ", d);  // d = 4
      
          return 0;
      }
      

    4 宏表达式与函数的对比

    • 宏表达式被预处理器处理,编译器不知道宏表达式的存在;预处理器不会对宏定义进行语法检查,宏定义时出现的语法错误只能被编译器检测

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

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

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

      // 宏表达式的错误用法
      #define _SUM_(n) ((n > 0) ? (_SUM_(n - 1) + n) : 0)
      int s = _SUM_(10);
      

    5 宏定义的常量/表达式的作用域

    • 对于宏

      • 没有作用域的限制
      • 定义完宏之后,后面的代码都可以使用
      • 作用域是针对变量和函数而言的
    • 示例3:分析宏常量/表达式的作用域

      #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(5);
      
          printf("PI = %f
      ", PI);       // PI = 3.1415926 
          printf("d = 5; a = %f
      ", r);  //  d = 5; a = 
          
          return 0;
      }
      

    6 内置宏

    含义 示例
    _FILE_ 被编译的文件名 file.c
    _LINE_ 当前行号 25
    _DATE_ 编译时的日期 Sep 2 2020
    _TIME_ 编译时的时间 10:20:18
    _STDC_ 编译器是否遵循标准C规范 1
    • 示例
    #include <stdio.h>
    #include <malloc.h>
    
    //申请x个类型为type的内存空间
    #define MALLOC(type, x) (type*)malloc(sizeof(type)*x)
    
    //逗号表达式,从左向右地运行:先将指针所指向的内存释放,再将指针置为空,内置的free函数只能将指针所指向的内存释放
    #define FREE(p) (free(p), p=NULL)
    
    //打印日志
    #define LOG(s) printf("[%s] {%s:%d} %s 
    ", __DATE__, __FILE__, __LINE__, s)
    
    #define FOREACH(i, m) for(i=0; i<m; i++)
    #define BEGIN {
    #define END   }
    
    int main()
    {
        int x = 0;
        int* p = MALLOC(int, 5);
        
        LOG("Begin to run main code...");
        
        FOREACH(x, 5)
        BEGIN
            p[x] = x;
        END
        
        FOREACH(x, 5)
        BEGIN
            printf("%d
    ", p[x]);
        END
        
        FREE(p);
        
        LOG("End");
        
        return 0;
    }
    
    //输出结果
    [Sep  2 2020] {test.c:22} Begin to run main code...
    0
    1
    2
    3
    4
    [Sep  2 2020] {test.c:36} End
    
  • 相关阅读:
    yarn 完美替代 npm
    Vue调试神器vue-devtools安装
    PHPStorm 忽略 node_modules 目录
    npm 更改为淘宝镜像的方法
    php快速获取所有的自定义常量用户常量
    我们为什么要在 PHPStorm 中标记目录
    PhpStorm 合理标注目录让索引和扫描更加地高效
    Linux sleep命令
    Shell命令行中特殊字符与其转义详解(去除特殊含义)
    shell编程—— EOF
  • 原文地址:https://www.cnblogs.com/bky-hbq/p/13604479.html
Copyright © 2020-2023  润新知