C++ 入门(五)— 头文件(Header files)

文章目录

  • 头文件的用途
    • 使用标准库头文件
    • 使用头文件传播前向声明
    • 避免将函数或变量定义放在头文件中
    • 尖括号与双引号
    • VSCode中添加来自其他目录的头文件
  • 头文件保护
    • 标头保护不会阻止标头包含在不同的代码文件中
    • pragma once
    • 总结

头文件的用途

C++ 代码文件(扩展名为 .cpp)并不是 C++ 程序中唯一常见的文件。 另一种类型的文件称为头文件。 头文件通常使用 .h 作为 扩展名。

头文件的主要用途是将声明传播到代码 (.cpp) 文件。

头文件允许我们将声明放在一个位置,然后在需要的地方导入它们。 这可以节省多文件程序中的大量输入。

使用标准库头文件

#include <iostream>//标准库int main()
{std::cout << "Hello, world!";// std::cout   使用标准库头文件return 0;
}

使用头文件传播前向声明

创建三个脚本:
在这里插入图片描述

add.h

int AddFunc(int x, int y); 

add.cpp

#include "add.h" 
int AddFunc(int x, int y)
{return x + y;
}

main.cpp

#include "add.h" 
#include <iostream>int main()
{std::cout << "The sum of 3 and 4 is " << AddFunc(3, 4) << '\n';return 0;
}

当预处理器处理该行时,它会将 add.h 的内容复制到此时的当前文件中。因为我们的 add.h 包含函数 add() 的正向声明,所以该正向声明将被复制到 main.cpp 中。
最终结果是一个程序,其功能与我们在 main.cpp 顶部手动添加转发声明的程序相同。

因此,我们的程序将正确编译和链接。请添加图片描述
然后我们然后按上图进行编译,过程步骤:

  • 编译处理:
    1. 对 add.cpp,add.h 编译处理:
      g++ -c add.cpp add.h
      编译后,会生成 add.o、add.h.gch文件:
      在这里插入图片描述
      此时是乱码的,我们可以通过反编译命令查看 add.o文件信息:
      在命令行执行 objdump -h add.o
      在这里插入图片描述
    2. 以同样的方式对main.cpp 编译处理:
      g++ -c main.cpp
      生成 main.o文件
    3. 链接 add.o和main.o文件
      g++ main.o add.o -o main.exe
      生成 main.exe 文件
      它也是乱码的,我们可以通过反编译命令查看 main.exe文件信息:
      在命令行执行objdump -h main.exe
    4. 最后,运行./main.exe,可以看到输出结果:
      在这里插入图片描述

避免将函数或变量定义放在头文件中

这样做通常会导致违反单一定义规则 (ODR) 的情况,即头文件包含在多个源文件中。
比如,在 add.h文件中:

int AddFunc(int x, int y)
{return x + y;
}

尖括号与双引号

当我们使用尖括号时,我们告诉预处理器这是一个不是我们自己编写的头文件。预处理器将仅在 指定的目录中搜索标头。它们配置为项目/IDE 设置/编译器设置的一部分,通常默认为包含编译器和/或操作系统附带的头文件的目录。预处理器不会在项目的源代码目录中搜索头文件。include directoriesinclude directories

当我们使用双引号时,我们告诉预处理器这是我们编写的头文件。预处理器将首先在当前目录中搜索头文件。如果它在那里找不到匹配的标头,它将搜索 .include directories

VSCode中添加来自其他目录的头文件

对于 GCC/G++ 用户

使用 g++,可以使用 -I 选项指定备用包含目录:
g++ -o main -I/source/includes main.cpp
-I 后面没有空格。

对于 VS Code 用户

在 tasks.json 配置文件中,在“Args”部分添加一个新行:
“-I/source/includes”,

头文件保护

对于头文件,很容易出现头文件中的定义被多次包含的情况。当一个头文件 #includes 另一个头文件(这很常见)时,可能会发生这种情况。

可以通过一种称为标头保护(也称为包含保护)的机制来避免上述问题。标头防护是采用以下形式的条件编译指令:

#ifndef SOME_UNIQUE_NAME_HERE
#define SOME_UNIQUE_NAME_HERE// your declarations (and certain types of definitions) here#endif

#included 此标头时,预处理器会检查之前是否已定义SOME_UNIQUE_NAME_HERE。

所有头文件都应具有标头保护。SOME_UNIQUE_NAME_HERE可以是您想要的任何名称,但按照惯例,它设置为头文件的完整文件名,键入全部大写字母,使用下划线作为空格或标点符号。
例如,square.h 将具有标头保护:

#ifndef SQUARE_H
#define SQUARE_Hint getSquareSides()
{return 4;
}#endif

甚至标准库标头也使用标头保护。如果要查看 Visual Studio 中的 iostream 头文件,则会看到:

