- •Язык программирования Си
- •7. Понятие о препроцессоре языка Си 29
- •8. Операторы языка Си и приемы программирования 30
- •9. Массивы. Адресная арифметика языка Си 51
- •Правила записи программы на языке Си
- •Правила формального описания синтаксиса языка программирования
- •Идентификаторы языка Си
- •Понятие о типах данных.
- •Системы счисления. Представление данных в эвм.
- •Основные типы данных языка Си
- •Правила записи констант различных типов
- •Беззнаковый тип для целых данных
- •Символьные строки
- •Понятие функции
- •Стандартная функция printf
- •Стандартная функция scanf
- •Операции и выражения
- •Простейшие арифметические операции
- •Операция присваивания
- •Оператор-выражение
- •Использование в выражениях операндов разных типов
- •Операции преобразования типов
- •Стандартные математические функции
- •Простейшие функции, определяемые программистом
- •Дополнительные арифметические операции
- •Дополнительные операции присваивания
- •Битовые операции
- •Операции отношения
- •Логические операции
- •Операция определения размера данных
- •Приоритеты операций
- •Понятие о препроцессоре языка Си
- •Операторы языка Си и приемы программирования
- •Оператор цикла while
- •Условный оператор и условная операция
- •1) Короткие операторы:
- •2) Группы коротких операторов:
- •3) Длинные группы операторов:
- •Запись алгоритмов с помощью диаграмм Несси - Шнейдермана (структограмм )
- •Некоторые приемы программирования
- •Оператор прерывания цикла
- •Оператор продолжения цикла
- •Пример организации простейшего меню
- •Множественный выбор. Оператор переключения
- •Оператор цикла do-while.
- •Перечисления. Работа с клавиатурой ibm pc
- •Пример организации светового меню
- •Массивы. Адресная арифметика языка Си
- •Описание массива
- •Ввод-вывод массива
- •Инициализация массива
- •Программа вычисления длины строки символов
- •Двумерные массивы (массивы массивов)
- •Адресная арифметика языка Си
- •Указатели и одномерные массивы
- •Указатели и двумерные массивы
- •Указатели и функции
- •Оператор typedef
- •Дополнительные описания указателей для ibm pc
- •Непосредственная работа с экранной памятью
- •Дополнительные сведения о функциях
- •Области видимости и глобальные данные
- •Время жизни переменных и классы памяти языка Си
- •Передача аргументов в функцию
- •Возврат значений из функций
- •Работа с динамической памятью
- •Стандартные функции управления динамической памятью
- •Пример использования динамической памяти
- •Особенности работы с двумерными массивами
- •Пересчет индексов вручную
- •Массивы с постоянной длиной строки
- •Общий случай двумерного массива
- •Особенности работы с массивами большого размера
- •Модульное программирование в системе Turbo c
- •Обеспечение корректной стыковки модулей
- •Создание библиотек функций
- •Некоторые библиотечные функции языка Си
- •Функции консольного ввода/вывода (уникальны для tc)
- •Функции обработки строк.
- •Функции распознавания вида символа
- •Функции преобразования данных
- •Структуры языка c.
- •Описание структуры
- •1 Способ
- •2 Способ
- •Трактовка имени структуры.
- •Доступ к элементу структуры.
- •Инициализация структур.
- •Структуры и функции.
- •Поля бит в структурах.
- •Объединения.
- •Дополнительные сведения о препроцессоре языка c.
- •Условное выражение.
- •Приоритеты и направления операций.
- •Динамические данные.
- •Линейные списки.
- •Организация данных в виде стека.
- •Организация данных в виде очереди.
- •Организация данных в виде деревьев.
- •Библиотека ввода-вывода языка c.
- •Открытие потока.
- •Закрытие потока.
- •Предопределенные указатели потоков.
- •Функции ввода-вывода.
Оператор цикла do-while.
Оператор цикла do-while предназначен для реализации циклических алгоритмов и имеет следующую форму записи
БНФ:
цикл_do-while =
"do" оператор "while" "("выражение")" ";"
Оператор выполняется циклически до тех пор, пока выражение отлично от нуля. В отличие от оператора while, тело оператораdo-whileвыполняется хотя бы один раз до первого вычисления условия.
Работу оператора do-whileпроиллюстрируем на примере программы, которая определяет корень уравненияx-cos(sin(x))=0методом итераций, который заключается в циклическом вычислении очередного приближенияx_newпо предыдущему приближениюx_old, согласно выражениюx_new=cos(sin(x_old)), вытекающему из исходного уравнения. Процесс итерации заканчивается тогда, когда x_new станет равен x_old. Программа, реализующая этот алгоритм, приведена ниже.
#include <stdio.h>
#include <math.h>
/* Решение уравнения x-cos(sin(x))=0 */
void main (void)
{
double x_new=0.9, x_old, eps=0.0001;
do
{
x_old = x_new;
x_new = cos(sin(x_old));
} while ( fabs( x_new - x_old ) > eps );
printf ( "x=%lf", x_new );
}
Сравнение двух вещественных чисел осуществляется с использованием точности eps. Это необходимо потому, что из-за погрешностей округления прямая проверка на равенство двух вещественных чисел скорее всего даст в результате 0 (ложь).
Перечисления. Работа с клавиатурой ibm pc
Перечисления используются для задания символических имен константам целого типа.
БНФ:
перечисление =
"enum" [ имя_перечисления ]
"{"
имя_конст [ "=" конст_выр ]
{ "," имя_конст [ "=" конст_выр ] }
"};"
Здесь имя_перечисления - любое символическое имя; имя_конст - символическое имя, назначаемое константе; конст_выр - константное выражение, то есть такое, которое не содержит переменных и функций и может быть определено на этапе компиляции.
Если константное выражение отсутствует, то имени назначается значение предыдущего выражения, увеличенное на единицу. Если отсутствует выражение, соответствующее первому имени константы, то ему назначается значение 0. Например:
enum DAYS { MON=1, TUE, WED, THU, FRI, SAT, SUN };
enum MONTH { JAN=1, FEB, MAR, APR, MAY, JUN,
JUL, AUG, SEP, OCT, NOV, DEC };
В дальнейшем в программе эти имена можно использовать вместо целых констант. Например, DEC вместо 12, THU вместо 4 и т. д.
Рассмотрим использование перечислений для организации удобной работы с клавиатурой IBM PC.
В библиотеке conio имеется функция, осуществляющая ввод одиночного символа (точнее его кода) без отображения его на экране дисплея. Она имеет следующий прототип:
int getch( void );
При обращении к этой функции выполнение программы приостанавливается до нажатия на клавишу. После нажатия на клавишу код соответствующего символа возвращается в виде целого числа.
Некоторым клавишам клавиатуры не соответствует ни один символ из кодовой таблицы. При нажатии на подобные клавиши getch()вначале возвращает нулевое значение. Если при этом обратиться к функции повторно, то она возвратит условный номер клавиши на клавиатуре, так называемый скэн-код. Это свойство используется в функцииGetCh()для расширения возможностейgetch(). ФункцияGetCh()будет возвращать коды символов в обычных случаях. При нажатии специальной клавишиGetCh()возвратит скэн-код, увеличенный на 256 (0x100) или на 512 (0x200), в зависимости от того, была ли нажата клавишаShiftили нет. Текст функцииGetCh()приводится ниже.
#include <conio.h>
#include <bios.h>
/* Ввод одиночного символа с клавиатуры */
int GetCh( void )
{
int ch;
if( ( ch = getch() ) == 0 )
ch = getch() | ( bioskey(2) & 3 ? 0x200 : 0x100 );
return ch;
}
Здесь, выражение bioskey(2) & 3осуществляет проверку нажатия клавишиShiftи отлично от нуля, если последняя нажата.
Прототип функции GetCh() и коды специальных клавиш перечисления KeyboardCodes, получаемых с помощью этой функции, следует поместить в файл, например, keyboard.h и в дальнейшей использовать не числовые значения кодов, а только символические имена. Фрагмент перечисления KeyboardCodes приведен ниже:
enum KeyboardCodes
{
kbF1 = 315, kbF2, kbF3, kbF4, ..., kbF10,
kbShiftF1 = 596, kbShiftF2, kbShiftF3, ..., kbShiftF10,
kbCtrlF1 = 350, kbCtrlF2, kbCtrlF3, ..., kbCtrlF10,
kbAltF1 = 360, kbAltF2, kbAltF3, ..., kbAltF10,
kbAlt1 = 376, kbAlt2, kbAlt3, ..., kbAlt0,
kbAltQ = 272, kbAltW, kbAltE, ..., kbAltP,
kbAltA = 286, kbAltS, kbAltD, ..., kbAltL,
kbAltZ = 300, kbAltX, kbAltC, ..., kbAltM,
kbCtrlA = 1, kbCtrlB, kbCtrlC, ..., kbCtrlZ,
kbUp = 328, kbDown = 336, kbTab = 9,
kbCtrlUp = 397, kbCtrlDown = 401, kbCtrlTab = 404,
kbAltUp = 408, kbAltDown = 416, kbAltTab = 421,
kbShiftUp = 584, kbShiftDown = 592, kbShiftTab = 527,
kbRight = 333, kbLeft = 331, kbEsc = 27,
kbCtrlRight = 372, kbCtrlLeft = 371,
kbAltRight = 413, kbAltLeft = 411, kbAltEsc = 257,
kbShiftRight = 589, kbShiftLeft = 587,
kbPgUp = 329, kbPgDn = 337, kbIns = 338,
kbCtrlPgUp = 388, kbCtrlPgDn = 374, kbCtrlIns = 513,
kbAltPgUp = 409, kbAltPgDn = 417, kbAltIns = 418,
kbShiftPgUp = 585, kbShiftPgDn = 593, kbShiftIns = 594,
kbHome = 327, kbEnd = 335, kbDel = 339,
kbCtrlHome = 375, kbCtrlEnd = 373, kbCtrlDel = 515,
kbAltHome = 407, kbAltEnd = 415, kbAltDel = 419,
kbShiftHome = 583, kbShiftEnd = 591, kbShiftDel = 595,
kbEnter = 13, kbBackspace = 8,
kbCtrlEnter = 10, kbCtrlBackspace = 127,
kbAltEnter = 284, kbAltBackspace = 270
};
Предложенная методика работы с клавиатурой IBM PC не требует никаких изменений исходных текстов программ, использующих функцию GetCh(), в случае изменения аппаратных средств.