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 Наша первая программа

Один комментарий на “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»

  4. Вася:

    Ну и объясните мне, почему спец символы не работают?

  5. Вася:

    printf(«Hello, World!!!rn»);

  6. Вася:

    «..Отлично! Наша программа работает…»
    Программа не работает, просит ввести .\ перед именем программы.
    Как-то все немного не так да?

  7. bv7:

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

    d:\MYPROG01>gcc main.c
    C:\MinGW\bin\..\lib\gcc\mingw32\3.4.5\..\..\..\..\mingw32\bin\ld.exe: C:/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../libmingw32.a(setargv.o):(.text+0x3d): undefined reference to __chkstk_ms'
    C:\MinGW\bin\..\lib\gcc\mingw32\3.4.5\..\..\..\..\mingw32\bin\ld.exe: C:/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../libmingwex.a(glob.o):(.text+0x709): undefined reference to
    __chkstk_ms'
    C:\MinGW\bin\..\lib\gcc\mingw32\3.4.5\..\..\..\..\mingw32\bin\ld.exe: C:/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../libmingwex.a(glob.o):(.text+0x777): undefined reference to __chkstk_ms'
    C:\MinGW\bin\..\lib\gcc\mingw32\3.4.5\..\..\..\..\mingw32\bin\ld.exe: C:/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../libmingwex.a(glob.o):(.text+0x90d): undefined reference to
    __chkstk_ms'
    C:\MinGW\bin\..\lib\gcc\mingw32\3.4.5\..\..\..\..\mingw32\bin\ld.exe: C:/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../libmingwex.a(glob.o):(.text+0x955): undefined reference to __chkstk_ms'
    C:\MinGW\bin\..\lib\gcc\mingw32\3.4.5\..\..\..\..\mingw32\bin\ld.exe: C:/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../libmingwex.a(glob.o):(.text+0x9e7): more undefined references to
    __chkstk_ms' follow
    collect2: ld returned 1 exit status

    d:\MYPROG01>

    переменную среды C:\MinGW\bin добавил.

  8. Юрий:

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

    • Исполняемый файл не будет, а вот если наш проект пересобрать в Linux, то для Linux сформируется свой исполняемый файл, который будет так же успешно работать. Исполняемые файлы не мультиплатформенны из-за разной реализации ядер.

  9. Сергей:

    Автор , вот установил пакеты Mingw , хорошо , а дальше в какой программе создавать файлы ?

  10. Сергей:

    Атмел студио или кодвижнавр или другая программа ?

  11. Володя:

    В строке команды printf есть ошибка. Hello, World!!!rn вместо Hello, World!!!\r\n

  12. Имя:

    Установил MinGW c оффсайта. При компиляции защитник Виндовс говорит, что в исполняемом файле троян. Проверил на сайте вирустотал исполняемый файл, 22 антивируса говорят, что заражен. Битдефендер говорит что заражен: Файл G:\a.exe заражен Gen:Variant.Ursu.8410

  13. igorstepok:

    Добрый день!
    Не могли бы вы подсказать. Ситуация такова.
    Установил MinGW с оффсайта ссылки на который на этом сайте. После компиляции программы, Защитник Виндовс (Виндовс 10) в исполняемом файле обнаружил троян. Я проверил скомпилированный файл на онлайн сервисе virustotal 22 из 70 антивирусов обнаружили троян. На работе проверил платным Битдефендер, он обнаружил Файл G:\a.exe заражен Gen:Variant.Ursu.8410.

  14. Alive_corpse91:

    Здравствуйте. Большое вам спасибо за вашу работу. С помощью вас начал программировать микроконтроллеры. Только вот большие пробелы в знание языка СИ. Как раз для таких как я, вы начали цикл уроков по основам языка Си. Я запнулся уже на первом уроке. Скачал и установил компилятор MinGW. Повторяя в один в один, шаг за шагом. Запустил консоль прописал путь. Тут полезли ошибки. Вот одна из них cannot find crt 2.o:find such or directory. И так далее. Помогите сдвинутся с мертвой точки.

  15. Сергей:

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

  16. Евгений:

    Ошибка:
    d:\Prog\C\1>gcc main.c
    d:/mingw/bin/../lib/gcc/mingw32/9.2.0/../../../../mingw32/bin/ld.exe: d:/mingw/bin/../lib/gcc/mingw32/9.2.0/../../../libmingw32.a(main.o):(.text.startup+0xc0): undefined reference to `WinMain@16'
    collect2.exe: error: ld returned 1 exit status

    MinGW переустанавливал, gcc —help запускается

  17. gogaze:

    Программу MinGW установил (система Windows7x64), повторил все, что в этом уроке — круто и познавательно!!!
    Автору — моя благодарность и уважение!

  18. Andry:

    Здравствуйте!
    как сделать чтобы консоль не закрывалась?

  19. TheBlindWatchmaker:

    Путь к компилятору путь к исходнику аргумент путь к «результату»
    C:\MinGW\bin\gcc C:\test.c -o C:\test.exe
    если в результате создаётся исполняемый файл, то по всей видимости проблема с путями.
    С путями я так и не разобрался.
    Win7

  20. TheBlindWatchmaker:

    И закрывать консоль не понадобится. Дай команду C:\test или C:\test.exe

  21. TheBlindWatchmaker:

    Всё что написано Автором в сокращённой форме проверил работает. Ссылку на построение инструкций скинуть не могу смотрел параллельно два сайта правильные команды подбирал по наитию. Ни на одном не было ссылки на документацию кстати это сильно упростило бы проблему и отсекло кучу вопросов с нытьём.

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

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

*