Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

книги / Язык Си

..pdf
Скачиваний:
6
Добавлен:
20.11.2023
Размер:
7.64 Mб
Скачать

for (j=0; j<4; j++) //перебираем столбцы {b = a [kl] [j];

a[kl][j] = a[k2] [j]; a[k2] [j] = b;

}

//печать двумерного массива for(i=0;i<4;i++) {for(j=0;j<4;j++)

printf("%3d",a[i] [j]); printf("\n");

}

getch(); return 0;

}

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

Задача 6. Отсортировать массив по возрастанию методом обмена. Исходная последовательность: 13 10 5 11 2.

Существует три общих метода сортировки массивов: обмен,

выбор, вставка.

Одним из самых известных методов сортировки обменом яв­ ляется сортировка «пузырьком». Его популярность объясняется интересным названием и простотой самого алгоритма. Однако в общем случае это один из самых худших алгоритмов сортировки по скорости выполнения (на маленьких массивах это не заметно, но на массивах в несколько тысяч элементов весьма ощутимо).

Данный алгоритм сортировки состоит в повторяющихся про­ ходах (итерациях) по сортируемому массиву. В каждой итерации элементы последовательно сравниваются попарно, и, если порядок в паре неверный, выполняется обмен элементов. Итерации повто­ ряются до тех пор, пока на очередной итерации не окажется, что обмены больше не нужны. Это означает, что массив отсортирован.

При выполнении одной итерации элемент, стоящий не на своем месте, «всплывает» до нужной позиции, как пузырек в воде, отсю­ да и название алгоритма.

 

Итерация

Сравнение

 

Обмен

Вид массива

Индексы

Врздмассива

Делать

Вид массива

п/п

перед нача­

сравниваемых

обмен?

после обмена

лом итерации

элементов

1310 5 112

 

 

0-1

Да

10 13 5 112

1

13 10 5 11 2

1-2

10/5 511 2

Да

10 5 13 112

2-3

10 513112

Да

105 11 132

 

 

 

 

3^1

10 5 1113 2

Да

10 5 11 2 13

 

 

0-1

105 11 2 13

Да

5 10 112 13

2

10 5112 13

1-2

5 1011 2 \Ъ

Нет

 

 

 

2-3

5 10 112 13

Да

5 102 11 13

"3

5102 11 13

0-1

5102 11 13

Нет

 

J

1-2

5 /0 2 11 13

Да

5 2 10 11 13

4

 

52 10 11 13

0-1

5210 11 13

Да

2 5 10 1113

#include<conio.h>

#include<stdio.h>

main ()

