Как сделать файл cpp

Обновлено: 05.07.2024

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

Все действия будут производиться на Ubuntu версии 16.04.
Используя компилятор g++ версии:

Состав компилятора g++

Мы не будем вызывать данные компоненты напрямую, так как для того, чтобы работать с C++ кодом, требуются дополнительные библиотеки, позволив все необходимые подгрузки делать основному компоненту компилятора — g++.

Зачем нужно компилировать исходные файлы?

Исходный C++ файл — это всего лишь код, но его невозможно запустить как программу или использовать как библиотеку. Поэтому каждый исходный файл требуется скомпилировать в исполняемый файл, динамическую или статическую библиотеки (данные библиотеки будут рассмотрены в следующей статье).

Этапы компиляции:

Перед тем, как приступать, давайте создадим исходный .cpp файл, с которым и будем работать в дальнейшем.

driver.cpp:

1) Препроцессинг

Самая первая стадия компиляции программы.

Получим препроцессированный код в выходной файл driver.ii (прошедшие через стадию препроцессинга C++ файлы имеют расширение .ii), используя флаг -E, который сообщает компилятору, что компилировать (об этом далее) файл не нужно, а только провести его препроцессинг:

Взглянув на тело функции main в новом сгенерированном файле, можно заметить, что макрос RETURN был заменен:

В новом сгенерированном файле также можно увидеть огромное количество новых строк, это различные библиотеки и хэдер iostream.

2) Компиляция

На данном шаге g++ выполняет свою главную задачу — компилирует, то есть преобразует полученный на прошлом шаге код без директив в ассемблерный код. Это промежуточный шаг между высокоуровневым языком и машинным (бинарным) кодом.

Ассемблерный код — это доступное для понимания человеком представление машинного кода.

Используя флаг -S, который сообщает компилятору остановиться после стадии компиляции, получим ассемблерный код в выходном файле driver.s:

Мы можем все также посмотреть и прочесть полученный результат. Но для того, чтобы машина поняла наш код, требуется преобразовать его в машинный код, который мы и получим на следующем шаге.

3) Ассемблирование

Так как x86 процессоры исполняют команды на бинарном коде, необходимо перевести ассемблерный код в машинный с помощью ассемблера.

Ассемблер преобразовывает ассемблерный код в машинный код, сохраняя его в объектном файле.

Объектный файл — это созданный ассемблером промежуточный файл, хранящий кусок машинного кода. Этот кусок машинного кода, который еще не был связан вместе с другими кусками машинного кода в конечную выполняемую программу, называется объектным кодом.

Далее возможно сохранение данного объектного кода в статические библиотеки для того, чтобы не компилировать данный код снова.

Получим машинный код с помощью ассемблера (as) в выходной объектный файл driver.o:

Но на данном шаге еще ничего не закончено, ведь объектных файлов может быть много и нужно их всех соединить в единый исполняемый файл с помощью компоновщика (линкера). Поэтому мы переходим к следующей стадии.

4) Компоновка

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

Таблица символов — это структура данных, создаваемая самим компилятором и хранящаяся в самих объектных файлах. Таблица символов хранит имена переменных, функций, классов, объектов и т.д., где каждому идентификатору (символу) соотносится его тип, область видимости. Также таблица символов хранит адреса ссылок на данные и процедуры в других объектных файлах.
Именно с помощью таблицы символов и хранящихся в них ссылок линкер будет способен в дальнейшем построить связи между данными среди множества других объектных файлов и создать единый исполняемый файл из них.

Получим исполняемый файл driver:

5) Загрузка

Последний этап, который предстоит пройти нашей программе — вызвать загрузчик для загрузки нашей программы в память. На данной стадии также возможна подгрузка динамических библиотек.

Запустим нашу программу:

Заключение

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

Здраствуйте. У меня такой вопрос.
Предположим нужно сгенерировать какой-нибудь код на C++ и сохранить его в файлах .h и .CPP. (программа на С++ генерирует)
Не могли бы вы подсказать как это сделать.
То есть, как вообще с помощью C++ создать файл с такими расширениями?
(заранее извиняюсь если вопрос глупый, но мне не понятно)

