Язык программирования c си

Введение в язык Си

Язык Си, созданный Денисом Ритчи в начале 70-х годов
в Bell Laboratory американской корпорации AT&T, является одним из
универсальных языков программирования. Язык Си считается языком системного
программирования, хотя он удобен и для написания прикладных программ. Среди
преимуществ языка Си следует отметить переносимость программ на компьютеры
различной архитектуры и из одной операционной системы в другую, лаконичность
записи алгоритмов, логическую стройность программ, а также возможность получить
программный код, сравнимый по скорости выполнения с программами, написанными
на языке ассемблера. Последнее связано с тем, что хотя Си является
языком высокого уровня, имеющим полный набор конструкций структурного
программирования, он также обладает набором низкоуровневых средств,
обеспечивающих доступ к аппаратным средствам компьютера. С 1989 года язык
Си регламентируется стандартом Американского института национальных стандартов
ANSI С. В настоящее время, кроме стандарта ANSI C разработан международный
стандарт ISO C (International Standard Organization C).

В пособии в разделах 1-6 рассматриваются основные конструкции языка Си (общие для
Си и Си++). Примеры программ приведены в разделе 7.

Программа, написанная на языке Си, состоит из операторов.
Каждый оператор вызывает выполнение некоторых действий на соответствующем
шаге выполнения программы.

При написании операторов применяются латинские прописные
и строчные буквы, цифры и специальные знаки. К таким знакам, например,
относятся: точка (.), запятая (,), двоеточие (:), точка с запятой (;) и др.
Совокупность символов, используемых в языке, называется алфавитом языка.

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

Различают видимые и управляющие символы.
Первые могут быть отображены на экране дисплея либо отпечатаны на принтере.
Вторые вызывают определенные действия в машине, например: звуковой сигнал -
код 710, возврат курсора на один шаг - код 810,
горизонтальная табуляция - код 910, перевод курсора на новую
строку - код 1010, перемещение курсора в начало строки -
код 1310 и т.д. Такие управляющие символы имеют десятичные
номера 0 - 31, 127.

Для представления каждого символа в персональном компьютере используется
один байт, поэтому общее число символов равно 28 = 256. Кодовая
таблица, которая устанавливает соответствие между символом и его кодом,
имеет 256 строк вида:

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

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

  1. Они должны начинаться с буквы латинского алфавита (а,...,z,
    А,...,Z) или с символа подчеркивания (_).
  2. В них могут использоваться буквы латинского алфавита, символ
    подчеркивания и цифры (0,...,9). Использование других символов
    в идентификаторах запрещено.
  3. В языке Си буквы нижнего регистра (а,...,z), применяемые в
    идентификаторах, отличаются от букв верхнего регистра (А,...,Z).
    Это означает, что следующие идентификаторы считаются разными:
    name, NaMe, NAME и т.д.
  4. Идентификаторы могут иметь любую длину, но воспринимается и
    используется для различения объектов (функций, переменных, констант
    и т.д.) только часть символов. Их число меняется для разных
    систем программирования, но в соответствии со стандартом ANSI C не
    превышает 32 (в Си++ это ограничение снято). Если длина идентификатора
    установлена равной 5, то имена count и counter будут идентичны,
    поскольку у них совпадают первые пять символов.
  5. Идентификаторы для новых объектов не должны совпадать с
    ключевыми словами языка и именами стандартных функций из библиотеки.

В программах на языке Си важная роль отводится комментариям.
Они повышают наглядность и удобство чтения программ. Комментарии обрамляются
символами /* и */. Их можно записывать в любом месте программы.

В языке Си++ введена еще одна форма записи комментариев.
Все, что находится после знака // до конца текущей строки, будет также рассматриваться как
комментарий. Отметим, что компилятор языка Си, встроенный в систему
программирования Borland C++, позволяет использовать данный комментарий
и в программах на Си.

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

Программы оперируют с различными данными, которые могут быть
простыми и структурированными. Простые данные - это целые и вещественные
числа, символы и указатели (адреса объектов в памяти). Целые числа не
имеют, а вещественные имеют дробную часть. Структурированные данные - это
массивы и структуры; они будут рассмотрены ниже.

