C语言头文件和条件编译

2023-10-31

目录

一,条件编译

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 标识只编译一次 可以解决


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C语言头文件和条件编译 的相关文章

  • linux运维基础视频教程免费分享!

    linux运维基础视频教程免费分享 linux运维即linux运维工程师 Linux是一套免费使用和自由传播的类Unix操作系统 是一个基于POSIX和UNIX的多用户 多任务 支持多线程和多CPU的操作系统 它能运行主要的UNIX工具软件
  • WPF的MVVM框架Stylet开发文档 17.设计模式支持

    17 设计模式支持 介绍 设计模式 或 设计时 是指当您的项目加载到 Visual Studio XAML 设计器或 Expression Blend 中时 您将看到 XAML 的渲染版本 大多数时候 设计者不会尝试评估您的任何绑定或为它们
  • ip、子网掩码、网关、默认网关

    这里写目录标题 ip 网络地址 主机地址 子网 子网掩码 子网掩码的表示方法 为什么要使用子网掩码 子网掩码的分类 网关 默认网关 ip ip地址 网络地址 主机地址 又称 网络号和主机号 我们把网络号相同的主机称之为本地网络中的主机 网络
  • JVM跨平台原理

    Java有一个其他语言都没有特点 那就是跨平台 跨平台是什么意思呢 我们首先来看看平台是指什么 平台就是指我们计算机的操作系统 例如 Windows Linux Mac等操作系统 跨平台的意思就是Java程序 在一次编译后 在这些平台上都可
  • 混淆技术研究-OLLVM混淆-控制流平坦化(FLA) - WIP

    简介 控制流平坦化通过将程序中的条件分支语句转化为等价的平铺控制流来实现 通常 这包括将原始的分支语句 如if语句 switch语句 中的每个分支提取出来 并将它们放置在一系列连续的基本块中 然后使用一个状态变量或标志来选择要执行的基本块

