zoukankan      html  css  js  c++  java
  • 15 条件编译

    1 条件编译的基本概念

    • 条件编译是宏定义和预处理器的应用

    • 应用场合:开发不同档次的产品(低端/中端/高端) => 同一份代码产生不同的产品

    • 条件编译的行为类似于C语言中的 if...else...

    • 条件编译本质是预编译指示命令,用于控制是否编译某段代码

    • 示例1:预编译指令

      • Code

        #include <stdio.h>
        
        #define C 1
        
        int main()
        {
            const char* s;
        
            #if( C == 1 )
                s = "This is first printf...
        ";
            #else
                s = "This is second printf...
        ";
            #endif
        
            printf("%s", s);
            
            return 0;
        }
        // 输出结果
        This is first printf...
        
      • 单步编译:gcc -E test.c -o test.i

        int main()
        {
            const char* s;
                s = "This is first printf...
        ";
            
            
            
            return 0;
        }
        

    2 条件编译的本质

    • 预编译器根据条件编译指令有选择的删除代码

    • 编译器不知道代码分支的存在

    • if...else... 语句在运行期进行分支判断

    • 条件编译指令在预编译期进行分支判断

    • 可以通过命令行定义宏:-D,而不用 #define 来定义

    • 示例2:通过命令行定义宏

      #include <stdio.h>
      
      int main()
      {
          const char* s;
      
          #ifdef C
              s = "This is first printf...
      ";
          #else
              s = "This is second printf...
      ";
          #endif
      
          printf("%s", s);
          
          return 0;
      }
      
      • GCC 直接编译运行结果:This is second printf...
      • 通过命令行定义宏编译:gcc -DC=1 test.c -o test ,运行结果:This is first printf...

    3 #include 的本质

    • #include 的本质是将已经存在的文件内容嵌入到当前文件中

    • #include 的间接包含同样会产生嵌入文件内容的操作

    • 间接包含同一个头文件会产生编译错误

    • 示例3:重复包含头文件

      // test.c
      #include <stdio.h>
      #include "test.h"
      #include "global.h"
      
      int main()
      {
          const char* s = hello_world();
          int g = global;
          
          printf("%s
      ", NAME);
          printf("%d
      ", g);
          
          return 0;
      }
      
      
      // test.h
      #ifndef _TEST_H_
      #define _TEST_H_
      #include "global.h"
      const char* NAME = "test.h";
      char* hello_world()
      {    
          return "Hello world!
      ";
      }
      #endif
      
      
      // global.h
      #ifndef _GLOBAL_H_
      #define _GLOBAL_H_
      int global = 10;
      #endif
      
      • GCC 编译

        In file included from test.c:3:
        global.h:2: error: redefinition of 'global'
        global.h:2: error: previous definition of 'global' was here
        
      • 单步编译:gcc -E test.c -o test.i ,可以发现因为头文件的重复包含,global 变量被重复定义了

    • 条件编译可以解决头文件重复包含的编译错误

      // test.h
      #ifndef _TEST_H_
      #define _TEST_H_
      #include "global.h"
      const char* NAME = "test.h";
      char* hello_world()
      {    
          return "Hello world!
      ";
      }
      #endif
      
      
      // global.h
      #ifndef _GLOBAL_H_
      #define _GLOBAL_H_
      int global = 10;
      #endif
      
      // 输出结果
      test.h
      10
      

    4 条件编译的意义

    • 条件编译可以按不同的条件编译不同的代码段,因而可以产生不同的目标代码

    • #if... #else...#endif 被预编译器处理,而 if...else... 语句被编译器处理,必然被编译进目标代码

    • 条件编译主要应用于

      • 不同的产品线共用一份代码
      • 区分编译产品的调试版和发布版
    • 示例4:条件编译应用

      • DEBUG 宏的值决定是 Debug 版本的还是 Release 的,所打印的日志不一样
      • HIGH 宏的值决定是高水平的还是水平的版本,所提供的功能不一样
      #include <stdio.h>
      #include "product.h"
      
      #if DEBUG
          #define LOG(s) printf("[%s:%d] %s
      ", __FILE__, __LINE__, s)
      #else
          #define LOG(s) NULL
      #endif
      
      #if HIGH
      void f()
      {
          printf("This is the high level product!
      ");
      }
      #else
      void f()
      {
      }
      #endif
      
      int main()
      {
          LOG("Enter main() ...");
          
          f();
          
          printf("1. Query Information.
      ");
          printf("2. Record Information.
      ");
          printf("3. Delete Information.
      ");
          
          #if HIGH
          printf("4. High Level Query.
      ");
          printf("5. Mannul Service.
      ");
          printf("6. Exit.
      ");
          #else
          printf("4. Exit.
      ");
          #endif
          
          LOG("Exit main() ...");
          
          return 0;
      }
      
      
      //product.h
      #define DEBUG 1
      #define HIGH  1
      
  • 相关阅读:
    Codeforces Beta Round #92 (Div. 2 Only) B. Permutations 模拟
    POJ 3281 Dining 最大流 Dinic算法
    POJ 2441 Arrange the BUlls 状压DP
    URAL 1152 Faise Mirrors 状压DP 简单题
    URAL 1039 Anniversary Party 树形DP 水题
    URAL 1018 Binary Apple Tree 树形DP 好题 经典
    pytorch中的forward前向传播机制
    .data()与.detach()的区别
    Argparse模块
    pytorch代码调试工具
  • 原文地址:https://www.cnblogs.com/bky-hbq/p/13604494.html
Copyright © 2011-2022 走看看