小白学习C++——头文件

当我们想在一个cpp文件中创建函数,然后想在另一个cpp文件中使用,当我们尝试编译那个文件时,编译器不知道那个文件的存在,所以编译会报错。
所以我们需要一个共同的地方来存放声明(注:是函数的声明而非定义,我们只能定义函数一次)

举例

#include<iostream>

void Log(const char* message)
{
	std::cout<<message<<std::endl;
}

int main()
{
	Log("Hello World!");
	std::cin.get();
}

上述例子中,主函数调用了一个函数Log,它的作用是能帮助我们打印信息到控制台。

新建一个源文件Log.cpp写一个新的初始化函数InitLog和原来的打印函数:

#include <iostream>

void InitLog()
{
	Log("Initializing Log");
}

void Log(const char* message)
{
	std::cout << message << std::endl;
}

此时编译一下的话肯定会发生错误,因为在这个文件中编译器不认识Log函数,我们并没有对其进行声明。
添加一个Log函数的声明后,我们就可以成功编译运行这个文件了。

#include <iostream>

void Log(const char* message);//声明时别忘记添加分号

void InitLog(const char* message)
{
	Log("Initializing Log");
}

void Log(const char* message)
{
	std::cout << message << std::endl;
}

到现在为止,我们找到了一个告诉Log.cpp文件那个Log函数位于某处的方法——添加一个函数声明。
但如果我们有多个文件都用到了这个函数,需要在每一个文件中都复制粘贴这个声明吗?
The answer is YES!但有另外一个方法可以让这一切变的简单清爽一点,就是头文件。include预处理指令可以将我们的头文件复制粘贴到每个地方,这正是现在我们需要的。
我们新建一个头文件:右击头文件——添加——新建项——新建头文件.h——命名Log.h
在这里插入图片描述在这里插入图片描述

头文件Log.h声明了两个函数InitLog和Log:

#pragma once

void InitLog();
void Log(const char* message);

在main函数里再调用一下InitLog函数,此时编译会报错,因为原main.cpp文件中同样没有这对这两个函数进行声明,所以我们include一下头文件Log.h:

#include <iostream>
#include "Log.h"

int main()
{
	InitLog();
	Log("Hello World!");
	std::cin.get();
}

同样的,在Log.cpp文件中,删去原来对于Log函数的声明void Log(const char* message),添加上头文件Log.h:

#include "Log.h"

#include <iostream>

void InitLog()
{
	Log("Initializing Log");
}

void Log(const char* message)
{
	std::cout << message << std::endl;
}

然后在main中运行程序,则程序也可以运行成功。运行结果如图:
在这里插入图片描述

头文件中自动生成的#pragma once

我们注意到pragma也是以#开头的,所以它其实也是一个预处理指令,pragma once的意思实际上指的是只include这个文件一次。
所以Pragma once实际上是一种header guard(头文件保护符),它是为了防止我们把单个头文件多次include到一个cpp单元里。
我们如果在一个cpp文件中多次include同一个头文件,编译器会报错!!!比如说我们创建一个struct来举例。
struct是指结构体,是常用的自定义构造类型(常见的数据打包方法),它需要唯一的名字(也就是你定义的结构体的名字不能相同)。
现在我们在Log.h中添加一个struct的定义并且把pragma once注释掉:

//#pragma once

void InitLog();
void Log(const char* message);
struct player{};//里面不添加任何变量,就是一个空的。

然后新建一个common头文件common.h:

#pragma once

#include"Log.h"

回到Log.cpp文件中,假如我们同时include了两个头文件:

#include "Log.h"
#include"common.h"
#include <iostream>

void InitLog()
{
	Log("Initializing Log");
}

void Log(const char* message)
{
	std::cout << message << std::endl;
}

编译器会报错,因为struct被重复定义了两次,我们如果回到Log.h把注释掉的pragma once恢复,编译就不会出错,顺利进行了。

### C++头文件报错的原因及解决方案 #### 1. 配置问题 当使用 VSCode 编辑 C++ 程序时,如果未正确配置 `c_cpp_properties.json` 文件,则可能导致头文件无法被识别并引发错误。具体表现为头文件路径缺失或不匹配[^1]。 解决方法是通过快捷键组合 `Ctrl+Shift+P` 打开命令面板,输入 `C/C++: Edit Configurations (UI)` 或手动编辑 `c_cpp_properties.json` 文件,在 `"includePath"` 字段中添加正确的头文件路径。 ```json { "configurations": [ { "name": "Linux", "includePath": [ "${workspaceFolder}/**", "/usr/include" ], "defines": [], "compilerPath": "/usr/bin/gcc", "cStandard": "gnu11", "cppStandard": "gnu++14", "intelliSenseMode": "gcc-x64" } ], "version": 4 } ``` #### 2. 编译器设置不当 VSCode 的 IntelliSense 可能未能检测到当前使用的编译器及其默认包含路径。这通常可以通过点击头文件下的红色波浪线下方的提示选项来修复。选择合适的编译器路径(如 `gcc.exe`, `g++.exe` 或其他支持的工具链)可解决问题[^2]。 #### 3. 自定义头文件路径遗漏 对于自定义头文件,需确保其所在目录已被加入项目的构建配置中。若仅修改部分配置而忽略其余关联项(例如 `.vscode/tasks.json` 和 `.vscode/launch.json`),则仍可能出现类似的错误[^3]。 调整方式如下: - **tasks.json**: 定义如何调用外部编译程序; - **launch.json**: 设置调试环境变量; 以下是典型的任务配置示例: ```json // tasks.json { "label": "build", "command": "g++", "type": "shell", "args": [ "-g", "${file}", "-o", "${fileDirname}/${fileBasenameNoExtension}" ] } ``` #### 4. 跨版本兼容性问题 某些情况下,不同版本间的差异也可能引起冲突——比如从旧版 IDE 迁移到新版开发环境中运行遗留代码库时遇到的情况[^4]。此时建议重新审视整个工程结构以及依赖关系,并考虑更新至最新稳定状态或者适配现有平台特性需求后再做进一步操作。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值