随机推荐

  • C++ 虚继承和多态性

    类体系的函数重载 在一个类中声明重载 派生类定义和基类同名 同参数的函数 即在派生类中重载 类指针的关系 基类指针指向基类对象 派生类指针指向派生类对象 基类指针指向派生类对象 派生类指针指向基类对象 基类指针可以直接指向派生类对象 但是使
  • 线程的锁问题

    1 公平锁与非公平锁 公平锁 排队进行 非公平锁 抢占式 同步代码块 同步方法都属于非公平锁 显式锁Lock可以指定是否为公平锁 true 公平锁 false 给公平锁 默认 private Lock l new ReentrantLock
  • 7.反引号 ` `

    1 反引号第一种使用情况 fun main 登录功能 2021年8月8日测试环境下 测试登录功能 需求编码人是Derry Derry 123456 private fun 登录功能 2021年8月8日测试环境下 测试登录功能 需求编码人是D
  • selenium自动化测试实战案例哔哩哔哩信息至Excel

    文章目录 前言 明确目标 最终效果 开发环境 思路分析 实现步骤 运行效果 以下是全部代码 前言 最近在B站学习知识 于是看完了视频就想着练习一下巩固一下知识 就地取材的做了个B站selenium小项目 感觉还挺适合新手入门的 于是迫不及待
  • LeetCode-410.最小区间、滑动窗口、双指针

    你有 k 个升序排列的整数数组 找到一个最小区间 使得 k 个列表中的每个列表至少有一个数包含在其中 我们定义如果 b a lt d c 或者在 b a d c 时 a lt c 则区间 a b 比 c d 小 示例 1 输入 4 10 1
  • 【chineseocr_lite】踩的坑

    chineseocr lite版本 https github com ouyanghuiyu chineseocr lite git 最重要的电脑环境 v100服务器 cuda10 python3 6 环境对了就成功90 另本环境是cuda
  • UWB自组网定位方案_基于UWB技术的消防应急救援定位解决方案

    目前国内应急救援市场都是基于被动定位应用 在特殊情况下救援也大多处于单兵作战的情况 并不能及时知道自己和自己组员的位置信息和状态 且没有场景感知和室内外一体位置信息结合 使相关救援人员处于更加危险境地 本篇就带大家详细了解一下微能信息针对消
  • JDBC中的Connection

    jdbc中的Connection连接基本用法 package Jdbc import java sql Connection import java sql DriverManager import java sql SQLExceptio
  • Google Sign In error 12500

    接入Google登录遇到12500报错 网上查到的原因是后台配置包的签名哈希值不正确 但是我们的应用并没有使用firebase管理 尝试多次之后终于找到了解决方法 在开发者后台应用管理界面 创建一个新的凭据 类型为Andorid 该凭据下包
  • 层层优化重复代码,我又搞了一个通用模板

    后端思维 最近工作中 我通过层层优化重复代码 最后抽出个通用模板 因此跟大家分享一下优化以及思考的过程 我会先造一个相似的例子 然后一步步带大家如何优化哈 看完一定会有帮助的 优化前的例子 第一步优化 抽取公用方法 第二步优化 反射对比字段
  • 除了李飞飞,那些影响 AI 技术发展的女性工程师

    自 1911 年以来 国际妇女节已经走过了一个多世纪 我们为一个更平等的世界努力过 并且仍将继续努力 近年来 随着数据科学和机器学习的迅猛发展 AI 从业者的需求激增 然而 人工智能领域女性从业者的数量远低于男性 根据 Wired 和 El
  • 〖Web全栈开发②〗—网络编程基础(下)

    Web全栈开发 网络编程基础 下 一 TCP 网络应用程序开发流程 1 TCP 网络应用程序开发流程的介绍 2 TCP 客户端程序开发流程的介绍 3 TCP 服务端程序开发流程的介绍 4 小结 二 socket之send和recv原理剖析
  • Java BIO API及代码测试

    文章目录 0 网络编程 1 JAVA最初的网络应用 BIO 1 1服务端代码编写 1 2客户端代码编写 1 3升级版服务端代码 支持同时处理多连接 1 4再次升级服务端代码 支持浏览器请求 2 拓展学习 ServerSocket 类 及AP
  • 蓝桥杯算法提高VIP-队列操作

    题目 题目链接 题解 模拟队列 代码 include
  • 删除vim打开文件末尾的^M

    最近在Windows下写了一个shell脚本 拿到Linux下执行的时候一直提示找不到文件 但是文件明明就存在 在Linux用vi vim 打开脚本 文件内容不为空 仔细检查脚本内容也没有出错 只是每行 末尾 多出来一个 M 符号 去掉这个
  • Qt使用QTcpSocket及QTcpServer传输文件

    服务端具体代码如下 h include
  • Python学习笔记合集(Pyhton基础总结)

    Python学习笔记合集 Python学习笔记合集 Pyhton基础总结 第一天主要讲了Python基本语句 上 第二天主要讲了Python基本语句 下 第三天主要讲了import导包 库 和Python条件语句 第四天主要讲了Python
  • 闭包【JavaScript基础面试题】

    闭包的定义 如果一个函数能访问外部的变量 那么就形成了一个闭包 闭包形成的原理 当一个普通函数执行结束之后 函数内的变量会被全部销毁 垃圾回收 但是 如果某些变量在函数外部会被用到 那么该变量就不会被销毁 因此形成了闭包 可以看下面的例子
  • [INFO] [copilotIgnore] inactive,github copilot没反应怎么解决

    在使用github copilot的时候 插件不工作 后台出现了这种输出 这种情况下就是它的激活出现了问题 如果账号的使用权没有问题的话 就将该插件disable之后再重新enable 重新观察输出 就会看到copilot在重新链接引擎了
  • C语言头文件和条件编译

    目录 一 条件编译 1 ifdef else endif 2 ifndef 用法 3 if和 elif 4 上述指令的嵌套使用 5 line 和 error 6 pragma 二 include 1 头文件被包含的方式 1 1 本地文件包含