1樓:San Cheung
既然是c++,就簡單粗暴直接用namespace包裹吧。
PS:不建議你使用這種全域性變數的組織方式,這也算是c/c++的乙個大坑。
2樓:dyntkj
感覺好像在哪本書裡見過(如果沒猜錯的話看下去就有答案了。)首先,標頭檔案裡一般不能定義變數。
/* a.h */
#ifndef A_H
/* 防止重複包含 */
#define A_H
extern
inta
;/* 宣告變數 */
#endif
/* b.h */
#ifndef B_H
/* 防止重複包含 */
#define B_H
#include
"a.h"
extern
intb
;/* 宣告變數 */
#endif
/* a.c: 和a.h配套使用 */
#include
"a.h" /*防止變數定義和宣告不一致*/inta=0
;/* 此處為變數定義 */
/* b.c: 和b.h配套使用 */
/* 內容和a.h相似,此處省略 */
/* c.cpp */
#include
"a.h"
#include
"b.h"
#include
intmain
(void
)其次,不要忘了把a.c和b.c一同編譯掉:
gcc -c -o a.o a.c
gcc -c -o b.o b.c
gcc -c -o c.o c.cpp
gcc -o c a.o b.o c.o
或者更直接的:
gcc -o c a.c b.c c.cpp實際上我們還要考慮C語言和C++語言的鏈結不相容(因為a和b在.c檔案裡定義),用extern "C"來說明C語言鏈結。
#ifdef __cplusplus
/* 如果被C++原始碼包含 */
extern
"C"#endif
3樓:丁冬
@shiaozzzz的方法是對的,不過要注意一下命名:
Certain sets of names and function signatures are always reserved to the implementation:
— Each name that contains a double underscore _ _ or begins with an underscore followed by an uppercase letter (2.12) is reserved to the implementation for any use.
— Each name that begins with an underscore is reserved to the implementation for use as a name in the global namespace.
-- ISO/IEC 14882:2011 17.6.4.3.2
翻譯一下就是說兩種情況下你的命名可能與編譯器/標準庫實現發生衝突:1.在任何位置使用雙下劃線開頭,或以乙個下劃線+乙個大寫字母開頭的符號;2.在全域性命名空間使用乙個下劃線開頭的符號;
所以最好不要用_A_H_這樣的符號當header guard用,可以改成A_H_。
另一種方式沒有標準保證,可移植性差一些,不過能用的地方也不少:
#pragma once
4樓:
最簡單的辦法是加標頭檔案保護。
類似於#ifndef A_H_
#define A_H_
int a = 0;
#endif
在 C 中防止標頭檔案被重複包含時為什麼同時使用 ifndef 和 pragma once?
吉林小伙 vc6 你新增的class標頭檔案就會自動加上ifndef和pragma once,如 SuperSodaSea 說得一樣,的確是為了相容性。後來的ide就直接拋棄ifndef了,畢竟分析它也是要耗時間的。gcc也有對ifndef的優化。實際上,編譯器對頭檔案的處理是有優化的,並不是你in...
C 類和其友元類的標頭檔案該怎樣相互包含
宣告的時候不用包含所宣告類的標頭檔案,所以友元宣告直接宣告就好了,否則會出現互相包含,造成很大的麻煩。include只是把多個檔案複製在一起,所以只需要乙個宣告,他們最終還是會遇到的。 李白 看到這個問題,說一下我的理解.宣告友元的那個類我們稱為A,由於它需要搜尋另乙個類B的函式名形參等等資訊,因此...
boost為什麼僅包含標頭檔案就能用?
痴佬陳 boost的元件有兩種,一種是完全在.hpp中實現的,於是只要包含標頭檔案即可。但是還有很多元件是需要鏈結庫檔案的,這時候boost就使用了一種叫做自動鏈結的技術。首先,在boost在編譯過程中,會根據編譯選項按照一定的規則命名庫檔案。然後,利用巨集來組裝預處理命令,就能鏈結到指定的庫檔案了...