Главная :: Программы для программирования :: Программирование в Си :: Управляющие структуры Си
Ночь. Сидит программист за компом, дописывает последние строчки новой программы. Но тут неожиданно звонок в дверь. Программист за дверь - а там смерть с косой, но маленькая. - Блин не вовремя ты дай допишу программу, а там и забирай меня... - Не переживай мужик, я не за тобой. Я за твоим винтом!

Управляющие структуры Си

В этом уроке рассмотрим основные управляющие конструкции Си.

Условный оператор if ... else. Форма оператора следующая:

if ( условие )
  оператор1
else
  оператор2

Если условие истинно, то выполнятся первый оператор, иначе второй. Если в условии отрабатываются несколько операторов, то они помещаются фигурные скобки. Вторая часть (else) может опускаться если нам не нужно обрабатывать ложное условие. Допускается вложение условных операторов. При сравнении на равенство необходимо помнить, что a = b пишется как a == b (двойное равно, иначе мы получим присваение, т.е. a пример значение равное b). Другие операции сравнения: больше (>), меньше (<), не равно (!=), логическая операция И (&&), логическая операция ИЛИ (||).

Пример на Си (запустите для различных значений переменных a и b):

// Условный оператор - поиск минимального из двух чисел
printf("Минимальное из значений %i и %i равно ", a, b);
int a = 1;
int b = 2;
if ( a < b )
  printf("%d", a);
else
  printf("%d", b);
if ( a == b )
  printf(" (оба числа одинаковые)");
printf("\n");

Далее рассмотрим структуры цикла.

Итерационный цикл - цикл управляемый счетчиком.

Структура следующая:

for ( инициализация; условие; операция ) {
  операторы
}

Первый параметр инициализирует счетчик, второй - условие при истиности которого выполняются операторы, третий - операция выполняемая перед новой итерацией.

Рассмотрим на примере вычисления факториала числа:

printf("вычисление факториала\n");
const int N = 5;
int i, f = 1;
for (i = 1; i <= N; i++) {
  f *= i;
  printf("%d! = %d\n", i, f);
}

В качестве операции в примере используется постфиксная форма интремирования (увеличение переменной на 1). Цикл повторяется до тех пор, пока i меньше или равно N. Операция f *= i (присваение с умножением) эквивалентна форме f = а * i.

Цикл с предусловием - цикл управляемый условием.

Структура следующая:

while ( условие ) {
  операторы
}

Цикл выполняется пока условие истинно (условие проверяется в начале). Пример:

// Цикл с предусловием
printf("вычисление суммы чисел\n");
i = 0;
f = 0;
while (i < 5) {
  f += ++i;
  printf("S(%d) = %d\n", i , f);
}

Операция f += ++i эквивалентна двум операторам i++; f = f + i;

Цикл с постусловием - цикл управляемый условием.

Структура следующая:

do {
  операторы
} while ( условие )

Цикл выполняется пока условие истинно (условие проверяется в конце, т.е. тело цикла выпольняется по крайней мере один раз). Пример:

// Цикл с постусловием
printf("вычисление квадратов\n");
i = 0;
do {
  f = i * i;
  printf("%d^2 = %d\n", i, f);
  i++;
} while ( f < 25 );

Полный текст программы со всеми рассмотренными конструкциями:

#include "stdio.h"

int main() {
int a = 1;
int b = 2;

// Условный оператор - поиск минимального из двух чисел
printf("Минимальное из значений %i и %i равно ", a, b);
if ( a < b )
  printf("%d", a);
else
  printf("%d", b);
if ( a == b )
  printf(" (оба числа одинаковые)");
printf("\n");

// Итерационный цикл
printf("вычисление факториала\n");
const int N = 5;
int i, f = 1;
for (i = 1; i <= N; i++) {
  f *= i;
  printf("%d! = %d\n", i, f);
}

// Цикл с предусловием
printf("вычисление суммы чисел\n");
i = 0;
f = 0;
while (i < 5) {
  f += ++i;
  printf("S(%d) = %d\n", i , f);
}

// Цикл с постусловием
printf("вычисление квадратов\n");
i = 0;
do {
  f = i * i;
  printf("%d^2 = %d\n", i, f);
  i++;

} while ( f < 25 );
return 0;
}

Оператор выбора switch. Форма оператора следующая:

switch (выражение) {
  case константа_1 : операторы ; break;
  ...
  case константа_n : операторы ; break;
  default : операторы ; break;
}

Оператор switch вычисляет выражение и переходит к первому совпадающему значению после case. Далее выполняются операторы этого блока и по команде break происходит выход из структуры. Если ни одно из значений не совпадает с константами из case, то выполняются операторы блока default. Отметим, что константы в case блоке определяются на этапе компиляции, поэтому они не могут содержать переменных и функций.

