Подтвердить что ты не робот

Почему некоторые из них нуждаются в .h, а другие нет?

Почему карта импортируется как #include <map>, но stdio импортируется как #include <stdio.h>?

4b9b3361

Ответ 1

Все стандартные заголовки С++ не хотят .h в конце. Я где-то читал, что концепция состоит в том, что им не нужны фактические файлы, , даже если я никогда не видел реализацию, сделав это другим способом edit: на самом деле внутренняя среда компилятора должна работать с учетом включенных заголовков, но фактически не включать их в качестве файлов; см. комментарий @Yttrill.

Для объекта stdio.h в приложении С++ вы не должны включать <stdio.h>, но вместо этого вы должны включить <cstdio>. В общем случае вы не должны включать "нормальные" заголовки C, но их С++-азизированные копии, у которых в конце концов нет .h, имеют перед собой c и помещают все символы, определенные в них в пространстве имен std. Итак, <math.h> становится <cmath>, <stdlib.h> становится <cstdlib> и т.д.

В общем, вы должны использовать С++-версии версий заголовков C, чтобы избежать загрязнения глобального пространства имен (при условии, что вы не один из тех парней, которые поместили using namespace std; всюду), и чтобы воспользоваться некоторыми улучшениями на С++ для стандартные заголовки C (например, добавлена ​​перегрузка к некоторым математическим функциям).


В общем, реализация всего этого просто делается путем наличия таких файлов без расширения в каталоге, в котором компилятор ищет файлы заголовков. Например, в моей установке g++ 4.4 у вас есть:
[email protected]:/usr/include/c++/4.4$ ls
algorithm           cstdarg              functional        sstream
array               cstdatomic           initializer_list  stack
backward            cstdbool             iomanip           stdatomic.h
bits                cstddef              ios               stdexcept
bitset              cstdint              iosfwd            streambuf
c++0x_warning.h     cstdio               iostream          string
cassert             cstdlib              istream           system_error
ccomplex            cstring              iterator          tgmath.h
cctype              ctgmath              limits            thread
cerrno              ctime                list              tr1
cfenv               cwchar               locale            tr1_impl
cfloat              cwctype              map               tuple
chrono              cxxabi-forced.h      memory            typeinfo
cinttypes           cxxabi.h             mutex             type_traits
ciso646             debug                new               unordered_map
climits             deque                numeric           unordered_set
clocale             exception            ostream           utility
cmath               exception_defines.h  parallel          valarray
complex             exception_ptr.h      queue             vector
complex.h           ext                  random            x86_64-linux-gnu
condition_variable  fenv.h               ratio
csetjmp             forward_list         regex
csignal             fstream              set

С++-ized C заголовки в теории могут быть просто

namespace std
{
#include <original_C_header.h>
};

но в целом они сложнее решать специфические для реализации проблемы (особенно в отношении макросов) и добавлять связанные с С++ функциональные возможности (см., например, предыдущий пример добавленных перегрузок в <cmath>).


Кстати, стандарт С++ (§D.5) не говорит, что заголовки <c***> должны вести себя так, как если бы они включали заголовки <***.h> в директиве namespace std, но наоборот:

Для совместимости со стандартной библиотекой C библиотека Standard С++ предоставляет заголовки 18 C [...] Каждый заголовок C, имя которого имеет форму name.h, ведет себя так, как если бы каждое имя, помещенное в пространство имен стандартной библиотеки соответствующим заголовком cname, также помещалось в область пространства имен пространства имен std и сопровождалось явным использованием- декларация (7.3.3)

Обратите внимание, что такие заголовки считаются устаревшими (§С .2.1), поэтому это основная причина, по которой вы не должны их использовать:

C.2.1 Изменения заголовковДля совместимости со стандартной библиотекой C библиотека Standard С++ предоставляет заголовки 18 C (D.5), но их использование устарело в С++.

Ответ 2

Это просто имя фактического файла на диске. В вашем стандартном каталоге include (возможно) нет файла с именем map.h или stdio.

Стандартная библиотека С++ отошла от предыдущего стиля использования .h к отсутствию .h в конце имен файлов. Возможно, это связано с тем, что синтаксис больше похож на шаблоны:

#include<vector>

vector<int> v;

(Упреждающий комментарий: Да, я знаю, что это нужно для создания std::, но это всего лишь иллюстрация.)

Ответ 3

Это так, как он определен стандартом С++ - как это бывает, map и stdio.h даже не должны быть реальными файлами.

Как примечание, stdio.h - это заголовок, который был первоначально импортирован в С++ из стандартных библиотек C - версия С++ cstdio. С практической точки зрения это обычно означает, что при включении cstdio вы получаете материал из stdio.h, но в пространстве имен std.

Просто пояснить: stdio.h, который вы включаете в С++, является версией С++ того, что первоначально было заголовком C. Но С++ способ записи include - cstdio.