Главная Обратная связь

Дисциплины:






Передача масивів у функції



10. Напишіть і запустіть програму на виконання що написана нижче. Дослідіть хід її роботи.

  /* Ім'я масиву це те ж саме, що &аггау[0] * / include <stdio.h> main () { char array[5]; printf(" array = %p\n&array[0] = %p\n", array, &array[0]); return 0; }   array = FFF0 &array[0] = FFF0   Лістингу 6.12. Ім'я масиву - це те ж саме, що і адреса його першого елементу Для передачі масиву як параметра функції вкажіть його ім'я без всяких дужок. Наприклад, якщо масив hourlyTemperatures був оголошений як int. hourlvTemeratures[24]; оператор виклику функції modifyArray(hourlvTemeratures, 24); передає масив hourlyTemperatures і його розмір у функцію modifyArray. При передачі масиву у функцію часто передається і розмір масиву, щоб функція змогла обробити певну кількість його елементів.  

C автоматично передає масив у функцію шляхом імітації передачі параметра по посиланню - функції, що при цьому викликаються, можуть змінювати значення елементів в початкових масивах зухвалих функцій. Адже ім'я масиву фактично є адресою його першого елементу! Оскільки передається початкова адреса масиву, функція, що викликається, точно знає, де зберігається цей масив. Таким чином, коли функція, що викликається, змінює у своєму тілі елементи масиву, вона змінює справжні елементи масиву в їх початкових елементах пам'яті.

Ця програма демонструє, що ім'я масиву дійсно є адресою його першого елементу, виводячи значення array і &аrrау[0] із специфікацією перетворення %р - спеціальною специфікацією для виведення адрес. Специфікація перетворення % р зазвичай виводить адреси виді шістнадцятиричних чисел. Шістнадцятиричні (основа 16) числа складаються з цифр від 0 до 9 і букв від А до F. Вони часто використовуються для скороченого запису великих цілочисельних значень. У додатку Д даний детальний опис взаємин між двійковими (основа 2), вісімковими (основа 8), десятковими (основа 10; стандартні цілі числа) і шістнадцятиричними цілими числами. Вихідні дані показують, що як array, так і &аггау[0] мають одне і те ж значення, а саме FFF0. Виведення цієї програми є системно-залежним, але адреси завжди співпадатимуть.

Для того, щоб функція при зверненні до неї могла прийняти масив, в списку параметрів цієї функції повинно бути вказано, що очікується передача масиву. Наприклад, заголовок для функції modifyArray міг би бути записаний як

void modifyArray(int b[], int size)

Список параметрів показує, що функція modifyArray чекає прийому масиву цілих чисел в параметрі b і числа елементів масиву в параметрі size. Розмір масиву в дужках в заголовку не потрібно. При його вказівці компілятор його ігнорує. Оскільки масиви автоматично передаються шляхом імітації передачі параметра по посиланню, то, коли функція, що викликається, використовує ім'я масиву Ь, вона насправді посилається на фактично існуючий масив в зухвалій функції (масив hourlyTemperatures в попередньому виклику). Далі ми введемо інші позначення для вказівки того, що функція приймає масив. Ми побачимо, що ці позначення засновані на близькому зв'язку між масивами і покажчиками в мові С.



Зверніть увагу на незвичайний зовнішній вигляд прототипу функції modifyArray

void modifyArray(int [], int);

Цей прототип можна було б записати у виді

void modifyArray(int anyArrayName[], int anyVariableName);

проте, як ми дізналися, компілятор мови С ігнорує імена змінних в прототипах.

Хороший стиль програмування 6.6

Деякі програмісти включають імена змінних в прототипи функцій для того, щоб зробити програми зрозумілішими. Компілятор ігнорує ці імена.

Не забувайте, що прототип повідомляє компілятору про кількість параметрів і тип кожного з них (у тому порядку, в якому ці параметри передаватимуться).

11. Напишіть і запустіть програму на виконання що написана нижче. Дослідіть хід її роботи.

/* Передача у функцію масиву і окремого елементу масиву */ #include <stdio.h> #define SIZE 5 void modifyArray(int [], int); /* виглядає незвично */ void modifyElement(int); main () { int a [SIZE] = {0, 1, 2, 3, 4}; int i ; printf("Effects of passing entire array call " "by reference: \n\nThe values of the " "original array are:\n");   for (i = 0; i <= SIZE - 1; i++) printf("%3d", a [i]); printf("\n"); modifyArray (a, SIZE); /* масив а передається по посиланню */ printf("The values of the modified array are: \n"); for (i = 0; i <= SIZE - 1; i++) printf("%3d", a[i]);   printf("\n\n\nEffects of passing array element call " "by value:\n\nThe value of a[3] is %d\n", a[3]); modifyElement (a [ 3] ); printf("The value of a[3] is %d\n", a [3]); return 0; } void modifyArray (int b[], int size) { int j ; for (j = 0; j <= size - 1; j + +) b [ j1 *= 2; } void modifyElement(int e) { printf("Value in modifyElement is %d\n", e *= 2); } Effects of passing entire array call by reference: The values of the original array are: 0 1 2 3 4 The values of the modified array are: 0 2 4 6 8 Effects of passing array element call by value: The value of a[3] is 6 Value in modifyElement is 12 The value of a[3] is 6 Лістингу 6.13. Передача у функцію масиву і його окремого елементу У програмі показана відмінність між передачею цілого масиву і елементу масиву. Спочатку програма виводить п'ять елементів цілочисельного масиву а. Потім масив а і його розмір передаються у функцію modify Array, в якій кожен елемент масиву а множиться на 2. Після цього в програмі main відбувається повторне виведення масиву а. Як показують дані, що виводяться, функція modify Array дійсно змінила елементи масиву а. Тепер програма виводить значення а[3] і передає його у функцію modifyElemcnt. Функція modifyElement множить свій параметр на 2 і виводить нове значення. Зверніть увагу, що коли елемент а[3] повторно виводиться у функції main, його значення залишається тим самим, оскільки окремі елементи масиву передаються за значенням. У ваших програмах можуть виникати ситуації, коли функція не повинна змінювати елементи масиву. Оскільки масиви завжди передаються шляхом імітації передачі параметра по посиланню, модифікація значень в масиві насилу піддається контролю. Для запобігання зміні у функції значень елементів масиву в мові С передбачений спеціальний модифікатор типу const. Коли параметру-масиву передує const, елементи масиву стають константами в тілі функції і будь-яка її спроба змінити елемент масиву призводить до помилки часу компіляції. Це дає можливість програмістові виправити програму так, щоб вона не намагалася змінювати елементи масиву. Хоча модифікатор const строго визначений в стандарті ANSI, в різних системах Із способи його підтримки різні.

