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

Министерство образования и науки Российской Федерации Саратовский государственный технический университет им. Ю.А. Гагарина

Балаковский институт техники, технологии и управления

СИ: РАБОТА С МАССИВАМИ

Методические указания к выполнению практической работы по курсу

«Языки программирования» для студентов направления «Информационные системы и технологии» для всех форм обучения

Одобрено редакционно-издательским советом Балаковского института техники,

технологии и управления

Балаково 2015

2

ЦЕЛЬ РАБОТЫ - развитие практических навыков при решении задач на методы обработки одномерных и многомерных массивов на языке програм-

мирования СИ.

ОБЩИЕ ПОНЯТИЯ

Описание массивов

Массивы - это группа элементов одинакового типа (double, float, int и

т.п.). Массивы могут быть одномерными и многомерными. В языке СИ опре-

делены только одномерные массивы, но поскольку элементом массива может быть массив, можно определить и многомерные массивы. Они формализуют-

ся списком константных выражений следующих за идентификатором масси-

ва, причем каждое константное выражение заключается в свои квадратные скобки.

При объявлении массива необходимо указать тип элементов и их количе-

ство. Объявление массива имеет два формата:

спецификатор-типа описатель [константное выражение];

спецификатор-типа описатель;

описатель - это идентификатор массива.

Спецификатор-типа задает тип элементов объявляемого массива. Эле-

ментами массива не могут быть функции и элементы типа void.

Константное-выражение в квадратных скобках задает количество эле-

ментов массива. Константное-выражение при объявлении массива может быть опущено в следующих случаях:

-при объявлении массив инициализируется;

-массив объявлен как формальный параметр функции;

-массив объявлен как ссылка на массив, явно определенный в другом файле.

Каждое константное выражение в квадратных скобках определяет число элементов по данному измерению массива, так что объявление двухмерного массива содержит два константных выражения, трехмерного - три и т.д. От-

3

метим, что в языке СИ первый элемент массива имеет индекс равный 0.

Например:

int a[2][3]; /* представлено в виде матрицы

a[0][0]

a[0][1] a[0][2]

 

a[1][0]

a[1][1] a[1][2]

*/

double b[10]; /* вектор из 10

элементов, имеющих тип double */

int w[3][3] = { { 2, 3, 4 },

 

{3, 4, 8 },

{1, 0, 9 } };

Вданном примере объявлен массив w[3][3]. Списки, выделенные в фи-

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

Как и в других языках высокого уровня, в языке СИ можно использовать сечения массива, однако на использование сечений накладывается ряд огра-

ничений.

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

тываемых пользователем.

Например: int s[2][3]

Если при обращении к некоторой функции написать s[0], то будет пере-

даваться нулевая строка массива s. int b[2][3][4]

то есть, при обращении к массиву b можно написать, например, b[1][2] и бу-

дет передаваться вектор из четырех элементов, а обращение b[1] даст двух-

мерный массив размером 3 на 4.

Пример объявления символьного массива.

char str[n] = "объявление символьного массива",

где n – количество элементов.

4

При указании n следует учитывать, что в символьном интервале находит-

ся на один элемент больше, так как последний из элементов является управ-

ляющей последовательностью '\0'.

Указатели на многомерные массивы в языке СИ - это массивы массивов,

то есть такие массивы, элементами которых являются массивы. При объявле-

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

Например, при выполнении объявления двумерного массива int arr2[4][3]

в памяти выделяется участок для хранения значения переменной arr, которая является указателем на массив из четырех указателей. Для этого массива из четырех указателей тоже выделяется память. Каждый из этих четырех указа-

телей содержит адрес массива из трех элементов типа int, и, следовательно, в

памяти компьютера выделяется четыре участка для хранения четырех масси-

вов чисел типа int, каждый из которых состоит из трех элементов.

Таким образом, объявление arr2[4][3] порождает в программе три разных объекта: указатель с идентификатором arr, безымянный массив из четырех указателей и безымянный массив из двенадцати чисел типа int. Для доступа к безымянным массивам используются адресные выражения с указателем arr.

Доступ к элементам массива указателей осуществляется с указанием одного индексного выражения в форме arr2[2] или *(arr2+2). Для доступа к элемен-

там двумерного массива чисел типа int должны быть использованы два ин-

дексных выражения в форме arr2[1][2] или эквивалентных ей *(*(arr2+1)+2) и

(*(arr2+1))[2]. Следует учитывать, что с точки зрения синтаксиса языка СИ указатель arr и указатели arr[0], arr[1], arr[2], arr[3] являются константами и их значения нельзя изменять во время выполнения программы.

При размещении элементов многомерных массивов они располагаются в памяти подряд по строкам, то есть быстрее всего изменяется последний ин-

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

5

элемента и только одно индексное выражение.

Например, обращение к элементу arr2[1][2] можно осуществить с помо-

щью указателя ptr2, объявленного в форме int *ptr2=arr2[0] как обращение ptr2[1*4+2] (здесь 1 и 2 - это индексы используемого элемента, а 4 - это число элементов в строке) или как ptr2[6]. Заметим, что внешне похожее обращение arr2[6] выполнить невозможно, так как указателя с индексом 6 не существу-

ет.

Для обращения к элементу arr3[2][3][4] из трехмерного массива тоже можнo использовать указатель, описанный как float *ptr3=arr3[0][0] с одним индексным выражением в форме ptr3[3*2+4*3+4] или ptr3[22].

Методы доступа к элементам массивов. В языке СИ между указателя-

ми и массивами существует тесная связь. Например, когда объявляется мас-

сив в виде int array[25], то этим определяется не только выделение памяти для двадцати пяти элементов массива, но и для указателя с именем array, зна-

чение которого равно адресу первого по счету (нулевого) элемента массива,

то есть сам массив остается безымянным, а доступ к элементам массива осу-

ществляется через указатель с именем array. С точки зрения синтаксиса языка указатель array является константой, значение которой можно использовать в выражениях, но изменить это значение нельзя.

Поскольку имя массива является указателем, допустимо, например, такое присваивание:

int array[25]; int *ptr; ptr=array.

Здесь указатель ptr устанавливается на адрес первого элемента масcива,

причем присваивание ptr=array можно записать в эквивалентной форме ptr=&arrey[0].

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

Первый способ связан с использованием обычных индексных выражений в

6

квадратных скобках, например, array[16]=3 или array[i+2]=7. При таком спо-

собе доступа записываются два выражения, причем второе выражение за-

ключается в квадратные скобки. Одно из этих выражений должно быть ука-

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

Указатель, используемый в индексном выражении не обязательно должен быть константой, указывающей на какой-либо массив, это может быть и пе-

ременная. В частности, после выполнения присваивания ptr=array доступ к шестнадцатому элементу массива можно получить с помощью указателя ptr в

форме ptr[16] или 16[ptr].

Второй способ доступа к элементам массива связан с использованием ад-

ресных выражений и операции разадресации в форме *(array+16)=3 или

*(array+i+2)=7. При таком способе доступа адресное выражение, равное ад-

ресу шестнадцатого элемента массива, тоже может быть записано разными способами *(array+16) или *(16+array).

При реализации на компьютере первый способ приводится ко второму, то есть индексное выражение преобразуется к адресному. Для приведенных примеров array[16] и 16[array] преобразуются в *(array+16).

Для доступа к начальному элементу массива (т.е. к элементу с нулевым индексом) можно использовать просто значение указателя array или ptr. Лю-

бое из присваиваний

*array = 2; array[0] = 2; *(array+0) = 2; *ptr = 2; ptr[0] = 2; *(ptr+0) = 2.

7

присваивает начальному элементу массива значение 2, но быстрее всего вы-

полнятся присваивания *array=2 и *ptr=2, так как в них не требуется выпол-

нять операции сложения.

Работа с элементами массивов

При нахождении суммы (произведения) элементов массива задаем пере-

менную, тип которой должен совпадать с типами элементов массива. Данной переменной необходимо присвоить начальное значение, которое в дальней-

шем не будет влиять на результат суммы (произведения). Для суммы элемен-

тов массива начальным значением является нуль, для произведения – едини-

ца. Далее в цикле переменная увеличивается на (в) значение текущего эле-

мента массива.

Для нахождения максимального (минимального) элемента массива необ-

ходимы две вспомогательные переменные. В первой переменной в результа-

те выполнения всех действий окажется максимальный (минимальный) эле-

мент, во второй – номер данного элемента. Назовем данные переменные max (min) и k. Первым шагом переменной max (min) присваиваем значение перво-

го элемента массива, переменной k присваиваем значение 1. Затем организу-

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

Если сравниваемый элемент больше максимального (меньше минимального),

то в переменную max (min) заносим значение данного элемента, а в перемен-

ную k заносим номер данного элемента. В данном примере заполним массив методом ввода элементов с клавиатуры.

Сортировка элементов массива – это упорядочение элементов массива по возрастанию (убыванию). Сортировка может быть осуществлена методом пузырька, методом прямого выбора элементов, квадратичной выборкой.

