2010-03-22 75 views
6

在閱讀了關於編譯問題(特別是C++)的幾個問題之後,注意到在很多情況下這個問題是缺少頭文件#include。我忍不住想知道我的無知,並問自己(現在給你):#include在C/C++頭文件

爲什麼缺少的標題不會自動檢查,並添加或請求程序員?

此類功能可用於Netbeans中的Java導入語句。

+4

java是否可以處理頭文件? – Peter 2010-03-22 14:12:26

+0

它們被稱爲import語句 – bragboy 2010-03-22 14:13:52

+2

Java的'import'更像是C++的''using'',而不像'#inc'。 – fredoverflow 2010-03-22 14:26:12

回答

12

請記住在java.util.Datejava.sql.Date之間的Java衝突嗎?如果有人在他們的代碼中使用Date,則無法分辨他們是否忘記了import java.util.Dateimport java.sql.Date

在Java和C++中,都無法確定地告訴缺少import/include語句。所以這兩種語言都不會嘗試您的IDE可能會針對代碼中使用的未聲明的符號提出建議。

這個問題在C++中更加複雜,因爲標準說任何標準頭文件都可以包含任何其他標準頭文件。因此,使用函數或類時非常容易,不需要直接包含定義它的頭文件,因爲編譯器會間接地包含正確的頭文件。根據它們是否共享該標題依賴關係,所得到的代碼在某些實現中工作,但不在其他代碼中工作。

C++ IDE通常不可能判斷頭文件依賴性是「保證」還是隻是用戶不應該依賴的附帶實現細節。很顯然,對於標準庫,它可能只知道在哪些頭文件中定義了什麼,但只要您到達第三方庫,它就很不確定。

我認爲大多數C++程序員希望能夠查找哪些頭文件定義了哪些符號。使用Java,單一公用類每文件規則可以大大簡化這一操作,並且只需導入所需的軟件包/類。 C++沒有包,並且IDE找到名爲my_namespace::something::MyClass的類的唯一方法是在每個頭文件中搜索它。

+0

感謝您的解釋史蒂夫 – Carlos 2010-03-22 17:31:09

0

NetBeans是一個IDE(集成開發環境)。一些C/C++ IDE確實有這個功能......但並不是每個人都知道它或利用它。

2

因爲第二你相信電腦認爲爲你,你有一個重大案件的SkyNet在你手上。

一般而言,電腦在做出選擇時非常糟糕,除非是非常簡單的電腦。從依賴性地獄中拉出一些東西根本不是你應該委託它的任務,因爲那種想法導致了潦草的編碼和錯誤的代碼。

4

最後我記得,如果導入語句錯過,Java也會報錯。這是NetBeans GUI,讓您的生活更輕鬆。

可能您應該嘗試爲您的C/C++代碼找到智能GUI。

7

爲什麼丟失的標題不會自動檢查並添加或向程序員請求?

但它們會自動檢查。

  1. 我的編譯器無法找到標題時編譯失敗。
  2. 我的IDE(eclipse)添加了一個視覺線索,它無法找到我包含的頭文件,它強調了#include行並提供了一個工具提示,告訴我問題是什麼。

它不會自動添加包含,因爲它無法知道哪些包含我忘記了。編譯器不是通靈的。

0

因爲通常知道需要包含哪些頭文件才能正確定義某些內容是一個難題。這將是一個相當不錯的功能,讓您的IDE能夠猜測簡單的案例並提供幫助。

1

編譯器不應該爲你考慮。如果在兩個不同的庫中有同名的函數呢?它如何知道要包含哪個頭和鏈接哪個庫?在我看來,讓一個編譯器或IDE靜靜地修復你的草率代碼是一個壞主意。

1

差異的部分原因是由於一些基本的設計決策在兩者之間做了不同的處理。特別是,Java要求類的名稱與文件的名稱相匹配,所以您使用的類的名稱幾乎告訴它需要導入的內容。

在C或C++中,您給標題的名稱根本不一定與內容匹配。如果你想足夠糟糕,你可以將你的頭文件命名爲1.h,2.h,3.h,等等 - 甚至是1.bas,2.pas,3.java,4.ada和其他任何其他的誤導你的名字你喜歡。這顯然是一個糟糕的主意,但如果你這樣做了,編譯器一點都不會困擾。因此,C或C++工具更難以猜測需要包含哪些頭部以獲得特定類型的定義。理論上,它可以(例如)在你編寫的所有頭文件中構建一個包含所有函數,類,類型等的大型數據庫,並且當你使用它時,告訴你哪些頭文件定義了什麼名稱,但我不知道實際上是這樣做的IDE。

2

如果我參考一個名爲sqrt的函數,如果我沒有指定它,編譯器如何知道要查找哪個文件?它可以是我整個硬盤上的任何文件。

與Java不同,C++並沒有真正考慮任何「特殊」文件。 Java擁有巨大的(膨脹的)類庫,程序員可以自動訪問它。

在C++中,這個概念不存在。你告訴編譯器搜索哪些路徑,並且每當你包含一個文件時,它將在這些路徑中搜索文件名。

如果碰巧找到標準庫文件,它會使用它。如果碰巧找到第三方文件,它會使用它。

編譯器不知道知道sqrt在標頭math.h中定義。或者說它也是通常在cmath中定義實際上,由標頭定義的功能可能會變化。也許,如果我定義了適當的預處理器符號,某些函數將從特定頭文件中刪除,其他函數將被啓用。

但是與Java不同,Java只能通過檢查庫文件的元數據來確定由庫定義的函數和類,而在C++中,頭必須被編譯。編譯它的結果可能會因包含它的上下文而異。

因此,C++編譯器不能猜測應該包含哪個頭以便定義剛剛使用的函數。

+0

感謝好友,使很多感覺 – Carlos 2010-03-22 17:30:39

相關問題