|
|
  |
Вопросы по C от ламера, В книжках ответа чёта не нахожу |
|
|
|
Apr 23 2009, 19:52
|

Чайник, 1 литр
   
Группа: Свой
Сообщений: 655
Регистрация: 17-05-06
Из: Moscow
Пользователь №: 17 168

|
Стоило остановиться еще там: Цитата(Скопидор @ Apr 15 2009, 11:47)  В 2 этапа: сначала по отдельности компилируем все файлы (получаем OBJ-файлы), потом линкуем. Правильно? Ну компилируем, линкуем, да. Как именно выполняется компиляция, линкование; что скрыто за этими терминами; результаты работы компилятора; результаты работы линкера? Книги типа учебника по C++ для первого курса универа Т.А. Павловской с задорным страусом на обложке ессно вам ответов на эти вопросы не дадут! Берите литературу серьёзнее, раз вас интересует как оно изнутри устроено. Это даже вне C\C++ как языка. Это общий подход в языках выского уровня. PS: вы ж разбираться не стали, но громко предлагаете синими буквами сомнительных наклонностей потрындеть о ваших догадках по этому вопросу; чего ж вы хотели кроме RTFM в ответ?..
|
|
|
|
Guest_Скопидор_*
|
Apr 23 2009, 20:07
|
Guests

|
Цитата(singlskv @ Apr 23 2009, 22:46)  #include "..." #include <...> обычно означает включить объявления а не определения переменных и функций (исключения конечно есть, но пока это не Ваш случай) если Вы включаете по include просто С код, то тогда это просто разбиение кода на несколько файлов, это дурной тон, но иногда делают и так... .h(.hpp) файлы библиотек(iostream например) для того и нужны чтоб правильно прилинковать библиотеки и указать на глобальныее переменные/вызовы функций которые там реализованны. Так что раздельная компиляция это совсем не миф...  более того, это просто СТАНДАРТ. Т.е. короче говоря, в библиотечных файлах (типа iostream) ВСЕГДА находятся только объявления (не определения) типов, переменных и т.п. и прототипы функций. Когда препроцессор, просматривая исходник, «утыкается» в директиву #include <iostream>, то он ВСЕГДА вставляет содержимое РЕАЛЬНО СУЩЕСТВУЮЩЕГО (в системной директории компилятора) файла iostream, содержащего только объявления, в исходник юзверя. Затем компилятор преобразует полученный после работы препроцессора файл в объектный модуль (формат ELF или COFF). При этом в этом файле сохраняются ссылки на объекты (т.е. переменные, типы и т.п.), определённые в других файлах. Затем компилятор преобразует в объектный код все остальные CPP-файлы проекта. После этого линкер, анализируя объектный файл, полученный после компиляции PRIMARY CPP-файла (т.е. файла содержащего main) «прилепливает» к нему код из объектных файлов системных библиотек и объектных файлов, полученных после компиляции всех других CPP-файлов, и получает исполняемый файл (экзешник для DOS и Win). При этом это ЛИНКЕР определяет какой код из системных библиотек «прилеплять», а какие не надо. Я правильно понимаю?
|
|
|
|
|
Apr 23 2009, 20:17
|
Профессионал
    
Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007

|
Цитата(Скопидор @ Apr 23 2009, 23:07)  Я правильно понимаю? Почти правильно. Так оно и было, лет этак 30 тому назад. Сейчас этот процесс несколько усложнился тем, что include-файлы теперь включают : 1. inline функции, которые могут вызываться как функции, а может компилятор их текст включить в код вызывающей функции. 2. template шаблоны. Но в общем процесс сборки программы вы уловили правильно.
|
|
|
|
Guest_Скопидор_*
|
Apr 23 2009, 20:26
|
Guests

