
- •Основы алгоритмизации и программирования, язык Си
- •Введение
- •Блок-схема алгоритма Общие требования к блок-схеме алгоритма
- •Линейные и разветвляющиеся процессы
- •Циклические процессы
- •Итерационные процессы
- •Комментарии
- •Типы данных
- •Данные целого типа
- •Данные вещественного типа
- •Модификатор const
- •Переменные перечисляемого типа
- •Константы
- •Описание переменных
- •Локальные переменные
- •Операции и выражения
- •Операция присваивания
- •Арифметические операции
- •Операции поразрядной арифметики
- •Логические операции
- •Операции отношения
- •Инкрементные и декрементные операции
- •Операция sizeof
- •Порядок выполнения операций
- •Приоритет операций
- •Преобразование типов
- •Операция приведения
- •Операция запятая
- •Ввод и вывод информации
- •Директивы препроцессора Директива #include
- •Директива #define
- •Понятие пустого и составного операторов
- •Условные операторы
- •Операторы организации цикла
- •Оператор цикла for
- •Оператор цикла while
- •Оператор цикла do … while
- •Вложенные циклы
- •Операторы перехода (break, continue, return, goto)
- •Примеры программ
- •Массивы Одномерные массивы
- •Примеры программ
- •Многомерные массивы (матрицы)
- •Примеры программ
- •Указатели Понятие указателя
- •Описание указателей
- •Операции с указателями
- •Связь между указателями и массивами
- •Массивы указателей
- •Многоуровневые указатели
- •Примеры программ
- •Символьные строки
- •Ввод/вывод строк.
- •Функции работы со строками.
- •Примеры программ
- •Функции
- •Прототип функции.
- •Определение функции.
- •Параметры функции
- •Параметры по умолчанию
- •Передача массива в функцию
- •Inline функции
- •Класс памяти
- •Автоматические переменные
- •Статические переменные
- •Регистровые переменные
- •Блочная структура
- •Примеры программ
- •Указатели на функции
- •Примеры программ
- •Рекурсия
- •Примеры программ
- •Аргументы в командной строке
- •Функции с переменным числом параметров
- •Примеры программ
- •Сортировка
- •Пузырьковая сортировка.
- •Шейкер сортировка
- •Сортировка вставкой
- •Сортировка выбором
- •Метод Шелла
- •Метод Хора
- •Структуры
- •Доступ к элементам структуры
- •Инициализация структур
- •Указатели на структуры.
- •Структуры и функции
- •Примеры программ
- •Поля бит
- •Объединения
- •Переменные с изменяемой структурой
- •Примеры программ
- •Организация списков и их обработка
- •Операции со списками при связном хранении
- •Построение обратной польской записи
- •Односвязный линейный список, очередь
- •Двусвязный линейный список
- •Циклический список, кольцо
- •Двусвязный циклический список
- •Примеры программ
- •Деревья
- •Потоки и файлы
- •Файлы Основные сведения о файловой системе
- •Организация посимвольного ввода и вывода
- •Определение конца файла feof()
- •Организация ввода и вывода строк
- •Удаление файлов
- •Дозапись потока
- •Позиционирование в файле
- •Текстовые и двоичные файлы
- •Функции fread() и fwrite()
- •Примеры программ
- •Хеширование
- •Схемы хеширования
- •Метод открытой адресации с линейным опробыванием
- •Метод цепочек
- •Машинное представление графов
- •Примеры программ
- •Литература
Понятие пустого и составного операторов
Составной оператор – это несколько операторов объединенных в блок с помощью фигурных скобок “{}”, или разделенных запятой. Такой блок можно рассматривать как один оператор, например:
#include<stdio.h>
void main ()
{
{ // первый вариант составного оператора
int i=1, j=2, k;
k=i+j; printf(“\n k=i+j = %d”, k);
k*=2; printf(“\n k= %d”, k);
} // второй вариант составного оператора
int i=0, j, k;
k=i+=j, j=4;
}
Пустой оператор – состоит только из знака “;”, например:
#include<stdio.h>
void main ()
{ int i= 2;
i*=3; ; // обычный и пустой операторы
; // пустой оператор
; ; // двойной пустой оператор
} // конец составного оператора и пустой оператор
Условные операторы
В языке С(С++) существует группа операторов позволяющая организовать ветвление в программе. В С(С++) имеются три оператора, которые могут нарушить простой линейный характер выполнения программы. К ним относятся: if (если) else (иначе) (ветвления), switch (переключатель) и goto (безусловного перехода).
Оператор ветвления предназначен для выбора в программе из нескольких возможных вариантов единственного варианта продолжения вычислительного процесса. Выбор выполняется исходя из результатов анализа значения некоторого выражения.
Оператор if имеет следующую общую форму записи:
if (проверка условия) {группа операторов 1 }
[else {группа операторов 2 }]
При выполнении оператора if сначала выполняется проверка условия. Если результат - истина (любое отличное от нуля значение), то выполняется группа операторов 1.
Если результат анализа условия - ложь (равен 0 ), то выполняется группа операторов 2. Если слово else отсутствует, то управление передается на следующий после if оператор.
В качестве условия может использоваться арифметическое, логическое выражение, выражение сравнения, целое число, переменная целого типа, вызов функции с соответствующим типом возвращаемого значения.
Ниже приведен пример функции, использующей оператор if . . . else:
void main(void)
#include <stdio.h>
{ short i;
printf("введите число i \n i= ");
scanf("%d",&i);
printf("введенное число ");
if (i>10) printf("больше 10 ");
else printf("меньше 10 ");
}
Если необходимо осуществить выбор из более чем двух условий, то можно конструкцию if ... else расширить конструкцией else if. Это позволяет ввести в анализ дополнительное условие, что приведет к увеличению ветвления в программе.
Одним из условий правильности работы программы, использующей конструкции вида if ...; else ...; if ...; else ...; ..., является соблюдение правил:
- каждый оператор else соответствует ближайшему оператору if, если только ближайший if не входит в группу операторов, выполняющихся при условии верхнего (предыдущего if).
- условия проверяются в том порядке, в котором они перечислены в программе;
- если одно из условий истинно, то выполняется оператор соответствующий этому условию, а проверка оставшихся условий не производится;
- если ни одно из проверенных условий не дало истинного результата, то выполняются операторы, относящиеся к последнему else;
- последний else является необязательным, следовательно, он и относящийся к нему оператор может отсутствовать.
. . . . . .
if (i==j){ n++; if (i==j){ n++;
k*=j;} k*=j;
if (n>10 && k<n) if (n>10 && k<n)
printf(”n=%d”,n); printf(”n=%d”,n);
else n%=2; } else n%=2;
Если анализируется более одного логического условия, то они заключаются в () и разделяются логическими операциями || (или) и && (и).
Понятия: истина и ложь. В С(С++) каждое выражение, в том числе и условное, имеет значение. При этом каждое условное значение принимает либо истинное, либо ложное значение.
void main(void)
{ int true,false;
true=(4>2); // истина
false=(3>5); // ложь
printf(”true=%d false=%d”,true,false);
}
Результатом работы функции является:
true = 1 false = 0
Следовательно, значение ”истина” - это 1, а "ложь" - 0. Более того, как следует из приводимого ниже примера, только значение 0 соответствует ложному высказыванию, при остальных значениях выражение в () принимает истинное значение.
#include<stdio.h>
main()
{ if (1) printf("истина1");
else printf("ложь1");
if (0) printf("истина 0");
else printf("ложь 0");
if (-2) printf("истина 2");
else printf("ложь 2");
}
Это свойство может быть использовано для сокращения логических условий. Например, выражения if(k!=0) и if(k) эквивалентны, так как оба принимают значение "ложь" только в случае k=0.
Необходимо различать следующие высказывания:
if(k=3) и if(k==3)
Первое из них имеет всегда истинное значение, так как в результате его выполнения переменная k принимает значение 3, и, следовательно, выражение в скобках не равно 0 (истинно) всегда. Во втором случае выражение истинно только в случае, когда k примет значение 3.
Переключатель switch. Использование оператора if позволяет выбрать один из двух путей. В отличие от него оператор switch используется для выбора одного из многих путей. Общая структура оператора switch имеет следующий вид:
switch (выражение)
{ case константа 1: вариант 1; break;
. . . . .
case константа n: вариант n; break;
[default: вариант n+1; break;]
}
В операторе switch производится проверка на совпадение вычисленного значения выражения с одним из значений, входящих во множество констант. Константа представляет собой целочисленную константу или константное выражение (символьные константы автоматически преобразуются в целочисленные). В операторе switch не должно быть одинаковых констант. В процессе выполнения оператора switch выражение сравнивается с каждой из констант. При совпадении выполняется соответствующий константе вариант (один или более операторов), иначе выполняется вариант, помеченный ключевым словом default, а при его отсутствии операторы, следующие за ”}”. Оператор break, приводит к немедленному выходу из switch (или далее из ниже рассматриваемых операторов цикла). Кроме break, для выхода из switch может быть использован также return.
#include <stdio.h>
void main(void)
{ int i;
char c;
while((i=getchar())!=EOF) /* EOF --> Ctrl + Z */
{ switch (i)
{ case 97: c='a'; /* из-за отсутствия оператора break выполняется */
/* следующая ветвь и c принимает значение 'b'*/
case 98: c='b'; break;
case 99: c='c'; break;
default: c=NULL; return; /*выход из функции*/
} printf("c= %c\n",c);
}
}
Ниже приведены несколько примеров программ, в которых используется переключатель switch.
Пример простейшего калькулятора:
#include<stdio.h>
void main( )
{ float a, b, res; int prizn= 1;
char opr;
do{ puts("\nВведите выражение (число_1 знак число_2 ):");
scanf("%f%c%f", &a, &opr, &b);
} while( ( b == 0 ) && (( opr ==’/’) || (opr == ‘:’));
switch (opr)
{ case '+': res=a+b; break;
case '-': res=a-b; break;
case '*': res=a*b; break;
case ':': case '/': res=a/b; break;
default: printf("\операция не определена"); pr= 0; break;
}
if(pr) printf("\n Результат: %f", res);
}
Операция условия ?:. В С(С++) имеется короткий способ записи оператора if ... else. Он называется "условным выражением" и записывается с помощью операции ?:. Эта операция состоит из двух частей и содержит три операнда. Общий вид условного выражения следующий:
переменная=операнд 1? операнд 2: операнд 3;
Операнд 1 вычисляется с точки зрения его эквивалентности нулю. Он может быть целого, плавающего или адресного типа. Если операнд 1 имеет ненулевое значение, то вычисляется операнд 2 и результатом условной операции является значение выражения операнд 2. Если операнд 1 равен нулю, то вычисляется операнд 3 и переменная принимает вычисленное значение. Вычисляется только один из операндов. Например:
n=(k>3)?n++:n+5;
то есть если k>3, то n=n++, иначе n=n+5;
В качестве операндов 2 и 3 могут быть использованы более сложные выражения, например:
i=j>1?(j=4*n,k+=j):(n--,++m*=2);