В языке различают понятия "тип данных" и "модификатор типа". Тип
данных - это, например, целый, а модификатор - со знаком или без знака.
Целое со знаком будет иметь как положительные, так и отрицательные
значения, а целое без знака - только положительные значения. В языке Си
можно выделить пять базовых типов, которые задаются следующими
ключевыми словами:

  • char - символьный;
  • int - целый;
  • float - вещественный;
  • double - вещественный двойной точности;
  • void - не имеющий значения.

Дадим им краткую характеристику:

  1. Переменная типа char имеет размер 1 байт, ее значениями
    являются различные символы из кодовой таблицы, например: 'ф', ':', 'j'
    (при записи в программе они заключаются в одинарные кавычки).
  2. Размер переменной типа int в стандарте языка Си не определен. В
    большинстве систем программирования размер переменной типа int соответствует
    размеру целого машинного слова. Например, в компиляторах для 16-разрядных
    процессоров переменная типа int имеет размер 2 байта. В этом случае знаковые
    значения этой переменной могут лежать в диапазоне от -32768 до 32767.
  3. Ключевое слово float позволяет определить переменные вещественного
    типа. Их значения имеют дробную часть, отделяемую точкой,
    например: -5.6, 31.28 и т.п. Вещественные числа могут быть записаны
    также в форме с плавающей точкой, например: -1.09e+4. Число перед
    символом "е" называется мантиссой, а после "е" - порядком. Переменная типа
    float занимает в памяти 32 бита. Она может принимать значения в диапазоне
    от 3.4е-38 до 3.4e+38.
  4. Ключевое слово double позволяет определить вещественную
    переменную двойной точности. Она занимает в памяти в два раза больше
    места, чем переменная типа float (т.е. ее размер 64 бита). Переменная
    типа double может принимать значения в диапазоне от 1.7e-308 до 1.7e+308.
  5. Ключевое слово void (не имеющий значения) используется для
    нейтрализации значения объекта, например, для объявления функции, не
    возвращающей никаких значений.

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

  • unsigned
  • signed
  • short
  • long

Модификаторы записываются перед спецификаторами типа, например:
unsigned char. Если после модификатора опущен спецификатор, то компилятор
предполагает, что этим спецификатором является int. Таким образом,
следующие строки:


long а;
long int а;

являются идентичными и определяют объект а как длинный целый. Табл. 1
иллюстрирует возможные сочетания модификаторов (unsigned, signed, short,
long) со спецификаторами (char, int, float и double), а также показывает
размер и диапазон значений объекта (для 16-разрядных компиляторов).

Таблица 1        
          
  

ТипРазмер в байтах (битах)Интервал изменения
char1 (8)от -128 до 127
unsigned char1 (8)от 0 до 255
signed char1 (8)от -128 до 127
int2 (16)от -32768 до 32767
unsigned int2 (16)от 0 до 65535
signed int2 (16)от -32768 до 32767
short int2 (16)от -32768 до 32767
unsigned short int2 (16)от 0 до 65535
signed short int2 (16)от -32768 до 32767
long int4 (32)от -2147483648 до 2147483647
unsigned long int4 (32)от 0 до 4294967295
signed long int4 (32)от -2147483648 до 2147483647
float4 (32)от 3.4Е-38 до 3.4Е+38
double8 (64)от 1.7Е-308 до 1.7Е+308
long double10 (80)от 3.4Е-4932 до 3.4Е+4932

Все переменные до их использования должны быть определены (объявлены).
При этом задается тип, а затем идет список из одной или более
переменных этого типа, разделенных запятыми. Например:


int a, b, c;
char x, y;

В языке различают понятия объявления переменной и ее определения.
Объявление устанавливает свойства объекта: его тип (например, целый),
размер (например, 4 байта) и т.д. Определение наряду с этим вызывает
выделение памяти (в приведенном примере дано определение переменных).

Переменные можно разделять по строкам произвольным образом, например:


float a;
float b;

Переменные в языке Си могут быть инициализированы при их определении:


int a = 25, h = 6;
char g = 'Q', k = 'm';
float r = 1.89;
long double n = r*123;

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


int a; /* Определение глобальной переменной */

