2. Структура простейшей одномодульной программы
Как отмечалось выше, весь исходный текст одномодульной программы должен находиться в одном файле. Выделим среди одномодульных программ класс простейших одномодульных программ. К этому классу программ будем относить программы, состоящие только из одной функции main() .В
настоящей части пособия будут рассматриваться только такие программы. Отметим еще одно ограничение приводимых программ – в них будут отсутствовать так называемые внешние переменные. Внешними переменными называются переменные, которые объявляются вне функций. Программы, приводимые в настоящей части пособия, содержат три структурных компонента: ● Комментарий, относящийся ко всей программе в целом. ● Директивы препроцессора. ● Определение функции main(). Остановимся на каждом из этих компонентов подробнее.
2.1. Комментарии в программе на языке Си
Комментарии используются для целей документирования программ. Комментарии не влияют на выполнение программы. При компиляции они удаляются из программы. Стандарт С99 позволяет использовать в программах комментарии двух видов: ● Комментарии, традиционные для языка Си. ● Однострочные комментарии, заимствованные из языка С++.
Традиционный комментарий в языке Си – это последовательность символов, входящих в его алфавит, которая начинается двумя символами “/*” и заканчивается этими же символами, следующими в обратной последовательности “*/.”. Такой комментарий может располагаться на нескольких строках. Приведем пример традиционного комментария. /* Лабораторная работа № 1 Программирование линейных вычислительных процессов */ Однострочный комментарий начинается с двух символов косая черта “//”. Такой комментарий включает в себя все символы текущей строки, следующие за этими символами. Ниже приводится пример применения однострочных комментариев. // Лабораторная работа № 2 // Программирование разветвляющихся вычислительных процессов Следует учитывать, что не все компиляторы языка Си, используемые на практике, поддерживают однострочные комментарии.
2.2. Начальные сведения о препроцессоре
Препроцессор – это программа, которая выполняет предварительную обработку исходного текста программы, написанной на языке Си. Иногда препроцессор является самостоятельной системной программой, в других случаях он входит в состав компилятора. Препроцессор управляется так
называемыми директивами. В простейшем случае директива препроцессора имеет следующую структуру: # имя_директивы содержательная_часть Директива препроцессора всегда начинается с символа “#”, за которым следует имя директивы. Приведем примеры директив препроцессора: #include #include #define MAXSIZE 100 В приведенном выше примере имеются три директивы препроцессора.
Имя первой директивы include, а в ее содержательной части находится заключенное в угловые скобки имя системного заголовочного файла stdio.h. Эта директива предписывает препроцессору включить вместо рассматриваемой директивы содержимое системного заголовочного файла stdio.h.
Наличие в модуле такой директивы необходимо в том случае, когда в нем содержатся вызовы функций стандартного ввода – вывода. В заголовочном файле stdio.h содержаться объявления функций стандартного ввода – вывода (о понятии объявления функции смотри немного ниже). Вторая директива c именем include выполняет такую же работу, что и первая директива препроцессора, но для математического заголовочного файла math.h. Этот заголовочный файл необходимо подключать в том случае, когда в исходном тексте модуля имеются вызовы библиотечных математических функций. Третья директива предписывает препроцессору заменить в рассматриваемом файле исходного текста все вхождения слова MAXSIZE константой 100 . Директива define используется для определения так называемых символических констант. В рассматриваемом случае такой константой является MAXSIZE . В языке Си существует традиция записывать заглавными буквами имя символической константы, определенной с помощью директивы define .
2.3. Определение функции main().
● Функция main() должна вернуть в точку своего вызова целочисленное значение. Об этом свидетельствует зарезервированное слово int , с которого начинается заголовок, которое является спецификатором одного из целочисленных типов языка Си. ● У функции main () отсутствуют параметры. На это указывает зарезервированное слово void , стоящее в скобках.
Второй компонент определения функции main() – тело, содержащее алгоритм, ею реализуемый. В теле располагается последовательность предложений языка Си, которая заключена в фигурные скобки. Ниже приводится простейшая программа. Это минимальная программа, которая может быть написана на языке Си.
Она не выполняет никаких полезных действий, что дает основание считать ее пустой. /* Пустая программа. Файл empty.c */ int main( void ) < return 0; >В рассматриваемой программе тело функции main() содержит единственное предложение, которым является инструкция return . Эта инструкция формирует результат, возвращаемый функцией main(). Этот результат функция main() передает операционной системе. Возврат значения, равного нулю, воспринимается операционной системой как нормальное завершение работы функции main() .
2.4. Пример простейшей программы
Постановка задачи Даны два целых числа a и b . Вычислить их сумму y . Программа Ниже приводится программа, предназначенная для решения данной задачи, а затем даются необходимые к ней пояснения. /* Программа, выполняющая сложение двух целых чисел
Файл | Summa.c |
*/ |
#include #include int main( void ) < int a, b, y; clrscr(); printf(“ Первое число =”); scanf(“%d”, printf(“ Второе число =”) scanf(“%d”, y = a + b;
К функциям ввода – вывода в рассматриваемой программе относятся функции printf() , scanf() и getch(). Основную работу по вводу – выводу выполняют первые две функции. Последняя функция ( getch() ) может оказаться необходимой для задержки экрана. В некоторых системах программирования необходимость в ее использовании может отсутствовать.
Эта функция ожидает от пользователя нажатия на любую клавишу. Перейдем к рассмотрению функций printf() и scanf() . Функции printf() и scanf() относятся к так называемым функциям форматированного ввода – вывода. Функция printf() применяется для вывода на дисплей, а функция scanf() – для ввода с клавиатуры. В этих функциях предусмотрены специальные средства для управления процессом ввода – вывода.
Эти средства называются спецификациями преобразования. В функции scanf() спецификации преобразовании используются всегда. В простейших вариантах использования функции printf() спецификации преобразования могут отсутствовать. Спецификации преобразования, если они имеются, всегда находятся в первом аргументе вызова рассматриваемых функций.
Для этого аргумента используется специальное название: форматная строка. Каждая такая спецификация начинается с символа процент ( % ) и заканчивается символом, определяющим тип преобразования. В связи с тем, что рассматриваемая программа работает только с данными целого типа, в функциях ввода – вывода используется тип d , предназначенный для преобразования данных целого типа.
Рассмотрим объем работы, которую необходимо было выполнить в настоящей программе по вводу – выводу. Во-первых, необходимо было обеспечить ввод двух исходных чисел: a и b . Для этого следует использовать функцию scanf() . Оба эти числа можно ввести с помощью одного вызова этой функции. Однако предпочтительнее вводить каждое число с использованием отдельного вызова этой функции.
Представляется, что такая организация ввода упрощает работу пользователя по вводу данных и уменьшает количество ошибок, которые может допустить программист при его организации. Этот способ ввода и принят в рассматриваемой программе.
Вызов функции scanf() в программе должен быть предварен выводом наводящего сообщения, которое уведомляет пользователя, о том какая информация от него запрашивается. Эти наводящие сообщения выводятся в программе с помощью вызова функции printf().
Остановимся подробнее на организации ввода переменной a . В программе для этой цели служит следующий фрагмент кода: printf(“a=”); scanf(“%d”, Функция printf() здесь вызывается с одним аргументом – форматной строкой, однако спецификации преобразования в ней отсутствуют. Такая форма вызова функции printf() используется для вывода на экран сообщений для пользователя. Текст, находящийся между кавычками, выводится на экран дисплея. Вызов функции scanf() имеет два аргумента.
Первым аргументом является форматная строка, содержащая одну спецификацию преобразования ( %d ), которая уведомляет компьютер о том, что вводимая c клавиатуры порция информации должна рассматриваться как целое число. Второй аргумент определяет адрес памяти, в которую следует направить введенное с помощью функции scanf() число.
Для получения этого адреса образуется выражение (оператор взятия адреса) предписывает компилятору вычислить адрес переменной a . Выражение Эта инструкция предписывает вычислить выражение, стоящее справа от символа “=”, и результат вычисления сохранить в переменной y . Символ “=” в языке Си называется оператором присваивания. Перейдем к рассмотрению вопросов, связанных с выводом результатов вычислений.
Вызов функции printf() , выполняющей эту работу, имеет следующий вид : printf(“ Сумма =%dn”, y); В рассматриваемом вызове функции printf() форматная строка кроме уже знакомой спецификации преобразования %d содержит некоторые другие символы. К их числу относятся символы, предшествующие спецификации преобразования.
Особенность этих символов, состоит в том, что каждый из них имеет графическое изображение. Эти символы образуют текст ( Сумма = ), назначение которого служить пояснением к выводимой числовой информации. В конце форматной строки находятся два символа (n), составляющие так называемую управляющую последовательность.
Рассматриваемая управляющая последовательность носит название “новая строка”. Ее назначение в приведенном вызове состоит в переводе курсора на новую строку экрана. Кроме форматной строки в рассматриваемом вызове присутствует второй аргумент, представленный переменной y , значение которой требуется вывести на экран.
Спецификация преобразования, содержащаяся в форматной строке ( %d ), предписывает компилятору выполнить преобразования выводимого численного значения переменной y . Дело заключается в том, что информация, хранящаяся в памяти компьютера, связанная с этой переменной, имеет машинную форму. Информация, появляющаяся на экране в результате работы вызова функции printf() , представляет собой последовательность символов. Руководствуясь спецификацией %d , компьютер должен построить строковое изображение числа, хранящегося в переменной y и поместить его в выводимой строке вместо спецификации преобразования. Таким образом, одни элементы форматной строки выводятся один к одному на экран дисплея (например, Сумма=), другие выполняют управляющее действие (например, n), наконец,
Источник: studfile.net
Обзор и описание языка программирования Си
Си — язык программирования общего назначения, который очень известен своей эффективностью, экономичностью ресурсов и переносимостью на других программные платформы. Все эти преимущества обеспечивают качество разработки программного обеспечения, их быстроту и сравнительно небольшой размер. Программы написанные на Си по скорости работы можно даже сравнить с программами написанными на языке ассемблера.
Несмотря на то, что Си не включает в себя встроенные компоненты по работе с вводом-выводом, распределению памяти, управлению процессами, его системное окружение позволяет подключать объектные модули с такими функциями. Этого вполне достаточно, чтобы разрабатывать программное обеспечение абсолютно любого уровня, как небольшие программы, так и комплекс сложных программных систем.
Языковые особенности Си позволяют делать программы независимыми операционной системы или платформы.
Наиболее важными особенностями языка программирования Си являются:
- обеспечение полного набора операторов структурного программирования
- большой набор операций, в том числе операции прямой трансляции в машинный код
- поддержка указателей на переменные и функции
Указатели в Си позволяют создавать указатели и ссылаться на объекты таким же путем, как это делает компьютер. Арифметика указателей осуществляет доступ и манипуляции с адресами памяти. Си имеет препроцессор для обработки текстовых файлов перед компиляцией. Препроцессор может быть использован для любых текстовых файлов.
Таким образом, Си это гибкий язык программирования, позволяющий писать качественные программные продукты с высокой скоростью работы.
Синтаксис
В программах написанных на Си используются множество символов и множество представимых символов. Множество символов — это буквы, цифры, знаки пунктуации. Комбинирование этих символов создают конструкции языка. Множество представимых символов — это подмножество множества символов, состоящее из всех букв, цифр, символов которые можно представить как графически отдельные символы.
Программный код на Си может содержать только символы которые определены для множества символов. Лишь только комментарии, символьные константы и строковые литералы могут содержать любой символ. Другие, неверно используемые символы означают ошибку для компилятора Си, о чем он будет выводить сообщать.
Буквы и цифры
Множество символов Си включает в себя малые и большие буквы английского алфавита и 10 арабских цифр:
- большие английские буквы: A B C D E F G H I J K L M N O P Q R T U V W X Y Z
- малые английские буквы: a b c d e f g h i j k l m n o p q r t u v w x y z
- десятичные арабские цифры: 0 1 2 3 4 5 6 7 8 9
Цифры и буквы используются для наименования ключевых слов, констант, идентификаторов.
Символы пробела
Язык Си включает пробельные символы — пробелы, перевод строки, табуляцию, новую страницу, возврат каретки, вертикальную табуляцию, новую строку. Пробельные символы разделяют символы программного кода друг от друга.
Специальные символы и знаки пунктуации
Специальные символы и знаки пунктуации в Си используются для выполнения совершенно различных задач. Они могут использоваться в строковых литералах, комментариях, константах.
ESC-последовательности
ESC-последовательности — специальные символьные комбинации, представляющие собой пробельные символы и неграфические символы в строках. Они используются для таких действий, как возврат каретки и табуляции и т.п.
Операции
Операции в Си как и в любом другом языке программирования представляют комбинации символов для работы с разными величинами.
- Логическое НЕ: !
- Побитовое дополнение: ~
- Сложение: +
- Вычитание, отрицание: —
- Умножение: *
- Деление: /
- Остаток: %
- Сдвиг влево:
- Сдвиг вправо: >>
- Меньше:
- Меньше или равно:
- Больше: >
- Больше или равно: >=
- Равно: ==
- Не равно: !=
- Побитовое И: >=
- Сдвиг влево с присваиванием: <
- Побитовое И с присваиванием: https://unetway.com/blog/obzor-i-opisanie-azyka-programmirovania-si» target=»_blank»]unetway.com[/mask_link]
Основы языка Си
Программа на языке Си состоит из набора директив препроцессора, определений функций и глобальных объектов. Директивы препроцессора управляют преобразованием текста до его компиляции. Глобальные объекты определяют используемые данные или состояние программы. А функции определяют поведение или действия программы. Простейшая программа на Си, которая была определена в прошлых темах:
#include int main(void)
Инструкции
Простейшим строительным элементом программы на Си являются инструкции (statements). Каждая инструкция выполняет определенное действие. В конце инструкций в языке Си ставится точка с запятой (;). Данный знак указывает компилятору на завершение инструкции. Например:
printf(«Hello world!»);
Вызов функции printf, которая выводит на консоль строку «Hello world!» является инструкцией и завершается точкой с запятой.
Набор инструкций может представлять блок кода. Блок кода оформляется фигурными скобками, инструкции, составляющие тело этого блока, помещаются между открывающей и закрывающей фигурными скобками:
В этом блоке кода две инструкции. Обе инструкции представляют вызов функции printf() и выводят определенную строку на консоль.
Директивы препроцессора
Для вывода данных на консоль в примере выше используется функция printf() , но чтобы использовать эту функцию, чтобы она вообще стала нам доступна в программе на Си, необходимо в начале файла с исходным кодом подключать заголовочный файл stdio.h с помощью директивы include .
Директива include является директивой препроцессора. Кроме данной include есть еще ряд директив препроцессора, например, define.
Каждая директива препроцессора размещается на одной строке. И в отличие от обычных инструкций языка Си, которые завершаются точкой с запятой ; , признаком завершения препроцессорной директивы является перевод на новую строку. Кроме того, директива должна начинаться со знака решетки #.
Непосредственно директива «include» определяет, какие файлы надо включить в данном месте в текст программы. По умолчанию мы можем подключать стандартные файлы из каталога так называемых «заголовочных файлов», которые обычно поставляются вместе со стандартными библиотеками компилятора. И файл «stdio.h» как раз является одним из таких заголовочных файлов.
Вообще сам термин «заголовочный файл» (header file) предполагает включение текста файла именно в начало или заголовок программы. Поэтому заголовочные файлы подключаются, как правило, в начале исходного кода. Кроме того, заголовочный файл должен быть подключен до вызова тех функций, которые он определяет. То есть, к примеру, файл stdio.h хранит определение функции printf, поэтому этот файл необходимо подключить до вызова функции printf.
Но в целом директивы препроцессора необязательно должны быть размещены в начале файла.
При компиляции исходного кода вначале срабатывает препроцессор, который сканирует исходный код на наличие строк, которые начинаются с символа #. Эти строки расцениваются препроцессором как директивы. И на месте этих директив происходит преобразование текста. Например, на месте директивы #include вставляется код из файла stdio.h.
Функция main
Стартовой точкой в любую программу на языке Си является функция main() . Именно с этой функции начинается выполнение приложения. Ее имя main фиксировано и для всех программ на Си всегда одинаково.
Функция также является блоком кода, поэтому ее тело обрамляется фигурными скобками, между которыми идет набор инструкций.
Стоит отметить, что в разной литературе и примерах можно встретить модификации этой функции. В частности, вместо определения выше мы могли бы написать по другому:
#include void main()
#include int main()Использование этих определений не было бы ошибкой, и программа также вывела бы строку «Hello world» на консоль. И для большинства компиляторов это было бы нормально.
Далее мы подробнее рассмотрим определение функций, но здесь надо учитывать следующий аспект. Определение функции в виде int main(void) зафиксировано в стандарте языка С11. Компиляторы прежде всего ориентируются на стандарт языка, его спецификацию. Поэтому если мы используем то определение, которое дано в стандарте языка, то больше шанс, что оно будет поддерживаться всеми компиляторами. Хотя опять же повторюсь, в использовании второго варианта или int main() большой ошибки не будет.
Полностью последний стандарт C11 можно посмотреть по ссылке.
В представленной на рисунке структуры программы на языке С строка #include является заголовком. Заголовки содержат специализированную информацию для компилятора об общих условиях выполнения программы и требуемых ей ресурсах. В рассмотренном случае мы указываем компилятору на то, чтобы при выполнении программы он учел информацию, содержащуюся в файле io.h – забегая вперед скажем что этот файл содержит инструкции для портов ввода/вывода микроконтроллера.
Символ # указывает на то, что представленная инструкция должна быть обработана препроцессором, который выполняет предварительную обработку текста программы перед началом компиляции и подключает внешние библиотеки.
Какие заголовки (управление портами ввода/вывода, функции задержки и т.д.) следует подключить определяется потребностями конкретной программы. Если вы забыли подключить необходимый заголовок, то программа не скомпилируется – компилятор выдаст сообщение об ошибке. К слову сказать, эти ошибки легко устраняются – ведь компилятор сам подсказывает какие заголовки следует подключить.
Функции
По сути программа на языке С представляет собой набор функций, каждая из которых может вызывать для выполнения любые другие функции. Функций в программе может быть много, но обязательной является только одна из них, называемая «main» («главная»). Выполнение программы на языке С начинается всегда с нее. Программист не может изменить название главной функции «main», но названия для всех других функций программы он может выбирать произвольно.
Функции в языке С легко узнать по их отличительному признаку – круглым скобкам после их имени. В общем случае в скобках содержится набор параметров, которые могут передаваться в функцию для ее работы, а также набор переменных, через которые функция может передавать результаты ее работы во внешнюю функцию (которая ее вызвала). Если скобки пустые, как например, в представленном примере с функцией main(), то это значит что у функции нет ни входных, ни выходных параметров.
Идущая следом за названием функции фигурная скобка отмечает начало последовательности операторов, образующих тело функции. Закрывающая фигурная скобка > отмечает конец этой последовательности операторов. На этой скобке выполнение функции завершается.
Фигурные скобки также используются для того, чтобы объединить несколько операторов программы в составной оператор или блок.
Операторы
Как правило, тело функции в языке Си представляет собой набор операторов, в конце каждого из которых стоит точка с запятой ;. Можно размещать каждый оператор на своей строке или несколько операторов на одной строке – компилятору это неважно, главное чтобы они разделялись точкой с запятой (этот символ свидетельствует о конце оператора). Но для восприятия человеком, конечно, удобнее чтобы каждый оператор располагался на отдельной строке. Допускается использование и пустых строк чтобы визуально отделить структурные элементы программы.
Операторы выполняются последовательно в том порядке, в котором они записаны. Но структура программы не обязательно должна быть линейной – при наличии циклов и условий возможны пропуски выполнения отдельных операторов (условия) или многократное выполнение одних и тех же операторов (циклы).
Комментарии
Комментарии — это примечания, помогающие понять смысл программы. В языке Си текст комментариев записывается между значками /* */ . То, что написано между этими значками, компилятору совершенно неважно – он все это игнорирует. Это важно только для человека, который анализирует текст программы.
Комментарии можно размещать как на одной строке с операторами, так и на разных (обычно ниже или выше строки с оператором). Комментарии могут занимать несколько строк и для них не обязательно наличие в конце точки с запятой.
Наличие комментариев считается хорошим стилем программирования поскольку позволяет лучше понимать смысл программы не только ее автору (особенно по прошествии некоторого времени, в течение которого он над ней не работал), но и другим людям, которые в дальнейшем будут работать с этой программой.
Внутри комментариев нельзя использовать символы, определяющие начало и конец комментариев. К примеру, неправильная запись внутри комментария:
/* комментарии к программе /* управления электродвигателем */ */
/* комментарии к программе управления */ электродвигателем */
Язык Си для микроконтроллеров AVR поддерживает и другой метод записи комментариев — строка, начинающаяся с символов //. К примеру
// Это комментарий в одну строку
В качестве итога можно отметить, что для написания хорошо читаемой программы целесообразно придерживаться следующих правил:
- размещайте один оператор на строке;
- применяйте пустые строки для «отделения» одной логической части программы от другой;
- используйте комментарии.
Источник: microkontroller.ru