Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Текст_лекций_Си.doc
Скачиваний:
18
Добавлен:
16.03.2016
Размер:
1.06 Mб
Скачать

Формат: ;

if (x > y)

if (z = = w)

if( w<p ) y = 1;

else p = q;

else ; // при x>y && z!=w переход к оператору с меткой m1

else x = 4;

m1: z = 5;

    1. Составной оператор

Употребляется везде, где стандарт языка Си предусматривает один оператор, а для решении задачи требуется несколько.

Формат { <оператор>; [<оператор>;]... }

Пример:

Задача: x = max (a, b) y = min(a, b)

if ( a>b ) {

x = a;

y = b; }

else { x = b;

y = a; }

    1. Циклы

      1. Цикл while

Формат: while (e) /* e–условие продолжения цикла */

<оператор>; /* Тело цикла */

Все требования у условию и к выражению такие же, как и в конструкции ветвления.

Эквивалентная схема

label: if ( !e ) goto next;

S;

goto label;

next: ...........

Пример: Дано: a[i], i=1...100. Найти сумму(a[i]>0) и сумму(a[i]<0).

pol = otr = i = 0;

while ( i <= 100 ){

if (a[i] > 0 ) pol += a[i];

if (a[i] < 0) otr += a[i];

i++ ; }

Напечатать слова "Hello world" 100 раз.

int c;

c = 100;

while ( c-- )

printf ( "Hello world\n" );

Понятие истины в Си растяжимо: истинно все, что не равно нулю. В частности, 100 - это истина. А выражение c– –, стоящее в условии (помните постфиксную форму инкремента?), вернет значение переменной с, а затем уменьшит его на единицу. При выполнении цикла в сотый раз условие вернет 1, а в переменной с окажется 0. После этого условие выполнится в 101-й раз, вернет 0, запишет в с –1, и, так как 0 – это ложь, цикл выполняться больше не будет.

      1. Цикл for

е1 – присваивание начального значения управляющей переменной.

е2 – проверка выполнения условия продолжения цикла.

е3 – изменение значения управляющей переменной.

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

е2 и е3 перевычисляются при каждом проходе цикла  for это цикл с переменными границами!

for наиболее универсальный цикл в языке Си (и в других алгоритмических языках).

Формат for ( [e1]; [e2]; [e3] )

S;

Эквивалентная схема

e1;

while ( e2 )

{ S; e3; }

Пример:

1. Дано: a[i], i=1...100. Найти сумму(a[i]>0) и сумму(a[i]<0).

pol = otr = 0;

for ( i = 0; i<100; i++ ) {

if ( a[i]>0 ) pol+=a[i];

if ( a[i]<0 ) otr+=a[i];

}

2. Определить количество цифр натурального числа L.

for ( k=0; L!=0; L/=10 )

k++;

Пример: for ( ; e2; ) S;  while ( e2 ) S;

for ( ; ; ) S;  while ( 1 ) S;

3. Найти 1–й отрицательный элемент массива. Если его нет, то 0.

for (i=0; i<100 && a[i] > = 0; i++ ) ;

if ( i= =100 ) {

y = 0; }

else {y = a[i]; }

      1. Цикл do

Его особенность в том, что проверка условия происходит не перед выполнением тела цикла, а после него, поэтому тело цикла обязательно выполнится хотя бы один раз. Иногда это бывает полезно. В остальном, этот цикл сходен с while.

Формат

do {

< оператор > ;

} while (e);

Эквивалентная схема

label: <оператор>;

if ( e ) goto label;

Пример:

Дано: a[i], i=1...100. Найти сумму(a[i]) и произведение(a[i]).

sum = i = 0;

pr=1;

do { sum + = a[i];

pr*=a[i];

i++;

} while ( i<100 );

      1. Вложенные циклы.

В качестве <тела_цикла> в любом цикле может выступать другой цикл. Следует помнить только о составном операторе.

  • Умножение матриц

for ( i=0; i<m; i++ ) {

for ( j=0; j<l; j++ ) {

c[i][j] = 0;

for (k=0; k<n; k++ ) {

c[i][j] + = a[i][k]*b[k][j]; } } }

  • Сортировка массива методом "пузырька"

pr=1;

while (pr) {

pr=0;

for ( i=0; i<n–1; i++ ) {

if (a[i]>a[i+1] ) {

b = a[i];

a[i] = a[i+1];

a[i+1] = b;

pr = 1; } }

}

    1. Управляемые переходы

      1. Оператор break

Break осуществляет немедленный безусловный выход из цикла, то есть переход на первый оператор, непосредственно следующий за циклом.

Формат break ;

Эквивалентная схема

for ( e1; e2; e3 ) { for ( e1; e2; e3 ) {

............ ............

if ( e4 ) break ; if ( e4 ) goto exit ;

............ ............

} }

................ exit : ...

Пример:

Дано x[i], i=1...30. Найти длину 1–й подпоследовательности положительных элементов.

for ( pr = kol = i = 0; i<30; i++) {

if (x[i] > 0) {

kol++;

pr = 1; }

if (x[i]<=0 && pr) break; }

      1. Оператор continue

Формат continue

Эквивалентная схема

for ( e1; e2; e3 ) { for ( e1; e2; e3 ) {

............ ............

if ( e4 ) continue; if ( e4 ) goto next ;

............ ............

} next: ; }

ЗАМЕЧАНИЕ. Почти всегда можно обойтись.