int function (int b, char c); /* Объявление функции (т.е. описание
ее заголовка)*/

void main (void)
{ //Тело программы
int d, e; //Определение локальных переменных
float f; //Определение локальной переменной
...
}
int function (int b, char c) /* Определение функции и формальных
параметров (по существу - локальных
переменных) b и c */
{ //Тело функции
char g; //Определение локальной переменной
...
}

Отметим, что выполнение программы всегда начинается с вызова функции
main( ), которая содержит тело программы. Тело программы, как и тело
любой другой функции, помещается между открывающей и закрывающей фигурными
скобками.

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

Наряду с переменными в языке существуют следующие виды констант:

  • вещественные, например 123.456, 5.61е-4. Они могут снабжаться
    суффиксом F (или f), например 123.456F, 5.61e-4f;
  • целые, например 125;
  • короткие целые, в конце записи которых добавляется буква
    (суффикс) H (или h), например 275h, 344H;
  • длинные целые, в конце записи которых добавляется буква
    (суффикс) L (или l), например 361327L;
  • беззнаковые, в конце записи которых добавляется буква U (или
    u), например 62125U;
  • восьмеричные, в которых перед первой значащей цифрой записывается
    нуль (0), например 071;
  • шестнадцатеричные, в которых перед первой значащей цифрой
    записывается пара символов нуль-икс (0x), например 0x5F;
  • символьные - единственный символ, заключенный в одинарные кавычки,
    например 'О', '2', '.' и т.п. Символы, не имеющие графического
    представления, можно записывать, используя специальные комбинации, например
    \n (код 10), \0 (код 0). Эти комбинации выглядят как два символа, хотя
    фактически это один символ. Так же можно представить любой двоичный образ
    одного байта: '\NNN', где NNN - от одной до трех восьмеричных цифр.
    Допускается и шестнадцатеричное задание кодов символов, которое представляется
    в виде: '\х2В', '\хЗ6' и т.п.;
  • строковые - последовательность из нуля символов и более, заключенная
    в двойные кавычки, например: "Это строковая константа". Кавычки не
    входят в строку, а лишь ограничивают ее. Строка представляет собой массив
    из перечисленных элементов, в конце которого помещается байт с символом
    '\0'. Таким образом, число байтов, необходимых для хранения строки, на
    единицу превышает число символов между двойными кавычками;
  • константное выражение, состоящее из одних констант, которое
    вычисляется во время трансляции (например: а=60+301);
  • типа long double, в конце записи которых добавляется буква L
    (или l), например: 1234567.89L.

Операции ввода/вывода в языке Си организованы посредством библиотечных
функций (причем их довольно много).

Самый простой механизм ввода - чтение по одному символу из стандартного
входного потока (с клавиатуры) с помощью функции getchar( ). Она
имеет следующий прототип (т.е. описание заголовка):


int getchar(void);

Здесь определен тип единственного аргумента (void) и тип возвращаемого
функцией значения (int).

Си (как и ОС UNIX, с которой он долгое время был связан) создавался программистами и для программистов, круг которых был бы ненамного шире круга разработчиков языка. Несмотря на это, область использования языка значительно шире задач системного программирования.

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

Некоторые особенности других языков программирования, которые отсутствуют в Си:

Часть отсутствующих возможностей относительно легко имитируется встроенными средствами (например, сопрограммы можно имитировать с помощью функций longjmp и setjmp), часть добавляется с помощью сторонних библиотек (например, для поддержки многозадачности и для сетевых функций можно использовать библиотеки pthreads, sockets и т. п.; существуют библиотеки для поддержки автоматической сборки мусора[1]), часть реализуется в некоторых компиляторах в виде расширений языка (например, вложенные функции в GCC).

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

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

Набор используемых символов

