Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 18, средняя оценка - 4.78
MayaNash
1285 / 453 / 47
Регистрация: 24.08.2011
Сообщений: 2,203
#1

Назначение заголовочных файлов - C++

15.07.2013, 19:03. Просмотров 2322. Ответов 35
Метки нет (Все метки)

Я читала учебник и википедию - никак не доходит.

В общем, может я неправильно поняла: есть у меня "Моя программа.cpp", и есть "Заголовочный файл.hpp". В заголовочном файле прописаны прототипы функций, и классы без определения их методов, этот заголовочный файл включается в мою программу. Все определения содержатся, собственно, в моей программе.
Если это так, то я не понимаю, какой смысл выделять это в отдельный файл, если можно прописать то же самое в самом начале. Просто чтобы был отдельный список, и не надо было скакать вверх-вниз, если надо вспомнить какие параметры нужно передать в функцию?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
15.07.2013, 19:03
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Назначение заголовочных файлов (C++):

Про добавление заголовочных файлов в заголовочных файлах - C++
В который раз эта вещь засовывает мозги в блендер! Я про то, что не могу однозначно запомнить (основываясь на моих знаниях о директиве...

Раздельная компиляция (нюансы использования заголовочных файлов и файлов реализации) - C++
Почему во многих учебниках функции-члены класса внутри класса только объявляют, но определяют вне самого класса (не, ну как бы в классе, но...

Подключение заголовочных файлов и файлов реализации - C++
Здравствуйте,при создании класса в visual studio руками не компилится проект,при создании через add class все работает,для примера написал...

Подключение заголовочных файлов - C++
Имею два файла Large Factorial.h #include <sstream> #include <iostream> #include <iomanip> #include <math.h> #include...

Подключение заголовочных файлов - C++
Начал изучать С++, скачал несколько книг и заметил что в одних при включении заголовочных файлов (например iostream.h) используется запись:...

Объявление заголовочных файлов - C++
Скажите в чем разница между объявлением вида: #include <iostream> и вида #include "iostream"

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
MayaNash
1285 / 453 / 47
Регистрация: 24.08.2011
Сообщений: 2,203
15.07.2013, 19:27  [ТС] #16
0x10, и что с этим множеством определений делать? Кстати, а что делает #pragma once?
0x10
2460 / 1632 / 238
Регистрация: 24.11.2012
Сообщений: 4,015
15.07.2013, 19:27 #17
Цитата Сообщение от gray_fox Посмотреть сообщение
Ну так объектный модуль то один будет)
А, прям настолько все в кучу спихать...

Цитата Сообщение от gray_fox Посмотреть сообщение
+ есть inline
Помним, но пока не принципиально.
gray_fox
What a waste!
1506 / 1209 / 68
Регистрация: 21.04.2012
Сообщений: 2,544
Завершенные тесты: 3
15.07.2013, 19:28 #18
Цитата Сообщение от Керра Посмотреть сообщение
то с этим множеством определений делать?
Не создавать множество определений, только одно.
0x10
2460 / 1632 / 238
Регистрация: 24.11.2012
Сообщений: 4,015
15.07.2013, 19:29 #19
Керра, определение должно быть одно. Иначе будет ошибка линковки.

pragma once предотвращает множественное включение одного файла.
MayaNash
1285 / 453 / 47
Регистрация: 24.08.2011
Сообщений: 2,203
15.07.2013, 19:31  [ТС] #20
Спасибо большое
ValeryS
Модератор
6556 / 5022 / 464
Регистрация: 14.02.2011
Сообщений: 16,763
17.07.2013, 08:34 #21
Цитата Сообщение от Керра Посмотреть сообщение
программе.
Если это так, то я не понимаю, какой смысл выделять это в отдельный файл, если можно прописать то же самое в самом начале. Просто чтобы был отдельный список, и не надо было скакать вверх-вниз, если надо вспомнить какие параметры нужно передать в функцию?
видишь ли оно так и происходит
#include дает команду препроцессору вставить в файл все что находится в другом файле
препроцессор это такая штука которая работает еще до компилятора

например есть файлы
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// file1.h
 
int fnc_file1(void);// объявление ;
 
..........................
 
// file1.c
#include "file1.h"
int fnc_file1(void)  // определение
{
 return 2;
}
 
.........................................
// file2.c
#include "file1.h"
int  a=fnc_file1();//использование
они после препроцессора превратятся
в
C++
1
2
3
4
5
6
7
8
9
10
11
12
// file1.c
int fnc_file1(void); // объявление
int fnc_file1(void)  //определение
{
 return 2;
}
 
.........................................
// file2.c
 
int fnc_file1(void); // объявление
int  a=fnc_file1();// использование
можешь так же ручками написать, никто ругать не станет
а если нужно использовать 100 функций ??? все 100 прописывать
вот и разбили на файлы, заголовков и реализации
следующий уровень использования
ктото уже скомпилировал file1 создал из него библиотеку, но как её использовать если не знаем что за функции в ней и как они выглядят?
вот и нужен заголовочный файл

простейший пример window.h где реализованы функции программист может и не знать а заголовочный файл вот он

теперь о #pragma once
говорит что два раза не надо включать заголовочный файл
например если напишем так
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// file1.h
 
int fnc_file1(void); // объявление
 
..........................
 
// file1.c
#include "file1.h"
int fnc_file1(void)  // определение
{
 return 2;
}
 
.........................................
// file2.c
#include "file1.h"
#include "file1.h"
int  a=fnc_file1();//использование
после препроцессора превратится в

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
// file1.c
int fnc_file1(void);// 
int fnc_file1(void)
{
 return 2;
}
 
.........................................
// file2.c
 
int fnc_file1(void); // Два объявления!!!!
int fnc_file1(void);
int  a=fnc_file1();

конечно никто в здравом уме так писать не будет, но есть неявное подключение

например
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// file1.h
 
int fnc_file1(void);// объявление ;
 
..........................
 
// file3.h
#include "file1.h"
 int fnc_file3(void);// объявление ;
 
..........................
 
// file1.c
#include "file1.h"
int fnc_file1(void)  // определение
{
 return 2;
}
 
// file3.c
#include "file3.h"
int fnc_file3(void)  // определение
{
 return 5;
}
.........................................
// file2.c
#include "file1.h"
#include "file3.h" 
int  a=fnc_file1();//использование
int  b=fnc_file3();
они после препроцессора превратятся в
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// file1.c
int fnc_file1(void); // объявление
int fnc_file1(void)  //определение
{
 return 2;
}
 
// file3.c
int fnc_file1(void); // объявление придет из  file3.h   #include "file1.h"
int fnc_file3(void) ;
int fnc_file3(void)  // определение
{
 return 2;
}
 
 
.........................................
// file2.c
 
int fnc_file1(void);
int fnc_file1(void); // объявление придет из  file3.h   #include "file1.h"
int fnc_file3(void) ;
int  a=fnc_file1();// использование


для таких случаев и служит #pragma once
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// file1.h
#pragma once 
int fnc_file1(void);// объявление ;
 
..........................
 
// file3.h
#include "file1.h"
 int fnc_file3(void);// объявление ;
 
..........................
 
// file1.c
#include "file1.h"
int fnc_file1(void)  // определение
{
 return 2;
}
 
// file3.c
#include "file3.h"
int fnc_file3(void)  // определение
{
 return 2;
}
.........................................
// file2.c
#include "file1.h"
#include "file3.h" 
int  a=fnc_file1();//использование
int  b=fnc_file3();
они после препроцессора превратятся в
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// file1.c
int fnc_file1(void); // объявление
int fnc_file1(void)  //определение
{
 return 2;
}
 
// file3.c
int fnc_file1(void); // объявление придет из  file3.h   #include "file1.h"
int fnc_file3(void) ;
int fnc_file3(void)  // определение
{
 return 5;
}
 
 
.........................................
// file2.c
 
int fnc_file1(void);
//int fnc_file1(void); // объявление из  file3.h   #include "file1.h" не придет сработает #pragma once 
int fnc_file3(void) ;
int  a=fnc_file1();// использование
для этих же случаев служит Include guard
это конструкция типа
C++
1
2
3
4
 #ifndef MACRO1 //  если макрос определен то пропускаем все до #endif
 #define MACRO1 // иначе определим макрос 
 .........   // и чтото делаем
 #endif
вот пара ссылок
http://ru.wikipedia.org/wiki/Pragma_once
http://ru.wikipedia.org/wiki/Include_guard
несколько сумбурно получилось но надеюсь понятно
BigLow
55 / 55 / 2
Регистрация: 07.07.2013
Сообщений: 345
17.07.2013, 09:23 #22
у меня есть вопрос по этой теме.
предположим есть проект в котором 3 файла: main.cpp, 1.h. и 1.cpp.
в main.cpp мы пишем #include "1.h", в 1.cpp пишем #include "1.h". т.е. main.cpp использует 1.h и 1.cpp тоже использует 1.h
но связь между main.cpp и 1.cpp как таковой нет!

как main.cpp ищет этот самый 1.cpp?
Schizorb
509 / 461 / 16
Регистрация: 07.04.2012
Сообщений: 865
Записей в блоге: 1
Завершенные тесты: 1
17.07.2013, 09:35 #23
Цитата Сообщение от BigLow Посмотреть сообщение
как main.cpp ищет этот самый 1.cpp?
Компилируются они отдельно, да. А уже на этапе линковки связываются в исполняемый файл. Если вызываете компилятор и линковщик через командную строку, то там соответственно руками прописываете имена нужных файлов.
ValeryS
Модератор
6556 / 5022 / 464
Регистрация: 14.02.2011
Сообщений: 16,763
17.07.2013, 09:38 #24
Цитата Сообщение от BigLow Посмотреть сообщение
как main.cpp ищет этот самый 1.cpp?
а никак не ищет
после работы компилятора образуются два объектных файла main.obj и 1.obj (расширение могут быть и другими)
и тут в дело в ступает линкер, он берет объектные файлы и создает из них что надо(исполняемый файл,библиотеку, файл прошивки) линкер знает какие файлы собирать в кучу, это зависит или от командной строки или от настроек среды написания(точнее среда создает командную строку для линкера)
объектные файлы может создавать не только компилятор Си но и другие компиляторы
например файл main.cpp обрабатывает компилятор Си и создает main.obj
а файл 1.asm обрабатывает компилятор ассемблера и создает 1.obj
линкер даже не будет знать что исходники написаны на разных языках, главное чтобы он понимал объектный файл
BigLow
55 / 55 / 2
Регистрация: 07.07.2013
Сообщений: 345
17.07.2013, 09:49 #25
Цитата Сообщение от Schizorb Посмотреть сообщение
Если вызываете компилятор и линковщик через командную строку, то там соответственно руками прописываете имена нужных файлов.
у меня visual studio. и в сам проект просто добавляю нужные файлы. получается VS при компиляции автоматически устанавливает нужные связи?

Не по теме:

говорили мне не использовать эту visual studio потому что не поймешь как связываются файлы проекта, а я не послушался. теперь мучаюсь

alsav22
5417 / 4813 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
17.07.2013, 09:54 #26
Цитата Сообщение от BigLow Посмотреть сообщение
как main.cpp ищет этот самый 1.cpp?
Зачем ему его искать? Файлы друг друга не ищут. Для компилятора, который видит в единицу времени один файл, видеть другие файлы не нужно. Он скомпилирует, по отдельности, в объектные файлы, все .cpp файлы (с включёнными в них .h файлами), которые есть в проекте (это в IDE). Из двух .cpp и одного .h он сделает два объектных файла, с которыми дальше будет работать компоновщик. Вот он уже видит, в каждый момент времени, все собранные компилятором объектные файлы.

Добавлено через 1 минуту
Цитата Сообщение от BigLow Посмотреть сообщение
Не по теме:
говорили мне не использовать эту visual studio потому что не поймешь как связываются файлы проекта, а я не послушался. теперь мучаюсь
И в чём мучения?
ValeryS
Модератор
6556 / 5022 / 464
Регистрация: 14.02.2011
Сообщений: 16,763
17.07.2013, 09:54 #27
Цитата Сообщение от BigLow Посмотреть сообщение
меня visual studio. и в сам проект просто добавляю нужные файлы.
ключевое слово "в проект"
если ты просто создашь файл и бросишь в папку, то компилятор не будет знать что компилировать а линкер что прилинковывать
Цитата Сообщение от BigLow Посмотреть сообщение
говорили мне не использовать эту visual studio потому что не поймешь как связываются файлы проекта, а я не послушался. теперь мучаюсь
Я тоже на нем сижу и несколько не мучаюсь, просто нужно изучать инструмент а не тупо его использовать
или ты предпочитаешь вручную компилировать и ручками прописывать пути файлы и пр.
так visual studio тоже это позволяет, правда редко кто пользуется
Schizorb
509 / 461 / 16
Регистрация: 07.04.2012
Сообщений: 865
Записей в блоге: 1
Завершенные тесты: 1
17.07.2013, 10:00 #28
BigLow, ну да, при использовании IDE это все автоматически происходит, для файлов, добавленных в проект. Хотя студийный компилятор можно и в консоли вызывать.

Добавлено через 3 минуты

Не по теме:

Цитата Сообщение от alsav22 Посмотреть сообщение
И в чём мучения?
Наверное в том, что трудно разобраться, что конкретно происходит при нажатии заветной кнопочки в IDE

ValeryS
Модератор
6556 / 5022 / 464
Регистрация: 14.02.2011
Сообщений: 16,763
17.07.2013, 10:05 #29
Цитата Сообщение от Schizorb Посмотреть сообщение
Наверное в том, что трудно разобраться, что конкретно происходит при нажатии заветной кнопочки в IDE
так это про любую IDE можно сказать
у меня три среды VS,Keil, CodeVisionAVR и во всех есть " заветная кнопочка" ручками редко прописываю
Schizorb
509 / 461 / 16
Регистрация: 07.04.2012
Сообщений: 865
Записей в блоге: 1
Завершенные тесты: 1
17.07.2013, 10:13 #30
Цитата Сообщение от ValeryS Посмотреть сообщение
так это про любую IDE можно сказать
Так я и говорю про любую. Но одно дело, когда вы уже понимаете, как все внутри устроено. Другое дело новичок, который хочет разобраться, а ему IDE предлагает - "нажми на кнопку - получишь результат". На этапе обучения все же ручками полезно писать.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
17.07.2013, 10:13
Привет! Вот еще темы с ответами:

Иерархия заголовочных файлов - C++
Вопрос такой. Есть 2 заголовочных файла с классами: core.h interface.h В core.h происходит #include interface.h В...

Отличие заголовочных файлов - C++
чем отличается string.h cstring string

Подключение заголовочных файлов. - C++
У меня есть заголовочный файл: ...\1\2\file.h. в папке "1" есть file2.h. Как подключить к "file.h" "file2.h"?

Подключение заголовочных файлов - C++
Здравствуйте. Возникают ошибки при компиляции проекта: 1. Указывает на указатель: 2. Указывает на указатель и коллекцию указателей: ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
17.07.2013, 10:13
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru