Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методичка С#.doc
Скачиваний:
1
Добавлен:
01.04.2025
Размер:
1.13 Mб
Скачать

Лабораторна робота № 13 робота з функціями Мета роботи

Метою даної лабораторної роботи є придбання навичок програмування з використанням функцій. Задачею роботи є також ознайомлення зі способами використання покажчиків для роботи з масивами, класами пам'яті мови С, способами обміну даних між функціями.

Завдання

1. Скласти алгоритм і написати програму обробки двовимірного масиву згідно з індивідуальним завданням. В основній функції main () здійснити уведення вихідних даних і вивід результатів роботи. Обробку масиву зробити у функціях. Варіанти завдань надано в додатку 12. Номер варіанта призначається викладачем.

2. Здійснити налагодження програми і її тестування.

3. Скласти звіт про роботу.

Вказівки до виконання завдання

Функція – це самостійний фрагмент програми, призначений для виконання конкретної задачі. Використання функцій дозволяє уникнути повторного програмування і додає програмі модульну структуру.

У програму функція вводиться в три етапи. Першим етапом є оголошення функції. В оголошенні вказується тип функції, що збігається з типом значення, яке повертається, ім'я функції і список аргументів. У списку аргументів досить указати їхній тип і кількість, імена аргументів можна не вказувати. Оголошення функції може мати вигляд:

int imax (int a, int b);

Цей рядок повідомляє компілятору, що у програмі буде функція imax, яка повертає ціле значення. Аргументами функції є два цілих числа.

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

int k, l, m;

m=imax(k, l);

При виявленні виклику функції у програмі компілятор виконує функцію і повертається у викликаючу програму.

Третім етапом є визначення функції. Воно має вигляд:

int imax(int a, int b)

{

тіло функції

}

Змінні a і b є локальними для даної функції. Для повернення значень використовується оператор return, що дозволяє припинити виконання функції і повернути одне значення.

Приклад: визначити мінімальне з двох чисел.

#include <stdio.h>

int imin(int k, int l); /* оголошення функції */

int main()

{

int a, b;

printf (“Уведіть два цілих числа. \n”);

scanf(“%d %d”,&a, &b);

printf (“Мінімальне з двох чисел %d.\n”,imin(a, b)); /* виклик функції */

return 0;

}

/* визначення функції */

int imin(int k, int l)

{

int min;

if(k>l)

min=l;

else

min=k;

return min;}

Функція в цьому прикладі може бути записана в іншому вигляді:

int imin(int k, int l)

{

int min=k;

if(l<k)

min=l;

return min;

}

Якщо врахувати, що значення, яке повертається, може бути виразом, то функція може бути записана ще компактніше:

int imin(int k, int l)

{return (k<l)? k:l;

}

Стандарт мови С не допускає передачу масивів як аргументів функції, тому для їхньої передачі використовуються покажчики.

Покажчик – це змінна, значенням якої є адреса комірки:

p=&c; /* покажчик p зберігає адресу перемінної c */

У випадку, коли необхідно одержати значення, що зберігається за даною адресою, використовується операція непрямої адресації: *.

x=*p; /* змінної x привласнюється значення, на яке вказує p */

Для роботи з покажчиками у програмі потрібно не тільки оголосити покажчики, але і вказати тип змінної, на яку вони будуть указувати:

int p; / p – покажчик на змінну цілого типу */

char * pc; /* pc – покажчик на змінну символьного типу */

float * pt; /* pt – покажчик на змінну типу float */

Для виводу на екран значень покажчика використовується специфікатор %p:

printf(“Значення покажчика pc=%p.\n”,pc);

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

Покажчики являють собою ефективний спосіб обробки масивів. Ім'я масиву є адресою його першого елемента, тобто, якщо m – це масив, правильно наступне: m==&m[0]. Обидва ці елементи є константами, але вони можуть бути привласнені як значення змінної покажчика, наприклад:

int x[10], *p;

p=x; /* присвоєння покажчику адреси масиву */

Оскільки додавання одиниці до покажчика збільшує його на розмір пам'яті збереженого за цією адресою значення, то додаток одиниці до покажчика, якому привласнена адреса першого елемента масиву, приведе до того, що цей покажчик буде зберігати адресу наступного елемента масиву:

int x[10];

int * p, * c;

p=x; /* присвоєння покажчику адреси першого елемента масиву p==&x[0] */

c=p+1;/* присвоєння покажчику адреси другого елемента масиву c==&x[1]*/

Розглянемо функцію, що використовує масив. Для передачі масиву у функцію використовується покажчик. У цьому випадку формальними параметрами, що вказуються в оголошенні функції, повинні бути покажчик на змінну того ж типу, яка зберігається в масиві, і ціле число. Фактичними параметрами, що вказуються у виклику функції, будуть ім'я масиву, що є адресою його першого елемента, і розмір масиву. Також можна передати масив, використовуючи як аргументи покажчики на перший і останній елементи масиву.

Приклад. Визначити середнє арифметичне елементів масиву.