Язык Си был создан уже после внедрения стандарта ASCII, поэтому использует почти все его графические символы (нет только $ @ `). Более старые языки вынуждены были обходиться более скромным набором — так, Фортран, Лисп и Кобол использовали только круглые скобки (), а в Си есть и круглые (), и квадратные [], и фигурные {}. Кроме того, в Си различаются заглавные и строчные буквы, а более старые языки использовали только заглавные.

Текст, заключённый в служебные символы /* и */ (в этом порядке), полностью игнорируется компилятором. Вложение комментариев не допускается. Компиляторы, совместимые со стандартом C99, также позволяют использовать комментарии, начинающиеся с символов // и заканчивающиеся переводом строки

Ключевые слова

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

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

#include<stdio.h>
/* Пример 2: вычисление длины окружности */
main()
{
int radius;
float length;
printf("Введите значение радиуса: \n");
scanf("%d",&radius);
length=3.1415*2*radius;
printf("Радиус - %d\n, длина - %f\n",radius,length);
}

   В языке Си все переменные должны быть объявлены до их использования. В нём определены 5 типов данных, которые считаются базовыми:


Конспект распространяется свободно в формате PDF.
Для просмотра требуется бесплатный просмотрщик
Acrobat Reader.
Конспект курса условно разбит на 4 части:

  1. Введение в программирование на языке Си (860 Кб)29.03.2014
    Изучение основных конструкций языка и приемов написания программ.
  2. Xранение и обработка данных (792 Кб)21.11.2013
    Язык Си: массивы, матрицы, структуры, символьные строки, структуры, рекурсия.
  3. Разработка программ на языке Си (937 Кб)01.03.2014
    Приемы проектирования программ,
    структурное программирование, целочисленные алгоритмы, численные методы,
    моделирование.
  4. Динамические структуры данных в языке Си (666 Кб)11.06.2009
    Списки, стеки, деревья, графы.

Презентации

    * 10. ДОПОЛНИТЕЛЬНАЯ ИНФОРМАЦИЯ О ТИПАХ

* 10. ДОПОЛНИТЕЛЬНАЯ ИНФОРМАЦИЯ О ТИПАХ

    10.1. Структуры и объединения

10.1. Структуры и объединения

    10.3. Массивы, указатели и индексация

10.3. Массивы, указатели и индексация

    10.4. Явные преобразования указателей

10.4. Явные преобразования указателей

    * 11. КОНСТАНТНЫЕ ВЫРАЖЕНИЯ

* 11. КОНСТАНТНЫЕ ВЫРАЖЕНИЯ

    * 12. СООБРАЖЕНИЯ О ПЕРЕНОСИМОСТИ

* 12. СООБРАЖЕНИЯ О ПЕРЕНОСИМОСТИ

    * 13. СТАНДАРТНАЯ БИБЛИОТЕКА ВВОДА И ВЫВОДА

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

Тело функции, заключенное в фигурные скобки, представляет собой набор операторов, каждый из которых оканчивается символом точка с запятой ;. При написании программы на Си можно поместить несколько операторов на одной строке или разместить один оператор в нескольких строках. Символ "точка с запятой" указывает компилятору конец оператора, но для человека удобнее, если каждый оператор будет размещен на отдельной строке. Кроме того, можно использовать пустые строки, чтобы отделить одну часть программы от другой.

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

Первые шаги в трансляции программы

До передачи управления препроцессору компилятор должен провести программу через ряд этапов трансляции. Компилятор начинает свою работу с того, что устанавливает соответствие символов исходного кода с исходным набором символов. При этом обрабатываются многобайтные символы и триграфы — расширения символов, которые обеспечивают интернациональное применение языка С. (Обзор этих расширений приведен в справочном разделе VII приложения Б.)

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

Расширенное представление данных

  • Функции: дополнительные сведения о функции malloc()
  • Использование С для представления разнообразных типов данных
  • Новые алгоритмы и увеличение возможностей концептуальной разработки программ
  • Абстрактные типы данных

24 минуты

-

26 минут

-

27 минут

-

    20. Строки управления компилятором

20. Строки управления компилятором

    20.3. Условная компиляция

20.3. Условная компиляция

    22.1. Структуры и объединения

22.1. Структуры и объединения

    22.3. Массивы, указатели и индексация

22.3. Массивы, указатели и индексация

    22.4. Явные преобразования указателей

22.4. Явные преобразования указателей

    23. Константные выражения

23. Константные выражения

    24. Соображения о переносимости

24. Соображения о переносимости

    26. Сводка синтаксических правил

26. Сводка синтаксических правил

    26.4. Внешние определения

26.4. Внешние определения


Наверх