|
Цитата(singlskv @ Apr 23 2009, 23:48)  Раздражение здесь может быть только от одного, многим видно, что Вы не сделали и десятой доли усилий, чтоб это познать самому без посторонней помощи... Сделайте усилие над собой, а потом задавайте вопросы... и тогда Вам с удовольствием помогут. Вы телепат? Ну если 2 книги по C++, заученные чуть ли не наизусть - это по-Вашему не усилия, тогда я действительно не приложил НИКАКИХ усилий. Просто у меня мало свободного времени читать книги десятками томов. Вот и хотелось чтоб на каждый конкетный (может и глупый, как кажется некоторым с позиции их опыта) вопрос, такой же конкретный, и главное ОБОСНОВАННЫЙ ответ. Я думал, что если человек что-то хорошо понимает, в чём-то хорошо разбирается, то ему не будет трудно это объяснить человеку, который пока это не понимает, но хочет понять Цитата(singlskv @ Apr 24 2009, 00:13)  ...где-то так, более подробно можно обсуждать только после подробного изучения Вами соответствующей документации... О какой документации идёт речь? В книгах, которые я читал, идеология раздельной компиляции и принципы «дробления» текста программного проекта по файлам, процесс раздельной компиляции и линковки программы описаны очень поверхностно, «в двух словах».
|
|
|
|
|
Apr 24 2009, 04:24
|

Беспросветный оптимист
     
Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646

|
Цитата(Скопидор @ Apr 24 2009, 00:07)  Т.е. короче говоря, в библиотечных файлах (типа iostream) ...
Я правильно понимаю? В целом да, за исключением одной неточности: библиотечные файлы (lib) содержат специально упакованный объектный код. То, что вы подключаете инклудом - это не библиотечные, а заголовочные файлы, вот они и содержат всё что вы написали. А код из библиотек подставляется на этапе линковки. В заголовочных файлах С++ (hpp) могут содержаться описания классов, и это вроде как код, но на самом деле этот код виртуальный, а "материализуется" он в том месте, где вы объявляете экземпляр класса. Вообще вместо разных умных (и глупых) книжек советую попробовать слепить какой-нибудь хелловорд в GCC, причём без разных навороченных оболочек. Просветление наступает очень быстро. Кстати, будете смеяться, но большинство гуёвых прогеров, которые пользуются разными визуальными примочками типа дельфи-билдера, никогда не видели функцию main() Некоторые даже не подозревают, что она всё-таки существует
--------------------
Программирование делится на системное и бессистемное. ©Моё :) — а для кого-то БГ — это Bill Gilbert =)
|
|
|
|
Guest_Скопидор_*
|
Apr 24 2009, 07:31
|
Guests

