C语言头文件和条件编译

目录

一,条件编译

1,#ifdef,#else ,#endif

2,#ifndef

用法

3,#if和#elif

4,上述指令的嵌套使用

5,#line 和 #error 

6,#pragma

二,#include

1,头文件被包含的方式

1.1,本地文件包含

1.2,库函数包含 

2,嵌套文件包含 


一,条件编译

调试性的代码删除可惜,保留碍事,可以使用条件编译

1,#ifdef,#else ,#endif

类似于if else语句的判断

#ifdef NAME : 如果预处理已经定义了标识符(NAME),则执行#else,#endif 之前的所有指                               令,并编译所有C代码,如果没有定义,且有#else 和 #endif之间的所有代码

预处理不用识别花括号{} ,所以使用#else .#endif 来标记指令块。

#else:根据需要判断是否出现

#endif:必须要存在,结束的标志。

//#ifdef 用法
#define LIKETHIS 
int main()
{
#ifdef LIKETHIS    //如果定义这个标识符就执行下面这句话
    printf("666"); //这里是输出666
#else              //否则就执行下面这句话
    printf("777");
#endif 
}
//如果出现
//#define 的位置不一样结果也不一样
int main()
{
#ifdef LIKETHIS
#define LIKETHIS  
    printf("666"); 
#else
    printf("777"); //这里是输出777
#endif 
}

2,#ifndef

用法与#ifdef类型,但是逻辑与之相反

#ifndef  NAME: 如果没有定义NAME,就执行#else 或 #endif 前面的代码,常用于定义之前                           未定义的常量

用法

  1.  通常包含多个头文件时,其文件中也可能包含相同宏定义,防止相同的宏被重复定义,在首次定义一个宏的头文件中使用#ifndef 指令激活定义,随后其它文件的定义都会被忽略。
    #ifndef SIZE  //如果没有定义
     #define SIZE 100
    #endif
  2. 用较小的代码测试程序
    /* test1.h */  //标识一个文件
    //文件中包含
    #ifndef SIZE
     #difinf SIZE 100 
    #endif
    
    /* test2.h */ //标识另一个文件
    //文件中包含
    #define SIZE 10 
    #include "test1.h"
    //先定义SIZE ,SIZE被设置成10 ,进入test1.h的时候
    //#ifndef 不会执行 

3,#if和#elif

 #if : 后跟整型常量表达式,如果表达式为非零,则表达式为真。可以使用关系运算符和逻辑         运算符

 #if 很像 if 

#if MAX == 1 //判断是否为真 ,真执行 ,否结束
 #include "test.h"
#endif

 也可以按照 if else 的形式 使用 #elif

#if MAX == 1
  #include "test1.h" 
#elif MAX == 6
  #include "test2.h"
#else
  #include "test3.h"
#endif
//这种用法类似于 if ,else if ,else ;

也可以用来判断名称是否被定义:

//判断名称有没有被使用
#if define (NAME1)    //如果定义了 NAME1 
    #include "test1.h"
#elif define (NAME2) 
    #include "test2.h"
#else
    #include "test3.h"
#enfif
//仍然和 if else 语句类似的 用法
//这种方式相当于使用 #ifdef
#ifdef NAME1
    #include "test1.h"
#endif

//也可以这样判断
#if !define (NAME!)
    #include "test1.h"
…………
#endif
//这种方式相当于使用 #ifndef
#ifndef NAME1
    #include "test1.h"

4,上述指令的嵌套使用

简单嵌套直接上代码:

#if defined (NAME1)
    #ifdef NAME2
       #include"test1.h"
    #endif
    #ifdef NAME3
       #include "test2.h"
    #endif 
#elif defined (STU1)
    #ifndef STU2
       #include "test3.h"
    #endif
#else
    #if  !defined(STU3)
       #include "test4.h"
     #endif 
#endif
//这段代码知识演示可以嵌套没有实际意义

5,#line 和 #error 

 #line 指令重置__LINE__ 和__FILE__ 宏 报告的行和文件名

使用:

#line 1000 //把当前的行号重置为1000
#line 10 "test1.h" //把行号重置为 10 ,文件名重置为 test1.h 

 #error 指令让预处理器发出一条错误消息,该消息包含指令中的文本,如果可能的话,会中断编译过程

使用:

#if __STDC_VERSION__ != 1
   #error NOT c11
#endif
//会根据编译器的版本输出

6,#pragma

设定编译器的状态或者是指示编译器完成一些特定的动作,在保持与C和C++语言完全兼容的情况下,给出主机或操作系统专有的特征。依据定义,编译指示是机器或操作系统专有的,且对于每个编译器都是不同的。

//让编译器支持 C9X
#pragma c9x on

还提供了_pragma 预处理运算符:把字符串转换成普通的编译指示

_pragma("zheshiyiduanshenqidedaima")
//等价于
#pragme zheshiyiduanshengjidedaima 

//因为_pragma运算符不使用#,所以可以当作是宏展开的一部分
#define PRAGMA(X) _pragma(#X)
#define LIMRG(X) PRAGMA(jiu xiang zhe yang X)

//有的编译器可能无法使用 _pragma

二,#include

1,头文件被包含的方式

1.1,本地文件包含

   #include "text.h"    ,对本地头文件使用  双引号  (" ")进行包含

查找策略:现在源文件所在的目录下查找,如果该头文件未找到,编译器就像查找库函数头文件                      一 样,在标准位置查找,如果还是找不到编译器就会报错

1.2,库函数包含 

#include <stdio.h> ,对库函数头文件 使用 <> 进行包含

查找策略:直接去标准路径下取查找,如果找不到就提示错误

注:对库文件也可以使用"" 双引号包含,但是会降低位查找的效率,也不容易区分是库文件还是           本地文件 

2,嵌套文件包含 

多个文件使用一个公共模块,造成文件的重复

使用条件编译解决

  1. 每个头文件的开头写:
    #ifndef __TEST_H__
      #define __TEST_H__
        //头文件内容
    #endif
    
  2. 使用 #pragma once 标识只编译一次 可以解决


  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值