1. 程式人生 > >#pragma once 與#ifndef,#define,#endif的差別 、重複定義等相關問題

#pragma once 與#ifndef,#define,#endif的差別 、重複定義等相關問題

今天寫程式時,對編譯預處理和#pragma once,#ifndef,#define,#endif產生了一些困惑,以前都是知道個大概,今天一下子查了很多資料,下面就是一些我現在對這個問題的認識,弄清楚這些,再加上我轉的一篇.h和.cpp區別的部落格,對於認清重定義,預處理幫助很大

.cpp檔案是一個編譯單元,obj檔案是編譯的輸出檔案,連結是將所有地obj檔案連結起來組成一個exe。連結過程中如果有不同的cpp檔案中包含相同的函式名,變數名(注意不包括變數的引用、函式的宣告、以及static函式和變數),連結將會報重複定義的錯誤,很多時候如果把函式和變數的定義寫在.h檔案,多個cpp包含此.h檔案,就極可能會發生這樣的錯誤,所以應該把函式的實現、變數的定義寫在.cpp中,在.h中宣告。這裡有一種情況是例外,就是模板函式,其實STL容器的原始碼實現就都寫在.h中,那是因為模板有模板的機理,在這裡就不展開了。

上述是在發生在連結時期的重定義,是指兩個或多個cpp之間有衝突的變數和函式,是連結時發現的。還有一種重定義可能會發生在編譯時期。在同一個編譯單元,也就是cpp中,多數cpp可能存在巢狀包含,一個頭檔案被一個cpp包含了兩次,不僅造成編譯效率降低,而且如果此標頭檔案中含有定義,那就會被重定義。而#pragma once 與,#ifndef,#define,#endif就是這個問題的解決辦法。但兩者之間又有一些小區別:

1,、 #pragma once是和檔案繫結的,有檔案標誌,編譯時會檢查標頭檔案有沒有被編譯過,而不用進入檔案中檢查。編譯效率會比預處理頭方法高,但如果程式中有同一個.h檔案的多個副本,一個cpp不慎包含了多個副本.h檔案,那麼#pragma once對此是失效的,因為他只認檔案不認程式碼。

2、#ifndef,#define,#endif是和巨集繫結的,編譯時編譯器會進入標頭檔案中,檢查巨集有沒有被定義,雖然效率比不上#pragma once,但上面 #pragma once失效的情況,在這裡不會發生。此外使用#ifndef要防止多個.h檔案的巨集重名,也很煩。

3、#pragma once由編譯器提供保證,是平臺相關的,而#ifndef,#define,#endif是語言支援的,所以移植性好於#pragma once,但目前看來#pragma once似乎移植起來也基本沒什麼問題。

4、有方法把這兩種方法結合起來用,但看起來並沒有什麼卵用,反而增加了程式碼閱讀者的困擾

相關推薦

#pragma once #ifndef#define#endif差別 重複定義相關問題

今天寫程式時,對編譯預處理和#pragma once,#ifndef,#define,#endif產生了一些困惑,以前都是知道個大概,今天一下子查了很多資料,下面就是一些我現在對這個問題的認識,弄清楚這些,再加上我轉的一篇.h和.cpp區別的部落格,對於認清重定義,預處理幫

#pragma once #ifndef防止重編譯區別

cin blank ndt 防止 store ycm bds csv 獎章 郎P爬慚史73伎X1http://docstore.docin.com/spk6612 蒲2U萄z渴y欣背贍4oehttp://docstore.docin.com/sina_5847888885

#pragma once#ifndef

1.相同點: 都是為了避免同一個標頭檔案被包含多次。在編譯器對這兩種方式都支援的情況下,區別很小。 方式一: #pragma once ...//這裡放宣告語句 方式二: #ifndef 巨集名 #def 巨集名 ...//這裡放宣告語句 #endif 2.不同點: (1)#i

C++中#pragma once #ifndef 的區別解析

原文地址:http://blog.csdn.net/hkx1n/article/details/4313303   作用:為了避免同一個檔案被include多次,C/C++中有兩種方式,一種是#ifndef方式,一種是#pragma once方式。 在能夠支援這兩種方式的編譯器

#pragma once #ifndef

轉自:https://www.cnblogs.com/terrytian88/p/5820159.html 為避免同一個檔案被包含多次,有以下兩種處理方式:          方式一:由語言支援, 所以移植性好    

【c/c++】#pragma once #ifndef 的區別解析

原文地址:http://blog.csdn.net/hkx1n/article/details/4313303 作用:為了避免同一個檔案被include多次,C/C++中有兩種方式,一種是#ifndef方式,一種是#pragma once方式。 在能夠支援這兩種方式的

標頭檔案保護符和#pragma once #pragma once #ifndef的區別

為了避免同一個檔案被include多次 1   #ifndef方式 2   #pragma once方式 在能夠支援這兩種方式的編譯器上,二者並沒有太大的區別,但是兩者仍然還是有一些細微的區別。     方式一:     #ifndef __SOMEFILE_H__     #define __SOMEFIL