12. Напишіть і запустіть програму на виконання що написана нижче. Дослідіть хід її роботи.

/* Демонстрація модифікатора типу const * / #include <stdio.h> void tryToModifyArray(conat int []); main () { int a[] = {10, 20, 30}; tryToModifyArray(a); printf("%d %d %d\n", a[0 ], a [ 1], a [ 2]); return 0; } void tryToModifyArray(conat int b[]) { b [ 0] /= 2; /* помилка */ b [ 1] /= 2; /* помилка */ b [ 2] /= 2; /* помилка */ } Compiling FIG6_14.C: Error FIG6_14.C 16: Cannot modify a const object Error FIG6_14.C 17: Cannot modify a const object Error FIG6_14.C 18: Cannot modify a const object Warning FIG6_14.C 19: Parameter 'b' is never used Демонстрація модифікатора типу const Програма демонструє описувач const. Функція tryToModifyArray визначена з параметром const intb[], який вказує, що масив b виявляется константним і не може бути змінений. Результатом роботи програми є повідомлення про помилки (компілятор Borland C++). Кожна з трьох спроб функції змінити елементи масиву призводить до помилки компілятора "Неможливо змінити константний об'єкт".  

Лабораторна робота №19. Тема: Сортування масивів

Мета: Освоїти роботу із сортуванням масивів.

Хід роботи

1. Напишіть дану програму, проаналізуйте її. Змініть значення SIZE 10 на свій номер по списку.