{int i,j,n=5;

int a[5]={13,10,5,ll,2},b;

f o r ( i = l ; i < 5 ; i + + , n — )

fo r (j = l ; j < n ; j + + ) i f ( a [j ] < a [j - 1 ] )

{b=a[j ];

a [ j ] = a [ j - l ] ; a [ j -1 ] =b ;

}

f o r ( i = 0 ; i < 5 ; i + + )

p r i n t f ( "%3dfI, a [i] ) ;

g e t c h (); r e t u r n 0;

}

Задача 7. Отсортировать массив по возрастанию методом выбора. Исходная последовательность: 1310 5112.

При данном типе сортировки из последовательности выбира­ ется элемент с наименьшим значением и обменивается с нулевым элементом. Затем из оставшихся п - 1 элементов снова выбирается элемент с наименьшим значением и обменивается с первым эле­ ментом и т.д.

Значения перед началом итерации

Номер итерации: 1

Минимальный элемент: min = 13

Вид массива: 13 10 5 11 2

Номер итерации: 2

Минимальный элемент: min = 10

Вид массива: 2 10 5 1113

Номер итерации: 3

Минимальный элемент: min = 10

Вид массива: 2 5 10 1113

Действие

Запоминание

минимального

Сравнения

элемента

 

Переменные

Вид массива

 

tf[l]-min

13/05112

min=10

tf[2]-min

13 10 511 2

min=5

fl[3]-min

13 10 5 / / 2

 

tf[4]-min

13 10 5 11 2

min=2

Обмен

 

Переменные Вид массива

 

я[0]-тш

2 10 5 11 13

 

Сравнения

 

Переменные

Вид массива

 

tf[2]-min

2 105 11 13

min=5

a[3]-min

2 10 5 11 13

 

tf[4]-min

2 10 5 1113

 

Обмен

 

Переменные Вид массива

 

я[1]-тш

2 5/011 13

 

Сравнения

 

Переменные

Вид массива

 

я[3]-тш

2 5 1011 13

 

я[4]-тш

2 5 10 И 13

 

Обмен не нужен, поскольку минимальный элемент

min =10 уже на своем месте

Номер итерации:

Сравнения

 

4

 

Переменные Вид массива

 

Минимальный элемент:

tf[4]-min

2 5 10 11/5

 

min = 11

 

Обмен не нужен, поскольку

 

Вид массива:

 

минимальный элемент

 

2 5 10 1113

 

min =11 уже на своем месте

 

#include<conio.h>

 

 

#include<stdio.h>

 

 

main()

 

 

 

{int

i,j,k,n=5;

 

 

 

int

a [5]={13,10,5,11,2},min,b;

делать

int

exchange;

//если exchange=l, то надо

 

 

//обмен,если

exchange=0, то

нет

for(i=0;i<n-l;i++)

 

 

{exchange=0;

 

 

 

min

= a[i];

 

 

 

for(j=i+l;j<n;j++)

if(a[j]<min)

{min=a[j];

k=j;

exchange=l;

}

if(exchange == 1) //надо ли делать обмен? {b=a[к];

а[к]=а[i] ;

а [i ] =Ь;

}

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

printf("%3d",a[i]);

getch(); return 0;

}

Задача 8. Отсортировать массив по возрастанию методом вставок. Исходная последовательность: 1310 5112.

Сначала упорядочиваются два первых элемента массива. За­ тем вставляется третий элемент в соответствующую порядку по­ зицию по отношению к первым двум элементам (т.е. теперь уже три первых элемента расположены в нужном порядке). После это­ го в список из трех элементов вставляется четвертый элемент в нужную позицию (теперь упорядочено уже четыре элемента) и т.д.

Итерация

1 X

'J L

3

А

4

Действие

Результат

Запомнить 10

Ь=10

Сравнить а[0] и Ъ

75 10 5 11 2

Сдвинуть 13 вправо

13 13 5 112

На старое место 13 вставить Ъ

10 13 5 112

Запомнить 5

Ь=5

Сравнить а[1\ и b

10755 112

Сдвинуть 13 вправо

10 13 13 112

Сравнить я[0] и Ъ:

10 13 13 11 2

Сдвинуть 10 вправо

1010 13 112

На старое место 10 вставить Ъ

510 13 11 2

Запомнить 11

Ь=11

Сравнить а[2] и Ъ

5 10 75 11 2

Сдвинуть 13 вправо

5 10 13 13 2

Сравнить а[1] и Ъ

5 10 13 13 2

На старое место 13 вставить Ъ

5 10 77 13 2

Запомнить 2

Ь=2

Сравнить а[3] и Ъ

5 10 11 752

Сдвинуть 13 вправо

5 10 11 13 13

Сравнить а[2] и Ъ

5 10 77 13 13

Сдвинуть 11 вправо

5 10 11 11 13

Сравнить а[1] и Ъ

5 70 11 11 13

Сдвинуть 10 вправо

5 10 10 11 13

Сравнить я[0] и Ъ

510 10 11 13

Сдвинуть 5 вправо

5 5 10 11 13

|На старое место 5 вставить Ъ

25 1011 13

#include<conio.h>

 

 

 

#include<stdio.h>

 

 

 

main()

 

 

 

 

{int

i,j,n=5;

 

 

 

int

a [5]= {13,10,5,11,2}, b ;

 

for(i=l;

i<n; i++)

 

 

{b =

a [i];

 

 

 

for(j=i-l; j>=0; j— )

 

 

{if(a[j]<b)//если элемент слева меньше b,

break;

//то

сдвигать

вправо больше

не надо,

a[j+l]

= а [j];

//иначе

- делаем сдвиг

вправо

}

а [j+1] = b;

}

for(i=0;i<n;i++) printf("%3dn,a [i]);

getch(); return 0;

}

В общем случае сортировка вставками является самым быст­ рым методом из трех рассмотренных.

ДОМАШНЕЕ ЗАДАНИЕ

1.Написать программу, которая находит в одномерном мас­ сиве максимальный элемент.

2.Написать программу, которая находит в двумерном масси­ ве минимальный элемент.

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

4.Написать программу, которая выводит часть массива до элемента, значение которого равно нулю. В массиве допускается только один элемент, значение которого равно нулю.

5.Написать программу, которая находит в одномерном мас­ сиве второе максимальное число. Вторым максимальным числом считает число, которое меньше максимального элемента, но боль­ ше всех остальных элементов.

6.Написать программу, которая умножает каждую строчку заданной матрицы на минимальный элемент этой строки.

ЛЕКЦИЯ 8. МАКРОСЫ, КОНСТАНТЫ, СТРОКИ

8.1. Макросы

Макрос - это средство замены одной последовательности символов на другую. Для осуществления замен должны быть зада­ ны соответствующие макроопределения.

8.1.1. Задание макросов

Макрос задается следующим образом:

Mefine имя макроса строка замещения

Mefine - директива препроцессора, используется для зада­ ния макроопределений. Директивы препроцессора начинаются со знака # и находятся в заголовке программы.

С помощью директивы Mefine можно вводить собственные обозначения базовых типов.

Пример. Создание нового типа REAL.

#define REAL long double

main()

{int i,j;

REAL x,z [6];

float a,b;

return 0;

}

На этапе препроцессорной обработки все текстовые обозна­ чения REAL найденные в программе будут заменены на замещаю­ щий текст long double, поэтому на этапе компиляции ошибок не будет.

Пример. Найти площадь круга.

#include<stdio.h>

#include<conio.h>

#define PI 3.14159

main()

{float r,S;

r = 2.3;

S = PI*r*r;

printf("S=%f",S);

getch();

return 0;

}

На этапе препроцессорной обработки все имена PI в про­ грамме будут заменены на указанный в директиве замещающий текст «3.14159».

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

Пример. Найти сумму элементов двумерного массива.

#include<conio.h>

#include<stdio.h> #define n 4 #define m 3 main()

{int i,j,S=0;

int a [n] [m]={ {13,10,-5},{11,2,3}, {-6,9,0},{2,13,-10}};

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

S+=a[i][j];

printf (nS=%d",S) ; getch();

return 0;

}

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

целочисленные константы 4 и 3. Также п и т использованы в ус­ ловиях цикловfor при работе с элементами массива.

Если замещающий текст в директиве не задан, то во всем тек­ сте идентификаторы макроса просто стираются:

#define AAA //идентификатор AAA в тексте просто

//удалится

8.1.2.Макросы с параметрами

Вобщем случае имя макроса (идентификатор) служит обо­ значением некоторого выражения. Любое выражение всегда имеет параметры. Макрос с параметрами имеет следующий вид опреде­ ления:

Mefine имя макроса(параметры) замещающий текст

Между идентификатором макроса и открывающей скобкой не должно быть пробела.

Вызов макроса осуществляется выражением

имя макроса(аргументы);

Пример. Найти площадь круга.

#include<stdio.h>

#include<conio.h> //задание макроса

#define

CIRC(x)

(3.14159*(x)* (x))

main()

S;

 

{float

//вызов макроса

S = CIRC(2.3);

printf("S=%10.6f",S);

getch();

 

return

0;

 

}

Строка S = C7Z?C(2.3); после препроцессирования будет иметь

вид

S = (3.14159* (2.3)*(2.3));