条件编译、版本环境判断、宏、头文件、以及多文件编译相关

条件编译:


    条件语句(if、switch、for、while、do while)会根据条件选择执行哪些代码,预处理器根据条件选择哪些代码参与下一步的编译。

负责条件编译的预处理指令有:   

        #if        #ifdf        #ifndf        #else if        #else         #endif

头文件卫士:
 

        #ifndef FILE_H //判断FILE_H是否存在,不存在则条件为真
        #define FILE_H //定义FILE_H宏
        
        ...
        #endif//FILE_H //#ifndef的结尾


        这个固定搭配写法,一般写在头文件中,防止头文件被重复包含。
        


注释代码:
 

//只能注释单行代码,早期的编译器不支持
/* 多行注释,但不能嵌套*/   //意思是/* /* */ */这种格式是不支持的
#if 1  //0注释,1取消注释
//可注释大块代码,可以嵌套
#endif


        

 版本、环境判断:


        编译器的位数:
            #if _WORDSIZE == 64
            #endif
        操作系统:
            #if __linux__
            #endif
            
            #if __WIN32|__WIN32__|__WIN64__
            #endif
            
        判断gcc还是g++:
            #if __cplusplus
            #else
            #endif

不常用的预处理指令:
 #line:可以设置该代码后面的行数
举例.#line
printf("%d\n",__LINE__);
#error  //在预处理阶段提示错误信息,一旦预处理遇到它,将不再继续编译,不能单独使用,必须与条件判断系统语句配合使用
#warning //在预处理阶段提示警告信息
#pragma GCC poison <标识符> 把标识符设置病毒,禁止在代码中使用
         
每个系统在进入对齐和补齐都有一个最大对齐和补齐字节数n,也就是超出n字节按n字节计算,例如:linux32位系统 n=4,windows32 n=8
        
#pragma pack(n) 设置最大补齐和补齐字节数
设置要求:
1、n < 系统默认 的最大对齐、补齐字节数
2、n必须是2的x次方,也就是必须是1、2、4、8、16这一类的整数
                
        宏函数的边长参数:
            #define func(...) __VA_ARGS__
            注意: 这种用法必须配合,printf/fprintf/sprintf系列支持变长参数函数的使用
            为了保护语法的一致性,可以使用do while 语句包含宏函数的代码
            do{
                
                }while(0)
            1.仅仅只支持字符串常量,不支持可变参数
            #define LOGFUNC(...) (printf(__VA_ARGS__))
            2.仅仅只支持可变参数,不支持字符串常量
            #define LOGSTRINGS(fm, ...) printf(fm,__VA_ARGS__)


                
    在编译时定义宏:


        gcc xxx.c -D ARR_LEN=3
        -D ARR_LEN=3 <=> #define ARR_LEN=3

        
    DEBUG宏:
        专门用于调试程序的宏函数,这种宏函数在程序测试、调试、试运行阶段执行,在程序正式上限阶段不执行。
        一些操作提示,如:xxx操作成功,xxx操作失败,xxx不存在,分配内存的记录、释放内存的记录,这类型消息开发人员、测试人员需要看到,但用户不需要看到
        

  void* _my_malloc(size_t size,const char* file,const char* func,size_t line)
            {
                void* ptr = malloc(size);
                printf("%s %s %u malloc %p  %u byte\n",file,func,line,ptr,size);
                return ptr;
            }
            #ifdef DEBUG
            # define my_malloc(size) _my_malloc(size,__FILE__,__func__,__LINE__)
            #else
            # define my_malloc(size) malloc(size)
            #endif//DEBUG
        
            #ifdef DEBUG
            # define my_free(ptr) do{                                        \
                free(ptr);                                                   \
                printf("%s %s %u free %p\n",__FILE__,__func__,__LINE__,ptr); \
            }while(0)
            #else
            # define my_free(ptr) free(ptr)
            #endif//DEBUG
        
            #ifdef DEBUG
            # define debug(...) do{\
                printf("file:%s func:%s line:%d:",__FILE__,__func__,__LINE__); \
                printf("\33[01;32m");\
                printf(__VA_ARGS__);\
                printf("\33[00m");\
            }while(0)
            #else
            # define debug(...) do{}while(0)
            #endif//DEBUG


    
    多文件编程:


        当程序的业务逻辑越来越复杂,代码量越来越多,就需要多人组成团队协同开发,那么就必须把任务拆分成若干个文件。
        一般的拆分方案:
            main.c 只当做程序的入口,不实现业务逻辑代码。
            
            用于实现程序的具体业务逻辑代码:
            模块名.h  用说明.c文件中有哪些函数、全局变量,也就是函数声明、全局变量声明。
            模块名.c   具体的函数实现,全局变量定义
            
            项目中常用的、通用的工具:宏函数、函数...
            tools.h
            tools.c
            
            只用于类型设计,类型重定义...
            type.h 结构体、联合、枚举、宏常量、宏函数
    
    头文件中可以写什么:
        由于头文件可能会被若干个.c文件包含,那么每包含一次,.c文件中就会有一份头文件中的内容,所以头文件中的内容必须可以重复,因此我们只呵呵在头文件中实现以下内容:
        
        1、头文件卫士
        2、#include 语句
        3、宏常量、宏函数
        4、全局变量的声明(变量的声明可以有多份,但定义只能有一份)
        5、函数声明
        6、结构、联合、枚举复合的类型设计
        7、类型重定义
        
    头文件互相包含、递归包含:


