Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
практичні алгоритмізація дл студ.docx
Скачиваний:
0
Добавлен:
01.04.2025
Размер:
6.12 Mб
Скачать

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

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++). Кожна з трьох спроб функції змінити елементи масиву призводить до помилки компілятора "Неможливо змінити константний об'єкт".