|
Цитата(sergeeff @ Apr 24 2009, 01:33)  И в результате всей совместной деятельности форумчан и напряжения вашей головы, процесс сборки программы стал более понятен? Да. И наверное не только мне, а всем прочим ламерам в C++, которые тоже только начинают изучение C++ и приходят на этот форум P.S.Но смею Вас заверить, что достигнув некоторого уровня понимания процесса получения исполняемого файла из нескольких библиотечных и нескольких файлов юзверя, мои ламерские вопросы не закончатся  Так что готовьтесь.  Тем более что на вопросы, которые я писал выше ответов так и не последовало (вопросы про enum, допустимые символы в строковом литерале и функцию main) Цитата(MrYuran @ Apr 24 2009, 08:24)  Вообще вместо разных умных (и глупых) книжек советую попробовать слепить какой-нибудь хелловорд в GCC, причём без разных навороченных оболочек. Просветление наступает очень быстро. Да фазу «Хелло ворлда» я прошёл уже месяца 3 назад. После чего стал «копать глубже». А потом, я не понимаю, как, написав «Хелло ворлд», и получив исполняемый файл нажатием одной единственной кнопочки «Rebuild All» я пойму как оно там всё «в кишках» компилятора происходит? От меня же это всё скрыто. Я вижу только одну кнопочку. Цитата(MrYuran @ Apr 24 2009, 08:24)  Кстати, будете смеяться, но большинство гуёвых прогеров, которые пользуются разными визуальными примочками типа дельфи-билдера, никогда не видели функцию main() Некоторые даже не подозревают, что она всё-таки существует Точно также как я не подозревал (до того как начал "копать") как происходит процесс создания исполняемого файла когда работал только с кнопкой "Rebuild All"  И на вопрос «как происходит получение исполняемого файла» я совершенно искренне ответил бы «по нажатии кнопки 'Rebuild All'» ////////////////////////////////// Цитата(MrYuran @ Apr 24 2009, 08:24)  В целом да, за исключением одной неточности: библиотечные файлы (lib) содержат специально упакованный объектный код. И формат этого lib-файла отличается от формата объектника, получаемого после компиляции PRIMARY-файла (т.е. файла, содержащего main)? А юзверь может дополнить системную библиотеку своими lib-файлами? А «подправить» lib-файл коммерческого компилятора (типа Microsoft Visual C++) у юзверя есть возможноть? //////////////////////////////////////// Цитата(MrYuran @ Apr 24 2009, 08:24)  А код из библиотек подставляется на этапе линковки. А как линкер узнаёт, какой код из объектников системных файлов нужно «пришить» к объектнику Primary-файла? Путём анализа содержимого объектника Primary-файла? А отличается ли формат объектного файла Primary-файла от формата объектных файлов других CPP-файлов, входящих в проект? А где можно почитать про формат объектных файлов (как системных {т.е. lib}, так и юзверя)?
Сообщение отредактировал Скопидор - Apr 24 2009, 07:19
|
|
|
|
Guest_Скопидор_*
|
Apr 24 2009, 09:03
|
Guests

|
Цитата(mdmitry @ Apr 24 2009, 12:09)  Вы так и не озвучили, какие книги использовали  Книги по C++
|
|
|
|
Guest_Скопидор_*
|
Apr 24 2009, 09:17
|
Guests

|
Цитата(andrew_b @ Apr 24 2009, 13:08)  Не тролльте. Вы тоже.
|
|
|
|
Guest_Скопидор_*
|
Apr 24 2009, 09:44
|
Guests

|
Цитата(mdmitry @ Apr 24 2009, 13:34)  участвовать в дальнейшем обсуждение для себя не считаю уместным. "Хозяин - Барин"© Цитата(mdmitry @ Apr 24 2009, 13:34)  На конкретный вопрос принято отвечать конкретно А я разве не конкретно ответил? P.S. А мне что некоторые как отвечали, когда я просил КОНКРЕТНЫХ ответов? А? Отвечали в стиле "RTFM", "Учи матчасть", "у тебя в голове - каша", "Читай книги" (как будто я их не читаю)
Сообщение отредактировал Скопидор - Apr 24 2009, 09:52
|
|
|
|
Guest_Скопидор_*
|
Apr 24 2009, 11:51
|
Guests

|
Цитата(Скопидор @ Apr 15 2009, 02:13)  5.Если main – функция, то можно ли её рекурсивно вызвать внутри её самой? Можно. Новички в C++!!! Кому надо привожу пример: CODE // Рекурсивные вызовы функции main из функции main // Реально достигнутый максимальный уровень вложенности main равен 12302 // Компилятор: Microsoft Visual C++ версии 6.0 // ОС: Windows XP SP2 // main.cpp // 15:05 24 апреля 2009 г. // #include <iostream> using namespace std;
int i = 0; const int Level_max = 12302; // Больше значение установить нельзя !!!
void main () { if (i <= Level_max ) { cout << "i = " << i << '\n'; // Выводим на экран значение счётчика уровня вложенности i++; // Увеличиваем счётчик уровня вложенности main (); // Вызываем рекурсивно main из main } }
// Получили на экране:
/* i = 0 i = 1 i = 2 i = 3 i = 4 i = 5 i = 6 ......... i = 12296 i = 12297 i = 12298 i = 12299 i = 12300 i = 12301 i = 12302 i = Press any key to continue */
Причина редактирования: Уменьшение видимого размера цитаты исходника.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|