当前位置: 首页 > news >正文

c/c++的include机制简述

一 引言

做c/c++编程的对#include指令都不会陌生,绝大多数也都知道如何使用,但我相信仍有人对此是一知半解,

C:
#include <stdio.h>C++:
#include <iostream>


表示包含C/C++标准输入头文件。包含指令不仅仅限于.h头文件,可以包含任何编译器能识别的C/C++代码文件,包括.c,.hpp,.cpp,.hxx,.cxx等,甚至.txt,.abc等等都可以

二 名词解释

preprocess
预处理:为方便编译器处理而设置的一种机制,包括一些常用预处理指令和语句,我们统称为预处理系统。
如#include #define #if...#else...#endif #pragma等
这些指令的实现是由编译器来决定的(implementation specified)

提到预处理指令,顺便说一下头文件防止重复包含的2种方法

1 保护宏:

#ifndef _ABCDE_H
#define _ABCDE_H/*
代码部分
*/#endif

在被包含过一次之后,宏_ABCDE_H已经有了,下次再碰到就会略过从#define _ABCDE_H开始到#endif之间的代码
还有一种特定编译器支持的指令:

2 #pragma once

能保证该文件(物理上的)只被编译一次,也能起到防止重复包含的作用
但这2种方式是有区别的:
1)Macro guard可移植性好,绝大多数编译器都支持,而且万一不小心拷贝了几分相同的代码也不会出问题,但你得确保这个宏名不会与其他的宏冲突,否则等编译器报出一大堆错误的时候你可能会觉得莫名其妙;
2)#pragma once指令简单,它能保证该文件(物理上的)只被编译一次,不用去费劲的想不同的宏名,但如果有几份该文件的拷贝,显然起不到作用。

declaration
声明:指将一个名称引入当前编译单元,或者重新声明一个前面已经声明过的名称,声明指定了如何解释一个名称和该名称具有的属性;
例如:

int main(void)
{// 声明了变量a,类型为intint a;// 声明了变量pa,类型为指向int型的指针类型int *pa;
}

definition
定义:除了以下情况,声明就是定义

  1. 声明函数但不包括函数体;
  2. 声明包含extern链接限定符,例如:extern int a;
  3. 声明既没有初始化语法,也没有函数体;
  4. 类声明中声明静态数据成员;
  5. 类名字声明;
  6. typedef声明;
  7. using声明或者using指令;

以上情况适用于C具有的特征,C++则完全适用,一般来说定义要为其对象分配或预留存储空间,而声明则不用。


translation unit
编译单元:一个源文件,.c .cpp等和它所包含的文件一起,在经过预处理之后形成一个源码文件,标准称之为translation unit(编译单元)包括一系列的声明和定义;一个program(程序)由一个或多个编译单元组成。编译器将各个翻译单元编译为目标代码(.obj),通过连接器(linker)将这些编译后的编译单元(即目标代码)连接成完整的指令序列(可执行文件、静态库、动态库等)。


one definition rule
一次定义规则:是指定义在所有进入连接的编译单元中只能有一次。


3.观点、例子

头文件只放声明:

example_a.h:void function();example_a.cpp:#include "example_a.h"void function()
{}

被包含的文件可以使用任意扩展名:

只要是用符合标准的代码编写的文本文件,就可以使用#include来进行包含,包括.cpp .c等常见的源文件扩展名;

example_b_1.bvoid function();example_b_1.cpp:#include "example_b_1.b"
void function()
{}example_b_2.bvoid function1();
void function2();example_b_21.cpp:void function1()
{}example_b_22.cpp:#include "example_b_1.b"
#include "example_b_21.cpp"
void function2()
{}

上面的例子中,example_b_21.cpp仅被包含在xample_b_22.cpp中,不再被其他的文件包含,而且不加入工程中;

标准头文件的使用