Так, начну с того, что *.CPP файл, это обычный текстовый файл.
Создать его можно функцией
//----------------------ВЗЯЛ ИЗ MS SDK-------------------------------
HANDLE CreateFile(
LPCTSTR lpFileName, // pointer to name of the file
DWORD dwDesiredAccess, // access (read-write) mode
DWORD dwShareMode, // share mode
LPSECURITY_ATTRIBUTES lpSecurityAttributes, // pointer to security attributes
DWORD dwCreationDistribution, // how to create
DWORD dwFlagsAndAttributes, // file attributes
HANDLE hTemplateFile // handle to file with attributes to copy
);
//---------------------------------------------------------------------
так, функция возвращает идентификатор созданного файла (Handle).
первый параметр функции это и есть имя файла. В нашем случае это SuperFile.cpp. правильно. нам же нужен *.cpp файл?
далее,
второй параметр есть тип доступа к объекту может быть
0 - железка сама решает как файл может быть открыт программой
GENERIC_READ - только чтение
GENERIC_WRITE - запись.
можно комбинировать, если мне не изменяет память при помощи операции побитового или. тоесть GENERIC_READ | GENERIC_WRITE
далее,
значит тут идет параметр, регулирующий, как будет вести себя система при одновременном открытии данного файла несколькими приложениями, возможны варианты:
FILE_SHARE_DELETE - если одно приложение работает с файлом, а от другого приходит запрос на его удаление, файл будет удален
FILE_SHARE_READ - соответственно дает читать одновременно всем
ну и FILE_SHARE_WRITE - писать одновременно все.
Можешь поставить 0, и тогда только одна прога может читать/писать этот файл в один момент времени.
далее,
идет указатель на структуру SECURITY_ATTRIBUTES, ее нужно объявить выше. туда будут помещены кое какие данные, тут писать не буду.
далее идет интересный параметр,
отвечающий за реакцию функции на разные обстаятельства при создании файла, если указать
CREATE_NEW - функция навернется если файл уже существует
собственно эту константу и ставь. а то я печатать запарюсь
и последний параметр, отвечает за атрибуты файла
FILE_ATTRIBUTE_HIDDEN - вот так ты сделаешь скрытым
FILE_ATTRIBUTE_NORMAL - так нормальным сделаешь.
есть куча возможностей,
далее идет последний. о да, наконец то, последний параметр, отвечает за указание системе, как создать файл.
есть вариации, можно реализовать отложенную запись на диск, писать файл в кэш, а потом уже на диск.
но нам тут нужен параметр.
в общем я особо не вник пиши NULL
вот рабочий пример вызова функции

HANDLE hFile =
CreateFile("C:\\test121233.cpp", GENERIC_READ|GENERIC_WRITE, 0, &tt, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);

Бог сделал людей разными, а генерал Кольт уравнял шансы Да, народ,
кто силен в английском, переведите инфу про последний параметр. Бог сделал людей разными, а генерал Кольт уравнял шансы это параметр, принимающий Хендл на временный файл, а временный файл, это файл имеющий атрибут копии. Я вас правильно понял?
если да, то смысл такого действия.
просто в MS SDK писалось нечто насчет отложенной записи на диск и прочего. Бог сделал людей разными, а генерал Кольт уравнял шансы studenth персональное спасибо)
Только я так понял, это для Visual, а мне бы для builder'a. На одном форуме сказали, что это в принципе обычные текстовые файлы и с ними можно работать так же(создавать, редактировать и т.д)

Я наверно некорректно выразился, технически перевел, вот цитата :

Файл-шаблон, атрибуты которого используются для открытия. В Windows 95/98 не используется и должен быть равен 0

Кроме того : hTemplateFile is not supported and the function fails if it is nonzero. - Этот параметр не поддерживается и функция вернет фальш если не поставить в него 0 (Null)

Только я так понял, это для Visual, а мне бы для builder'a.

Если честно, я не пользуюсь Visual, только продукцией фирмы Borland.
Это функция из прикладного интерфейса программирования Win32.
Ее можно без труда использовать в обоих средах.

Вот мой make-файл:

И вот мой главный cpp:

Он компилируется без предупреждения, когда я запускаю «make», но во время выполнения он сообщает мне: «ошибка при загрузке общих библиотек: libhts.so.2 не может открыть файл общих объектов»

Любая помощь приветствуется! Заранее спасибо.

Решение

Это не проблема с вашим make-файлом как таковым; у вашего make-файла есть некоторые проблемы, но проблема, с которой вы сталкиваетесь, заключается в понимании того, как правильно связываться с общими библиотеками. Другими словами, если вы запустите тот же набор команд из командной строки оболочки, вместо использования make-файла, у вас возникнет та же проблема.

Вы должны искать документацию по вашей опции командной строки ссылки -L и прочитайте о разнице между ссылка времени а также время выполнения места расположения библиотеки

-lfoo опция сообщит компоновщику ссылку в библиотеку с именем foo , -Lsome/dir опция скажет компоновщику найти эту библиотеку foo в каталоге some_dir ,

Если компоновщик находит статическую библиотеку libfoo.a тогда любые части этой библиотеки, необходимые для связи вашей программы, будут включены непосредственно в вашу программу. Это делает вашу программу больше, но это означает, что в время выполнения ничего кроме вашей программы не нужно искать.

