预编译(3)

news2025/1/10 11:12:56

目录

命名约定:

#undef

命令行定义

条件编译

常见的条件编译指令

 头⽂件的包含

头⽂件被包含的⽅式:

本地⽂件包含 

库⽂件包含

嵌套文件包含 


命名约定:

一般来讲函数的宏的使用语法很相似。所以语言本身没法帮我们区分二者那我们平时的一个习惯是:

  • 把宏名全部大写
  • 函数名不要全部大写

#undef

  1. 这条指令用于移除一个宏定义 。 
  2. 如果现存的一个名字需要被重新定义,那么它的旧名字首先要被移除。

 

命令行定义

许多C的编译器提供了一种能力,允许在命令行中定义符号。

用于启动编译过程。

例如:

  • 当我们根据同一个源文件要编译出一个程序的不同版本的时候,这个特性有点用处。
  • 假定某个程序中声明了一个某个长度的数组,如果机器内存有限,我们需要一个很小的数组,但是另外一个机器内存大些,我们需要个数组能够大些。
int main()
{
   int arr[sz;int i = 0;
   for(i=0; i<SZ; i++)
   {
       arr[i] = i;
   }
   
   //打印
   for(i=0; i<SZ; i++)
   {
      printf("%d",arr[i]);
   }

   return 0;
}

 直接编译会报错,且这个只有在Linux中使用。

使用了命令行代码,对SZ进行的定义,指定为一个数 

这就是类似于一种变长数组,数组的大小是一个变量值,变量值可以随意更改,而这个是在Linux中进行指定数组大小的 。

条件编译

 就是  满足条件就编译,不满足条件放弃编译,类似于判断语句或者判断条件。

只有满足2==3才会进入下一步也就是printf("hehe\n")

预编译前后对比

 

 

常见的条件编译指令

1.
#if 常量表达式
 //...
#endif
//常量表达式由预处理器求值。
如:
#define __DEBUG__ 1
#if __DEBUG__
 //..
#endif

2.多个分⽀的条件编译
#if 常量表达式
 //...
#elif 常量表达式
 //...
#else
 //...
#endif

3.判断是否被定义
#if defined(symbol)
#ifdef symbol
#if !defined(symbol)
#ifndef symbol


4.嵌套指令
#if defined(OS_UNIX)
 #ifdef OPTION1
 unix_version_option1();
 #endif
 #ifdef OPTION2
 unix_version_option2();
 #endif
#elif defined(OS_MSDOS)
 #ifdef OPTION2
 msdos_version_option2();
 #endif
#endif

 头⽂件的包含

头⽂件被包含的⽅式:

本地⽂件包含 

#include "filename"

查找策略:先在源⽂件所在⽬录下查找,如果该头⽂件未找到,编译器就像查找库函数头⽂件⼀样在 标准位置查找头⽂件。 如果找不到就提⽰编译错误。(两种方法)

库⽂件包含

#include <filename.h>

查找策略:查找头⽂件直接去标准路径下去查找,如果找不到就提⽰编译错误。

库文件的包含方式因为查找次数的原因,可以写出本地文件包含的方式,但是因为本地文件包含方式只有在第二次查找才会去标准库中进行搜擦,所以效率会慢很多。

嵌套文件包含 

出现多个头文件的包含。

如:

 

而在预编译中,函数申明的次数可以看出,这种头文件的重复使用,会出现多次函数声明 。

如果直接这样写,test.c⽂件中将add.h包含5次,那么add.h⽂件的内容将会被拷⻉5份在test.c中。

如果add.h ⽂件⽐较⼤,这样预处理后代码量会剧增。

如果⼯程⽐较⼤,有公共使⽤的头⽂件,被⼤家 都能使⽤,⼜不做任何的处理,那么后果真的不堪设想。

如何解决头⽂件被重复引⼊的问题? 

 答案:条件编译。

 每个头⽂件的开头写:

#ifndef __TEST_H__
#define __TEST_H__
//头⽂件的内容
#endif //__TEST_H_

 或

 #pragma once

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1053769.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

代码随想录-哈希表|ACM模式

目录 前言&#xff1a; &#xff08;1&#xff09;基本概念 &#xff08;2&#xff09;常见的三种哈希结构 242.有效字母的异位词 题目描述&#xff1a; 输入输出描述&#xff1a; 思路和想法: 349. 两个数组的交集 题目描述&#xff1a; 输入输出描述&#xff1a; …

Mac上如何修复损坏的音频?试试iZotope RX 10,对音频进行处理,提高音频质量!

iZotope RX 10是一款由iZotope公司开发的音频修复和编辑软件。它被广泛用于电影、电视、音乐和游戏等行业的音频后期制作&#xff0c;以及声音设计和修复工作。 在RX 10中&#xff0c;iZotope从头开始重新设计了全新的Repair Assistant修复助手&#xff0c;并且推出了相应的修…

嵌入式学习笔记(40)看门狗定时器

7.5.1什么是看门狗、有何用 (1)看门狗定时器和普通定时器并无本质区别。定时器可以设定一个时间&#xff0c;在这个时间完成之前定时器不断计时&#xff0c;时间到的时候定时器会复位CPU&#xff08;重启系统&#xff09;。 (2)系统正常工作的时候当然不希望被重启&#xff0…

【小沐学前端】Node.js实现基于Protobuf协议的UDP通信(protobuf.js)

文章目录 1、简介1.1 node1.2 Protobuf 2、下载和安装2.1 node2.2 Protobuf2.2.1 安装2.2.2 工具 3、node 代码示例3.1 HTTP3.2 UDP单播3.4 UDP广播 4、Protobuf 代码示例4.1 例子: awesome.proto4.1.1 加载.proto文件方式4.1.2 加载.json文件方式4.1.3 加载.js文件方式 4.2 例…

vSAN7.0更换硬盘步骤

更换容量盘 预先检查 查看故障硬盘 清单->集群->监控->vsan->skyline运行->物理磁盘->运维运行状况 检查数据同步状态 清单->集群->监控->vsan->重新同步对象&#xff0c;数值全为0表示未重建。 数据迁移检查 清单->集群->监控->…

推荐算法——Apriori算法原理

0、前言&#xff1a; 首先名字别读错&#xff1a;an pu ruo ao rui 【拼音发音】Apriori是一种推荐算法推荐系统&#xff1a;从海量数据中&#xff0c;帮助用户进行信息的过滤和选择。主要推荐方法有&#xff1a;基于内容的推荐、协同过滤推荐、基于关联规则的推荐、基于知识的…

八大排序源码(含优化)

文章目录 1、直接插入排序2、希尔排序3、选择排序4、冒泡排序5、堆排序6、快速排序快速排序递归实现霍尔法挖坑法前后指针法快速排序小区间优化 快速排序非递归实现 7、归并排序归并排序递归实现归并排序非递归 8、计数排序 大家好&#xff0c;我是纪宁&#xff0c;这篇文章是关…

36.骑士周游算法及其基于贪心算法的优化

概述 骑士周游算法&#xff0c;叫做“马踏棋盘算法”或许更加直观。在国际象棋8x8的棋盘中&#xff0c;马也是走“日字”进行移动&#xff0c;相应的产生了一个问题&#xff1a;“如果要求马 在每个方格只能进入一次&#xff0c;走遍全部的64个方格需要如何行进&#xff1f;”…

【STM32基础 CubeMX】按键的检测

文章目录 前言一、按键原理图分析二、cubeMX配置key GPIO三、代码分析3.1 cubemx生成的代码3.2 1个库函数 四、按键点灯示例代码总结 前言 在嵌入式系统开发中&#xff0c;按键检测是一个基础而重要的任务&#xff0c;特别是在使用STM32系列微控制器的项目中。按键通常被用于与…

C++ - 开放地址法的哈希介绍 - 哈希表的仿函数例子

前言 哈希其实是一种搜索方式&#xff0c;像暴力查找&#xff0c;有序数组的二分查找&#xff0c;二分查找就很快了&#xff0c;可以达到O(log n)。但是有序数组有一个 弊端&#xff0c;就是要先进行排序&#xff0c;这就有消耗&#xff0c;这还好&#xff0c;当要插入删除修改…

Go-Python-Java-C-LeetCode高分解法-第八周合集

前言 本题解Go语言部分基于 LeetCode-Go 其他部分基于本人实践学习 个人题解GitHub连接&#xff1a;LeetCode-Go-Python-Java-C 欢迎订阅CSDN专栏&#xff0c;每日一题&#xff0c;和博主一起进步 LeetCode专栏 本文部分内容来自网上搜集与个人实践。如果任何信息存在错误,欢迎…

UE5.1编辑器拓展【一、脚本化资产行为,通知,弹窗,高效复制多个同样的资产】

目录​​​​​​​ 插件制作 添加新的类&#xff1a;AssetActionUtility 添加新的模块&#xff1a;EditorScriptingUtilities 路径了解 添加debug的头文件 代码【debug.h】内涵注释&#xff1a; 写函数 .h文件 .cpp文件 插件制作 首先第一步是做一个插件&#xff1a…

Flink中序列化RoaringBitmap不同方式的对比

背景 在flink中&#xff0c;我们有时候会使用到RoaringBitmap进行统计计数等操作&#xff0c;而当使用RoaringBitmap时&#xff0c;这就涉及到了最重要的问题&#xff0c;如何序列化&#xff1f;序列化的目的是为了进行网络通信或者状态序列化的目的&#xff0c;本文的重点是比…

根据GWAS数据估算样本量N和使用千人基因组填充maf的参考文献

https://github.com/GenomicSEM/GenomicSEM/wiki/2.1-Calculating-Sum-of-Effective-Sample-Size-and-Preparing-GWAS-Summary-Statistics

【LeetCode热题100】--104.二叉树的最大深度

104.二叉树的最大深度 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) { this.val val; }* TreeNode(int val, TreeNode left, TreeNode right) …

