Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Text_lektsy_Si-dlya_studentov.pdf
Скачиваний:
6
Добавлен:
08.05.2015
Размер:
1.22 Mб
Скачать

a[i][j]=i=i+1; i=2 a[2][3]=2

5.2 Оператор перехода

Формат goto <метка>; <помеченный оператор>

<метка> := <идентификатор>, полноценный идентификатор, созданный по правилам языка Си.

<помеченный оператор>:= <метка>: <оператор>;

Пример: goto label;

label: x++;

5.3 Условный оператор. Пустой оператор

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

Формат

if ( <выражение> )

<оператор 1>;

[else

<оператор 2>; ] Конструкция работает предельно просто: если условие не равно нулю, то выполня-

ется оператор_1, в противном случае – оператор_2. Обратите внимание, что опера-

тор_1 и оператор_2 должны представлять собой только одно выражение. Как вы уже догадались, так как условие должно возвращать некоторое значение, то оно не мо-

жет быть составным.

Примеры: if (a>b) c=a;

else

 

c=b;

 

 

Обход

 

if ( x*x + y*y > r*r ) z=0; /* без else */

x+1

 

x<0

y=

 

x>=0

 

1−x

 

 

 

 

if (x<0) y=x+1;

else

y=1–x;

23

Вложенные if.

 

if

(x > y)

 

 

 

if

(z = = 0)

 

 

else

x = 5;

 

 

x = –5;

 

else

 

 

 

 

if

(z > 10)

 

 

 

 

else

y = 5;

 

 

 

 

 

 

y = –5;

 

 

x2−5

 

y=

 

 

+3

 

 

x

 

 

x−7

 

 

 

 

 

 

 

 

if

(x < 0)

 

 

else

y = x*x–5;

 

if

(x<=5)

 

 

 

 

else

y = sqrt(x)+3;

 

 

 

 

 

 

y=x–7;

Пустой оператор.

Формат:;

x<0 0<=x<=5 x>5

Не выполняет никакого действия.

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;

 

5.4 Составной оператор

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

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

Пример:

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

x = a;

24

y = b; } else { x = b; y = a; }

5.5 Циклы

5.5.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 – это ложь, цикл выполняться больше не будет.

5.5.2Цикл for

е1 – присваивание начального значения управляющей переменной. е2 – проверка выполнения условия продолжения цикла.

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

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

25

е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]; }

5.5.3Цикл do

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

Формат do {

< оператор > ;

}while (e);

Эквивалентная схема label: <оператор>; if ( e ) goto label;

26

Пример:

Дано: 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 );

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

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

Умножение матриц 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; }

}

 

 

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

5.6.1Оператор break

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

Формат

break ;

 

 

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

 

 

for ( e1; e2; e3 ) {

 

for ( e1; e2; e3 ) {

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

 

 

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

if ( e4 ) break ;

 

if ( e4 ) goto exit ;

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

 

 

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

}

 

 

}

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

 

exit :

...

27

Пример:

Дано 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; }

5.6.2Оператор 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 */ …

}

}

}

5.7 Оператор 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 придает больше гибкости конструкции.

28

Еще одно замечание: в качестве меток 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 : <поместить в стек>;

}

 

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

1)Суммирование элементов одномерного массива a[i], i = 1,n. for ( s=i=0; i<n; i++ )

s += a[i];

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

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

{

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

 

s += a[i][j];

}

3) Суммирование двух массивов (матриц) одинакового размера. for ( i=0; i<n; i++ ) {

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

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

29

ai =ai+1

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

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

for ( j=0; j<n; j++ ) s += b[i][j]; d[i]=s; }

5) Выполнить транспонирование матрицы а[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;

}

 

6) Умножить матрицу а[i][j], размером n×m, на матрицу b[i][j], размером k×m. Другими словами вычислить:

k

Cij=l1ail*bij; 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 }

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

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

n = n–1; /*n– –*/ for ( i=k; i<n; i++) a[i] = a[i+1];

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

ai+1=ai

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

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

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

a[k]=b;

30

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

10) Включить в массив а[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++*/

11) Удалить из матрицы строку с номером k. n=n–1; /*n– –*/

