C Урок 1. Наша первая программа. Часть 2

 

 

 

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

 

Теперь давайте попробуем создать какой-нибудь исходный код на C и получить из него функционирующую программу.

Для этого создадим каталог (папку, директорий) где-нибудь, например, с именем MYPROG01 и создадим в данном каталоге файл с именем, например, main.c, так как файлы с исходным кодом принято создавать с расширением .c. Файл мы создадим вот такого содержания

 

 

Это и будет наша первая программа, которая выведет в консоль текст Hello, World!!!, а также возвратит каретку и переведёт строку благодаря специальным символам 'r' и 'n'.

Что же находится в нашем исходном коде.

Для начала мы подключаем файл stdio.h, в котором находятся прототипы (пока можете не вдаваться в значение этого слова, позже мы с прототипами будем работать сами постоянно) функций стандартной библиотеки C, связанной с вводом-выводом.

Далее идёт функция (в C все подпрограммы обёртываются в функции, об этом мы также поговорим позже) main(), которая является точкой входа в нашу программу и любая программа в C всегда начинает выполняться именно с этой функции. У функции есть имя main, служащее для того, чтобы функцию можно было вызвать откуда-либо, также есть параметры входящие, которые заключены в круглые скобки (в нашем случае функция никаких параметров не принимает), а также один возвращаемый параметр какого-либо типа (в нашем случае int — целочисленный знаковый тип, о типах мы тоже будем говорить позже). Также у любой функции, а наша функция тому не исключение есть тело — это часть функции, заключенная в фигурные скобки. В теле идут друг за другом команды, которые говорят «программе», что она должна делать в данный момент.

Первая команда

 

 

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

Следующая команда

 

 

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

Задача MinGW — преобразовать файл с исходным кодом в исполняемый типа exe.

Откроем консоль (командную строку), находясь в нашем каталоге и, оказывается для нашей операции вполне достаточно одной команды gcc, в параметрах которой мы указываем файл с исходным кодом

 

 

В случае успеха у нас появится файл с именем a.exe в текущем каталоге

 

 

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

 

 

Отлично! Наша программа работает.

Также мы можем назначить любое имя для выходного файла в параметре с помощью ключа -o (расширение можно также не вводить). Удалим a.exe и введём команду

 

 

У нас появится файл с нужным нам именем

 

 

Работоспособность его будет такая же, так как это тот же файл, только с другим именем

 

 

Как вообще происходит процесс создания исполняемого файла из файла (файлов) с исходным кодом?

Первый этап — это трансляция, которая превращает исходный код в объектный, и создаётся файл (или несколько файлов) с расширением -o.

Второй этап — это компоновка или линковка. На данном этапе объектный файл (или несколько) компонуется (компонуются) в один исполняемый файл.

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

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

Удалим файл myprog.exe, чтобы у нас в директории остался лишь файл main.c.

Затем введём вот такую команду, которая нам сформирует файл main.i со всем кодом, в т.ч. подключенным, в результате препроцессинга

 

 

Судя по размеру полученного файла, мы понимаем, сколько кода нам в него добавил препроцессор

 

 

Покажу лишь часть кода в этом файле, остальной посмотрите у себя

 

 

 

Далее мы из этого файла можем получить ассемблерный (main.s) с помощью следующей команды

 

Откроем данный файл и посмотрим его содержимое

 

 

Пока нам здесь мало что понятно, но до ассемблера мы когда-нибудь, надеюсь, тоже доберёмся.

Теперь непосредственно компиляция. Для создания объектного файла main.o дадим следующую команду

 

 

Имя выходного файла мы не указываем, так как по умолчанию формируется файл с тем же именем, что и исходный, если нужно какое-то другое имя на выходе, то можно использовать ключ -o.

Мы видим, что у нас появился объектный файл

 

 

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

Затем мы уже производим линковку (создаём исполняемый файл из объектного (или нескольких))с помощью следующей команды

 

 

После данной команды у нас появился исполняемый файл

 

 

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

Также в результате поэтапной сборки мы можем применить некоторые опции, например изменить уровень оптимизации кода, используя ключи -O0, -O1, -O2, -O3 при создании объектного файла (или нескольких).

Назначение различных уровней оптимизации описано много где, например вот тут.

Я пробовал различные уровни в случае формирования исполняемого кода из исходного файла нашего занятия. Результат мало чем отличается, так как у нас и кода-то особого нет. А в случае написания программ с огромным количеством кода оптимизация сильно помогает. Хотя всю отладку программ на этапе их создания и тестирования лучше производить с отключенной оптимизацией (без использования ключа, так как по умолчанию оптимизация отключена, либо с ключом -O0).

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

Всем спасибо за внимание!

Предыдущая часть Программирование на C Следующий урок

 

Исходный код

 

 

Смотреть ВИДЕОУРОК (нажмите на картинку)

 

C Наша первая программа

5 комментариев на “C Урок 1. Наша первая программа. Часть 2
  1. Нодир:

    Здравствуете спасибо за познавательные видео уроки и статьи. Возможна ли на MinGW программировать компьютерной графикой и начать самого простого вывод на экран пикселя? А то как то скучна решат задачи без рисования графиков , фракталов и.т.д

    • Спасибо за интерес!
      Можно конечно, практически весь функционал Windows, весь его API здесь доступен. Но к тому времени, когда мы будем писать графику, я думаю мы уже освоим сценарии и будем работать в среде.

  2. Александр:

    Чем то anjuta напоминает только она в Linux.

  3. zhenya_nguyen:

    Здравствуйте, во первых хотел сказать спасибо вам большое за познавательные уроки!
    во вторых хотел спросить, почему в ходе создании ассемблерного файла main.s из main.i (команда gcc -S main.i -o main.s) у меня не создается main.s? выдается куча варнингов такого типа «main.i:901:15: warning: null character(s) ignored»

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

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*