尚硅谷谷粒商城部分报错问题处理

1、启动报错&#xff1a; 内容&#xff1a; org.springframework.beans.factory.BeanCreationException: Error creating bean with name attrAttrgroupRelationController: Lookup method resolution failed; nested exception is java.lang.IllegalStateException: Failed t…

使用prometheus监控java服务

在prometheus官方下载页面没有看到jvm_exproter的下载地址但是官方页面是有推荐下载地址的 访问 Prometheus - Monitoring system & time series database prometheus官方网址 官方推荐地址下载是在github网络访问不方便的可以用下面的网址 wget https://repo1.maven…

【小程序 - 基础】页面导航、页面事件、生命周期、WXS脚本_04

目录 一、页面导航 1. 什么是页面导航 2. 小程序中实现页面导航的两种方式 2.1 声明式导航 2.1.1 导航到 tabBar 页面 2.1.2 导航到非 tabBar 页面 2.1.3 后退导航 2.2 编程式导航 2.2.1 导航到 tabBar 页面 2.2.2 导航到非 tabBar 页面 2.2.3 后退导航 2.3. 导航…

Proxyer实现内网穿透云服务器

Proxyer Proxyer是一个网络代理工具&#xff0c;它可以将本地计算机的网络流量&#xff08;如HTTP、HTTPS、TCP等&#xff09;转发到远程服务器。使用Proxyer可以在本地计算机上建立一个代理服务器&#xff0c;通过代理服务器来访问互联网上的资源。 yum仓库设置 rm -f /etc…

在Ubuntu上通过Portainer部署微服务项目

这篇文章主要记录自己在ubuntu上部署自己的微服务应用的过程&#xff0c;文章中使用了docker、docker-compose和portainer&#xff0c;在部署过程中遇到了不少问题&#xff0c;因为博主也是初学docker-compose&#xff0c;通过这次部署实战确实有所收获&#xff0c;在这篇文章一…