Язык Си.

Язык С и его последующие реализации C++ и C# занимают особое место среди языков программирования. Наряду со средствами языков высокого уровня, реализующими концепцию нисходящего структурного проектирования, язык содержит средства для программирования на низком, системном уровне (адрес значения, значение по указанному адресу, побитовые операции, операции сдвига). Благодаря гибкости и компактности своих конструкций С завоевал наибольшую популярность в среде профессиональных программистов и широко используется при разработке системных и прикладных программ.

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

Программа на языке С может иметь следующую структуру:

<программа С> º<раздел препроцессора>

<раздел функций>

<раздел препроцессора> º#<опция препроцессора>

{#<опция препроцессора>}

 

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

Начинается программа с подключения различных «модулей», необходимых для работы определенных функций (ввод из файл\вывод в файл, работа со строками, графикой и т.д.)

Для этого пишется:

#include <имя модуля.расширение>

Так, например, в результате обработки директивы #include <<имя файла>> (внешние угловые скобки – символы языка С) в текст программы вместо этой директивы будет помещен файл описания стандартных функций системы (файл библиотеки). Файлы библиотеки языка С имеют расширение h (например, stdio.h – файл описания функций ввода/вывода).

Директива #define <идентификатор> <конструкция С> задает так называемое макроопределение. В результате обработки этой директивы каждое вхождение <идентификатор> в текст программы после макроопределения заменяется на <конструкция С>. Например, #define n 100 – макроопределение целочисленной константы n.

Внимание: в языке С строчные и прописные буквы во всех конструкциях различаются. Так N и n – различные идентификаторы.

Далее идут глобальные переменные, константы, функции и прочее, прочее.

Любая программа на языке С состоит из одной и более функций, одна из которых должна иметь имя main, и именно ей передается управление из операционной системы. Функция - это коллективное имя для некото­рой группы описаний и операторов, заключенных в фигурные скобки { } и являющихся телом функции.

раздел функций> º<описаниефункции>

{<описаниефункции>}

<описаниефункции> º[<идентификатор типа>] <идентификатор>([< формальные параметры>])

<составной оператор>

Здесь <идентификатор типа> – тип возвращаемого значения (тип значения <идентификатор>).

<формальные параметры> º

º<идентификатор типа> <идентификатор>{, <идентификатор типа> <идентификатор>}

Идентификатор типа Размер, бит Диапазон
unsigned char 0÷255
Char -128÷127
Enum -32768÷32767
unsigned short 0÷65535
Short -32768÷32767
unsigned int 0÷65535
Int -32768÷32767
unsigned long 0÷4294967295
Long -2147483648÷2147483647
Float 3.4∙10-38÷3.4 10+38
Double 1.7∙10-308÷1.7 10+308
long double 1.7 10-4932÷1.7 10+4932

 

<идентификатор типа> задается стандартными служебными словами int (целый), long (длинный), short (короткий), unsigned (беззнаковый), char (символьный), float (действительный одинарной точности), double (действительный двойной точности), pointer (указатель), enum (перечислимый). Допустимые в языке типы данных, размеры выделяемой памяти в битах и диапазон представления приведены в табл. 1.1.


<составной оператор> º{

<оператор>|<выражение>;

{<оператор>|<выражение>;}

}

Здесь первая открывающаяся { и последняя закрывающаяся } являются символами алфавита языка С. Значение функции определяется значением <выражения> необязательного оператора return <выражение>, вложенного в <составной оператор>.Если значение функции не определяется (оператор return <выражение> отсутствует), то рекомендуем в качестве типа значения использовать void (отсутствие типа)

Синтаксис оператора return: return [выражение]

 

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

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

Если в определении функции отсутствует оператор return, то управление автоматически передается на вызов функции после выполнения последнего оператора вызванной функции. При этом не определено возвращаемое вызванной функцией значение. Если от функции не требуется возврат какого-либо значения, то функция объявляется с возвращаемым значением типа void.

В <составном операторе> могут содержаться операторы резервирования памяти, с помощью которых описываются локальные переменные

<резервирование памяти> º<идентификатор типа> <идентификатор>{, <идентификатор>}

Например, оператор int i, j; описывает переменные i и j как целые, а оператор float t; определяет переменную t как действительную одинарной точности.