#include <stdio.h>

#define M 20

float sum(int a[], int n); /* оголошення функції */

int main()

{

int x[M];

int і;

float sa;

printf(“Уведіть значення елементів масиву. \n”);

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

{

printf(“x[%d]=”,i);

scanf(“% d”, &x[i]);

}

sa=sum(x,M); /* виклик функції */

printf(“Середнє арифметичне елементів масиву %f.\n”, sa);

return 0;

}

float sum(int a[], int n) /* визначення функції */

{

int k, z=0;

float z1;

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

z+=a[k];

z1=z/n;

return z1;

}

Коментарі до програми: у мові С при оголошенні формального аргументу допускається така форма запису покажчика на змінну типу int: int a[]. Цей запис рівнозначний запису: int *a.

У попередньому прикладі ми розглядали одномірний масив. Тепер розглянемо, як зв'язані покажчики з двовимірними масивами. Ім'я масиву є адресою його першого елемента, а у двовимірному масиві перший елемент – це перший рядок. Якщо розглянути для прикладу масив int z[3][2], то z – це адреса двох змінних типу int. z[0] – це масив двох цілих значень, тому z[0]=&z[0][0]. Із сказаного вище виходить, що z – адреса об'єкта, що має розмір двох об'єктів типу int, а z[0]  адреса одної перемінної типу int. Але z і z[0] мають однакове значення. Збільшення на одиницю цих покажчиків приводить до різних величин: збільшення z на одиницю приведе до того, що цей покажчик буде вказувати на наступний рядок (*(z+1) – адреса елемента z[1][0]); збільшення z[0] на одиницю приведе до того, що цей покажчик буде вказувати на наступний елемент рядка (*z+1 – адреса елемента z[0][1], *z=z[0]).

Якщо необхідно створити функцію, що працює з двовимірними масивами, то передачу масиву можна організувати трьома способами:

1. Передавати масив рядками. У цьому випадку використовується функція, створена для роботи з одномірними масивами.

2. Через те масив розташовується в пам'яті комп'ютера в один рядок, його можливо обробляти як одномірний. У цьому випадку у функцію передається адреса першого елемента і загальна кількість елементів масиву. Наприклад, виклик функції буде мати вигляд:

int s [3][4];

dub(s[0], 3*4);

У цьому випадку також використовується функція для роботи з одномірним масивом.

3. За допомогою функції, що явно працює з двовимірним масивом. Розглянемо таку функцію на прикладі.

Приклад. Дано масив цілих чисел s[3][4]. Подвоїти елементи цього масиву.

#include<stdio.h>

void dub(int ar[][4], int size); /* оголошення функції */

int main90

{

int s[3][4]={

{2, 3, 4, 5},

{3, 5, 6, 9},

{10, 12, 8, 6}

};

int і, j;

dub(s, 3); /* виклик функції */

/* роздруківка масиву */

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

{

for(j=0;j<4;J==)

printf(“%4d”, s[i][j]);

printf (“\n”);

}

return 0;

}

void dub(int ar[][4], int size)

{

int i,j;

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

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

ar[i][j]=ar[i][j]*2;

}

Коментарі до програми: як аргумент функції використовується покажчик на масив, що складається з чотирьох (за кількістю стовпців) елементів типу int: int ar[][4]. Цей покажчик можна записати в іншому вигляді: int (*ar)[4]. Перший запис може бути використана тільки в тому випадку, якщо ar – формальний аргумент функції.

Дотепер у прикладах ми використовували масиви, що були оголошені усередині основної функції. Такі масиви були доступні тільки основній функції. Мова С має інструмент, що дозволяє різноманітити вид доступу до змінної або масивів. Це класи пам'яті.

Клас пам'яті призначає ступінь доступу елемента даних різним функціям програми і тривалість його збереження в пам'яті. Існують три класи пам'яті:

1. Автоматичні змінні або масиви. Вони визначаються усередині функції, доступні тільки для цієї функції й існують тільки у процесі роботи цієї функції.

2. Зовнішні змінні або масиви. Визначаються поза функцією і, на відміну від автоматичних, доступні усім функціям, що ідуть за їхнім оголошенням; існують увесь час роботи програми і ініціалізуються за умовчанням нулями.

3. Статичні змінні або масиви. Ці дані, подібно автоматичним змінним, є локальними для функції, але, подібно зовнішнім змінним, зберігають своє значення при виклику функції і за умовчанням ініціалізуються нулями.

У наступному прикладі дані описи перемінних різних класів пам'яті:

#include<stdio.h>

#define MAX 10

int x[MAX]; /* зовнішній масив */

int main()

{

static int y[MAX]; /* статичний масив */

int z[MAX]; /* автоматичний масив */

--------

}

Звіт про роботу повинний містити стислий опис роботи, алгоритм розв’язання задачі, текст програми і результати її роботи.

Лабораторна робота № 14

Робота з файлами.

Введення даних з файлу і запис у файл

Мета роботи