1. 程式人生 > >ifndef/define/endif作用和用法

ifndef/define/endif作用和用法

問題:ifndef/define/endif”主要目的是防止標頭檔案的重複包含和編譯,偶只知道這個概念不懂的是怎麼個用法,和為什麼要用它~~高手請指點一下~~謝謝~~~!!!

--------------------------------------------------------------------------------------------------
用法:

.h檔案,如下:
#ifndef XX_H
#define XX_H
...
#endif

這樣如果有兩個地方都包含這個標頭檔案,就不會出現兩次包含的情況 。。
因為在第二次包含時 XX_H 已經有定義了,所以就不再 include了
--------------------------------------------------------------------------------------------------
#ifndef GRAPHICS_H // 防止graphics.h被重複引用
#define GRAPHICS_H

#include <math.h> // 引用標準庫的標頭檔案

#include “myheader.h” // 引用非標準庫的標頭檔案

void Function1(…); // 全域性函式宣告

class Box // 類結構宣告
{

};
#endif
--------------------------------------------------------------------------------------------------
那是指你建立多個檔案時,多個檔案裡都包含這個標頭檔案
--------------------------------------------------------------------------------------------------
給你舉個例子,再順便分析一下:
假設你的工程裡面有4個檔案,分別是a.cpp,b.h,c.h,d.h。
a.cpp的頭部是:
#include "b.h "
#include "c.h "

b.h和c.h的頭部都是:
#include "d.h "

而d.h裡面有class D的定義。

這樣一來,
編譯器編譯a.cpp的時候,先根據#include "b.h "去編譯b.h這個問題,再根據b.h裡面的#include "d.h",去編譯d.h的這個檔案,這樣就把d.h裡面的class D編譯了;
然後再根據a.cpp的第二句#include "c.h ",去編譯c.h,最終還是會找到的d.h裡面的class D,但是classD之前已經編譯過了,所以就會報重定義錯誤。

加上ifndef/define/endif,就可以防止這種重定義錯誤。
--------------------------------------------------------------------------------------------------
A.h 裡
#ifndef A_H
#define A_H
...
#endif

B.h 和 C.h都include "A.h "