/* Програма сортує значення масиву в порядку зростання */ include <stdio.h> define SIZE 10 main () { int a[SIZE] = {2, 6, 4, 8, 10, 12, 89, 68, 45, 37}; int i, pass, hold;   printf("Data items in original order\n"); for (i = 0; i <= SIZE - 1; i++) printf("%4d", a [i]); for (pass = 1; pass <= SIZE - 1; pass++) /* проходів */ for (i = 0; i <= SIZE - 2; I++) /* один прохід */ if (a[i] > a[i + 1]){ /* одне порівняння */ hold = a[i] ; /* одна перестановка */ a[i] = a[i + 1]; a[i + 1] = hold; } printf(" \nData items in ascending order\n"); for (i = 0; i <= SIZE - 1; i++) printf("%4d" a [i]); printf("\n"); return 0; } Data items in original order 2 6 4 8 10 12 89 68 45 37 Data items in ascending order 2 4 6 8 10 12 37 45 68 89 Лістингу 6.15. Сортування масиву бульбашковим методом Сортування даних (тобто розташування даних в деякому спеціальному порядку, наприклад, за збільшенням або убуванню) є одним з найбільш важливих застосувань комп'ютера. Банк сортує усі чеки по номерах рахунків, щоб у кінці кожного місяця можна було підготувати особисті банківські декларації. Телефонні компанії сортують списки своїх рахунків по прізвищах і, усередині прізвищ, по іменах, щоб полегшити пошук телефонних номерів. Практично кожній організації доводиться сортувати які-нибудь дані (і у багатьох випадках - великі масиви даних). Сортування даних є захоплюючою проблемою, що вимагає найінтенсивніших зусиль дослідників в області інформатики. У цій главі ми обговоримо, можливо, найпростішу з відомих схем сортування. Програма сортує значення елементів десятиелементного масиву а в порядку їх зростання. Використовувана нами методика називається бульбашковим сортуванням або сортуванням зануренням, оскільки менші значення, подібно до повітряних бульбашок у воді, поступово "спливають" у верхню частину масиву, тоді як великі значення опускаються вниз. Метод вимагає декількох проходів по масиву. На кожному проході порівнюються послідовні пари елементів. Якщо елементи розташовані в зростаючому порядку (чи якщо їх значення співпадають), ми нічого не міняємо. Якщо елементи пари розташовані в убуваючому порядку, їх значення в масиві міняються місцями.

Спочатку програма порівнює а[0] і а[1], потім а[1] і а[2], потім а[2] і а[3] і так далі, поки порівняння а[8] і а[9] не завершить прохід. Зверніть увагу, що хоча існує 10 елементів, виконується тільки дев'ять порівнянь. Із-за способу проведення послідовних порівнянь велике значення за один прохід може переміститися в масиві на багато позицій вниз, а невелике значення може переміститися тільки на одну позицію вгору. За перший прохід найбільше значення гарантовано опускається в нижній елемент масиву а[9]. За другий прохід друге за величиною значення гарантовано опускається в а[8]. За дев'ятий прохід дев'яте за величиною значення виявляється в а[1]. В результаті цього найменше значення залишається в а[0], отже для сортування масиву потрібно тільки дев'ять проходів, навіть якщо він складається з десяти елементів.

Сортування виконується за допомогою вкладеного циклу for. У разі потреби перестановки вона виконується шляхом трьох привласнень

hold = а[i];

а [ i ] = а [ i + 1 ] ;

а [i + 1] = hold;

де в додатковій змінній hold тимчасово зберігається одне з двох обмінюваних значень. Перестановка не може бути виконана тільки двома привласненнями

а [ i ] = а [ i + 1 ] ;

а [ i + 1] = а [ i ] ;

Якщо, наприклад, a[i] рівне 7 і a[i + 1] рівне 5, то після першого привласнення обидва значення дорівнюватимуть 5 і значення 7 буде втрачено. Звідси необхідність в додатковій змінній hold.

Головним достоїнством бульбашкового сортування є те, що її легко запрограмувати. Проте бульбашкове сортування виконується повільно. Це стає очевидним при сортуванні великих масивів. У вправах ми розробимо досконаліші версії бульбашкового сортування. Нині вже розроблені набагато ефективніші методи сортування, чим бульбашкова. Пізніше ми досліджуємо деякі з них. У поглиблених курсах навчання програмуванню методи сортування і пошуку розглядаються більш повно.

 





sdamzavas.net - 2018 год. Все права принадлежат их авторам! В случае нарушение авторского права, обращайтесь по форме обратной связи...