#pragma once和#ifndef

2023-11-10

#pragma once用法总结
1.#pragma once这个宏有什么作用?

为了避免同一个头文件被包含(include)多次,C/C++中有两种宏实现方式:一种是#ifndef方式;另一种是#pragma once方式。

在能够支持这两种方式的编译器上,二者并没有太大的区别。但两者仍然有一些细微的区别。

2.两者的使用方式有何区别?

示例代码如下:

方式一:

 #ifndef  __SOMEFILE_H__

#define   __SOMEFILE_H__

 ... ... // 声明、定义语句

#endif

方式二:

#pragmaonce

… … // 声明、定义语句

3.两者各有何特点?

(1)#ifndef

#ifndef的方式受C/C++语言标准支持。它不仅可以保证同一个文件不会被包含多次,也能保证内容完全相同的两个文件(或者代码片段)不会被不小心同时包含。

当然,缺点就是如果不同头文件中的宏名不小心“撞车”,可能就会导致你看到头文件明明存在,但编译器却硬说找不到声明的状况——这种情况有时非常让人郁闷。

由于编译器每次都需要打开头文件才能判定是否有重复定义,因此在编译大型项目时,ifndef会使得编译时间相对较长,因此一些编译器逐渐开始支持#pragma once的方式。

(2)#pragma once

#pragma once 一般由编译器提供保证:同一个文件不会被包含多次。注意这里所说的“同一个文件”是指物理上的一个文件,而不是指内容相同的两个文件。

你无法对一个头文件中的一段代码作pragma once声明,而只能针对文件。

其好处是,你不必再担心宏名冲突了,当然也就不会出现宏名冲突引发的奇怪问题。大型项目的编译速度也因此提高了一些。

对应的缺点就是如果某个头文件有多份拷贝,本方法不能保证他们不被重复包含。当然,相比宏名冲突引发的“找不到声明”的问题,这种重复包含很容易被发现并修正。

另外,这种方式不支持跨平台!

4.两者之间有什么联系?

#pragma once 方式产生于#ifndef之后,因此很多人可能甚至没有听说过。目前看来#ifndef更受到推崇。因为#ifndef受C/C++语言标准的支持,不受编译器的任何限制;

而#pragma once方式却不受一些较老版本的编译器支持,一些支持了的编译器又打算去掉它,所以它的兼容性可能不够好。

一般而言,当程序员听到这样的话,都会选择#ifndef方式,为了努力使得自己的代码“存活”时间更久,通常宁愿降低一些编译性能,这是程序员的个性,当然这是题外话啦。

还看到一种用法是把两者放在一起的:

   #pragma once

   #ifndef __SOMEFILE_H__

   #define __SOMEFILE_H__

   ... ... // 声明、定义语句

   #endif

总结:
看起来似乎是想兼有两者的优点。不过只要使用了#ifndef就会有宏名冲突的危险,也无法避免不支持#pragma once的编译器报错,所以混用两种方法似乎不能带来更多的好处,倒是会让一些不熟悉的人感到困惑。
选择哪种方式,应该在了解两种方式的情况下,视具体情况而定。只要有一个合理的约定来避开缺点,我认为哪种方式都是可以接受的。而这个已经不是标准或者编译器的责任了,应当由程序员自己或者小范围内的开发规范来搞定。

为了避免同一个文件被include多次

1 #ifndef方式
2 #pragma once方式

在能够支持这两种方式的编译器上,二者并没有太大的区别,但是两者仍然还是有一些细微的区别。
方式一:

#ifndef __SOMEFILE_H__
#define __SOMEFILE_H__
... ... // 一些声明语句
#endif

方式二:

#pragma once
... ... // 一些声明语句

#ifndef的方式依赖于宏名字不能冲突,这不光可以保证同一个文件不会被包含多次,也能保证内容完全相同的两个文件不会被不小心同时包含。当然,缺点就是如果不同头文件的宏名不小心“撞车”,可能就会导致头文件明明存在,编译器却硬说找不到声明的状况

#pragma once则由编译器提供保证:同一个文件不会被包含多次。注意这里所说的“同一个文件”是指物理上的一个文件,而不是指内容相同的两个文件。带来的好处是,你不必再费劲想个宏名了,当然也就不会出现宏名碰撞引发的奇怪问题。对应的缺点就是如果某个头文件有多份拷贝,本方法不能保证他们不被重复包含。当然,相比宏名碰撞引发的“找不到声明”的问题,重复包含更容易被发现并修正。

方式一由语言支持所以移植性好,方式二 可以避免名字冲突

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

#pragma once和#ifndef 的相关文章

随机推荐

  • HIVE SQL 计算留存率 思路

    问题 计算每日访问用户 在之后日期的留存数 基础表 每日访问用户ID create external table if not exists user visit date user id bigint comment 用户ID comme
  • 鸿蒙系统笔记

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 文章目录 前言 一 OpenHarmony整体分层 二 使用步骤 1 引入库 2 读入数据 总结 前言 主要是学习鸿蒙系统的个人笔记 笔记非常烂 一 OpenHarmony整
  • 华为手机一键刷新在哪里_华为手机怎么开启应用自动更新?华为手机WIFI下自动更新软件教程...

    玩手机稍微久点的朋友都知道 保持手机内的应用为最新版本 不但可以尽早地用上新功能 而且还能最大限度地保证手机的安全 当然了 如果每次手机开机都去检查安装的应用是否为最新版本 时间一长也难免烦不胜烦 要是能够让手机内的所有应用都能自动升级自然
  • Docker上安装DM8数据库

    Docker Docker是一种运行于Linux和Windows上的软件 用于创建 管理和编排容器 Docker官网 Empowering App Development for Developers DockerLearn how Doc
  • SQL数据结构timestamp

    既然遇到了 那就记录它吧 hairy377 在sqlyog中建表时 需要自动获取时间或者根据表的改变修改时间 可以使用timestamp数据结构 默认值 CURRENT TIMESTAMP 如果需要记录更新的时间 则勾上更新 这是在sqly
  • docker报错:WSL 2 installation is incomplete

    docker报错 WSL 2 installation is incomplete 错误原因 大概率是wsl未安装或者是未升级成wsl2 检查wsl版本方法 在powershell中使用命令wsl l v 我的已经是升级成了wsl2 所以V
  • 【Hbuilder+vue项目学习】新项目初建

    下载uView空白模板 下载包中的内容 导入在Hbuilder X中导入项目即可创建成功 在gitee上管理项目 填写好名称 介绍等信息 点击创建即可 点击HbuilderX下的终端图标 进行上传项目操作 emmm终端一片空白 用不了 网上
  • 视觉注意力的循环神经网络模型

    我们观察PPT的时候 面对整个场景 不会一下子处理全部场景信息 而会有选择地分配注意力 每次关注不同的区域 然后将信息整合来得到整个的视觉印象 进而指导后面的眼球运动 将感兴趣的东西放在视野中心 每次只处理视野中的部分 忽略视野外区域 这样
  • 神经网络中关于卷积池化的计算(不为整数时,卷积向下取整,池化向上取整)

    输入图片大小为200 200 依次经过一层卷积 kernel size 5 5 padding 1 stride 2 pooling kernel size 3 3 padding 0 stride 1 又一层卷积 kernel size
  • 1015 德才论 (25分)

    1015 德才论 25分 宋代史学家司马光在 资治通鉴 中有一段著名的 德才论 是故才德全尽谓之圣人 才德兼亡谓之愚人 德胜才谓之君子 才胜德谓之小人 凡取人之术 苟不得圣人 君子而与之 与其得小人 不若得愚人 现给出一批考生的德才分数 请
  • 【数模】时间序列分析

    时间序列也称动态序列 是指将某种现象的指标数值按照时间顺序排列而成的数值序列 时间序列分析大致可分成三大部分 分别是描述过去 分析规律和预测未来 本讲将主要介绍时间序列分析中 预测未来 常用的三种模型 并将结合Spss软件对时间序列数据进行
  • Docker - 实现本地镜像的导出、导入(export、import、save、load)

    目录 一 使用 export 和 import 1 查看本机的容器 2 导出镜像 3 导入镜像 二 使用 save 和 load 1 查看本机的容器 2 保存镜像 附 两种方案的差别 1 文件大小不同 2 是否可以对镜像重命名 3 是否可以
  • STM32实战项目—停车计费系统

    文章目录 一 任务要求 1 1 概述 1 2 串口收发 1 2 1 串口输出内容 1 2 2 串口接收内容 1 3 说明 二 实现思路 2 1 指令判别 2 1 车辆进入 2 2 车辆驶出 2 3 费率调整 三 程序设计 3 1 串口接收消
  • 强化学习算法实现自动炒股

    强化学习算法自动炒股 本文利用强化学习算法 PG 来对股票市场的指数进行交易研究 感兴趣的朋友可以在这个基础上导入其他市场的数据 添加 observation 的维度 本文仅使用了 当天收盘价 和 与前一天收盘价的差值 两个维度 操作 ac
  • linux当前目录作用,详解linux下mnt目录作用

    linux下mnt目录的作用 mount 英文解释 登上 爬上 攀登 骑上 乘上 跨上 可直接理解为 挂载 挂接光驱 USB设备的目录 加载后 会在mnt里多出相应设备的目录 mnt是mount的缩写 Mount命令 需要注意的 1 挂载点
  • 打印工资条怎么做到每个人都有表头明细_这两种工资条制作技巧,HR们不能不知道!...

    每月一到发薪日 给员工发送工资条的时候 HR们都被一大堆的数据和表格弄得焦头烂额 如何快速整理数据 制作工资条是每个HR都想得到的答案 本文就手把手地教大家如何利用excel或工资条生成器 快速地制作工资条 一起来看看吧 第一种 传统方式
  • 基于SpringBoot的网络海鲜市场系统的设计与实现

    网络海鲜市场系统管理数据的工具是MySQL 编码的语言是Java 运用的框架是Spring Boot框架 该系统可以实现对商品的购买 对论坛帖子的发布与回复论坛帖子 查看商品资讯 修改或删除购物车商品 对订单信息进行管理等功能 网络海鲜市场
  • 几种常用发布方式 平滑发布、灰度发布、蓝绿发布

    发布方式 1 平滑发布 在发布的过程中不影响用户的使用 系统不会因发布而暂停对外服务 不会造成用户短暂性无法访问 保障服务一直可以持续使用 在单机模式下 启动多端口 如有 upstream myapp server 服务1 8080 app
  • JAVA开发管理(敏捷诞生的历史背景)

    诞生背景 随着软件规模的发展和商业化 软件开发模式的管理显得尤为重要 在软件规模较小时 一个人就可以单独完成软件的编写 测试和发布 当软件规模和复杂度越来越高时 我们不得不进行协调工作 多人完成一个软件的开发 在没有管理的背景下 软件的编写
  • #pragma once和#ifndef

    pragma once用法总结 1 pragma once这个宏有什么作用 为了避免同一个头文件被包含 include 多次 C C 中有两种宏实现方式 一种是 ifndef方式 另一种是 pragma once方式 在能够支持这两种方式的