Разница между #include <filename> и #include "filename" в C++
Основное различие: пути поиска файлов
Главное отличие между #include <filename> и #include "filename" заключается в том, где компилятор ищет указанный файл. Это поведение определено стандартом C++ и реализовано во всех компиляторах (GCC, Clang, MSVC и др.).
1. Угловые скобки: #include <filename>
Эта форма используется для подключения системных или стандартных заголовочных файлов. Компилятор ищет файл в стандартных системных директориях, которые заданы в настройках компилятора или переменных окружения. Обычно это пути вроде:
/usr/include(Linux/macOS)C:\Program Files\Microsoft Visual Studio\...\include(Windows)- Пути, указанные через флаг
-I(GCC/Clang) или/I(MSVC)
Пример: #include <iostream>, #include <vector>, #include <cstdio>.
2. Кавычки: #include "filename"
Эта форма предназначена для пользовательских (локальных) заголовочных файлов. Компилятор сначала ищет файл в той же директории, где находится исходный файл, который содержит директиву #include. Если файл там не найден, поиск продолжается в системных директориях (как в случае с угловыми скобками).
Пример: #include "myheader.h", #include "utils/config.h".
Важные нюансы и примеры
Рассмотрим ситуацию: у вас есть проект со структурой:
project/
├── main.cpp
├── myheader.h
└── include/
└── myheader.h (другая версия)
Если в main.cpp написать #include "myheader.h", компилятор сначала найдёт project/myheader.h. Если написать #include <myheader.h>, он будет искать в системных путях и, возможно, не найдёт файл вовсе (если не указать -I project).
Почему #include "iostream" работает?
Если вы написали #include "iostream" и это сработало, значит компилятор не нашёл файл iostream в текущей папке (там его нет) и перешёл к поиску в системных директориях, где и обнаружил стандартный заголовок. Это неправильная практика, так как:
- Замедляет компиляцию (лишний поиск в текущей папке).
- Может привести к ошибкам, если в текущей папке случайно окажется файл с таким же именем (например, злонамеренный
iostream).
Рекомендации
- Для стандартных библиотек — всегда используйте угловые скобки:
#include <iostream>. - Для своих заголовков — всегда используйте кавычки:
#include "myheader.h". - Для сторонних библиотек — обычно угловые скобки, если библиотека установлена в систему, или кавычки с указанием относительного пути, если она лежит рядом с проектом.
Пример правильного использования
// main.cpp
#include <iostream> // стандартная библиотека
#include <vector> // стандартная библиотека
#include "myheader.h" // мой собственный заголовок
#include "../lib/utils.h" // заголовок из соседней папки
int main() {
std::cout << myFunction() << std::endl;
return 0;
}
Запомните: угловые скобки — для системного, кавычки — для своего. Это правило сделает ваш код переносимым и понятным для других разработчиков.
<<Дополнение: настройка путей поиска и флаги компилятора
Первый ответ верно описывает стандартное поведение, но стоит добавить, что вы можете расширять пути поиска для обеих форм с помощью флагов компилятора.
Для угловых скобок
Флаг -I (GCC/Clang) или /I (MSVC) добавляет директории в список поиска для #include <>. Например:
g++ -I/usr/local/include -I./third_party main.cpp
Теперь #include <mylib.h> будет искать файл в /usr/local/include, ./third_party и стандартных путях.
Для кавычек
Если вы используете #include "file.h", а файл лежит не в той же папке, можно указать относительный или абсолютный путь прямо в директиве:
#include "include/file.h" // относительно текущей папки
#include "../shared/file.h" // подняться на уровень выше
Или добавить директорию через -iquote (GCC/Clang) — это добавит путь только для кавычек, не влияя на угловые скобки:
g++ -iquote./include main.cpp
Теперь #include "file.h" будет искать в ./include в первую очередь.
Практический совет
Для больших проектов используйте флаг -I для добавления корневых директорий с заголовками, а в коде пишите #include <module/submodule.h>. Это делает пути единообразными и не зависит от расположения исходного файла. Кавычки же оставьте для быстрых экспериментов или очень маленьких проектов.
Ответов пока нет.
Войдите чтобы оставить ответ