如何正确使用#include指令?

Mai*_*nID 15 c c++

有没有关于如何#include正确使用的材料?我没有找到任何详细解释这种用法的C/C++教科书.在正式项目中,我总是对处理它感到困惑.

Spe*_*nce 20

总是惹我生气的大事是这样的:

这将在标题路径中搜索:

#include <stdio.h>
Run Code Online (Sandbox Code Playgroud)

这将在您的本地目录中搜索:

#include "myfile.h"
Run Code Online (Sandbox Code Playgroud)

你应该用每个标题做的第二件事是:

myfilename.h:

#ifndef MYFILENAME_H
#define MYFILENAME_H
//put code here
#endif
Run Code Online (Sandbox Code Playgroud)

这种模式意味着你不能在编辑中重新定义标题(干杯到orsogufo指向我,这被称为"包含守卫").做一些关于C编译器如何实际编译文件(链接之前)的阅读,因为这将使#define和#include的世界对你有很大意义,C语言编译器在解析文本时不是很智能.(然而,C编译器本身是另一回事)

  • 大多数编译器允许`#pragma once`等效 (5认同)
  • @Spence:不,这不对.第二个包括也搜索一组目录(只是一个不同的集合) (5认同)
  • @xtofi:不,他们没有.这是一个MS扩展.很少有其他编译器支持它. (3认同)
  • 该模式被称为"包括警卫". (2认同)
  • 马丁是对的.""和"<>之间的区别并不确定.它的实现定义了这种差异.但是,大多数编译器会在使用""时首先查看文件相对路径. (2认同)

小智 14

  • 如果你有钱,请检查John Lakos的大规模C++软件设计.
  • 谷歌C++编码指南也有一些好的东西.
  • 在线检查Sutter Herb材料(博客).

基本上你需要了解哪些包含标题不是必需的,例如.前瞻性声明 还要尽量确保包含文件逐个编译,并且只在必须时将#includes放在h文件中(例如模板).


Mar*_*ork 11

因此,您的编译器可能支持包含文件的2个唯一搜索路径:
非正式地,我们可以调用系统包含路径和用户包含路径.
所述的#include <XX>搜索系统包括路径.
所述的#include"XX"搜索用户包括路径,则系统包括路径.

检查标准草案n2521:
第16.2节:

2 A preprocessing directive of the form 

  # include < h-char-sequence> new-line 

  searches a sequence of implementation-de?ned places for a header identi?ed
  uniquely by the speci?ed sequence between the < and > delimiters, and
  causes the replacement of that directive by the entire contents of the
  header. How the places are speci?ed or the header identi?ed is
  implementation-de?ned. 

3 A preprocessing directive of the form 

  # include " q-char-sequence" new-line 

  causes the replacement of that directive by the entire contents of the
  source ?le identi?ed by the speci?ed sequence between the " " delimiters.
  The named source ?le is searched for in an implementation-de?ned manner.
  If this search is not supported, or if the search fails, the directive is
  reprocessed as if it read

  # include < h-char-sequence> new-line 

  with the identical contained sequence (including > characters, if any)
  from the original directive. 
Run Code Online (Sandbox Code Playgroud)

这个例子就是gcc

  -isystem <dir>              Add <dir> to the start of the system include path
  -idirafter <dir>            Add <dir> to the end of the system include path
  -iwithprefix <dir>          Add <dir> to the end of the system include path
  -iquote <dir>               Add <dir> to the end of the quote include path
  -iwithprefixbefore <dir>    Add <dir> to the end of the main include path
  -I <dir>                    Add <dir> to the end of the main include path
Run Code Online (Sandbox Code Playgroud)

要查看您的gcc搜索的位置,请执行以下操作:

g++ -v -E -xc++ /dev/null -I LOOK_IN_HERE
#include "..." search starts here:
#include <...> search starts here:
  LOOK_IN_HERE
  /usr/include/c++/4.0.0
  /usr/include/c++/4.0.0/i686-apple-darwin9
  /usr/include/c++/4.0.0/backward
  /usr/local/include
  /usr/lib/gcc/i686-apple-darwin9/4.0.1/include
  /usr/include
  /System/Library/Frameworks (framework directory)
  /Library/Frameworks (framework directory)
End of search list.
Run Code Online (Sandbox Code Playgroud)

那么你如何使用这些知识呢?
有几种思想流派.但我总是列出我的库,从最具体到最一般.

文件:plop.cpp

#include "plop.h"
#include "plop-used-class.h"

/// C Header Files
#include <stdio.h>    // I know bad example but I drew a blank

/// C++ Header files
#include <vector>
#include <memory>
Run Code Online (Sandbox Code Playgroud)

这样,如果头文件"plop-used-class.h"应该包含<vector>,那么编译器就可以了.如果我把<vector>放在顶部,那么编译器就会隐藏这个错误.