for ( i=0; i<n; i++ ) { for ( i=0; i<n; i++ ) {

if ( a[i]<=0 ) continue ; if ( a[i]>0 ) { /* Обработка a[i]>0 */

/* Обработка a[i]>0 */ … } … } }

    1. Оператор switch

Реализует ситуацию множественного выбора, когда в зависимости от значения переменной ( e ) выполняется одно из нескольких условий.

Формат

switch ( e ) {

case c_e1: [<оператор_1>;][break;]

case c_e2: [<оператор_2>;][break;]

...................

case c_en: [<оператор_n>;][break;]

[default: <оператор_n+1>;]

}

Как работает эта конструкция? Как вы можете догадаться, она ищет строку "case значение_переменной_e" и исполняет участок кода от нее до конца блока switch или до зарезервированного слова break. Если соответствий не найдено, исполняется блок default.

Присутствие в формате break придает больше гибкости конструкции.

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

Например: switch ( a ) {

case 1: b = 5; // строка без break

case 2: printf ( "a = 1 или a = 2\n" ); break;

case 3: printf ( "a = 3\n" ); }

Как он будет себя вести? Если a = 1, то переменная b получит значение 5, а затем будет выведена строка "a = 1 или a = 2". Если же a = 2, то будет выведена так же строка. Таким образом, одно действие включает в себя другое, при этом в коде нет повторяющихся участков.

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

Например: switch (a) {

case 1:

case 2: printf ("a = 1 или a = 2\n"); break;

case 3:

case 4: printf ("a = 3 или a = 4\n"); break;

}

Пример:

switch ( symb ) {

case '+': <сложить>; break;

case '–': <вычесть>; break;

case '*': <умножить>; break;

case '/': <разделить>; break;

case '%': <найти остаток>; break;

default : <поместить в стек>; }

    1. Основные операции с массивами и матрицами

  1. Суммирование элементов одномерного массива a[i], i = 1,n.

for ( s=i=0; i<n; i++ )

s += a[i];

  1. Суммирование элементов матрицы a[i][j], i,j = 1,n.

for ( s=i=0; i<n; i++ ) {

for ( j=0; j<n; j++ )

s += a[i][j]; }

  1. Суммирование двух массивов (матриц) одинакового размера.

for ( i=0; i<n; i++ ) {

for ( j=0; j<n; j++ )

c[i][j] = a[i][j]+b[i][j]; }

  1. Вычислить сумму элементов каждой строки матрицы b[i][j], размером nm. Результат записать в виде вектора d[i].

for ( i=0; i<n; i++ ) {

s=0;

for ( j=0; j<n; j++ )

s += b[i][j];

d[i]=s; }

  1. Выполнить транспонирование матрицы а[i][j], т.е. заменить строки матрицы ее столбцами, а столбцы строками.

for ( i=0; i<n; i++ ) {

for ( j=0; j<m; j++)

b[i][j] = a[j][i]; }

Для квадратной матрицы.

for ( i=0; i<n; i++) {

for ( j=i+1; j<n; j++) {

p=a[i][j];

a[i][j]=a[j][i]; }

a[j][i] = p; }

  1. Умножить матрицу а[i][j], размером nm, на матрицу b[i][j], размером km. Другими словами вычислить:

i=1,n; j=1,m;

for ( i=0; i<n; i++) {

for ( j=0; j<m; j++ ) {

s=0;

for ( l=0; l<k; l++ )

s += a[i][j]*b[l][j];

}

c[i][j] = s }

  1. Удалить k-й элемент из массива а[i], размером n.

i=k,n–1 –сдвигаем хвост массива на одну позицию влево.

n = n–1; /*n– –*/

for ( i=k; i<n; i++)

a[i] = a[i+1];

  1. Включить в k-ю позицию массива элемент.

i=n; n–1;…;k – передвигаем хвост массива на одну позицию вправо. Перемещение начинаем с конца, иначе весь хвост будет заполнен элементом a[k].

for (i=n; i>k; i– –)

a[i+1]=a[i];

a[k]=b;

n=n+1 /*n++*/

  1. Включить в массив а[i], размером n элемент b. Сохранить упорядоченность массива по возрастанию.

i=0;

met: if ( i>n ) {

a[i+1] = b;

n=n+1; }

if ( b >= a[i] ) {

i = i+1;

goto met }

for ( j=n; j>i; j– –)

a[j+1]=a[j];

a[i]=b;

n=n+1; /*n++*/

  1. Удалить из матрицы строку с номером k.

n=n–1; /*n– –*/

for ( i=k; i<n; i++ ) {

for ( j=0; j<n; j++ )

b[i][j]=b[i+1][j]; }

  1. Включить в матрицу строку, заданную вектором с[i].

for ( i=n; i>k; i– –) {

for (j=1; j<m; j++)

b[i+1][j] = b[i][j]; }

for ( j=0; j<m; j++)

b[k][j]=c[j];

n++;

  1. Перестановка строк матрицы с номерами i и j с использованием вспомогательной переменная.

for (k=0; k<m; k++) {

p=a[i][k];

a[i][k]=a[j][k];

a[j][k]=p; }

Используется вспомогательный массив.

for ( k=0; k<m; k++ ) {

c[k]=a[i][k];

for (k=0; k<m; k++) {

a[i][k]=a[j][k]; }

a[j][k]=c[k];