D.h裡
include "B.h "
include "C.h "
在預編譯的過程中,執行到include "C.h "時會因為在上一句的時候已經定義了A_H這個巨集,所以此時的的
的ifndef條件不滿足,也就不會再一次包含A.h,起到了防止重複引用標頭檔案的效果。
--------------------------------------------------------------------------------------------------
1.比如你有兩個C檔案,這兩個C檔案都include了同一個標頭檔案。而編譯時,這兩個C檔案要一同編譯成一個可執行檔案,於是問題來了,大量的宣告衝突。還是把標頭檔案的內容都放在#ifndef和#endif中吧。
不管你的標頭檔案會不會被多個檔案引用,你都要加上這個。
一般格式是這樣的:
#ifndef <標識>
#define <標識>
......
......
#endif <標識>
在理論上來說可以是自由命名的,但每個標頭檔案的這個“標識”都應該是唯一的。標識的命名規則一般是標頭檔案名全大寫,前後加下劃線,並把檔名中的“.”也變成下劃線,如:stdio.h
#ifndef _STDIO_H_
#define _STDIO_H_
......
#endif
2.在#ifndef中定義變量出現的問題(一般不定義在#ifndef中)。
#ifndef AAA
#define AAA
...
int i;
...
#endif
裡面有一個變數定義在vc中連結時就出現了i重複定義的錯誤,而在c中成功編譯。
原因:
(1).當你第一個使用這個頭的.cpp檔案生成.obj的時候,int i在裡面定義了當另外一個使用這個的.cpp再次[單獨]生成.obj的時候,int i又被定義然後兩個obj被另外一個.cpp也include 這個頭的,連線在一起,就會出現重複定義.(2).把源程式副檔名改成.c後,VC按照C語言的語法對源程式進行編譯,而不是C++。在C語言中,若是遇到多個inti,則自動認為其中一個是定義,其他的是宣告。
(3).C語言和C++語言連線結果不同,可能(猜測)時在進行編譯的時候,C++語言將全域性變數預設為強符號,所以連接出錯。C語言則依照是否初始化進行強弱的判斷的。
(參考解決方法:
(1).把源程式副檔名改成.c。
(2).推薦解決方案: .h中只宣告 extern int i;
在.cpp中定義
#ifndef __X_H__
#define __X_H__
extern int i;
#endif //__X_H__ int i;

相關推薦

ifndef/define/endif作用用法

問題:ifndef/define/endif”主要目的是防止標頭檔案的重複包含和編譯,偶只知道這個概念不懂的是怎麼個用法,和為什麼要用它~~高手請指點一下~~謝謝~~~!!! -------------------------------------------------------------------

C++中#ifndef, #define, #endif作用使用的注意事項

在C++語言程式設計中,我們經常會接觸到標頭檔案,比如說宣告類,或者宣告名稱空間等,而每次在編寫xxx.h的標頭檔案時,程式設計書上都會讓我們在程式碼的前後加上如下的三句程式碼: #ifndef XXX_H_ #define XXX_H_ …… #endif 其中……代表

c/c++標頭檔案中#ifndef/#define/#endif用法

想必很多人都看過“標頭檔案中用到的 #ifndef/#define/#endif 來防止該標頭檔案被重複引用”。但是是否能理解“被重複引用”是什麼意思?標頭檔案被重複引用了,會產生什麼後果?是不是所有的標頭檔案中都要加入#ifndef/#define/#endif 這些程式碼

#ifndef.#define, #endif用法

檔案中的#ifndef.#define, #endif 很關鍵,是為了避免多重包含,比如如果兩個C檔案同時包含同一標頭檔案,那麼就會出現問題,所以使用這種方法可以有效避免這種情況。 一般用法: 以add.h為例 1 #ifndef _ADD_H_ 2 #defin

#ifndef #define #endif作用

#ifndef x //先測試x是否被巨集定義過 #define x 程式段1blabla~ //如果x沒有被巨集定義過,定義x,並編譯程式段 1 #endif   程式段2blabla~   //如果x已經定義過了則編譯程式段2的語句,“忽視”程式段 1#ifndef 和 #

面試題5:標頭檔案中的ifndef/define/endif有什麼作用

在一個大的軟體工程裡面,可能會有多個檔案同時包含一個頭檔案,當這些檔案編譯連結成一個可執行檔案時,就會出現大量重定義的錯誤。在標頭檔案中實用#ifndef #define #endif能避免標頭檔案

淺談#ifndef~#define~#endif~的作用

 /* #ifndef _STDAFX_H #define _STDAFX_H #include<iostream.h>         //cin  cout #include<malloc.h>           //malloc  free

#ifndef#define#endif用法【轉載…

    #define WINDOWS          這樣則編譯下面的命令列:     #define MYTYPE long          如果在這組條件編譯命令之前曾出現以下命令列:     #define WINDOWS 0          則預編譯後程序中的MYTYPE都用floa

巨集定義(#ifndef+#define+#endif)的作用

本文介紹#ifndef、#define、#endif三者一起使用的巨集定義的作用。 在標頭檔案中,我們經常會在標頭檔案中見到#i

innerHTML作用用法

innerHTML在JS是雙向功能:獲取物件的內容 或 向物件插入內容; 如:<div id="aa">這是內容</div> 我們可以通過 document.getElementById(‘aa’).innerHTML 來獲取id為aa的物件的內嵌內容; 也可

set的作用用法

set的主要功能就是相當於一個插入後能自動排序的陣列(從小到大)。但是要注意一個數值在set中只能出現1次或0次;   用法: 一.如何定義: 1.注意標頭檔案:#include <set>; 2.定義set型別的陣列:set<型別> &nb

Prefix.pch的作用用法

轉載https://www.cnblogs.com/zhuolaiqiang/archive/2011/04/25/2072274.html Hello World_Prefix.pch:副檔名.pch表示"precompiled header",這是一個你工程要用到的來自於外部框架的標頭檔案列

python中os.path.isdir()等函數的作用用法

需要 () pri pre pytho lis tdi port txt   一 用法和概念:   Python中的os模塊用於和系統進行交互,其中:    1 os.listdir()用於返回一個由文件名和目錄名組成的列表,需要註意的是它接收的參數需要是一個絕對的路徑

savedInstanceState的作用用法

寫過Android程式的都知道Activity中有一個名稱叫onCreate的方法。該方法是在Activity建立時被系統呼叫,是一個Activity生命週期的開始。可是有一點容易被忽視,就是onCreate方法的引數savedInstanceState。因為在一般的程式開發中,很少用到

子網掩碼的作用用法

1、子網掩碼的作用 在設定電腦IP時,會碰到兩個重要的引數,一個是IP地址,一個是子網掩碼。IP地址是網際網路上每個子網或每個主機在網路上的唯一身份標籤,那子網掩碼是幹什麼用的呢? 隨著網際網路的發展,越來越多的網路產生,有的網路多則幾百臺主機,少則區區幾臺,這樣就浪費了大量的IP地址,所以

MapReduce自定義分割槽partition的作用用法

預設分割槽數量為     key.hash%reducetask的個數 自定義分割槽     自己定義的 自定義分割槽很簡單,我們只需要繼承抽象類Partitioner,重寫getPartition方法即可,另外還要給任務設定分割槽:

java中列舉的作用用法

列舉(enum),是指一個經過排序的、被打包成一個單一實體的項列表。一個列舉的例項可以使用列舉項列表中任意單一項的值。列舉在各個語言當中都有著廣泛的應用,通常用來表示諸如顏色、方式、類別、狀態等等數目有限、形式離散、表達又極為明確的量。Java從JDK5開始,引

hive 中 Order by, Sort by ,Dristribute by,Cluster By 的作用用法

order by order by 會對輸入做全域性排序,因此只有一個reducer(多個reducer無法保證全域性有序) 只有一個reducer,會導致當輸入規模較大時,需要較長的計算時間。 set hive.mapred.mode=nonstrict; (default value

vue中is的作用用法

回顧vue官方文件的過程中發現了is這個特性,雖然以我的寫程式碼風格實在用不上,不過還是記錄一下這個知識點 is的作用 &lt;ul&gt; &lt;li&gt;&lt;/li&gt; &lt;li&gt;&lt;/li&

Spring_MVC 一些基本註釋作用用法

1.1 接受頁面資料 @RequestMapping("/add") public String add(Bookinfo bookinfo) { //呼叫業務層新增bookSerice.save(bookinfo); System.out.println(bo