五分钟c++ (7)头文件(header file)

C++头文件包含规则详解

在 C++ 中,使用 #include加尖括号 < > 或者双引号 "" 包含头文件。

< > 或者双引号 ""的主要区别在于编译器查找头文件的路径不同。现代 C++ 编程中,.h 扩展名通常表示 C 语言的头文件,而 C++ 标准库头文件则通常不带扩展名。


尖括号 < >

当你使用尖括号包含头文件时,例如 #include <iostream>,编译器会按照预定义的系统路径去查找。这些路径通常包括:

  • C++ 标准库的头文件路径。
  • 编译器自带的头文件路径。
  • 操作系统或特定库(如 Boost、Qt 等)安装的公共头文件路径。

这种方式主要用于包含标准库头文件第三方库的头文件。它告诉编译器:“这是一个系统级别的库文件,去标准位置找就行了。”

问题来了,那尖括号引用的文件到底存在什么地方? 具体在哪里,取决于你的编译器和操作系统。这些路径通常在编译器的环境变量配置文件中定义

常见的查找路径

1. 编译器默认路径

每个编译器(如 GCC/G++, Clang, MSVC)都有一组默认的头文件搜索路径。这些路径通常包括:

  • 标准库路径:例如 /usr/include/usr/local/include(在 Linux 和 macOS 上)。
  • 编译器自身附带的库路径:例如 GCC 编译器可能会在 /usr/lib/gcc/.../include 目录下查找。
  • 特定框架或 SDK 路径:例如,如果你在 Windows 上使用 Visual Studio,它会自动配置查找 Windows SDK 的头文件路径。

2. 环境变量

一些工具链会使用环境变量来指定额外的搜索路径。最常见的可能是 CPLUS_INCLUDE_PATHCPATH。你可以通过设置这些环境变量来告诉编译器去哪里查找头文件。

3. 编译命令中的参数

这是最直接的方式。你可以在编译时通过添加特定的命令行参数来手动指定头文件路径。

  • GCC/G++ 和 Clang:使用 I 参数。例如:Bash

    g++ my_program.cpp -I/path/to/my/headers

    这个命令告诉编译器除了默认路径外,还要去 /path/to/my/headers 目录查找头文件。

如何查看编译器正在使用的路径?

如果你想确切知道你的编译器到底在哪些路径下查找头文件,你可以用以下方法:

  • GCC/G++ 和 Clang:使用 v 参数可以输出编译器的详细信息,包括所有的头文件搜索路径。BashBash

    g++ -v my_program.cpp

    你也可以使用一个特殊的命令来单独列出头文件路径,例如:

    echo | g++ -Wp,-v

    这个命令会模拟预处理过程,并打印出所有搜索路径。

标准库(standard library)

当然,我们不需要每次找要用什么标准库都跑到系统里边一顿搜。现在最好的选择我觉得是直接问AI。如果你想更好的去寻找一个库的时候,可以去https://www.cppreference.com/里找,这个网站应该算是行业标准了。

c的标准库

对于传统的c语言来说,标准库里是带 .h 的,现代的c++的库已经没有了这个.h ,下边是c和c++常用的标准库:
在这里插入图片描述
在这里插入图片描述


双引号 ""

当你使用双引号包含头文件时,例如 #include "my_header.h",编译器会先在当前源文件所在的目录进行查找。如果找不到,它才会退回到预定义的系统路径去查找。

这种方式主要用于包含项目内部的、用户自定义的头文件。它告诉编译器:“这是一个我自己的文件,先在我旁边找找看,如果找不到再去找系统文件。”


代码示例

下边是一个简单的例子,里边有自定义的头文件,还用了string的标准库,这个列子展示了怎么用两种不同的头文件引用。

https://onlinegdb.com/GBNGQOlEf

1. my_utils.h

这个文件包含一个简单的函数声明。

// my_utils.h
#pragma once

// 这个函数将返回一个问候语
std::string get_greeting();`

注意:这里的 #pragma once 是一个预处理指令,用于确保这个头文件只被包含一次,作用类似传统的 #ifndef / #define / #endif 宏。

2. my_utils.cpp

这个文件包含 my_utils.h 中函数的具体实现。

// my_utils.cpp
#include "my_utils.h"
#include <string>

std::string get_greeting() {
    return "Hello from my custom header!";
}

3. main.cpp

这个文件是我们的主程序,它将展示如何使用两种不同的 include 方式。

// main.cpp
#include <iostream>   // 包含C++标准库头文件,使用尖括号 <>
#include "my_utils.h" // 包含自定义头文件,使用双引号 ""

int main() {
    // 使用标准库的cout和endl
    std::cout << "Using standard library: ";
    std::cout << get_greeting() << std::endl;

    return 0;
}

4. 输出

Using standard library: Hello from my custom header!

### C++ 头文件概述 C++ 中的头文件是一种用于声明函数、类和其他实体的重要工具。它们通常包含了程序所需的定义和接口,使得开发者可以方便地调用库中的功能或者共享代码[^1]。 #### 头文件的作用 头文件的主要作用是提供编译器所需的信息以便正确解析源码中的各种声明。通过包含头文件,程序员能够访问标准库的功能或是其他自定义模块的内容。这不仅提高了代码重用率还简化了大型项目的管理过程[^2]。 #### 常见类型的分类 根据用途的不同,C++头文件大致可分为两类: 1. **标准库头文件**: 这些是由 C++ 提供的标准库的一部分, 它们提供了丰富的数据结构 (如 vector,string) 和算法(如 sort,find). 用户无需自己实现这些基本操作. ```cpp #include <iostream> #include <vector> ``` 2. **用户定义头文件**: 开发者可以根据项目需求创建自己的头文件来组织代码逻辑或封装特定功能模块. ```cpp #include "myheader.h" ``` 注意,在使用双引号 `""` 包裹时会先查找本地目录下的同名文件;而尖括号 `<>` 则指示编译器去系统默认路径寻找相应资源[^3]. #### 正确使用的技巧 为了避免重复包含同一个头文件造成多重定义错误,一般采用如下两种方法之一: - 使用预处理指令防止多次引入同一份内容: ```cpp #ifndef MYHEADER_H_ #define MYHEADER_H_ class MyClass { // Class definition goes here... }; #endif /*MYHEADER_H_*/ ``` - 或利用现代C++特性 pragma once 来达到同样效果更简洁明了一些情况下可能不够兼容所有环境所以推荐前者作为通用解决方案[^4]: ```cpp #pragma once class AnotherClass { // Another class definition... }; ``` ```cpp // Example of including both types of headers in a cpp file #include <string> // Standard library header #include "person.h" // User-defined header int main() { std::string name = "John Doe"; Person person(name); return 0; } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值