Следующий пример показывает работу оператора выбора.

  int a = 2, b = 5;
  ...
  for (i = 0; i <= 5; i++) {
    switch (i) {
      case 0  : c = a + b; break;
      case 1  : c = a - b; break;
      case 2  : c = a * b; break;
      case 3  : c = (float) a / b; break;
      default : c = 0; break;
    }
    printf("Результат: i = %i, c = %f\n", i, c);
  }

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

  for (i = 0; i <= 5; i++) {
    if ( i == 0 )
      c = a + b;
    else
    if ( i == 1 )
      c = a - b;
    else
      if ( i == 2 )
        c = a * b;
      else
        if ( i == 3 )
          c = (float) a / b;
        else
          c = 0;
    printf("Результат: i = %i, c = %f\n", i, c);
  }

Результат выполнения кода будет одинаковым для обоих примеров (блок default выполняется во всех случаях, когда i не равно 0, 1, 2, 3):

Результат: i = 0, c = 7.000000
Результат: i = 1, c = -3.000000
Результат: i = 2, c = 10.000000
Результат: i = 3, c = 0.400000
Результат: i = 4, c = 0.000000
Результат: i = 5, c = 0.000000

Оператор выхода из структуры break может быть опущен. В этом случае, поиск совпадений будет продолжен после выполнения соответствующего блока case. Этот момент покажем на следующем примере:

  i = 2;
  j = 0;

  switch (i) {
    case 0  : i = 5; j++;
    case 1  : i = 0; j++;
    case 2  : i++; j++;
    case 3  : i += 2; j++;
    case 4  : i = 0; j++;
    case 5  : i = i - 2; j++;
    default : j++;
  }
  printf("Результат: i = %i, выборов: %i\n", i, j);

Счетчик j подсчитывает реальное число исполненых блоков case. В начале i = 2 и первый выполняемый блок case 2. В этом блоке i увеличивается на 1 и проверка продолжается, т.ч. следующим выполняется блок case 3 (i становиться равным 4), далее case 4 (i зануляется) и блок по умолчанию (он выполняется всегда, если до этого не был выполнен оператор break). Окончательно получаем:

Результат: i = -2, выборов: 5

Полный текст примера для оператора switch

#include "stdio.h"                                                                                                                        
                                                                                                                                          
int main(){                                                                                                                               
  int i, j;                                                                                                                               
  int a = 2, b = 5;                                                                                                                       
  float c;                                                                                                                                
                                                                                                                                          
  printf("Пример 1а:\n");                                                                                                                 
  for (i = 0; i <= 5; i++) {                                                                                                              
    switch (i) {                                                                                                                          
      case 0  : c = a + b; break;
      case 1  : c = a - b; break;
      case 2  : c = a * b; break;
      case 3  : c = (float) a / b; break;
      default : c = 0; break;
    }
    printf("Результат: i = %i, c = %f\n", i, c);
  }

  printf("Пример 1б:\n");
  for (i = 0; i <= 5; i++) {
    if ( i == 0 )
      c = a + b;
    else
    if ( i == 1 )
      c = a - b;
    else
      if ( i == 2 )
        c = a * b;
      else
        if ( i == 3 )
          c = (float) a / b;
        else
          c = 0;
    printf("Результат: i = %i, c = %f\n", i, c);
  }

  printf("Пример 2:\n");
  i = 2;
  j = 0;

  switch (i) {
    case 0  : i = 5; j++;
    case 1  : i = 0; j++;
    case 2  : i++; j++;
    case 3  : i += 2; j++;
    case 4  : i = 0; j++;
    case 5  : i = i - 2; j++;
    default : j++;
  }
  printf("Результат: i = %i, выборов: %i\n", i, j);
  return 0;
}

Операторы break и continue. Использование оператора break мы уже видели на примере структуры switch. Оператор break - это выход из цикла или конструкции switch. Пример (цикл по i от 0 до 4, но при i = 2 происходит выход из цикла):

  for (i = 0; i < 5; i++) {
    if ( i == 2 ) break;
    printf("Индекс: i = %i\n", i);
  }

Результат:

Индекс: i = 0
Индекс: i = 1

Оператор continue - переход на конец цикла (т.е. пропуск всех операторов от continue до конца структуры цикла). Пример (цикл по i от 0 до 4, но при i = 2 происходит переход на конец цикла):

  for (i = 0; i < 5; i++) {
    if ( i == 2 ) continue;
    printf("Индекс: i = %i\n", i);
  }

Результат:

Индекс: i = 0
Индекс: i = 1
Индекс: i = 3
Индекс: i = 4

Полный текст примера использования операторов break и continue:

#include "stdio.h"

int main() {
  int i;
  printf("Пример для break:\n");
  for (i = 0; i < 5; i++) {
    if ( i == 2 ) break;
    printf("Индекс: i = %i\n", i);
  }
  printf("Пример для continue:\n");
  for (i = 0; i < 5; i++) {
    if ( i == 2 ) continue;
    printf("Индекс: i = %i\n", i);
  }
  return 0;
}
Автор: Ильдар Насибуллаев