注意:头文件卫士只能解决重复包含的问题,但无法解决相互包含、递归包含的问题。

递归包含举例
                互相包含:
                a.h #include "b.h"
                b.h #include "a.h"
        
        
                递归包含:
                a.h #include "b.h"
                b.h #include "c.h"
                c.h #include "a.h"
        
        解决这种问题的文件,再设计一个.h文件,把他们共用的内存,实现在新的.h文件中,被他们共同包含即可。
    
    多文件编译过程:
        1、gcc xxx.h 检查头文件是否有语法错误,如果没有语法错误会生成xxx.h.gch,检查完毕后改文件要立即删除
        2、gcc -c xxx.c 把.c文件编译成二进制目标文件
        3、gcc *.o 把所有目标文件合成可执行文件,也可以-o 设置可执行文件的名字

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在VSCode中进行C++文件编译时,头文件的关联是非常重要的。以下是一些基本的步骤来确保头文件正确关联: 1. 在源文件中包含头文件:在您的源文件(.cpp文件)中,使用`#include`指令来包含相关头文件。例如,如果您有一个名为`example.h`的头文件,您可以在源文件中添加`#include "example.h"`来关联它。 2. 设置头文件搜索路径:如果您的头文件不在源文件所在的目录中,您需要设置头文件的搜索路径。在VSCode中,可以通过编辑`.vscode/tasks.json`文件中的构建任务来设置编译器的搜索路径。在编译命令中使用`-I`选项来指定头文件的路径。例如:`g++ -I/path/to/header-files main.cpp -o main` 3. 确保头文件和源文件同名:为了方便管理,通常将头文件和源文件命名相同,并使用`.h`和`.cpp`作为扩展名。这样可以更容易地找到和关联相应的头文件和源文件。 4. 使用预编译指令:如果您的头文件用于定义常量、或模板类/函数等,您可能需要在使用它们的源文件中添加适当的预编译指令。例如,如果您在头文件中定义了一个模板类,您需要在使用该类的源文件中添加`template class ClassName<Type>;`来实例化模板。 请注意,具体的步骤和配置可能因您的项目和开发环境而有所不同。您可能需要根据实际情况自定义构建任务和编译选项。 希望这些步骤能帮助您在VSCode中成功进行C++文件编译并正确关联头文件。如有任何问题,请随时向我提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值