C语言之头文件,宏和条件编译

文章目录


宏(macro)其实就是一个特定的字符串,用来直接替换。 在预处理阶段就会被替换。

  1. 使得程序的可读取有所提高,使用一个又有意义的单词来表示一个无意义数字(某个值)
  2. 方便对代码进行迭代更新, 如果代码中有多处使用到该值, 则只需要修改一处即可(定义)
  3. 提高程序的执行效率,可以使用宏来实现一个比较简单的操作。用来替代函数的调用-有点儿类似内联函数。

使用:

1.无参宏

意味着我们在使用该宏的时候不需要携带额外的参数 。其实就是定义常量

c 复制代码
#define PI 3.14 //定义常量
int main(int argc, char const *argv[])
 {
 printf("%f\n" , PI );
 return 0;
 }

2.有参宏

c 复制代码
#include  <stdio.h>
//定义有参数宏
#define MAX(a,b) a>b?a:b
int main(int argc, char const *argv[])
{
  int  a=1,b=2;
  int c=3,d=5; 
 	printf("%d\n", MAX(a,b));
	printf("%d\n", MAX(c,d));
}

宏只是直接文本替换,没有任何的判断以及语法检查的操作甚至运算

宏在编译的第一个阶段(预处理), 被处理完成,运行的过程中不占用时间(宏已经不存在)宏在预处理的时候直接展开。

  1. 有参宏: 只是文本替换,复杂的运算在里面可能出现问题。

  2. 宏只能写在同一行中(逻辑行),如果迫不得已需要使用多行来写一个宏则可以使用转义字符\把换行符转义掉


条件编译

在C语言中,程序员可以根据不同的条件,有选择性地编译不同的代码块(忽略其它的代码块),从而产生不同的目标文件,这种机制称为条件编译。

借助条件编译,我们可以在同一份源代码中包含针对不同操作系统、硬件架构或功能配置的代码,而无需维护多个独立的源文件。

条件编译是预处理器的功能,不是编译器的功能。条件编译通过以#开头的预处理命令来完成,包括 #if#elif#else#endif#ifdef#ifndef

无值宏

代码定义宏或者通过命令行结尾加-D or -U

c 复制代码
#define  DEV_MODE  //是否是开发模式
int main(int argc, char const *argv[])
{
    #ifdef DEV_MODE
        printf("开发大佬");
    #endif
     #ifndef DEV_MODE
        printf("不是开发大佬");
    #endif
    return 0;
}

有值宏:

预处理器在处理 #if 时:只能识别整数常量(integer constants)支持整数、字符常量(字符会转换为 ASCII 值)不支持字符串比较

c 复制代码
#include <stdio.h>
#define  DEV_MODE01 1  //true
#define  DEV_MODE02 0 //fasle
#define  DEV_MODE03 3  //true
#define  DEV_MODE04 'A' //true
#define  DEV_MODE05 "true" //不能这样定义,只能识别整数常量,没法判断是true还是false
int main(int argc, char const *argv[])
{
   // #是判断它的值是否为true
    #if DEV_MODE01
        printf("我是01!");
    #endif
    
     #if DEV_MODE02
        printf("我是02!");
    #endif
    
     #if DEV_MODE03
        printf("我是03!");
    #endif
     #if DEV_MODE04
        printf("我是04!");
    #endif
    return 0;
}

头文件

C语言得头文件是扩展名为 .h 的文件,包含了函数声明和宏定义,被多个源文件中引用共享。

头文件分为两类:

1.编译器自带的头文件 ---> 用< >括起来

2.程序员编写的头文件 ---> 用" "括起来

例如:

c 复制代码
#include <stdio.h> //编译器自带的头文件
#include "my_lib.h"//程序员编写的头文件

注意:引用头文件相当于复制头文件的内容,到对应的源文件中。
< >" "的区别在于头文件的搜索路径不同:
< >编译器会到系统路径下查找头文件;

而使用" ",编译器首先在当前目录下查找头文件,如果没有找到,再到系统路径下查找,当然你也可以直接给绝对路径
不管是标准头文件,还是自定义头文件,都只能包含变量和函数的声明,不能包含定义,否则在多次引入时会引起重复定义错误。

并且为了防止重复定义的错误,我们会使用条件编译,如下:

c 复制代码
#ifndef HEADER_FILE
#define HEADER_FILE

//头文件的内容

#endif

其实当我们自己写头文件的时候,可以每次直接先把这三行代码写上

这种结构就是通常所说的包装器 ifndef。当再次引用头文件时,条件为假,因为 HEADER_FILE 已定义。此时,预处理器会跳过文件的整个内容,编译器会忽略它。

常见的官方头文件:

相关推荐
txinyu的博客2 小时前
Linux 内存管理
linux·运维·开发语言·c++
m0_748252382 小时前
Ruby 数据类型概述
开发语言·mysql·ruby
天天睡大觉2 小时前
Python学习9
开发语言·python·学习
2301_797312262 小时前
学习Java39天
开发语言·python·学习
Xの哲學2 小时前
Linux自旋锁深度解析: 从设计思想到实战应用
linux·服务器·网络·数据结构·算法
Reenrr2 小时前
C++学习
开发语言·c++·学习
晚风吹长发2 小时前
深入理解Linux中用户缓冲区,文件系统及inode
linux·运维·算法·链接·缓冲区·inode
进阶小白猿2 小时前
Java技术八股学习Day18
java·开发语言·学习
cwplh2 小时前
DP 优化一:单调队列优化 DP
算法