- •Язык программирования Си
- •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.
- •Открытие потока.
- •Закрытие потока.
- •Предопределенные указатели потоков.
- •Функции ввода-вывода.
1) Короткие операторы:
if( a > b ) k = sin( x ); else k = x*x;
if( a > b ) k = sin( x );
else k = x*x;
2) Группы коротких операторов:
if( a > b ) { ... } else {... }
if( a > b ) { ... }
else { ... }
или
if( ... )
{ ..... }
else
{ ..... }
3) Длинные группы операторов:
if(... )
{
.
.
.
}
else
{
.
.
.
}
4) множественный выбор:
if ( a == 6 ) { ... }
else if ( a == 8 ) { ... }
else if ( a == 15 ) { ... }
else if ( a > 20 && a < 28 ) { ... }
else { ... }
В некоторых случаях вместо оператора if удобно использовать условную операцию ?:, которая позволяет сократить запись программ и число используемых переменных.
БНФ:
условное_операция = выр_0 "?" выр_1 ":" выр_2
Значение условной операции равно <выр_1>, если <выр_0> не равно 0 и <выр_2> в противном случае. Например, следующий оператор
if ( x>a ) f = sin( x-a ); else f = sin(x);
можно заменить условной операцией, и сразу вычислить f:
f = sin( x>a ? x-a : x );
Очевидно, в последнем случае получился более короткий код, поскольку обращений к переменной f и функции sinвдвое меньше.
Запись алгоритмов с помощью диаграмм Несси - Шнейдермана (структограмм )
Язык Си является достаточно развитым для того, чтобы вообще обойтись без каких-либо особых способов записи алгоритмов.
Однако для тех, кто только начинает программировать, может понадобится более наглядное средство иллюстрации алгоритмов.
Раньше для таких целей широко использовались так называемые блок-схемы. Однако их применение очень легко может привести к появлению программ с неоправданно сложной структурой, в которой трудно разобраться.
Для описания логики работы программ вместо блок-схем можно использовать диаграммы Несси - Шнейдермана, которые отличаются тем, что пригодны для описания только структуированных программ (состоящих из базовых логических структур).
Рассмотрим базовые логические структуры и их представление в виде структограмм.
Процесс - один или несколько операторов, выполнение которых происходит последовательно. Изображается в виде прямоугольника, управление в который передается сверху, а выходит из него снизу:
Проверка условия - управление передается в один из нижних процессов:
Цикл - пока. Процесс повторяется несколько раз пока истинно условие.
Некоторые приемы программирования
Рассмотрим некоторые типовые приемы программирования и использования рассмотренных выше операторов.
Для подсчета различных объектов, получающихся в процессе работы программы используют счетчики, которые представляют собой переменные целого типа, меняющие свои значения в процессе выполнения счета. Использование счетчика покажем на примере
программы, которая подсчитывает количество отрицательных значений функции sin( x ) для x меняющегося от xn до xk с шагом h.
Вначале запишем алгоритм с помощью диаграммы Несси-Шнейдермана.
Теперь можно рассмотреть программу на языке Си :
#include <math.h>
#include <stdio.h>
/* использование счетчика */
void main( void )
{
double xn, xk, h, x;
int Count; /* счетчик */
printf( "Введите xn, xk, h \n" );
scanf( "%lf%lf%lf", &xn, &xk, &h );
x = xn;
Count = 0; /* инициализация счетчика */
while( x <= xk )
{
if( sin(x) < 0 ) Count++; /* выполнение счета */
x += h;
}
printf( "Число отрицательных синусов = %d\n", Count);
}
Довольно часто в программах приходится вычислять суммы и произведения. При нахождении суммы надо выделить переменную для ее хранения, обнулить ее, затем циклически добавлять к ней очередное значение. Найдем сумму отрицательных значений функции sin(x)для x меняющегося отxnдоxkс шагом h. Следующая программа решает эту задачу:
#include <math.h>
#include <stdio.h>
/* нахождение суммы отрицательных значений синуса */
void main( void )
{
double xn, xk, h, x, sum;
printf( "Введите xn, xk, h \n" );
scanf( "%lf%lf%lf", &xn, &xk, &h );
x = xn;
sum = 0; /* обнуление суммы */
while( x <= xk )
{
if( sin(x)<0 ) sum += sin(x); /* вычисление суммы */
x += h;
}
printf( "Сумма = %lf\n", sum);
}
Для повышения эффективности программы можно описать еще одну переменную, например sinusи изменить оператор вычисления суммы:
if( ( sinus = sin(x) ) < 0 ) sum += sinus;
В этом случае экономится время за счет однократного вычисления синуса.
Для вычисления произведения необходимо выделить переменную для его хранения, занести в эту переменную единицу и в цикле домножать ее на очередное значение.
Во многих сложных алгоритмах требуется запоминать факты наступления различных событий, связанных с процессом выполнения программы. Для этих целей используются флаги, которые представляют собой переменные целого типа, принимающие определенные значения в зависимости от этих событий. Простейший пример использования флагов иллюстрирует фрагмент программы, моделирующий работу оператора if с помощью оператора while. Иными словами, показывается, что при реализации программ можно вообще обойтись без оператора if. Действительно, рассмотрим следующий оператор if:
if( a > b ) k = sin(x); else k = x * x;
Очевидно, такие же действия будет выполнять группа операторов, использующая флаг и приведенная ниже:
fl = 1; /* флаг */
while ( a > b && fl ) { k = sin(x); fl = 0; }
while ( fl ) { k = x * x; fl = 0; }
В данном случае флаг сигнализирует о выборе одной из альтернатив оператора if.
Следующая программа устанавливает факт наличия отрицательных значений sin(x) для x меняющегося от xn до xk c шагом h :
#include <math.h>
#include <stdio.h>
/* использование флагов */
void main( void )
{
double xn, xk, h, x;
int minus; /* флаг */
printf( "Введите xn, xk, h \n" );
scanf( "%lf%lf%lf", &xn, &xk, &h );
x = xn;
minus = 0; /* предполагается, что нет не одного
отрицательного значения */
while( x <= xk )
{
if( sin(x) < 0 ) minus = 1;
x += h;
}
if( minus ) printf( "Имеются отрицательные значения\n" );
else printf( "Все синусы положительные\n" );
}
В данной программе флаг устанавливается в 1, как только появляется отрицательный синус.