為什麼C++書上的.h文件上不加預編譯語句?

為什麼C++書上的.h文件上不加預編譯語句,而網上大神都加預編譯文件#ifndef,#define,#endif?


你可能看了假書。


就沒有一個人指出提主要表達的實際上是預處理而不是預編譯嗎?


你用的是哪一本C++書呢?

我們使用的是Paul Deitel, Harvey Deitel-C++ How to Program-Pearson (2014)

.h文件裡面都是加了的。

在首次提到這個的時候:

而且,他說這個是個好習慣:

在後面章節的例子中,也是加了的:

截3個頭文件的圖作為例子:

所以,有的C++書還是都加了的。


書里不寫是為了省行數吧,有時還會省去眾多#include語句。工作中的代碼往往還會加上大段大段的注釋說明,在書里也會省去。

而C/C++頭文件是一定要加#ifndef,#define,#endif的,或者用#pragma once。前者能保證被所有編譯器支持,但你得為你的宏起一個不會衝突的名字;後者能省去起名字的麻煩,但有的編譯器不識別。


C++ primer 中的 2.6.3 節,68 頁

順便請使用 SALES_DATA_H 而不是 __SALES_DATA__


#ifndef _SAMPLE_H_
#define _SAMPLE_H_

// Code...

#endif // _SAMPLE_H_

這是C/C++通用的一列預處理語句,它利用預處理控制流中對宏重定義的檢測,避免頭文件的內容被重複包含,進而避免由此引發的函數、變數、常量衝突等問題。

#pragma once

// Code...

在VisualStudio(VS)項目中,一般用第一行的#pragma once代替。它告訴編譯器,這個頭文件在用到它的源文件中只允許include一次,第二次見就不要了。效果上與上述代碼一樣,還省了宏定義。

#邁開 左腳
#邁開 右腳

// 走路

# 請點贊 // 你的善舉幫助更多的人了解真相

由於這些語錄套路固定,猶如「先邁開左腳,再邁開右腳就可以走路,請點贊」一樣。並且3行語句加至少兩行空行還很浪費地方,所以在書中省略掉這些東西很正常。


你的意思應該是防止重複 include 的宏。這不是語法問題,不加不會在編譯的時候怎麼樣。但是 symbol 重複引入可能會導致鏈接時 duplicate symbol(不明)。

頭文件之間往往有複雜的引用關係,所以才需要有防止重複引用的方式。不過如果你的頭文件只自己用而且只用一次,其實也不是一定要加宏。


#ifndef

#define

#endif

三個指令是測試想要申明的頭文件是否已經被申明過。c語言不對重複申明頭文件報錯,但是你重複申明可能會導致程序出錯。

而書上的demo程序很小,作者都清楚的知道申明過哪些頭文件,所以一般不使用


一方面書的質量也是參差不齊的。

另一方面,我比較贊同說書上demo很小的意見。#ifndef #define #endif就是為了防止頭文件里重複聲明的。但是一般教C++語言的書籍裡面最多的可能也不過就是在教 extern static 聲明的時候會用幾個module來舉例。其他的一個頭文件一個module文件就解釋清楚了。所以確實沒有必要搞這些預編命令。


#ifdef

#endif

已經過時,用#pragma once


一般頭文件開頭加#define是為了防止多次包含同一個頭文件,因為基本上所有的頭文件都這麼寫所以書里就省略了唄


書上是事例,不是全部可編譯項目


頭文件只編譯一次不加也可

加這些是防止多次重複編譯頭文件


這得看情況了。一般書上的範例都只是介紹大概內容,精力集中在講解本章節的知識點上,所以這些預編譯內容不會都詳盡地加上。作為讀者,自己心中明白不要漏掉它們就好。


書上的代碼簡單,自己加的.h不會在一個.c中重複包含


推薦閱讀:

C++ new分配的內存不delete會泄漏嗎?
C++ 有哪些奇技淫巧?
拷貝構造函數何時調用?
什麼是tlsf內存分配演算法? 它和普通的內存分配演算法有什麼區別?
C++派生類的成員或友員只能通過派生類對象來訪問基類的受保護成員?

TAG:計算機 | C編程語言 | C | CC |