#ifndef _IOSTREAM_
#define _IOSTREAM_// content here#endif

标头保护不会阻止标头包含在不同的代码文件中

标头保护的目标是防止代码文件接收受保护标头的多个副本。根据设计,标头保护不会阻止给定的头文件(一次)包含在单独的代码文件中。这也可能导致意外问题。

pragma once

现代编译器支持使用预处理器指令的更简单的替代形式的标头保护:

#pragma once// your code here

#pragma once其用途与标头防护相同:避免多次包含头文件。但它不是标准化的,只是大多数开发人员使用的习惯。

总结

标头防护旨在确保给定头文件的内容不会多次复制到任何单个文件中,以防止重复定义。

重复声明是可以的,但即使头文件由所有声明(无定义)组成,最好还是包含标头保护。

请注意,标头防护不会阻止将头文件的内容(一次)复制到单独的项目文件中。这是一件好事,因为我们经常需要从不同的项目文件中引用给定标头的内容。

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

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

相关文章

基于Java SSM框架实现教师管理系统项目【项目源码】

基于java的SSM框架实现教师管理系统演示 JAVA简介 Java主要采用CORBA技术和安全模型&#xff0c;可以在互联网应用的数据保护。它还提供了对EJB&#xff08;Enterprise JavaBeans&#xff09;的全面支持&#xff0c;java servlet API&#xff0c;JSP&#xff08;java server p…

网络空间测绘在安全领域的应用(下)

3.漏洞感知 漏洞感知能力在当今的网络安全领域是至关重要的&#xff0c;而其核心技术之一是漏洞验证技术。通过对漏洞信息与产品版本的关联&#xff0c;系统能够更准确地感知漏洞&#xff0c;但仅仅依靠这种数据关联会引发一系列问题。 首先&#xff0c;漏洞是程序中存在的隐…

YOLOv5改进:下采样系列 |一种新颖的基于 Haar 小波的下采样HWD,有效涨点系列

💡💡💡本文独家改进:HWD的核心思想是应用Haar小波变换来降低特征图的空间分辨率,同时保留尽可能多的信息,与传统的下采样方法相比,有效降低信息不确定性。 💡💡💡使用方法:代替原始网络的conv,下采样过程中尽可能包括更多信息,从而提升检测精度。 收录 YO…

Java-File类

目录 前言&#xff1a; 1.File类概述 2.File类属性 3.File类构造方法 4.File类普通方法 前言&#xff1a; 在Java中操作文件主要分为&#xff1a;1.文件系统的操作&#xff08;File类&#xff09;、2.文件内容的操作&#xff08;流对象&#xff09;。 本节主要介绍Java中的…

数据加密算法多样化的安全需求

数据加密算法是信息安全领域中非常重要的一环&#xff0c;它能够确保数据在传输和存储过程中的机密性和完整性。随着技术的发展&#xff0c;数据加密算法也在不断地演进和改进&#xff0c;以满足更为复杂和多样化的安全需求。 数据加密算法的基本原理是使用加密密钥和加密算法对…

【计算机网络】Socket的SO_REUSEADDR选项与TIME_WAIT

SO_REUSEADDR用于设置套接字的地址重用。当一个套接字关闭后&#xff0c;它的端口可能会在一段时间内处于TIME_WAIT状态&#xff0c;此时无法立即再次绑定相同的地址和端口。使用SO_REUSEADDR选项可以允许新的套接字立即绑定到相同的地址和端口&#xff0c;即使之前的套接字仍处…

Vim实战:使用Vim实现图像分类任务(一)

文章目录 摘要安装包安装timm 数据增强Cutout和MixupEMA项目结构编译安装Vim环境环境安装过程安装库文件 计算mean和std生成数据集 摘要 论文&#xff1a;https://arxiv.org/pdf/2401.09417v1.pdf 翻译&#xff1a; 近年来&#xff0c;随着深度学习的发展&#xff0c;视觉模型…

JUC并发编程01——进程,线程(详解),并发和并行

目录 1.进程和线程的概念及对比1.进程概述 2.线程3.对比 2.并行与并发1.并发2.并行 3.线程详解3.1.创建和运行线程3.1.1.Thread3.1.2.Runnable结合Thread 创建线程3.1.3.Callable 3.2线程方法APIrun startsleep yieldjoininterrupt打断线程打断 park终止模式 daemon不推荐使用的…

基于Java SSM框架实现校园快领服务系统项目【项目源码+论文说明】计算机毕业设计

基于java的SSM框架实现校园快领服务系统演示 摘要 随着科学技术的飞速发展&#xff0c;各行各业都在努力与现代先进技术接轨&#xff0c;通过科技手段提高自身的优势&#xff1b;对于校园快领服务系统当然也不能排除在外&#xff0c;随着网络技术的不断成熟&#xff0c;带动了…

