当前位置: 首页 > 知识库问答 >
问题:

c++ - 头文件保护为什么报warring?

胡星汉
2024-12-23

用c++写了一份尾插法单向链表,设计了Node.h和LinkList.h,两个类头文件,和LinkList.cpp和main.cpp源程序。在Node.h和LinkList.h中使用了#ifndef、#define、#endif头文件保护,项目编译运行成功,但是报错:
image.png

//Node.h
#ifndef NODE.H 
#define NODE.H 
#include <iostream>
using namespace std;
//单项链表节点对象 
class Node{
        
    public:
        int data;
        Node *next;
};

#endif
//LinkList.h
#ifndef LINKLIST.H
#define LINKLIST.H 
#include<iostream>
#include"Node.h"
using namespace std;
//单项尾插法链表 

class LinkList{
    public:
        LinkList(){
            head = new Node(); 
            head->next = NULL; 
            head->data=0;
            end = head;
        } 
        Node *head;  //头节点 
        Node *end;  //尾节点
        
        void create(int value);
        int receive(int nob);
        bool find(int value);
};

#endif

//LinkList.cpp
#include<iostream>
#include "Node.h"
#include "LinkList.h"
using namespace std;

void LinkList::create(int value){
        Node *node = new Node();
        node->data = value;
        node->next = NULL;
        this->end->next = node;
        this->end = node;
        this->head->data++;
}

int LinkList::receive(int nob){
    Node *p = this->head;
    
    for(int j = 0;j<=nob;j++){
        p = p->next;
    }
    
    return p->data;
}

bool LinkList::find(int value){ 
    if(this->head->data==0) return false; 
    Node *p = this->head->next;
    
    while(p!=NULL){
        if(p->data==value){
            return true;
        }    
        p = p->next;
    }
    
    return false;
}

//main.cpp
#include <iostream>
#include"Node.h"
#include"LinkList.h"

using namespace std; 

int main(int argc, char** argv) {
    
    LinkList temp;
    temp.create(96);
    temp.create(52);
    cout<<temp.find(52)<<endl;
    return 0;
}

报错信息:

1    13    C:\Users\y\Desktop\cpp\Node.h    [Warning] extra tokens at end of #ifndef directive
2    13    C:\Users\y\Desktop\cpp\Node.h    [Warning] missing whitespace after the macro name

询问了文心一言,说宏定义没有空格的原因,然而头文件保护没有跟着的数据,何来空格。

共有2个答案

鲜于光辉
2024-12-23

最初查看,你应该修改宏名,只是用大写字母和下划线:

#ifndef NODE_H 
#define NODE_H 

#ifndef LINKLIST_H
#define LINKLIST_H 

你还可以使用这样保护整个文件:

#pragma once

另外,我没有理解你的头文件保护没有跟着的数据是什么意思,可以解释下你的意思吗

燕琨
2024-12-23

回答

问题出在你的宏定义名称中包含了点号(.),这在 C++ 中通常不是宏定义名称的推荐做法。宏定义名称通常使用全大写字母和下划线(_)组成,以避免与变量名、函数名等混淆,同时也避免编译器处理时的潜在问题。

在你的代码中,#ifndef NODE.H#define NODE.H 以及 #ifndef LINKLIST.H#define LINKLIST.H 应该改为:

// Node.h
#ifndef NODE_H
#define NODE_H
#include <iostream>
using namespace std;

class Node {
public:
    int data;
    Node *next;
};

#endif

// LinkList.h
#ifndef LINKLIST_H
#define LINKLIST_H
#include <iostream>
#include "Node.h"
using namespace std;

class LinkList {
public:
    LinkList() {
        head = new Node();
        head->next = NULL;
        head->data = 0;
        end = head;
    }
    Node *head;  // 头节点
    Node *end;   // 尾节点

    void create(int value);
    int receive(int nob);
    bool find(int value);
};

#endif

使用 NODE_HLINKLIST_H 作为宏定义名称,可以避免由于点号(.)在宏定义中可能引起的解析问题。这通常是编译器在预处理阶段处理宏定义时的一个敏感点。

更改后,重新编译你的项目,警告应该会消失。

 类似资料:
  • 80386保护机制有助于找出和调试程序的BUG。80386支持很复杂的程序,它们可以包含成百上千的程序模块。在这样的程序中,关键问题是如何快而有效的找出程序的BUG,并将之造成的损坏降到最小。为了能让程序便于调试和生成高质量的产品,80386包含了检验内存访问、指令执行等很多保护机制。根据系统设计者的设计目标,这些保护机制可以使用,也可以忽略。

  • 根据这本在线书籍,C#中的关键字不能防止重排序写操作后跟读操作。它给出了这个例子,其中和最终都可以设置为,尽管和是: 这似乎符合10.5.3中的规范: 对易失性字段的读取称为易失性读取。易失性读取具有“获取语义”;也就是说,在指令序列中,它保证发生在对内存的任何引用之前,而对内存的任何引用发生在它之后。 对易失性字段的写入称为易失性写入。易失性写入具有“释放语义”;也就是说,它保证在指令序列中写入

  • 在Visual studio中新建了两个c++源文件和一个头文件,分别是main.cpp Log.cpp Log.h 其中主函数一直显示错误信息 作为新手,我不是很清楚,我正常引用了头文件为什么会报错,求大佬解答一下

  • 示例: 爱丽丝通过浏览器登录到“https://example.com”(使用cookie)。我想,她使用的是现代浏览器。 爱丽丝访问“https://evil.com”,而evil.com的客户端代码对“https://example.com”执行某种请求(经典CSRF场景)。 所以: null null

  • 问题内容: 出于好奇, 为什么将方法的访问修饰符设置为。为什么不能呢?有人可以向我解释这背后的任何具体原因吗? 另外,我知道该方法仅被调用一次。如果我在程序内部两次调用它,会发生什么情况?垃圾收集器会再次调用吗? 问题答案: 我用另一个问题回答您的问题: 为什么方法不应该受到保护? 通常,您应该尝试使事物尽可能私密。这就是封装的全部意义所在。否则,您 什么都 可以做。不能(因为派生类应该能够访问它

  • 问题内容: 定义为的受保护的具体原因是什么? 问题答案: 克隆受到保护的事实非常令人怀疑-事实是该clone方法未在Cloneable接口中声明。 它使该方法对于获取数据副本非常无用,因为你不能说: 我认为,Cloneable现在的设计在很大程度上被认为是一个错误(以下引用)。我通常希望能够实现接口的实现,Cloneable但不一定要实现接口Cloneable(类似于的使用Serializable

  • 我有一个用Java Spring MVC构建的web应用程序,并使用Spring Security进行登录。登录/退出工作很好。有两个用户角色“role_admin”和“role_user”。 我想确保我的方法只能由具有“role_admin”角色的用户访问。 我添加了批注,如下所示...

  • 我正在使用MIP文件示例命令行界面来应用标签。当尝试应用设置了保护的标签时,我得到“标签需要临时保护,但保护尚未设置”错误。因此,我尝试使用“- protect”选项保护该文件,并得到以下错误消息:“发生了不好的事情:服务不接受auth令牌。挑战:[' Bearer resource = " https://aadrm . com ",realm= " ",authorization = " ht