A. C 語言中多文件編譯的問題
第一個問題
請問,我是不是該這樣做:
在main.c中#include <tou.h>
在fun.c中同樣#include <tou.h>(好像是必需的,請詳細解釋)
這是必需的。因為編譯器只是把包含文件的代碼復制過來,既然你二個文件中都用到頭文件的內容,那當然要包含頭文件,否則就會出錯。
我的觀點,如果這兩步都是必需的 那麼當有很多個比如10個.c程序每個里頭都要#include <tou.h> 那麼文件是不是會特別大,當有100個.c程序都要包含一下的話,那麼不是非常重復么?) 那當然是會重復的。不過這個對程序的運行效率沒任何影響,只是在編譯過程中對文件的分析時間會稍長些,這也是沒有辦法的事,全看代碼編寫者如何組織結構了。
第二個問題:
會的。解決的方法就是在可能被多次包含的頭文件中開頭加上#pragma once,那樣就可以保證此頭文件代碼只被執行一次,而不會造成頭文件中函數多次重復定義至於引起這種情況的情況。當然你也可以自己用#ifdef等預編譯處理來解決。你問的問題不就是這種情況么?main.c和fun.c中都包含頭文件tou.h
第三個問題:
當我在main.c中這樣
#define unchar unsigned char
那麼當我在fun.c中還需要重新創建替換宏unchar嗎 可以不在創建而直接使用嗎?
答案是需重新創建,不能直接使用。但你可以把一些在多個文件中使用的宏、全局變數等統一定義到一個頭文件中,那這樣就可以避免多次定義了。
B. c51多文件編譯中全局變數怎麼聲明
多個C文件的情況下,一般有多個對應的H文件。
假設AAA.C中定義了全局變數int abc;,那麼在對應的H文件aaa.h中定義 extern int abc;
如果在BBB.C中需要使用變數abc,那麼在BBB.C頭上#include "aaa.h"即可
另外,如果沒有aaa.h存在,那麼在BBB.C頭上寫extern int abc;也可以。
C. C++中在頭文件里定義的變數的作用范圍是什麼
根據頭文件中變數的定義形式,作用范圍有所不同,有如下幾種情況:
1 在頭文件中定義靜態變數,如
static TYPE var = init_value;
其中= init_value部分可以省略。
等效於在每個引用該頭文件的源文件中,定義一個變數名為var, 類型為TYPE的靜態全局變數。每個文件中的var變數均歸屬於本源文件,各文件中的互不相同。
作用域為引用頭文件的源文件范圍內。
2 在頭文件中定義變數,但是不帶初始化值。
TYPE var;
這種情況下,相當於定義了一個全局變數var, 同時在所有引用該頭文件的源文件中聲明。
其作用域為整個項目的所有源文件。
在引用了該頭文件的源文件中可以直接使用var, 在沒有引用該頭文件的源文件中,可以通過
extern TYPE var;
進行聲明,從而使用var。
3 在頭文件中定義了帶初始化值的變數。
TYPE var = init_value;
當項目中,只有一個源文件中引用了該頭文件時,等同於在源文件中定義了這個全局變數,可在該文件中使用var。 在其它源文件中可以通過
extern TYPE var;
進行聲明,從而使用var。所以這種情況下變數的作用域也是整個項目。
需要注意的是,這種形式一旦在超過一個源文件中引用該頭文件,則會按照在不同文件中定義同名全局變數處理,這時會編譯出錯,自然也就沒有作用域的說法了。
D. c語言中多個文件的編譯問題
第一個問題
請問,我是不是該這樣做:
在main.c中#include
在fun.c中同樣#include
(好像是必需的,請詳細解釋)
這是必需的。因為編譯器只是把包含文件的代碼復制過來,既然你二個文件中都用到頭文件的內容,那當然要包含頭文件,否則就會出錯。
我的觀點,如果這兩步都是必需的
那麼當有很多個比如10個.c程序每個里頭都要#include
那麼文件是不是會特別大,當有100個.c程序都要包含一下的話,那麼不是非常重復么?)
那當然是會重復的。不過這個對程序的運行效率沒任何影響,只是在編譯過程中對文件的分析時間會稍長些,這也是沒有辦法的事,全看代碼編寫者如何組織結構了。
第二個問題:
會的。解決的方法就是在可能被多次包含的頭文件中開頭加上#pragma
once,那樣就可以保證此頭文件代碼只被執行一次,而不會造成頭文件中函數多次重復定義至於引起這種情況的情況。當然你也可以自己用#ifdef等預編譯處理來解決。你問的問題不就是這種情況么?main.c和fun.c中都包含頭文件tou.h
第三個問題:
當我在main.c中這樣
#define
unchar
unsigned
char
那麼當我在fun.c中還需要重新創建替換宏unchar嗎
可以不在創建而直接使用嗎?
答案是需重新創建,不能直接使用。但你可以把一些在多個文件中使用的宏、全局變數等統一定義到一個頭文件中,那這樣就可以避免多次定義了。
E. 如何 定義一個 可以在 多個原文件中使用的全局變數
「C++的全局常量只有靜態連接性能。這不同於C,如果試圖在C++的多個文件內使用全局變數會產生LNK2001錯誤。一種解決的方法是需要時在頭文件中加入該常量的初始化代碼,並在.CPP文件中包含該頭文件;另一種方法是使用時給該變數賦以常數。」 --------------------------- 描述:我有一組常量數組和變數數組,定義在單獨一個DATA_DEF.C文件中,在data_def.h中聲明。現在我的另外兩個文件main.cpp和function.cpp中都需要用到其中的數據,引用了data_def.h文件。(即:我想將DATA_DEF.h中的數據看做是對整個工程的全局量) 將數據定義寫在.cpp中,然後在.h中聲明 在需要使用的地方包含.h文件就可以了
F. 多個源文件的C程序。在file1定義一個全局變數a,其作用域為file1.在file2里extern聲明a,那a的作用域是
可以,但需要在一個工程下面。
例子見下:
聲明外部變數
現代編譯器一般採用按文件編譯的方式,因此在編譯時,各個文件中定義的全局變數是互相不透明的。也就是說,在編譯時,全局變數的可見域限制在文件內部。
下面舉一個簡單的例子:
創建一個工程,裡面含有A.cpp和B.cpp兩個簡單的C++源文件:
//A.cpp
inti;
intmain()
{
}
//B.cpp
inti;
這兩個文件極為簡單,在A.cpp中我們定義了一個全局變數i,在B中我們也定義了一個全局變數i。
我們對A和B分別編譯,都可以正常通過編譯,但是進行鏈接的時候,卻出現了錯誤,錯誤提示如下:
Linking...
B.obj:errorLNK2005:"inti"(?i@@3HA)alreadydefinedinA.obj
Debug/A.exe:fatalerrorLNK1169:
Errorexecutinglink.exe.
A.exe-2error(s),0warning(s)
這就是說,在編譯階段,各個文件中定義的全局變數相互是不透明的,編譯A時覺察不到B中也定義了i,同樣,編譯B時覺察不到A中也定義了i。
但是到了鏈接階段,要將各個文件的內容「合為一體」,因此,如果某些文件中定義的全局變數名相同的話,在這個時候就會出現錯誤,也就是上面提示的重復定義的錯誤。
因此,各個文件中定義的全局變數名不可相同。
在鏈接階段,各個文件的內容(實際是編譯產生的obj文件)是被合並到一起的,因而,定義於某文件內的全局變數,在鏈接完成後,它的可見范圍被擴大到了整個程序。
這樣一來,按道理說,一個文件中定義的全局變數,可以在整個程序的任何地方被使用,舉例說,如果A文件中定義了某全局變數,那麼B文件中應可以使用該變數。修改我們的程序,加以驗證:
//A.cpp
intmain()
{
i=100;//試圖使用B中定義的全局變數
}
//B.cpp
inti;
編譯結果如下:
Compiling...
A.cpp
C:\DocumentsandSettings\wangjian\桌面\tryextern\A.cpp(5):errorC2065:'i':undeclaredidentifier
Errorexecutingcl.exe.
A.obj-1error(s),0warning(s)
編譯錯誤。
其實出現這個錯誤是意料之中的,因為文件中定義的全局變數的可見性擴展到整個程序是在鏈接完成之後,而在編譯階段,他們的可見性仍局限於各自的文件。
編譯器的目光不夠長遠,編譯器沒有能夠意識到,某個變數符號雖然不是本文件定義的,但是它可能是在其它的文件中定義的。
雖然編譯器不夠有遠見,但是我們可以給它提示,幫助它來解決上面出現的問題。這就是extern的作用了。
extern的原理很簡單,就是告訴編譯器:「你現在編譯的文件中,有一個標識符雖然沒有在本文件中定義,但是它是在別的文件中定義的全局變數,你要放行!」
我們為上面的錯誤程序加上extern關鍵字:
//A.cpp
externinti;
intmain()
{
i=100;//試圖使用B中定義的全局變數
}
//B.cpp
inti;
順利通過編譯,鏈接。
G. c51多文件編譯中全局變數的聲明。
c51中如何實現對全局變數的聲明,注意項目含有多個文件,要聲明一個全局變數,使得各模塊都能使用該變數。:定義方法一般,所在模塊中象一般全局變數一樣定義如int x;其他要使用該變數的模塊中,聲明如:extern int a;
靜態變數只是在第一次使用的時候初始化,如果是全局變數,則加static與否結果相同。如果是局部變數,則其他模塊訪問不到。
靜態函數只有在本編譯文件中才能被調用。其他c文件則不能調用。因此在其他文件中可以申明同名函數,而不互相影響。
中斷函數在什麼模塊中使用都可以。只要申明中使用中斷函數申明格式即可。
另外,VC51是什麼東西,如果可能,請mail一個給我看看,可以嗎?
H. 多個M文件時如何調用另一個M文件中的變數
在網上查,有人答復說需要共用變數時將需共用變數的M文件放在同一個路徑里即可,試過這樣對於單獨的M文件是可以,但當出現我這種有函數文件的就提示說函數文件中用到的變數沒有被定義,但此刻工作空間中這些變數的值是存在的,求賜教~~
I. c語言 中 為什麼不將全局變數的定義放在頭文件中
首先要說明什麼是全局變數,c語言中全局變數一般是指定義在函數體外的變數。全局變數按可訪問性可分為外部變數和內部變數。
內部變數是指使用了static關鍵字修飾的全局變數,它的可訪問范圍(作用域)被限定在本源文件所在的鏈接文件模塊中,不能被其它文件模塊引用。反之沒有被static關鍵字修飾的全局變數則是外部變數,其它文件模塊可以通過extern關鍵字引用該全局變數並訪問。
要說明的是全局變數無論是內部變數還是外部變數,的存儲類別都是靜態的,也就是放到靜態內存區域中,它編譯鏈接階段就已經分配好了固定的內存。
搞清楚上面的內容,就很容易得出若把全局變數放在頭文件會有哪些問題;
一 對內部變數來說,每個include該頭文件的文件模塊中都會單獨為這個內部變數分配靜態內存空間,這個空間是相對獨立的,是一種空間浪費,同時還失去了全局變數訪問一致性的特點,實在沒有什麼意義。如果這個頭文件只被一個模塊使用,對於這個文件模塊來說應該沒啥問題。
二 對外部變數來講,這個頭文件被多個文件模塊include的情況下,鏈接過程會報錯,因為符號沖突,所有include這個頭文件的模塊都會有這個全局符號。在這個頭文件僅僅只被一個模塊include的時候可以正常使用。
經上分析得出要避免全局變數定義在頭文件中,因為當這個頭文件被多方include的時候會產生一些不必要的麻煩,就這么多。
全局變數作用域范圍較廣,被錯誤修改後排查定位問題比較困難,若非必要盡少使用。
下面說一下比較好的方式就是全局變數只定義在實現文件(.c,.m)中,對內部變數沒啥說的它只在文件模塊內部使用,對外部變數可以在該模塊頭文件中使用extern關鍵字修飾一下,這樣其它文件模塊只要直接include該頭文件就可以使用模塊中的外部變數了。
J. 多文件編程中的外部變數及條件編譯
extern 關鍵字是用來聲明外部變數的,如果用來定義,每引用一次就會被定義一次,當然會報重復定義的錯
全局變數,在聲明的地方不需要extern,直接
int curT = 0;
在需要引用這個變數的外部文件:
extern int curT;
就可以了