Для чего нужны Header файлы в С++? Почему нельзя писать без них?
Весь гугл перерыл, не могу понять. И википедию перечитал и вообще все что угодно перечитал. Правда не понимаю. Что мешает подключать просто .cpp файлы? Ну подключил ты его два раза, ну пусть компилятор только один раз подключает и все, раз он один черт все в один как бы файл склеивает, значит первое подключение будет выше остальных и будет видно им внизу. Пусть смотрит время изменения и перекомпилирует только изменившееся. Пусть автоматически генерирует и прикрепляет header файлы с описанием интерфейсов к откомпилированному бинарнику и т.п. Иными словами, почему рутиная работа по генерации хедер файлов, не автоматизирована и возложена на разработчика? Ведь компилятор рядом с откомпилированным бинарником может легко сам сгенерировать файл описания интерфейсов (который он получил, сканируя cpp файл). Можете привести ситуацию, в которой бы возникали ПРОБЛЕМЫ без использования хедер файлов? Это будет самое лучшее обьяснение.
Отслеживать
28.5k 12 12 золотых знаков 59 59 серебряных знаков 118 118 бронзовых знаков
задан 30 янв 2017 в 5:03
Maxmaxmaximus Maxmaxmaximus
943 2 2 золотых знака 9 9 серебряных знаков 19 19 бронзовых знаков
Комментарии не предназначены для расширенной дискуссии; разговор перемещён в чат.
5 фев 2017 в 9:57
Наверно уже сказали, но на всякий случай: Потому что можно писать без .h и можно просто включать .cpp Просто ты не понимаешь разницу между двумя подходами и не понимаешь поэтому, зачем это нужно — использовать заголовочные файлы.
9 янв 2020 в 7:01
6 ответов 6
Сортировка: Сброс на вариант по умолчанию
Проблема лежит в области обратной совместимости.
Посмотрите, любой новый язык программирования — да даже Паскаль, не говоря уже о Java или C# — не нуждаются в заголовочных файлах. Без сомнения, C++ тоже мог бы обойтись без них. В чём же дело?
Перенесёмся на полвека назад, в 1972 год. Представим себе компилятор языка C.
Допустим, мы хотим написать дизайн компилятора. Мы не можем скомпилировать всю программу за раз, у нас на это просто не хватит памяти. Компьютеры тогда были маленькими и медленными. Мы хотим компилировать программу по кусочкам, по нескольку функций за раз.
У нас сразу же возникает проблема: как скомпилировать функцию f , которая ссылается на другую функцию g ? Нам нужно отдельное описание других функций. Мы могли бы, конечно, прочитать все исходные файлы, для начала выяснить, какие функции у нас есть, и затем прочитать их второй раз и скомпилировать один за одним. Но это было слишком сложно и медленно, нужно было парсить определения функций дважды, и один раз выбрасывать результат! Это недопустимый расход процессорного времени! Плюс если держать в памяти определения всех функций, может снова-таки не хватить памяти.
На кого Деннис решил возложить сложную проблему отделения описания функции от её реализации, и подключения только нужных описаний при компиляции данной функции? На нас, программистов. Он решил, что мы должны сами помочь компилятору и скопипастить определения функций в отдельный файл, и сами указать компилятору, какие файлы с определениями нужны. (То есть первый шаг компиляции возлагается на нас.)
Это радикально упростило компилятор, но привело в свою очередь к проблемам. Что будет, если мы забыли подключить нужный заголовочный файл? Ответ: ошибка компиляции. Что будет, если смысл текста заголовочного файла меняется в зависимости от какого-нибудь макроса? Ответ: компилятор «тупой», и не пытается детектировать эту проблему, он перекладывает ответственность на нас.
На момент разработки языка это было правильное решение. Компилятор оказался практичным, быстрым, и программисты были не прочь помочь компиляции. Ну и если кто допускал ошибку, сам был виноват.
Перемотаем стрелки часов в 1983 год. Бьярн создаёт C++. Он решил взлететь на волне популярности языка C, и перенял модель компиляции C с отдельными translation unit’ами и связанными с этим проблемами прямо из C. Впрочем, первые версии C++ были просто препроцесоором языка C! Поэтому проблемы раздельной компиляции перекочевали из C в C++. Хуже того, добавились новые проблемы. Например, шаблоны классов выглядят как классы, но не генерируют объектного кода сами по себе, поэтому для них приходится идти на ухищрения и обходить недостатки системы раздельной компиляции (например, включением реализации в header и трюками компоновщика).
А дальше вступила в игру обратная совместимость. Сейчас, в 2017 году, есть так много кода, написанного в стиле «с заголовками», и так много кода исходит из различных тонкостей, связанных с этим, что менять парадигму уже поздно, поезд практически уехал.
Впрочем, существует проект модульной системы в C++, который должен помочь программистам избавиться от наследства полувековой давности. Он ещё не реализован, и в нём есть сложности уровня дизайна (например, в header’е был определён макрос, будет ли он виден, если мы перейдём от header’ов к модулям?) Надеюсь, в будущем разработчики языка таки смогут побороть проблему обратной совместимости.
include и заголовочный файлы
Заголовочный файл (иногда головной файл, англ. header file), или подключаемый файл — в языках программирования Си и C++ файл, содержащий определения типов данных, структуры, прототипы функций, перечисления, макросы препроцессора. Имеет по умолчанию расширение .h; иногда для заголовочных файлов языка C++ используют расширение .hpp. Заголовочный файл используется путём включения его текста в данный файл директивой препроцессора #include. Заголовочный файл в общем случае может содержать любые конструкции языка программирования, но на практике исполняемый код (за исключением inline-функций в C++) в заголовочные файлы не помещают. Например, идентификаторы, которые должны быть объявлены более чем в одном файле, удобно описать в заголовочном файле, а затем его подключать по мере надобности.
Заголовочные файлы оказываются весьма эффективным средством при модульной разработке крупных программ. Также, в практике программирования на С обычна ситуация, при которой, если в программе используется несколько функций, то удобно тексты этих функций хранить в отдельном файле. При подготовке программы пользователь включает в нее тексты используемых функций с помощью команд #include.
По традиции заголовочные файлы имеют расширение .h, а файлы, содержащие определения функций или данных, расширение .c. Иногда их называют «h-файлы» или «с-файлы» соответственно. Используют и другие расширения для этих файлов: .C, cxx, .cpp и .cc. Принятое расширение вы найдете в своем справочном руководстве.
Для включения файлов из стандартных каталогов (обычно каталоги с именем INCLUDE) надо вместо кавычек использовать угловые скобки < и >. Если имя_файла — в угловых скобках, то препроцессор разыскивает файл в стандартных системных каталогах. Если имя_файла заключено в кавычки, то вначале препроцессор просматривает текущий каталог пользователя и только затем обращается к просмотру стандартных системных каталогов. Например:
#include // включение из стандартного каталога. Имя в угловых скобках. #include "myheader.h" // включение из текущего каталога. Имя в кавычках. #include "..\CommonFiles\CmnHdr.h"
Включение из стандартных каталогов имеет то преимущество, что имена этих каталогов никак не связаны с конкретной программой (обычно вначале включаемые файлы ищутся в каталоге /usr/include/CC, а затем в /usr/include). К сожалению, в этой команде пробелы существенны:
#include < stream.h>// не будет найден
Было бы нелепо, если бы каждый раз перед включением файла требовалась его перетрансляция. Обычно включаемые файлы содержат только описания, а не операторы и определения, требующие существенной трансляторной обработки. Кроме того, система программирования может предварительно оттранслировать заголовочные файлы, если, конечно, она настолько развита, что способна сделать это, не изменяя семантики программы.
Укажем, что может содержать заголовочный файл:
Определения типов struct point < int x, y; >; Шаблоны типов template class V < /* . */ >Описания функций extern int strlen(const char*); Определения inline char get() < return *p++; >функций-подстановок Описания данных extern int a; Определения констант const float pi = 3.141593; Перечисления enum bool < false, true >; Описания имен class Matrix; Команды включения файлов #include Макроопределения #define Case break;case Комментарии /* проверка на конец файла */
Перечисление того, что стоит помещать в заголовочный файл, не является требованием языка, это просто совет по разумному использованию включения файлов. С другой стороны, в заголовочном файле никогда не должно быть:
Определений обычных функций char get() < return *p++; >Определений данных int a; Определений составных const tb[i] = < /* . */ >; констант
Один Заголовочный Файл (.h)
Проще всего решить проблему разбиения программы на несколько файлов поместив функции и определения данных в подходящее число исходных файлов и описав типы, необходимые для их взаимодействия, в одном заголовочном файле, который включается во все остальные файлы. Для программы калькулятора можно использовать четыре .c файла: lex.c, syn.c, table.c и main.c, и заголовочный файл dc.h, содержащий описания всех имен, которые используются более чем в одном .c файле.
Множественные Заголовочные Файлы (.h)
Стиль разбиения программы с одним заголовочным файлом наиболее пригоден в тех случаях, когда программа невелика и ее части не предполагается использовать отдельно. Поэтому то, что невозможно установить, какие описания зачем помещены в заголовочный файл, несущественно. Помочь могут комментарии. Другой способ — сделать так, чтобы каждая часть программы имела свой заголовочный файл, в котором определяются предоставляемые этой частью средства. Тогда каждый .c файл имеет соответствующий .h файл, и каждый .c файл включает свой собственный (специфицирующий то, что в нем задается) .h файл и, возможно, некоторые другие .h файлы (специфицирующие то, что ему нужно).
Что такое хедер в программировании
Если программа содержит много кода, то более оптимально было бы разнести отдельные части кода по отдельным файлам. Например, одни функции могут храниться в одном файле исходного кода, другие функции — в другом файле.
Например, определим файл sum.cpp , который будет иметь следующий код:
int sum(int a, int b)
Это функция вычисления суммы чисел.
Добавим еще один файл — , который будет содержать объявление функции sum:
int sum(int, int);
И также определим главный файл, который назовем app.cpp :
#include #include "sum.h" // подключаем файл sum.h int main() < int result < sum(5, 4)>; std::cout #include "sum.h"
Файл sum.h еще называется заголовочным файлом (header file), так как содержит объявление, заголовок функции. ПРичем в данном случае предполагается что все файлы располагаются в одном каталоге:
Можно было бы и не подключать файл sum.h и вообще не создавать его, а объявление функции поместить непосредственно в файл app.cpp. Но при изменении функции может потребоваться изменить и ее объявление. И если функция sum используется в нескольких файлах с исходным кодом, то в каждом из этих файлов придется менять ее объявление. В данном же случае достаточно изменить объявление функции в одном файле — sum.h.
При компиляции через g++ необходимо передать все файлы через пробел компилятору:
g++ app.cpp sum.cpp -o app
То же самое верно и для компиляции через Clang::
clang++ app.cpp sum.cpp -o app.exe
На выходе будет сгенерирован единый файл app.
При работе в Visual Studio заголовочные файлы обычны помещаются в каталог «Headers»:
А при компиляции все файлы автоматически компилируются в один.
Хедер
Хедер (от header — заголовок) — верхняя часть сайта, расположенная выше блока с основным контентом и отображаемая на всех страницах. Это первый элемент, который видит посетитель, поэтому одна из его важнейших задач — привлечь и удержать внимание пользователя. В хедере также размещаются ключевые навигационные компоненты сайта, такие как основное меню, поисковая строка, контактные данные и т.д. Русскоязычные разработчики и пользователи также используют термин «шапка сайта».
«IT-специалист с нуля» наш лучший курс для старта в IT
Значимость хедера
Этот элемент используется и имеет примерно одинаковую структуру на подавляющем большинстве сайтов. Причина в том, как посетитель считывает информацию со страницы. Исследования показывают, что глаза пользователя «сканируют» ее по одной из трех моделей:
- Диаграмма Гутенберга. Условно ее можно представить в виде буквы Z. Сначала пользователь смотрит на левый верхний угол сайта, затем переводит взгляд вправо до конца строки. Далее по диагонали спускается в левый нижний угол и снова переводит взгляд вправо.
- Z-паттерн. Это усложненная версия диаграммы Гутенберга, свойственная сайтам с блочной структурой. Пользователь также смотрит сначала на левый верхний угол, потом переводит взгляд вправо, спускается по диагонали вниз и снова вправо. Только из-за того, что блоков много, таких последовательных паттернов движения глаз несколько.
- F-паттерн. Согласно этой модели, пользователь сначала смотрит на левый верхний угол страницы, затем переводит взгляд вправо. Далее он спускается на 1 уровень ниже и снова смотрит слева направо. Если на первых двух «этажах» он не находит ничего интересного, то быстро просматривает оставшуюся часть сайта сверху вниз, а затем покидает страницу. Получается паттерн восприятия в виде латинской буквы F.
Общее в этих трех моделях заключается в том, что пользователь сначала просматривает верхнюю часть сайта слева направо. Именно в этом месте и располагается хедер страницы. С учетом того, что в среднем у сайта есть всего 3–4 секунды, чтобы привлечь и удержать внимание посетителя, эта задача ложится в первую очередь на шапку.
По этой же причине хедер выполняется сквозным — то есть он присутствует на всех страницах сайта. Ведь пользователь может прийти из поиска или по ссылке как на главную, так и на любую другую страницу. Если хедера на ней не будет, то страница не сможет привлечь внимание пользователя в течение 3–4 секунд.
Профессия / 8 месяцев
IT-специалист с нуля
Попробуйте 9 профессий за 2 месяца и выберите подходящую вам
Какой должна быть шапка страницы?
В структуре и дизайне сайта нет каких-то строгих законов, которые нужно неукоснительно исполнять. В конечном итоге то, как выглядит ресурс, определяется его направленностью и содержанием, особенностями психологии целевой аудитории, эстетическими предпочтениями самих владельцев и множеством других факторов. Однако на основе практического опыта использования сайтов можно выделить несколько общих критериев, которые помогают сделать шапку сайта максимально эффективной.
- Привлекательность. Так как хедер — это то, что пользователь видит при входе на страницу, сделать его нужно максимально заметным, простым для восприятия и эстетически привлекательным. Как вариант, можно оформить фон шапки фотографией или картинкой. В этом случае нужно подобрать его так, чтобы другие визуальные элементы были хорошо заметны, а глаза пользователя не уставали от просмотра.
- Информативность. В хедере должна содержаться основная информация, позволяющая пользователю быстро сориентироваться на сайте и выполнить важнейшие целевые действия — например, оформить покупку, проконсультироваться и т.д. Также необходимо, чтобы шапка на эмоциональном уровне сообщала посетителю, чему посвящен ресурс. Например, если это сервис по доставке пищи, то фоном хедера лучше сделать качественное и эстетичное изображение еды.
- Простота восприятия. Хедер не должен быть перегружен лишними визуальными элементами, чтобы они не сливались в единую информационную «кашу», в которой пользователю будет сложно разобраться. Менее значимые, но нужные пользователю компоненты (например поисковую строку) можно спрятать под компактными иконками.
- Скорость загрузки. Нужно учитывать, что хедер сильно влияет на то, как быстро будет загружаться сайт на ПК пользователя. Поэтому, при всей визуальной привлекательности анимации и видео, такие элементы нужно использовать с осторожностью. От них не будет никакого толка, если пользователю придется ждать, пока прогрузится страница. Кроме того, динамические элементы могут привести к лишнему напряжению глаз. В оформлении хедера лучше сделать акцент на средствах HTML и CSS.
- Соответствие общему дизайну. Внешний вид хедера должен не противоречить облику всей страницы. То есть в его дизайне нужно использовать аналогичную или похожую цветовую схему, стили выделения интерактивных объектов при наведении, шрифты и другие визуальные эффекты.
- Компактный размер. Не существует строгих требований к ширине и высоте хедера, но он не должен занимать значительную часть экрана и «вытеснять» собой контентную часть. Чрезмерно «раздутая» шапка потребует от пользователя проматывать страницу вниз, чтобы ознакомиться с основным содержанием. Но так как среднестатистический пользователь по своей природе «ленив», он может просто этого не сделать. Для сайтов услуг, интернет-магазинов и информационных порталов лучше использовать шапки высотой 100–200 пикселей. Для лендингов (одностраничных сайтов), которые работают немного по иным принципам, этот показатель можно увеличить до 300–400 пикселей, чтобы было больше места для размещения интерактивных элементов (кнопок, калькуляторов, счетчиков времени и т.д.).
Если какие-то из этих требований не соблюдаются в оформлении шапки конкретного сайта, это не всегда означает ее недоработку. Например, клиентами отраслевых сайтов, посвященных продаже промышленного оборудования, являются не рядовые пользователи, а производственные предприятия. Эта целевая аудитория не нуждается в излишней рекламе, она обычно хорошо знает, что ей нужно. Поэтому в таких сайтах акцент в оформлении смещен с дизайна на содержание: минимум эстетики, но максимум контента (характеристик, фотографий и т.д.).
Курс для новичков «IT-специалист
с нуля» – разберемся, какая профессия вам подходит, и поможем вам ее освоить
Что должно быть в шапке сайта?
Основные элементы, которые должны присутствовать в любом хедере:
- Айдентика. Под ней подразумевается совокупность всех визуальных элементов, ассоциирующих сайт с компанией в глазах пользователя. К айдентике относятся логотип, слоган, корпоративный стиль (цветовая схема, шрифты и т.д.). Их назначение состоит не только в ассоциировании ресурса с компанией, но также в привлечении и удержании внимания пользователя. Важно: логотип должен быть интерактивной ссылкой на главную страницу сайта. Это поможет пользователю быстро перейти на нее из любого раздела всего за один клик. Практика показывает, что логотип и слоган лучше размещать в шапке слева, так как именно туда большинство пользователей смотрят при заходе на сайт.
- Горизонтальное меню. Практика показывает, что большинство пользователей просматривают шапку слева направо по горизонтали. Это означает, что главное меню, содержащее основные разделы сайта, должно быть горизонтально ориентированным. Если у веб-ресурса обширная и разветвленная структура с несколькими уровнями вложенности, то подразделы нужно сделать выпадающими при нажатии или наведении на кнопки основных разделов. Это позволит не загромождать меню менее значимыми элементами.
- Поисковая строка. Для интернет-магазина, сайта услуг и информационного портала важно, чтобы пользователь мог сразу найти необходимую ему информацию без исследования всей структуры. Лучше всего эту задачу решает поисковая строка, которая обычно располагается в центральной части с небольшим смещением вправо. Если шапка небольшая и для полноценной поисковой строки не хватает места, то ее можно скрыть под иконкой, изображающей лупу.
- Контактная информация. В первую очередь это номер телефона (желательно городской или бесплатный с кодом 800) и адрес электронной почты на собственном домене сайта. Если компания работает в нескольких регионах, то в шапке лучше сделать их указатель с возможностью выбора. Это нужно не только для пользователей, но и для поисковых роботов. Номер телефона и адрес почты должны быть кликабельными, чтобы пользователь одним нажатием мышки смог позвонить в компанию или открыть форму отправки письма. Также следует предусмотреть кнопку «Заказать звонок» — она позволит посетителю созвониться с менеджером сайта в удобный для обеих сторон момент.
Помимо общих элементов, в шапке сайта обычно располагается несколько дополнительных — их набор определяется типом веб-ресурса:
- Корзина. Этот элемент необходим для интернет-магазинов, чтобы пользователь мог оформить заказ, находясь на любой странице сайта.
- Иконки соцсетей. Сегодня практически любая компания, поставляющая товары и/или услуги, представлена в социальных сетях. Разместив в шапке сайта иконки-ссылки на свои страницы в соцсетях, она получает дополнительный инструмент по привлечению пользователей.
- Кнопка оформления заказа. Этот элемент используется на сайтах услуг, и его название может различаться в зависимости от направления деятельности компании. Например, на сайте медицинского учреждения это «Записаться на прием», у юридической фирмы — «Заказать консультацию» и т.д. Кнопка оформления заказа должна быть хорошо различимой и достаточно крупной, а при наведении на нее курсора — менять цвет и/или размер. Так пользователь поймет, что это интерактивный элемент.
- Режим работы. В шапке лучше упомянуть, по каким дням и часам компания работает с посетителями, даже если это происходит в режиме 24/7. Если менеджеры отвечают ограниченное время, данная информация позволит пользователю связаться с ними в подходящий момент.
Очевидно, в хедер можно вставить множество различных элементов. Однако здесь важно соблюсти баланс между функциональностью, эстетичностью и простотой восприятия. Чрезмерная перегруженность шапки сайта, скорее всего, отпугнет пользователя, у него не останется желания пролистывать страницу дальше, даже если в контентной части будет нужная ему информация, услуга или товар.
Дизайн шапки сайта
Внешний вид шапки сайта во многом определяется тем, кто является его целевой аудиторией. Рассмотрим два основных направления.
B2C (для потребителей). Высокая конкуренция за внимание простых пользователей определяет привлекательный дизайн шапки сайта. Этой целевой аудитории важно, чтобы она выглядела эстетично, ведь среднестатистический потребитель часто совершает целевые действия (покупку товара, заказ услуги), подчиняясь эмоциям. При этом не обязательно привлекательность означает яркие цвета, картинки или даже анимацию. Напротив, современный потребитель достаточно искушен в вопросах дизайна. Тем не менее запрос на эстетическую привлекательность хедера остается актуальным. Он может быть ярким или минималистичным, но всегда соответствовать вкусам целевой аудитории. Для некоторых групп потребителей (например мам или детей) важно, чтобы сайт ассоциировался с приятными эмоциями. Здесь можно сделать акцент на теплых цветах, изображениях улыбающихся детей, мультипликационных персонажей и т.д.
B2B (для бизнеса). Предприниматели в своих решениях меньше руководствуются эмоциями, больше — целесообразностью и имеющимся бюджетом. Соответственно, для них эстетическое оформление шапки сайта отходит на второй план, а в приоритете остаются удобство и простота. Это не значит, что шапку на таких сайтах не нужно оформлять вообще — просто делать это придется иначе. Можно отказаться от красивого фона, но логотип компании лучше оставить, ведь предпринимателю важно понимать и запомнить, с кем он будет сотрудничать. А освободившееся от графических элементов место можно заполнить дополнительной полезной информацией: например, регионом и режимом работы, реквизитами компании, владеющей сайтом, и т.д.
Если у компании уже есть выработанный фирменный стиль (логотип, шрифты, цветовая схема и т.д.), то в дизайне хедера нужно использовать его элементы. То есть взять за основу предоставленный заказчиком брендбук, рекламные материалы, каталоги продукции. Кроме того, каждое изменение дизайна и юзабилити шапки сайта следует проверять на А/Б-тестах. Это позволит сразу отсеивать неэффективные решения.
IT-специалист с нуля
Наш лучший курс для старта в IT. За 2 месяца вы пробуете себя в девяти разных профессиях: мобильной и веб-разработке, тестировании, аналитике и даже Data Science — выберите подходящую и сразу освойте ее.