П р и п узы р ьк о во й ( о б м е н н о й ) с о р ти р о в к е упорядоченный спи-

сок В' получается из В систематическим обменом пары рядом стоящих эле-

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

8

Сортировка элементов массива м е то д о м п узы р ьк а заключается в следующем.

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

тов массива ищем минимальный. В случае, если первый элемент массива оказывается больше какого-либо последующего элемента, то они меняются местами.

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

мент.

Далее второй элемент массива сравнивается со всеми последующими элементами по аналогичной схеме и так далее.

Для организации такой схемы требуется вложенный цикл с заданным количеством итераций. Внешний цикл меняет значение переменной от пер-

вого элемента до предпоследнего. Внутренний цикл должен быть организо-

ван от текущего значения внешнего цикла до последнего элемента массива.

Для того, чтобы поменять местами два элемента массива, необходимо ис-

пользовать вспомогательную переменную.

Например:

B=<20,-5,10,8,7>, исходный список;

B1=<-5,10,8,7,20>, первый просмотр;

B2=<-5,8,7,10,20>, второй просмотр;

B3=<-5,7,8,10,20>, третий просмотр.

Пузырьковая сортировка выполняется при количестве действий Q=(n- m)*(n-m) и не требует дополнительной памяти.

М е то д п р я м о г о вы б о р а эл е м е н то в заключается в следующем.

В массиве находится минимальный элемент (если массив сортируется по возрастанию) и максимальный элемент (при сортировке по убыванию). Дан-

ный элемент ставится на первое место. Затем ищется минимальный (макси-

9

мальный элемент) среди элементов массива со второго по последний и ста-

вится на второе место. Процедура повторяется до предпоследнего элемента.

При решении задачи сортировки массива методом прямого выбора необ-

ходимо использовать вложенные циклы с заданным количеством итераций.

Внешний цикл отвечает за номер элемента, с которого ведется поиск, а внут-

ренний цикл осуществляет поиск минимального (максимального) элемента

среди заданных.

Кроме того, необходимы вспомогательные переменные, такие как номер минимального элемента, номер элемента массива, сравниваемого с мини-

мальным, переменную для обмена элементов массива, индекс для ввода и

вывода элементов массива.

Упорядоченный список В' получается из В многократным применением выборки из В минимального элемента, удалением этого элемента из В и до-

бавлением его в конец списка В', который первоначально должен быть пу-

стым.

Например:

B=<20,10,8,-5,7>, B'=< >

B=<20,10,8,7>, B'=<-5>

B=<20,10,8>,

B'=<-5,7>

B=<20,10>,

B'=<-5,7,8>

B=<20>,

B'=<-5,7,8,10>

B=< >,

B'=<-5,7,8,10,20> .

Функция select упорядочивает массив s сортировкой посредством выбора.

/* сортировка методом выбора

*/

double *select( double *s, int m, int n)

 

{

 

int i,j;

 

double c;

 

for (i=m; is[j])

 

{ c=s[i];

 

s[i]=s[j];

 

10

s[j]=c;

}

return(s);

}

При сортировке посредством выбора требуется Q=(n-m)*(n-m) действий и не требуется дополнительной памяти.

Кроме того, существует с о р ти р о вк а к ва д р а ти ч н о й вы б о р к о й , ме-

тод которой заключается в нижеследующем:

Исходный список В из N элементов делится на М подсписков В1,В2,...,Вm, где М равно квадратному корню из N, и в каждом В1 находится минимальный элемент G1. Наименьший элемент всего списка В определяет-

ся как минимальный элемент Gj в списке, и выбранный элемент Gj заменяет-

ся новым наименьшим из списка Bj. Количество действий, требуемое для сортировки квадратичной выборкой, несколько меньше, чем в предыдущих методах Q= N*N, но требуется дополнительная память для хранения списка

G.

СОДЕРЖАНИЕ И ТЕХНОЛОГИЯ РАБОТЫ

Для решения задач необходимо запустить MS VS 2005 (Пуск -

Microsoft Visual Studio 2005), создать новый проект.

1. В диалоговом окне Начальная страница (Start Page) нажать кнопку

Create Project.

2. В появившемся диалоговом окне New Project в полях и областях задать параметры:

поле Name - имя создаваемого проекта;

поле Location - установить папку для размещения файлов проек-

та;

область Project Types - выбрать вариант Visual C++ Projects;

области Templates - выбрать вариант Win32 Console Application;

нажать кнопку ОК.

3.Ввести программный код на языке программирования СИ.

11

Соседние файлы в папке 2к3с Языки программирования