for ( i=k; i<n; i++ ) { for ( j=0; j<n; j++ ) b[i][j]=b[i+1][j]; }

12) Включить в матрицу строку, заданную вектором с[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++;

 

13) Перестановка строк матрицы с номерами 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];

 

31

Глава 6. ВВОД – ВЫВОД данных

Ввод–вывод – это передача данных между переменными программы(ОП) и внешней памятью(ВП).

В Си предусмотрен только форматный обмен. <stdio.h> – файл прототипа.

Ввод:

клавиатура

 

 

буфер

 

 

переменная в памяти

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

переменная в памяти

 

 

буфер

 

 

Экран|принтер|файл

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Вывод:

Буфер имеет конечный размер и считывание из него происходит только после нажатия клавиши <Enter>.

Формат основных функций

{scanf | printf}(<управляющая строка>[, <список_данных>] );

<управляющая строка> := “[<произвольный текст>][<спецификации>]” <список_данных> := <имя_переменной> [ , <имя_переменной> [, …] ]

Элементы списка данных scanf( ) – адреса переменных, значения которых задаются, поэтому необходимо использовать операцию &(нахождение адреса).

Возвращаемые значения: printf ( )– число выводимых символов (байтов), scanf( ) – число введенных скалярных значений.

6.1 Управляющая строка

Содержит спецификации для функций ввода-вывода. Формат ОДНОЙ спецификации

%

[ <флаги> ] [W] [. D][l] <тип>

%

[признаки] [ширина_поля] [ .точность ] [модификатор] с_n.

Флаги для printf (для scanf не используются):

данное прижимается к левой границе поля вывода;

+число ВСЕГДА со знаком (актуально для положительных данных, в которых по умолчанию знак опускают, отрицательные всегда изображаются со знаком).

W – размер поля данного в символах (байтах).

D – обычно характеризует точность представления значения при выводе, ПРИ ВВОДЕ НЕ ИСПОЛЬЗУЕТСЯ (количество цифр, которые необходимо вывести справа от десятичной точки для типов float и double).

Модификаторы:

l – модификатор "длинных"(long для целых, double для чисел с плавающей точкой), указывает, что соответствующий элемент имеет тип long.

32

h – модификатор “коротких”, указывает, что соответствующий элемент имеет тип short int.

6.1.1Спецификация d (целые десятичные цифры)

ВВОД Формат спецификации

% [W] [l] d

W – максимальное число считываемых символов. l – модификатор для long.

Пример.

Внешнее представление

 

Спецификация

Значение в памяти

 

165<пробел>

 

d

165

 

+165<Enter>

 

d

165

 

165

 

 

2 d

16

 

165

 

 

1 d

1

 

431921

 

 

l d

431921

 

– 431921

 

4 l d

– 431

 

+ 431921<пробел>

 

10 l d

431921

 

ВЫВОД Формат спецификации

 

 

% [<флаги>] [W] [ .D] [l] d

 

 

 

 

D – минимальное число выводимых символов.

 

 

Пример.

 

 

 

 

Значение в памяти

 

Спецификация

 

Внешнее представление

2475

 

 

d

 

2475

 

2475

 

 

+ d

 

+ 2475

 

2475

 

 

<пробел> d

 

<пробел> 2475

– 2475

 

d

 

–2475

– 2475

 

+d

 

–2475

–2475

 

<пробел>d

 

–2475

–2475

 

3d

 

–2475

2475

 

 

10d

 

_ _ _ _ _ _ 2475

 

2475

 

 

+10d

 

_ _ _ _ _+2475

 

2475

 

 

–10d

 

2475_ _ _ _ _ _

 

2475

 

 

–+10d

 

+2475_ _ _ _ _

 

2475

 

 

10.5d

 

– – – – – 02475

–24

 

10.5d

 

_ _ _ _ – 00012

–24

 

.5d

 

–00024

3

 

 

5.0d

 

_ _ _ _ 3

 

–478126

 

10ld

 

_ _ _–478126

–478126

 

–10ld

 

–478126_ _ _

478126

 

 

+–10ld

 

+478126_ _ _

 

6.1.2.Спецификация f (вещественные числа с плавающей точкой)

ВВОД Формат спецификации

% [W] [l] f

33

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]