搜尋

首頁  >  問答  >  主體

为什么C/C++的预处理指令#include不自动让所包含的文件只包含一次?

在C/C++中#include所包含的头文件里面必须显式声明

#ifndef __HEADER_H_DEFINE__
#define __HEADER_H_DEFINE__

#endif

或者有些编译器支持

#pragma once

编译器完全有能力在执行预处理指令#include时使同一个文件只包含一次,但是却没有这么做,为什么?是否有需要包含同一个文件超过一次的情况?

大家讲道理大家讲道理2813 天前963

全部回覆(4)我來回復

  • 黄舟

    黄舟2017-04-17 11:17:45

    1、C/C++ 的函數和變數都可以重複宣告。條件判斷是為了防止不必要的函數被聲明,從而造成衝突。

    他是為了避免重複編譯,而不是解決重複聲明。

    2、#pragma once 同一個檔案不會被編譯多次。注意這裡所說的 同一個文件 是指物理上的一個文件,而不是指內容相同的兩個文件。

    C/C++ 沒有 Java 那種每個類別對應一個檔案的規定,所以即使使用了 #pragma once 也應該在頭文件裡面加上條件判斷。

    回覆
    0
  • 怪我咯

    怪我咯2017-04-17 11:17:45

    #include 不只可以包含h​​檔, 包含其他型別文件也是可以的.
    的確可以使得產生一個可執行檔包含同一個頭檔多次, 我給題主舉個拙劣的例子:

    foo.h:

    a = 43;
    

    foo.c:

    static int foo(void)
    {
        int a;
    #include "foo.h"
        return a;
    }
    
    int main(void)
    {
        int a;
        int b;
    
    #include "foo.h"
        b = foo();
        printf("a is %d, b is %d\n", a, b);
        return 0;
    }
    

    假如預處理器自動讓頭檔只包含一次, 那麼變數a將無法初始化.
    在實際工程中還是可以見到把一些很龐大的資料放在一個檔案, 然後 #include 這個檔案的賦值給變數的.
    另外也有 include 一個 c 文件的例子, 例如 redis.

    回覆
    0
  • PHP中文网

    PHP中文网2017-04-17 11:17:45

    還有一個作用,有些時候一個頭檔會被其他頭檔包含,例如
    types.h 被header_a.h 和header_b.h包含,然後一個C檔同時包含header_a.h和header_b.h的時候,如果沒有#ifdef/#define/#endif,那麼types.h就會被包含兩次,這樣在types.h中typedef unsigned int uint32_t;之列的宣告也會在同一個c檔中出現2次,編譯器會曝出redefinition of typedef 'foobar' 之類的warning或錯誤。

    回覆
    0
  • 巴扎黑

    巴扎黑2017-04-17 11:17:45

    很多工程是有多次包含同一個頭文件的需要的。原來看過flascc的頭檔。某一個頭檔被另一個包含了不下五次。一般是B中修改了巨集定義然後包含A,再次修改巨集定義再次包含A。

    回覆
    0
  • 取消回覆