骨传导耳机的技术原理是什么?和传统耳机相比有哪些优点?

骨传导耳机通过人体骨骼来传递声音&#xff0c;可以绕过耳道和耳膜直接传达音频到听者的内耳&#xff0c;开放双耳的佩戴方式可以在享受音乐或通话的同时保持对周围环境的感知&#xff0c;这种设计在户外活动或运动等场景下的使用尤为实用&#xff0c;可以避免堵塞耳朵&#xf…

CHS_08.2.3.6_1+生产者-消费者问题

CHS_08.2.3.6_1生产者-消费者问题 问题描述问题分析思考&#xff1a;能否改变相邻P、V操作的顺序&#xff1f;知识回顾 在这个小节中 我们会学习一个经典的进程同步互斥的问题 问题描述 并且尝试用上个小节学习的p v操作 也就是信号量机制来解决这个生产者消费者问题 问题的描…

大力说视频号第三课:视频小店

自从腾讯推出视频号之后&#xff0c;大家非常明显的感觉到&#xff0c;视频号正以势不可挡的姿势走向独立发展。那么&#xff0c;依托于微信生态的视频号&#xff0c;未来将迎来哪些精彩发展呢&#xff1f; 让我们一同来揭开“视频号小店”的神秘面纱&#xff0c;了解一下玩法…

有色金属矿山采选智能工厂数字孪生可视化,推进矿采选业数字化转型

有色金属矿山采选智能工厂数字孪生可视化&#xff0c;推进矿采选业数字化转型。随着科技的不断发展&#xff0c;数字化转型已经成为各行各业发展的必然趋势。有色金属矿采选业作为传统工业的重要组成部分&#xff0c;也面临着数字化转型的挑战。为了更好地推进有色金属矿采选业…

百无聊赖之JavaEE从入门到放弃(十七)时间处理相关类

目录 一.Date 时间类 二.DateFormat 类和 SimpleDateFormat 类 三.Calendar 日历类 “时间如流水&#xff0c;一去不复返”&#xff0c;时间是一维的。所以&#xff0c;我们需要一把刻度尺来表达和度 量时间。在计算机世界&#xff0c;我们把 1970 年 1 月 1 日 00:00:00 定…

张维迎《博弈与社会》多重均衡与制度和文化(4)路径依赖的困惑

在前述计算机产品标准化的问题中&#xff0c;有两个纳什均衡&#xff1a;都生产有5.25英寸软盘驱动器的计算机和都生产有3.5英寸软盘驱动器的计算机。假设一开始企业只能生产有5.25英寸软盘驱动器的计算机&#xff0c;生产3.5英寸软盘驱动器计算机的技术随后出现&#xff0c;企…

Next.js如何正确处理跨域问题?

以前一直使用Vue来写前端。去年下半年接手了一个基于React Next.js的项目&#xff0c;于是顺带学习了一下Next.js。由于Next.js的特点&#xff0c;这个项目的前后端是放在一起的。一开始没什么问题&#xff0c;看了半天文档就上手了。 上周我们需要在另一个网页项目中&#x…

C#,桌面游戏编程,数独游戏(Sudoku Game)的算法与源代码

本文包括以下内容&#xff1a; &#xff08;1&#xff09;数独游戏的核心算法&#xff1b; &#xff08;2&#xff09;数独游戏核心算法的源代码&#xff1b; &#xff08;3&#xff09;数独游戏的部分题目样本&#xff1b; &#xff08;4&#xff09;适老版《数独》的设计原则…

C#,哥伦布数(Golomb Number)的算法与源代码

1 哥伦布数&#xff08;Golomb Number&#xff09; 哥伦布数&#xff08;Golomb Number&#xff09;是一个自然数的非减量序列&#xff0c;使得n在序列中正好出现G&#xff08;n&#xff09;次。前几个15的G&#xff08;n&#xff09;值为&#xff1a;1 2 2 3 3 4 4 4 5 5 5 6…

计算机图形学 实验

题目要求 1.1 实验一&#xff1a;图元的生成&#xff1a;直线、圆椭区域填充 你需要完成基本的图元生成算法&#xff0c;包括直线和椭圆。 在区域填充中&#xff0c;要求你对一个封闭图形进行填充。你需要绘制一个封 闭图形&#xff08;例如多边形&#xff09;&#xff0c;并选…

Hadoop3.x基础(3)- MapReduce

来源: B站尚硅谷 目录 MapReduce概述MapReduce定义MapReduce优缺点优点缺点 MapReduce核心思想MapReduce进程常用数据序列化类型MapReduce编程规范WordCount案例实操本地测试提交到集群测试 Hadoop序列化序列化概述自定义bean对象实现序列化接口&#xff08;Writable&#xff…