#pragma once #ifndef比較分析

為了避免同一個檔案被include多次,C/C++中有兩種方式,一種是#ifndef方式,一種是#pragma once方式。在能夠支援這兩種方式的編譯器上,二者並沒有太大的區別,但是兩者仍然還是有一些細微的區別。 方式一: #ifndef __SOMEFILE

#pragma once #ifndef 解析

    為了避免同一個檔案被include多次,C/C++中有兩種方式,一種是#ifndef方式,一種是#pragma once方式。在能夠支援這兩種方式的編譯器上,二者並沒有太大的區別,但是兩者仍然還是有一些細微的區別。    方式一:    #ifndef __SOMEF

#pragma once#ifndef條件編譯區別

【1】#pragma once這個巨集有什麼作用? 為了避免同一個標頭檔案被包含(include)多次,C/C++中有兩種巨集實現方式:一種是#ifndef方式;另一種是#pragma once方式。在能夠支援這兩種方式的編譯器上,二者並沒有太大的區別。但兩者仍然有

轉帖:#pragma once #ifndef的區別

為了避免同一個檔案被include多次 1   #ifndef 方式 2   #pragma once方式 在能夠支援這兩種方式的編譯器上,二者並沒有太大的區別,但是兩者仍然還是有一些細微的區別。 方式一:     #ifndef __SOMEFILE_H__     #de

#pragma once #ifdef #define #endif 區別

pragma once   這是一個比較常用的指令,只要在標頭檔案的最開始加入這條指令就能夠保證標頭檔案被編譯一次   #pragma once用來防止某個標頭檔案被多次include,#ifndef,#define,#endif用來防止某個巨集被多次定義

#pragma once和#ifndef的區別

1)#ifndef的方式依賴於巨集名字不能衝突,這不光可以保證同一個檔案不會被包含多次,也能保證內容完全相同的兩個檔案不會被不小心同時包含。當然,缺點就是如果不同標頭檔案的巨集名不小心“撞車”,可能就會導致標頭檔案明明存在,編譯器卻硬說找不到宣告的狀況 2)#

保證標頭檔案只被編譯一次的方法#pragma once和#ifndef

#ifndef ABC_H #define ABC_H #endif 和 #pragma once 這兩種方法都可以保證所在標頭檔案只被編譯一次,區別是#pragma once比較新,在一些老編譯器上

matplotlib繪圖設定座標格式比如科學計數法公式表示

matplotlib繪圖 前言 匯入必要包 未設定座標格式 科學計數表示 前言 繪製實驗結果時,很多時候預設設定得到的圖形,並不能滿足我們的需求。如果我們希望繪製出來的圖形更加騷一點,更好看一點,我們怎麼做呢

關於如何在make一個Linux下的C/C++工程時自動新增版本號編譯日期資訊

本篇的目的:在makefile裡,將系統當前的時間傳遞進待編譯的C/C++工程中,用以指示編譯執行的時間,以及版本資訊等。 不多說了,先來看效果: 當前時間:2017.01.20  0:29 編譯完成後執行效果: [email protected]:~/Desk

MyBatis 和 ibatis的動態SQL語句配置符號不相容大於號小於號特殊符號問題

在XML對映SQL的檔案中,很多情況下會使用到大於號、小於號等特殊符號,這時候如果不進行控制是無法編譯通過的,這時候需要用到<![CDATA[  ]]>符號進行說明,將此類符號不進行解析,還有一種解決方法就是使用轉移字元,如,案例2,其實,這個問題不止在My

100+詭異的資料集20萬Eclipse Bug死囚遺言

摘要:近日,Robert Seaton整理了100多個最有趣的資料集,其中包括Jeopardy真題,死囚的最後一句話,20萬個Eclipse Bug,足球比賽相關,柏拉圖式的愛情,太陽系以外的行星,11.3萬個恐怖事件等。 【編者按】在資料爆發式增長的逼迫下,當下資料分析能力已得到長足的發展,機器學習更

檔案的上傳核心API的使用檔案下載註解(jdk的註解定義註解)

第一部分:檔案的上傳 1、什麼是檔案的上傳 1.1 把本地的檔案儲存到伺服器上,這個過程稱為檔案的上傳。比如,網盤、qq空間 1.2 實現檔案的上傳 (1)jspSmartUpload:應用在jsp的模型一 = 適於嵌入執行上傳下載操作的JSP檔案

(轉)C語言的條件編譯#if #elif #else #endif#ifdef #ifndef

n+1 ifdef int pan 不能 ica 推薦 代碼 表達式 有些程序在調試、兼容性、平臺移植等情況下可能想要通過簡單地設置一些參數就生成一個不同的軟件,這當然可以通過變量設置,把所有可能用到的代碼都寫進去,在初始化時配置,但在不同的情況下可能只用到一部分代碼,就