最新的C++标准库中的一切内容都被放在名字空间std中(名字空间中的内容对外是不可见的),但是带来了一个新问题,无数现有的C++代码都依赖于使用了多年的伪标准库中的功能,如声明在<iostream.h>等头文件中的功能,使用std包装标准库导致现有代码的不可用,为了兼容这种情况,标准委员会为包装了std的那部分标准库创建了新的头文件,新的头文件的文件名与旧的一样,只是没有.h这个后缀,如<iostream.h>就变成了<iostream>。对于C头文件,采用同样的方法,但还在每个头文件名前加了字符c,如<string.h>就变成了<cstring>,<stdio.h>变成了<cstdio>。最好使用新的文件头,使用新的文件头的C++程序,需要使用using namespace std或者using namespace std::指定的类名,等方法来使需要的类对于我们的代码可视。
 


 

相关文章:

c/c++的include机制简述

一 引言 做c/c编程的对#include指令都不会陌生&#xff0c;绝大多数也都知道如何使用&#xff0c;但我相信仍有人对此是一知半解&#xff0c; C: #include <stdio.h>C: #include <iostream> 表示包含C/C标准输入头文件。包含指令不仅仅限于.h头文件&#xff0c;可…...

YOLOv5算法改进(16)— 增加小目标检测层 | 四头检测机制(包括代码+添加步骤+网络结构图)

前言:Hello大家好,我是小哥谈。小目标检测层是指在目标检测任务中用于检测小尺寸目标的特定网络层。由于小目标具有较小的尺寸和低分辨率,它们往往更加难以检测和定位。YOLOv5算法的检测速度与精度较为平衡,但是对于小目标的检测效果不佳,根据一些论文,我们可以通过增加检…...

【计网 EMail】计算机网络 EMail协议详解:中科大郑烇老师笔记 (五)

目录 0 引言1 电子邮件EMail1.1 组成1.2 SMTP协议1.3 案例&#xff1a;Alice给Bob发送报文1.4 SMTP总结1.5 邮件报文格式1.6 POP3协议和IMAP协议 &#x1f64b;‍♂️ 作者&#xff1a;海码007&#x1f4dc; 专栏&#xff1a;计算机四大基础专栏&#x1f4dc; 其他章节&#xf…...

算法随想录算法训练营第四十三天|300.最长递增子序列 674. 最长连续递增序列 718. 最长重复子数组

300.最长递增子序列 题目&#xff1a;给你一个整数数组 nums &#xff0c;找到其中最长严格递增子序列的长度。子序列是由数组派生而来的序列&#xff0c;删除&#xff08;或不删除&#xff09;数组中的元素而不改变其余元素的顺序。例如&#xff0c;[3,6,2,7] 是数组 [0,3,1,…...

Nginx配置限流

Nginx配置限流 Nginx有限流功能&#xff0c;是基于漏桶算法实现的 limit_req_zone是配置在http模块中的 #设置限流 zone用来定义ip状态和url访问频率的共享区域&#xff0c;其中mylimit为区域名称&#xff0c;冒号后为区域大小&#xff0c;16000个IP地址的状态信息大约是1M&am…...

【SA8295P 源码分析 (四)】25 - QNX Ethernet MAC 驱动 之 emac_isr_thread_handler 中断处理函数源码分析

【SA8295P 源码分析】25 - QNX Ethernet MAC 驱动 之 emac_isr_thread_handler 中断处理函数源码分析 一、emac 中断上半部:emac_isr()二、emac 中断下半部:emac_isr_thread_handler()2.1 emac 中断下半部:emac_isr_sw()系列文章汇总见:《【SA8295P 源码分析 (四)】网络模块…...

C#,数值计算——分类与推理Phylo_clc的计算方法与源程序

1 文本格式 using System; using System.Collections.Generic; namespace Legalsoft.Truffer { public class Phylo_clc : Phylagglom { public override void premin(double[,] d, int[] nextp) { } public override double dminfn(double[…...

力扣第455题 分发饼干 c++ 贪心 经典题

题目 455. 分发饼干 简单 相关标签 贪心 数组 双指针 排序 假设你是一位很棒的家长&#xff0c;想要给你的孩子们一些小饼干。但是&#xff0c;每个孩子最多只能给一块饼干。 对每个孩子 i&#xff0c;都有一个胃口值 g[i]&#xff0c;这是能让孩子们满足胃口的饼干…...

Netty系列教程之NIO基础知识

近30集的孙哥视频课程&#xff0c;看完一集整理一集来的&#xff0c;内容有点多&#xff0c;请大家放心食用~ 1. 网络通讯的演变 1.1 多线程版网络通讯 在传统的开发模式中&#xff0c;客户端发起一个 HTTP 请求的过程就是建立一个 socket 通信的过程&#xff0c;服务端在建立…...

【题解 树形dp 拆位】 树上异或

「KDOI-06-S」树上异或 题目描述 给定一棵包含 n n n 个节点的树&#xff0c;第 i i i 个点有一个点权 x i x_i xi​。 对于树上的 n − 1 n-1 n−1 条边&#xff0c;每条边选择删除或不删除&#xff0c;有 2 n − 1 2^{n-1} 2n−1 种选择是否删除每条边的方案。 对于…...

SpringBoot项目访问后端页面404

检查项目的路径和mapper映射路径没问题后&#xff0c;发现本级pom文件没有加入web启动模块的pom文件中 maven做项目控制时&#xff0c;要注意将maven模块加入到web启动模块中...

设计模式-综合应用(一)

介绍 使用jQuery做一个模拟购物车的示例 用到的设计模式 工厂模式 单例模式装饰器模式 观察者模式状态模式 模板方法模式 代理模式 UML类图...

大数据Flink(一百):SQL自定义函数(UDF)和标量函数(Scalar Function)

文章目录 SQL自定义函数(UDF)和标量函数(Scalar Function)...

14、Set 和 Map 数据结构

文章目录 14、Set 和 Map 数据结构1. Set1.1 基本用法☆☆☆ 值唯一&#xff0c;没有重复的值☆☆☆ 接受数组、具有 iterable 接口的数据结构☆☆☆ 数组去重1&#xff1a;[...new Set(array)]☆☆☆ 字符串去重&#xff1a;[...new Set(ababbc)].join()☆ 两个对象总是不相等…...

数据结构与算法设计分析——动态规划

目录 一、动态规划的定义二、动态规划的基本要素和主要步骤&#xff08;一&#xff09;最优子结构&#xff08;二&#xff09;重叠子问题 三、贪心法、分治法和动态规划的对比&#xff08;一&#xff09;贪心法&#xff08;二&#xff09;分治法&#xff08;三&#xff09;动态…...

PHPExcel 字母列不够用,针对 AA、AB、AC ... ZZ 这样的列

在PHPExcel 导出功能中&#xff0c;如果字段超过26个字母时&#xff0c;会出现字母不够用A~Z后 AA~AZ来添加后续字段 php中&#xff0c;chr() 函数从指定 ASCII 值返回字符&#xff0c;可以自定义一个方法来返回对应的字母 // $num 列数 1,2,3,4,5,6,7...... function getCol…...

fastdds源码编译安装

如何根据源码编译 fastdds 如何根据源码编译 fastdds 这里是为了根据源码编译一个 fastdds 。 fastdds 依赖 fastcdr Asio TinyXMl2 下载 fastdds 源码 git clone gitgithub.com:eProsima/Fast-DDS.git 进入 下载好的 fastdds 中执行 git submodule update --init --recurs…...

第二证券:风电概念强势拉升,威力传动“20cm”涨停,双一科技等大涨

风电概念20日盘中强势拉升&#xff0c;到发稿&#xff0c;威力传动“20cm”涨停&#xff0c;双一科技涨超17%&#xff0c;顺发恒业亦涨停&#xff0c;金雷股份、大金重工涨约7%&#xff0c;新强联、海力风电涨超5%。 音讯面上&#xff0c;9月以来江苏、广东海风项目加快推动&a…...

DataFrame窗口函数操作

文章最前&#xff1a; 我是Octopus&#xff0c;这个名字来源于我的中文名--章鱼&#xff1b;我热爱编程、热爱算法、热爱开源。所有源码在我的个人github &#xff1b;这博客是记录我学习的点点滴滴&#xff0c;如果您对 Python、Java、AI、算法有兴趣&#xff0c;可以关注我的…...

【德哥说库系列】-RHEL8环境源码编译安装MySQL8.0

&#x1f4e2;&#x1f4e2;&#x1f4e2;&#x1f4e3;&#x1f4e3;&#x1f4e3; 哈喽&#xff01;大家好&#xff0c;我是【IT邦德】&#xff0c;江湖人称jeames007&#xff0c;10余年DBA及大数据工作经验 一位上进心十足的【大数据领域博主】&#xff01;&#x1f61c;&am…...

Debian系统简介

目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版&#xff…...

IGP(Interior Gateway Protocol,内部网关协议)

IGP&#xff08;Interior Gateway Protocol&#xff0c;内部网关协议&#xff09; 是一种用于在一个自治系统&#xff08;AS&#xff09;内部传递路由信息的路由协议&#xff0c;主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...

python如何将word的doc另存为docx

将 DOCX 文件另存为 DOCX 格式&#xff08;Python 实现&#xff09; 在 Python 中&#xff0c;你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是&#xff0c;.doc 是旧的 Word 格式&#xff0c;而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...

OpenLayers 分屏对比(地图联动)

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能&#xff0c;和卷帘图层不一样的是&#xff0c;分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...

Device Mapper 机制

Device Mapper 机制详解 Device Mapper&#xff08;简称 DM&#xff09;是 Linux 内核中的一套通用块设备映射框架&#xff0c;为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程&#xff0c;并配以详细的…...

基于Java Swing的电子通讯录设计与实现:附系统托盘功能代码详解

JAVASQL电子通讯录带系统托盘 一、系统概述 本电子通讯录系统采用Java Swing开发桌面应用&#xff0c;结合SQLite数据库实现联系人管理功能&#xff0c;并集成系统托盘功能提升用户体验。系统支持联系人的增删改查、分组管理、搜索过滤等功能&#xff0c;同时可以最小化到系统…...

JVM 内存结构 详解

内存结构 运行时数据区&#xff1a; Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器&#xff1a; ​ 线程私有&#xff0c;程序控制流的指示器&#xff0c;分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 ​ 每个线程都有一个程序计数…...

Java编程之桥接模式

定义 桥接模式&#xff08;Bridge Pattern&#xff09;属于结构型设计模式&#xff0c;它的核心意图是将抽象部分与实现部分分离&#xff0c;使它们可以独立地变化。这种模式通过组合关系来替代继承关系&#xff0c;从而降低了抽象和实现这两个可变维度之间的耦合度。 用例子…...

【FTP】ftp文件传输会丢包吗?批量几百个文件传输,有一些文件没有传输完整,如何解决?

FTP&#xff08;File Transfer Protocol&#xff09;本身是一个基于 TCP 的协议&#xff0c;理论上不会丢包。但 FTP 文件传输过程中仍可能出现文件不完整、丢失或损坏的情况&#xff0c;主要原因包括&#xff1a; ✅ 一、FTP传输可能“丢包”或文件不完整的原因 原因描述网络…...

Spring Boot + MyBatis 集成支付宝支付流程

Spring Boot MyBatis 集成支付宝支付流程 核心流程 商户系统生成订单调用支付宝创建预支付订单用户跳转支付宝完成支付支付宝异步通知支付结果商户处理支付结果更新订单状态支付宝同步跳转回商户页面 代码实现示例&#xff08;电脑网站支付&#xff09; 1. 添加依赖 <!…...