Если компоновщик находит общую библиотеку (также называемую динамической библиотекой) libfoo.so тогда компоновщик просто помещает ссылку на имя библиотеки libfoo.so в вашу программу (конечно, детали сложнее, чем это, но это общая идея). Это делает вашу программу меньше но это означает, что во время выполнения нужна не только ваша программа, но и общая библиотека, иначе ваша программа не может быть запущена.

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

Компоновщик во время выполнения просматривает различные места, о которых можно узнать, прочитав его документацию; например, в GNU / Linux временный компоновщик называется ld.so так что вы можете читать документы с man ld.so ,

Это сложная тема, и лучший способ сделать это зависит от ваших потребностей и потребностей.

Если вы просто хотите жестко прописать путь для поиска во время компиляции / компоновки, вы можете добавить -Rsome/dir вариант для вашей линии связи, по одному для каждого -L вариант, вот так:

Это будет хорошо работать, пока SAMTOOLS а также HTSLIB каталоги существуют и до сих пор содержат правильные общие библиотеки в них. Очевидно, что это большое ограничение, но мы не можем догадаться, каковы ваши конечные требования.

Видео урок

Основные особенности кода на C++

Прежде чем мы напишем первую программу на C++, надо узнать основные требования к коду на C++.Их не так много, как может показаться на первый взгляд. Вот собственно список:

  • каждая команда заканчивается точкой с запятой ; ;
  • в названии команд и прочих инструкций не может быть пробелов, а также они не могут начинаться с цифр;
  • язык С++ чувствителен к регистру символов. То есть, CODE, CoDe и code могут выполнять абсолютно разные задачи;

Это и есть главные правила, на которых основан фундамент программирования на C++.

Начало работы с C++

Для того чтобы начать работу, вы должны создать файл с расширением .cpp или новый проект в своей среде программирования.

Теперь давайте разберем главные аспекты C++ на примере. Для этого мы запустим тестовою программу, а затем шаг за шагом рассмотрим структуру программ в C++:

Можете скопировать данный код или напечатать самостоятельно (рекомендуется).

После выполнения программы мы увидим такое окно:

Разбор кода

Теперь давайте приступим к разбору написанного нами кода:

Как видите здесь нет ничего сложного, лишь пару шаблонных строк кода. Остальное же, ограничено лишь вашим воображением и знанием языка программирования. Пожалуй основы C++ мы изучили, осталось лишь подитожить все выше перечисленное.

Подводим итоги

Из главных правил хотелось бы выделить следующие:

На этом все. Можете пройти тест по пройденному материалу.

Пройдите тест и проверьте уровень усвоения материала. Какой из перечисленных операторов является корректным? Первый Вариант ответа начинается с цифры, что недопустимо.
Второй является верным.
Третий содержит пробел.
А четвертый, также начинается с цифры. Какая из следующих строк кода выведет строку Hello, CodeLessons! Какая функция в C++ запускается автоматически вместе с программой? какая директива используется для подключение дополнительного функционала? You have not finished your quiz. If you leave this page, your progress will be lost.

Требуется больше практики

Требуется больше практики

Уроки для новичков Комментарии

Добавить комментарий Отменить ответ

почему после вставки это не работает?

У вас ошибка в первой строчке:

Попробуйте еще разок)

return 0;
>
вот так выглядит

простите за мою не внимательность

та уже все я просто не так сделал все работает

using namespace std;

Вы обещали написать про использование области имен переменных std.

int main () cout <<"Nokia Asha 311!" <<endl; // Это название телефона
cout <<"Nokia Asha Touch!" <<endl; // Это название экрана
cout <<"GSM 850/900/1800/1900!" <<endl; // Это что присутствует в нем
cout <<"GPRS/EDGE class B,multislot class 33!" <<endl; // Это тоже
cout <<"UMTS 850/900/1700/1900/2100!" <<endl; // Это его функции
cout <<"Form factoring monobloc 106x52x12,9 mm!" <<endl; // Это его размеры
cout <<"System = Series 40 Developer Platform 2.0!" <<endl; // Это какая у него система и какие игры и программы поддержывает
cout <<"Li-On BL-4U,1110 mA\c!" <<endl; // Это какая у него батарейка

Поздравляю! Так держать)

Чувак, я скопировал и у меня высветилось море твоих ошибок)

Видимо у вас не компилируется файл. Проверьте настройки вашего компилятора в среде программирования.

Спасибо огромное, Дмитрий, Очень хорошие уроки и хоть это базовый уровень но всё равно круто быть программистом!!

Молодец. Спасибо.
Мне 65))) а хочу податься в программисты)))
Как ты думаешь, освою)?)

Конечно, работайте и все у вас получится! 🙂

return 0;
>
всё написал но CMD не высвечивается.

Попробуйте переустановить Codeblocks, а также компилятор MinGV

В начале программы напишите данную строчку setlocale (LC_ALL, "Rus");

Здорово! Пока не сложно. Но при запуске срабатывает антивирус и ищет проблему. Почему?

Читайте также: