Операторы условного цикла

    Операторы, вложенные в тему этой работы, предназначены для выполнения условных циклов. Синтаксис первого оператора имеет вид:
while( условие )
    оператор
  ,   второго:    
do
    оператор
while( условие ).
    Если значение условия такого цикла отлично от нуля, то выполняется оператор тела цикла и условие вычисляется снова. Так продолжается до тех пор, пока значение условия не станет нулевым, после чего цикл будет завершен и выполнение программы продолжится с оператора, следующего за циклом.
    Принципиально операторы циклов идентичны, но в первом варианте условие проверяется перед выполнением тела цикла. Если условие ложно изначально, то операторы тела цикла не выполняются ни разу. В структуре же второго цикла условие расположено после тела, т.е. сначала выполняется оператор, а затем вычисляется значение условия. Это обеспечивает одноразовое исполнение вложенного оператора тела в любом случае.
    Для примера возмем программу для вычисления натурального логарифма через ряд Тейлора с контролем числа знаков после запятой результата. После выполнения этой программы на экране появится консольное окно, в котором будет указано вычисленное число:



Код функции, вычисляющей значение логарифма представлен ниже:


// ****************************************************************************
// ** Функция расчета натурального логарифма
// ** Параметры: A - аргумент натурального логарифма
// ** S - число знаков после запятой
long double logarithm( long double A, int S )
{
  int N, Z;           // индекс цикла, длина вспомогательной строки
  long double B,      // элемент степенного ряда
              L = 0;  // результат логарифма
  div_t x;            // результат целочисленного деления
  AnsiString T = "";  // вспомогательная строка для контроля точности результата

  // Длина вспомогательной строки:
  Z = S + 2; // число знаков после запятой + strlen( "0." )

  // Цикл построения степенного ряда для вычисления натурального логарифма
  // ( продолжать цикл, пока длина строки не превышает установленный максимум )
  N = 1;
  while( T.Length() <= Z )
  {
    // Вычисление очередного элемента степенного ряда
    B = powl( ( A - 1 ), ( long double )N ) / ( long double )N;

    // Проверка четности слагаемого
    // через целочисленное деление
    x = div( N, 2 );

    // Контроль чередования знака просмотром остатка деления
    // четное слагаемое вычитается, нечетное слагаемое прибавляется
    if( x.rem == 0 ) L -= B; else +L = B;

    // Преобразовать число суммы степенного ряда во вспомогательную переменную
    // для контроля числа знаков после запятой
    T = FloatToStr( L );

    N++;
  }
  // Возврат результата
  return( L );
}

Нажмите здесь, если желаете увидеть целиком код программы.

    Вторым наглядным примером может быть представлена программа вычисления ранга квадратной матрицы.
    После заполнения массива матрицы пользователем:



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



    Код аналитического процесса представлен ниже:


// ****************************************************************************
// ** Гололовная программа
void main( void )
{
  float a[ 4 ][ 4 ], b[ 3 ][ 3 ], c[ 2 ][ 2 ]; // массивы
  int Rank,                 // ранг матрицы
      i, j, k, r, q, l, m, // индексы циклов и матриц
      di, dj, dr, dq;       // смещения индексов матриц для определения миноров
  float d;                  // детерминант матрицы

  // Предложить ввод данных
  printf( "\nEnter, please, array elements:\n" );

  // Заполнить массив значениями элементов
  for( i = 0; i < 4; i++ )
    for( j = 0; j < 4; j++ )
    {
      printf( "A[ %i ][ %i ] = ", i + 1, j + 1 );
      scanf( "%f", &a[ i ][ j ] );
    }

  // Вывести на экран матрицу
  for( i = 0; i < 4; i++ )
    printf( "\n %f %f %f %f ", a[ i ][ 0 ], a[ i ][ 1 ], a[ i ][ 2 ],  a[ i ][ 3 ] );

  // Проверить определитель на неравенство нулю
  if( ( d = det4( a ) ) != 0 ) // при положительном результате - ранг матрицы равен 4
    // Вывести значение детерминанта на экран
    printf( "determinant = %lf\n Rang = 4\n", d );
  else // иначе - проверить миноры 3-го порядка
  {
    i = 0; // индекс строки матрицы
    d = 0.0; // значение детерминанта минора
    // Условный цикл последовательного "вычеркивания" строк
    // из матрицы для получения минора,
    // ( при превышении индекса строки максимального значения
    // или при детерминанте текущего минора не равном нулю - цикл закончить )
    while( i < 4 && d == 0.0 )
    {
      di = 0; // смещение строкового индекса матрицы
      j = 0; // столбцовый индекс матрицы
      // Условный цикл последовательного "вычеркивания" столбцов
      // из матрицы для получения минора,
      // ( при превышении индекса строки максимального значения
      // или при детерминанте текущего минора не равном нулю - цикл закончить )
      while( j < 4 && d == 0.0 )
      {
        dj = 0; // смещение столбцового индекса матрицы
        // Вложенный цикл для взятия элементов матрицы в минор
        for( r = 0; r < 3; r++ )
        {
          // Если индекс строки минора совпадает с индексом строки матрицы
          // сделать смещение равным 1 для пропуска строки матрицы
          if( r == i ) di = 1;
          for( q = 0; q < 3; q++ )
          {
             // Если индекс столбца минора совпадает с индексом столбца матрицы
             // сделать смещение равным 1 для пропуска столбца матрицы
            if( q == j ) dj = 1;

             // Взять значение соответствующего элемента матрицы в ячейку минора
             b[ r ][ q ] = a[ r + di ][ q + dj ];
          }
        }
        // Определить детерминант минора
        d = det3( b );

        // Вывести на экран матрицу
        printf( "\n" );
        for( k = 0; k < 3; k++ )
           printf( "\n %f %f %f ", b[ k ][ 0 ], b[ k ][ 1 ], b[ k ][ 2 ] );

        // Вывести значение детерминанта на экран
        printf( " determinant = %lf", d );
        j++;
      }
      i++;
    }

    // После завершения циклов проверить определитель на неравенство 0
    if( d != 0.0 ) // при положительном результате - ранг матрицы равен 3
      printf( "\n Rang = 3\n" );
    else // иначе - проверить миноры 2-го порядка матрицы аналогичным
    { // алгоритмом, получая их из миноров 3-го порядка
      i = 0;
      d = 0.0;
      while( i < 4 && d == 0.0 )
      {
        di = 0;
        j = 0;
        while( j < 4 && d == 0.0 )
        {
          dj = 0;
          // Собрать минор 3-го порядка
          for( r = 0; r < 3; r++ )
          {
            if( r == i ) di = 1;
            for( q = 0; q < 3; q++ )
            {
               if( q == j ) dj = 1;
               b[ r ][ q ] = a[ r + di ][ q + dj ];
            }
          }
          r = 0;
          while( r < 3 && d == 0.0 )
          {
            q = 0;
            while( q < 3 && d == 0.0 )
            {
              dr = 0;
              // Вложенные циклы для формирования миноров 2-го порядка
              // из текущего минора 3-го порядка
              for( l = 0; l < 2; l++ )
              {
                if( l == r ) dr = 1;
                dq = 0;
                for( m = 0; m < 2; m++ )
                {
                  if( m == q ) dq = 1;
                  c[ l ][ m ] = b[ l + dr ][ m + dq ];
                }
                printf( "\n %f %f ", c[ l ][ 0 ], c[ l ][ 1 ] );
              }
              d = c[ 0 ][ 0 ] * c[ 1 ][ 1 ] - c[ 0 ][ 1 ] * c[ 1 ][ 0 ];
              printf( " determinant = %lf", d );
              q++;
            }
            r++;
          }
          j++;
        }
        i++;
      }
       // После завершения циклов проверить определитель на неравенство 0
      if( d != 0.0 ) // при положительном результате - ранг матрицы равен 2
        printf( "\n Rang = 2 \n" );
      else // иначе - проверить 1 элемент матрицы на неравенство 0
        if( a[ 0 ][ 0 ] != 0 ) // при положительном результате - ранг матрицы равен 1
          printf( "\n Rang = 1 \n" );
        else // иначе - ранг матрицы равен 0
          printf( "\n Rang = 0 \n" );
    }
  }

  printf( "\n Press any key..." );

  // Ждать нажатия клавиши
  getch();
}

Целиком код программы Вы можете увидеть здесь.

Заключение

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



Титульный лист