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

Дисциплины:






Оголошення покажчика



Покажчик – це змінна, котра призначена для збереження адресу об’єкта деякого типу.

Синтаксис:

[<специфікація типу>] * <описувач>;

Специфікація типу задає тип змінної, на яку посилається покажчик, а символ (*) визначає саму змінну як покажчик.

Оголошення покажчика специфікує ім’я змінної-покажчика і тип об’єкта, на який може вказувати ця змінна. Специфікація типу може задавати базовий, пустий, структурний тип чи тип об’єднання. Якщо специфікація типу пропущена, передбачається тип int.

В мові Сі використовуються змінні типу покажчик. Значенням такої змінної слугує адреса деякої величини. Якщо ми дамо покажчику ім’я ptr, то зможемо написати, наприклад, такий оператор:

ptr=&pooh; /* присвоєння адресу poohзмінній ptr*/

де &pooh– константа типу покажчик ( адрес деякої змінної pooh);

ptr– змінна типу покажчик.

В такому випадку ptr“вказує на”pooh.Різниця між двома формами запису:ptrі &pooh, полягає в тому, щоptr –змінна, в той час як &pooh –константа.

Таким чином, якщо, в змінній ptr міститься посилання на змінну pooh, тоді для доступу до значення цієї змінної можна скористатися операцією “непрямої адресації” :

val =*ptr; /* визначення значення, на яке вказує ptr*/

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

val=pooh;

Приклад:

pooh = 22;

ptr=&pooh; /* покажчик на pooh */

val =*ptr;

 

Результат виконання даного фрагмента – присвоєння значення 22 змінній val.

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

Приклад:

 

/* Програма яка здійснює обмін значеннями між двома змінними x i y*/

Main( )

{

int x = 5, y = 10;

printf(“Спочатку x = %d і y = %d. \n”, x, y);

interchange(&x,&y); /* передача адрес функції */

printf(“Тепер x = %d і y = %d. \n”, x, y);

}

interchange(u, v)

int *u, *v; /* u i v є покажчиками */

{

inttemp;

temp = *u; /* temp присвоюється значення, на яке вказує u */

*u = *v;

*v = temp;

}

Результат виконання програми:

Спочатку x = 5 і y = 10.

Тепер x = 10 і y = 5.

Таким чином шляхом передачі функції адрес змінних x і y ми представили їй можливість доступу до них. Використовуючи покажчики і операцію *, функція отримує доступ до величин, що поміщені у відповідні комірки пам’яті і міняє їх місцями.



1.2. Класи пам’яті

Класи пам’яті мови Сі дають можливість визначити, з якими функціями пов’язані які змінні і як довго змінна зберігається у програмі. Клас пам’яті дозволяє встановити два факти. По-перше, визначити, які функції мають доступ до змінної. (Межі, до яких змінна доступна, характеризують її “область дії”). По-друге, визначити, як довго змінна знаходиться в пам’яті.

Існує чотири ключових слова що використовуються для опису класів пам’яті: еxstern (для зовнішнього), auto(для автоматичного),static і register(для статичного і регістрового).

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

Наприклад:

/* глобальна змінна units */

intunits; /* зовнішня змінна */

main( )

{

extern int units;

funct( );

}

 

funct( )

{

extern int units;

. . . .

}

 

Ключове слово extern пропонує компілятору шукати визначення цієї змінної поза функцією. Зовнішні змінні, які визначенні раніше функції, доступні їй навіть якщо не оголошені усередині неї. В даному випадку змінна units буде доступна як функції main( ), так і функції funct( ).

По замовчуванню змінні, що оголошені усередині функції, є автоматичними і локальними (область дії такої змінної обмежена блоком {} , в якому ця змінна оголошена.) Можна, однак це підкреслити явно з допомогою необов’язкового ключового слова auto.

Приклад:

main( )

{

auto int units;

. . . .

}

 

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

Статичні змінні бувають як зовнішніми так і внутрішніми.

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

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

Регістрові змінні, зберігаються в регістрах центрального процесора, де доступ до них і робота з ними виконується набагато швидше, ніж над звичайними змінними що зберігаються у пам’яті. Однак, якщо кількість доступних регістрів “зайнята”, то змінна стає простою автоматичною змінною.

 

КЛАС ПАМ’ЯТІ КЛЮЧОВЕ СЛОВО ТРИВАЛІСТЬ ІСНУВАННЯ ОБЛАСТЬ ДІЇ  
Автоматичний Auto Тимчасово Локальна  
Регістровий Register Тимчасово Локальна  
Статичний Static Постійно Локальна  
Зовнішній Extern Постійно Глобальна (всі файли)  
Зовнішній статичний Static Постійно Глобальна (один файл)  

 

Класи пам’яті, які перелічені вище пунктирної лінії, оголошуються на внутрішньому рівні.

Класи пам’яті, які перелічені нижче пунктирної лінії, оголошуються на зовнішньому рівні.

1.3. Оголошення масивів

Масив – це набір елементів одного типу, які мають одне і тeж базове ім’я і відрізняються один від одного числовою ознакою.

Синтаксис:

[<специфікація типу>] <оголошувач> [<константний вираз>];

[<специфікація типу>] <оголошувач> [ ];

Масив дозволяє зберігати як єдине ціле послідовність змінних однакового типу. Оголошення масиву визначає тип елементів масиву і його ім’я, а також може визначати число елементів в масиві. Змінна типу масив бере участь у виразах як константа-покажчик на значення що задане специфікацією типу. Якщо специфікація типу опущена, то передбачається тип int.

Оголошення масиву може мати одну з двох синтаксичних форм, вказаних вище. Квадратні дужки, які знаходяться за <оголошувачем>, є ознакою типу масив.

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

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

Для створення масиву компілятору необхідно знати тип даних і належний клас пам’яті, а також повинна бути відома кількість елементів масиву. Масиви можуть мати ті ж типи даних і класи пам’яті що і прості змінні.

Зовнішні і статичні масиви можна ініціалізувати. Автоматичні і регістрові масиви ініціалізувати не можна.

 

Приклади декількох оголошень масивів:

int temp[365]; /* зовнішній масив з 365 цілих чисел */

int days[ ] = {30, 31}; /* ініціалізація зовнішнього масиву */

main( )

{

float rain[365]; /* автоматичний масив з 365 чисел типу float */

static char code[12]; /* статичний масив з 12 символів */

externtemp[ ]; /* зовнішній масив; розмір вказаний вище */

}

 

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

[<специфікація типу>] <оголошувач> [<константний вираз>] [<константний вираз>]…;

Кожен константний вираз у квадратних дужках визначає число елементів в даному вимірі масиву, тому оголошення двомірного масиву містить два константних вирази, тримірного – три і т.д.

Масиву виділяється пам’ять, яка є необхідною для розміщення всіх його елементів. Елементи масиву з першого по останній розташовуються у послідовних комірках пам’яті, по зростанню адрес. Елементи багатомірного масиву запам’ятовуються по рядках. Наприклад, масив, який представляє собою матрицю розміром два рядки на три стовпці char[2][3] буде зберігатися наступним чином: спочатку в пам’яті запам’ятовуються три елементи першого рядка, потім три елементи другого рядка.

1.4. Покажчики масивів

Позначення масиву представляє собою неявну форму використання покажчиків. Наприклад, ім’я масиву визначає також його перший елемент, тобто якщо dates[ ]–масив, тоді

dates = = & dates[0]

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

Приклад:

#include<stdio.h>

void main(void)

{

intdates[4];

int i, *pt;

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

scanf(" %d ", &dates[i]);

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

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

printf(" %d %р\n", pt[i], &pt[i]);

}

Якщо ми присвоюємо 4-м елементам масиву наступні значення: 23, 65, 89, 7, то результат виконання програми буде наступним:

23 325D:OF84

65 325D:OF86

89 325D:OF88

7 325D:OF8A

 

У другому стовпці виведені адреси комірок в яких знаходяться значення елементів масиву.

Таким чином, якщо datesвизначає адресу першого елемента масиву то *(dates) – його значення.

Наприклад:

dates + 2 = = & dates[2] /* адрес 3-го елемента масиву */

*(dates + 2) = = dates[2] /* значення 3-го елемента масиву */

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

Масиви можна використовувати в програмі в якості аргументів функції.

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

Скелет даної програми продемонстрований на прикладі.

Приклад:

main( )

{

intages[50]; /* масив з 50 елементів */

convert(ages);

. . . .

}

 

convert(years)

int years[ ]; /* покажчик на масив*/

{

. . . .

}

 

ages – аргумент функції convert, що є покажчиком на перший елемент масиву. Таким чином, оператор виклику функції передає їй покажчик, тобто адресу функції convert( ). Це означає що аргумент функції є покажчиком, тому функцію convert( )можна записати наступним чином:

convert( int years[ ] )

{

. . . .

}

 

Оператор int years[ ]; оголошує змінну years покажчиком масиву цілих чисел. Оператори, що використовують покажчик years у функції convert( ), фактично працюють з масивом ages, що знаходиться в тілі функції main( )

У випадку використання двомірного масиву порядок його елементів визначається тим, що найправіший індекс масиву змінюється першим. Тому, наприклад, якщо ми маємо оголошення:

int dear[3][2]; /* масив типу int із 3-ох стрічок і 2-ох стовпців */

int *pr; /* покажчик на цілий тип */

тоді pr = dear вказує адрес елемента першого стовпця першого рядка:

dear = = &dear[0][0]

Тоді:

pr + 1= = &dear[0][1] /* 1-й рядок, 2-й стовпець */

pr + 5 = = &dear[2][1] /* 3-й рядок, 2-й стовпець */

 

Визначення і опис функції що керує двомірним масивом записується наступним чином:

main( )

{

static intdear[3][4];

convert(dear);

. . . .

}

 

convert(dear)

int dear[ ][4];

{

. . . .

}

 

Оператор int dear[ ][4]; повідомляє компілятор про необхідність розбиття масиву на рядки по чотири стовпці.

Приклад програми яка здійснює сортування елементів масиву методом обміну:

 

#include<stdio.h>

#include<stdlib.h>

#definen 5

voidbul(inta[n][n]);

Void main(void)

{

inti,j,k;

inta[n][n];

system("cls");

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

{

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

{

printf("a[%d][%d] =", i+1, j+1);

scanf("%d", &a[i][j]);

}

}

printf("old array\n");

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

{

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

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

printf("\n");

}

bul(a);

printf("\nnew array\n");

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

{

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

{

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

}

printf("\n");

}

}

voidbul(inta[ ][n])

{

inti, k, j, c;

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

{

for(k = n-1; k>=0; k--)

{

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

{

if(a[i][j] < a[i][j+1])

{

c = a[i][j];

a[i][j] = a[i][j+1];

a[i][j+1] =c;

}

}

}

}

}

Приклад фрагменту програми що здійснює сортування елементів одновимірного масиву методом вибору:

 

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

{

k=i;

x=b[i];

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

{

if(b[j] > x)

{

k=j;

x=b[j];

b[k]=b[i];

b[i]=x;

}

}

}

 

Приклад програми що здійснює сортування елементів одновимірного масиву методом вставки:

 

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

{

x=b[i];

j=i-1;

while(b[j] < x && j>=0)

{

b[j+1] = b[j])

j--;

}

b[j+1] = x;

}

 

ЗАВДАННЯ

1. Скласти блок-схему алгоритму та програму мовою Cі згідно з завданням, отриманим від викладача за табл. 1: задану прямокутну матрицю A={aij} відсортувати за вказаним алгоритмом; для відсортованої матриці знайти значення функції F(fi(aij)); алгоритм сортування і обчислення fi(aij) оформити у вигляді функції; елементи матриці вводити з клавіатури; програма повинна вивести на екран відсортовану матрицю, всі значення fi(aij) та значення функції F(fi(aij)).

 

Таблиця 1

№ п/п Алгоритм впорядкування матриці Алгоритм для розрахунку fi(aij) та F(fi(aij)) Матриця  
Впорядкувати елементи стовпців матриці за спаданням їх значень методом вставки fi(aij)-максимальний елемент у кожному рядку матриці; F(fi(aij))-сума fi(aij). -12 7 23 13 4 67 15 34 -5 9 2 5 17 -23 45 26 -6 23 -5 -9 18 37 -8 26 12  
Впорядкувати елементи рядків матриці за зростанням їх значень методом обміну fi(aij)-мінімальний елемент у кожному стовпці матриці; F(fi(aij))-добуток fi(aij) 34 -8 27 7 12 -5 23 45 67 -2 13 -12 34 -3 25 17 56 -6 17 21 0 15 4 9 -14  
Впорядкувати елементи стовпців матриці за зростанням їх значень методом вибору fi(aij)-сума елементів у кожному рядку матриці; F(fi(aij))-середнє геометричне значення fi(aij) 2 0 33 -1 -21 78 7 -4 -3 11 -2 -7 -1 -9 0 13 61 60 42 -10 1 0 4 0 16  
Впорядкувати елементи рядків матриці за спаданням їх значень методом вставки fi(aij)-добуток елементів у кожному стовпці матриці; F(fi(aij))-середнє арифме-тичне значення fi(aij) 90 7 89 -2 17 1 -4 8 56 32 -4 -6 –99 19 39 2 4 -7 0 75 11 41 22 80 -5  
Впорядкувати елементи стовпців матриці за зростанням їх значень методом обміну fi(aij)-середнє арифметичне значення елементів у кожному рядку матриці; F(fi(aij))-добуток fi(aij) 40 72 6 92 98 18 -33 -48 81 26 1 -4 6 -2 0 36 9 0 4 1 -55 2 66 70 -3  
Впорядкувати елементи рядків матриці за спаданням їх значень методом вибору fi(aij)-середнє геометричне значення елементів у кожному стовпці матриці; F(fi(aij))-сума fi(aij) -3 -5 –45 -71 -5 0 1 3 2 7 11 9 45 0 4 9 19 55 44 90 -3 -4 –1 -5 0  
Впорядкувати елементи стовпців матриці за зростанням їх значень методом вставки fi(aij)-добуток елементів у кожному рядку під головною діагоналлю матриці; F(fi(aij))-сума fi(aij) 6 34 12 70 -1 -7 97 80 99 -99 1 6 -3 2 -8 3 33 -1 0 -78 -3 -5 -8 -56 -23  
Впорядкувати елементи рядків матриці за спаданням їх значень методом обміну fi(aij)-сума елементів у кожному стовпці над головною діагоналлю матриці; F(fi(aij))-добуток fi(aij) 9 67 –65 45 1 12 61 48 -5 -1 0 39 0 41 2 36 95 -8 -5 0 11 22 71 3 63  
Впорядкувати елементи рядків матриці за зростанням їх значень методом вибору fi(aij)-сума елементів у кожному стовпці над допоміжною діагоналлю матриці; F(fi(aij))-середнє геометричне значення fi(aij) 44 -2 -5 38 –91 2 0 6 3 22 13 1 -4 90 11 -3 -6 -98 -23 -24 10 34 32 31 69  
Впорядкувати елементи стовпців матриці за спаданням їх значень методом обміну fi(aij)-добуток елементів у кожному рядку під допоміжною діагоналлю матриці; F(fi(aij))-середнє арифметичне значення fi(aij) -1 -5 -47 -8 -1 -4 -98 –90 -45 -78 -3 -2 -5 -9 -4 -8 -67 –33 -91 -40 -2 -58 –11 -65 -77  
Впорядкувати елементи рядків матриці за зростанням їх значень методом вставки fi(aij)-середнє арифметичне значення елементів у кожному стовпці під головною діагоналлю матриці; F(fi(aij))-добуток fi(aij) 1 16 21 11 6 2 17 22 12 7 3 18 23 13 8 4 19 24 14 9 5 20 25 15 10  
Впорядкувати елементи стовпців матриці за спаданням їх значень методом обміну fi(aij)-середнє геометричне значення елементів в кожному рядку над головною діагоналлю матриці; F(fi(aij))-сума fi(aij) 0 2 -2 89 21 -1 -4 36 41 71 56 93 51 -2 -51 1 3 -8 0 9 23 41 5 8 -2  
Впорядкувати елементи рядків матриці за спаданням їх значень методом вставки fi(aij)-середнє арифметичне значення елементів у кожному стовпці над допоміжною діагоналлю матриці; F(fi(aij))-добуток fi(aij) 12 46 –23 72 -5 59 7 -8 0 67 7 -8 -4 -97 -55 77 -1 -5 34 -8 0 22 27 24 24  
Впорядкувати елементи рядків матриці за зростанням їх значень методом обміну fi(aij)-сума елементів у кожному стовпці під допоміжною діагоналлю матриці; F(fi(aij)) -середнє геометричне значення fi(aij) 87 98 57 29 95 -8 59 -2 9 -11 6 10 20 59 -23 12 13 51 46 -7 -2 87 69 90 -3  
Впорядкувати елементи стовпців матриці за зростанням їх значень методом вибору fi(aij)-добуток елементів у кожному рядку над головною діагоналлю; F(fi(aij))-середнє арифметичне значення fi(aij) 50 98 -4 85 -8 40 73 -2 -9 -19 1 6 73 21 0 0 25 2 -5 -3 99 19 95 92 -7  
Впорядкувати елементи рядків матриці за спаданням їх значень методом вставки fi(aij)-сума елементів у кожному стовпці під головною діагоналлю матриці; F(fi(aij))-середнє геометричне значення fi(aij) 3 5 9 24 2 -23 0 37 29 10 0 1 4 -2 -5 -5 -83 –74 82 -1 11 88 -5 81 -39  
Впорядкувати елементи стовпців матриці за зростанням їх значень методом обміну fi(aij)-середнє геометричне значення елементів у кожному рядку матриці; F(fi(aij))-середнє арифметичне значення fi(aij) 66 21 -3 -1 90 1 74 -2 80 -1 10 30 20 -50 91 2 4 5 81 0 33 69 -5 51 24  
Впорядкувати елементи рядків матриці за спаданням їх значень методом вибору fi(aij)-середнє арифметичне значення елементів у кожному стовпці над допоміжною діагоналлю; F(fi(aij))- добуток fi(aij) 33 -5 -9 -20 -11 0 -42 86 83 71 -6 -9 33 13 22 52 -5 -7 53 19 -3 98 72 68 0  
Впорядкувати елементи стовпців матриці за зростанням їх значень методом вставки fi(aij)-середнє геометричне значення елементів у кожному рядку над головною діагоналлю; F(fi(aij))-сума fi(aij) 34 45 65 23 98 1 -4 67 -3 -18 23 -5 -1 94 -25 2 24 –4 79 -63 10 29 25 30 -6  
Впорядкувати елементи рядків матриці за спаданням їх значень методом обміну fi(aij)-добуток елементів у кожному стовпці під головною діагоналлю матриці; F(fi(aij))-середнє арифметичне значення fi(aij) 19 62 –45 -1 84 23 54 -4 -2 68 36 39 96 94 97 -3 -8 -4 -6 -22 98 -5 -3 0 11  
Впорядкувати елементи стовпців матриці за зростанням їх значень методом вибору fi(aij)-добуток елементів у кожному рядку над допоміжною діагоналлю матриці; F(fi(aij))-сума fi(aij) 22 41 45 -45 -49 5 1 3 -2 0 34 97 48 72 -1 -3 -7 5 92 20 0 -3 -57 9 1  
Впорядкувати елементи рядків матриці за спаданням їх значень методом обміну fi(aij)-середнє арифметичне значення елементів у кожному стовпці матриці; F(fi(aij))-середнє геометричне значення fi(aij) 30 31 36 63 -2 2 24 -3 -7 -1 45 28 -98 2 -8 0 -1 -2 -3 93 11 10 72 85 66  
Впорядкувати елементи стовпців матриці за зростанням їх значень методом вставки fi(aij)-сума елементів у кожному рядку над головною діагоналлю матриці; F(fi(aij))-середнє геометричне значення fi(aij) 31 65 –83 -2 -85 9 -2 11 -4 70 52 73 -8 -1 60 57 83 -1 82 50 1 -3 -2 78 -9  
Впорядкувати елементи рядків матриці за спаданням їх значень методом обміну fi(aij)-добуток елементів у кожному стовпці під допоміжною діагоналлю матриці; F(fi(aij))-середнє арифметичне значення fi(aij) 10 32 1 -8 -1 2 4 91 -82 96 33 62 -1 -8 0 5 -5 6 -6 7 -19 0 3 -22 -3  
Впорядкувати елементи стовпців матриці за спаданням їх значень методом вставки fi(aij)-середнє геометричне значення елементів у кожному рядку під головною діагоналлю матриці; F(fi(aij))-сума fi(aij) 9 24 -2 86 -3 40 49 -4 -3 0 27 -76 77 -1 69 71 -89 -94 -51 50 2 96 42 36 -1  
Впорядкувати елементи рядків матриці за зростанням їх значень методом обміну fi(aij)-середнє арифметичне значення елементів в кожному рядку під головною діагоналлю матриці; F(fi(aij))-сума fi(aij) 7 6 -2 89 21 -1 -4 11 41 71 56 87 51 -3 -51 1 3 -8 9 6 12 33 2 3 -2  
Впорядкувати елементи стовпців матриці за зростанням їх значень методом вставки fi(aij)-сума елементів у кожному стовпці під допоміжною діагоналлю матриці; F(fi(aij)) -середнє геометричне значення fi(aij) 87 98 57 29 95 18 59 20 9 11 6 10 20 59 -23 12 13 51 46 17 12 87 69 90 23  
Впорядкувати елементи стовпців матриці за спаданням їх значень методом обміну fi(aij)-середнє арифметичне значення елементів у кожному рядку матриці; F(fi(aij))-добуток fi(aij) 66 21 -3 -1 90 1 74 -2 80 -1 10 30 20 -50 91 2 4 5 81 0 33 69 -5 51 24  
Впорядкувати елементи стовпців матриці за зростанням їх значень методом вибору fi(aij)-середнє геометричне значення елементів у кожному рядку над головною діагоналлю; F(fi(aij))-сума fi(aij) 34 45 65 23 98 1 -4 67 -3 -18 23 -5 -1 94 -25 2 24 –4 79 -63 10 29 25 30 -6  
Впорядкувати елементи рядків матриці за зростанням їх значень методом вибору fi(aij)-сума елементів у кожному рядку над допоміжною діагоналлю матриці; F(fi(aij))-добуток fi(aij) 22 41 45 -45 -49 5 1 3 -2 0 34 97 48 72 -1 -3 -7 5 92 20 0 -3 -57 9 1  
Впорядкувати елементи рядків матриці за спаданням їх значень методом обміну fi(aij)-середнє арифметичне значення елементів у кожному стовпці матриці; F(fi(aij))-середнє геометричне значення fi(aij) 30 31 36 63 -2 2 24 -3 -7 -1 45 28 -98 2 -8 0 -1 -2 -3 93 11 10 72 85 66  
Впорядкувати елементи рядків матриці за спаданням їх значень методом обміну fi(aij)-добуток елементів у кожному стовпці під допоміжною діагоналлю матриці; F(fi(aij))-середнє арифметичне значення fi(aij) 10 32 1 -8 -1 2 4 91 -82 96 33 62 -1 -8 0 5 -5 6 -6 7 -19 0 3 -22 -3  
Впорядкувати елементи стовпців матриці за зростанням їх значень методом вставки fi(aij)-добуток елементів у кожному рядку під головною діагоналлю матриці; F(fi(aij))-сума fi(aij) 6 34 12 70 -1 -7 97 80 99 -99 1 6 -3 2 -8 3 33 -1 0 -78 -3 -5 -8 -56 -23  
Впорядкувати елементи рядків матриці за зростанням їх значень методом вибору fi(aij)-сума елементів у кожному стовпці над допоміжною діагоналлю матриці; F(fi(aij))-середнє геометричне значення fi(aij) 44 -2 -5 38 –91 2 0 6 3 22 13 1 -4 90 11 -3 -6 -98 -23 -24 10 34 32 31 69  
Впорядкувати елементи рядків матриці за спаданням їх значень методом вставки fi(aij)-добуток елементів у кожному стовпці матриці; F(fi(aij))-середнє арифме-тичне значення fi(aij) 90 7 89 -2 17 1 -4 8 56 32 -4 -6 –99 19 39 2 4 -7 0 75 11 41 22 80 -5  

 

 

ІНСТРУКЦІЯ ДО ЛАБОРАТОРНОЇ РОБОТИ № 4

ОБРОБКА СИМВОЛЬНИХ РЯДКІВ. РОБОТА З ФАЙЛАМИ

 

Мета роботи – вивчити елементи мови Сі, рядки, рядкові константи, принципи потокового вводу-виводу, стандартні файли і функції для роботи з ними.

 

КОРОТКІ ТЕОРЕТИЧНІ ДАНІ

1.1. Ввід-вивід.

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

Бібліотека мови Сі підтримує три рівні вводу-виводу: потоковий ввід-вивід, ввід-вивід нищого рівня і ввід-вивід для консолі і портів. Останній рівень забезпечує зручний спеціалізований обмін даними з монітором і портами вводу-виводу.

1.2. Потоковий ввід-вивід

На рівні потокового вводу-виводу обмін даними відбувається побайтно. Такий ввід-вивід можливий як для власне пристроїв побайтного обміну (друкуючі пристрої, монітор), так і для файлів на диску, хоча пристрої зовнішньої памяті є пристроями поблочного обміну, тобто за одне звернення до пристрою відбувається зчитування чи запис фіксованої порції даних. Найчастіше мінімальною порцією даних, яка приймає участь в обміні даних, є блок розміром 512 байт або 1024 байт. При вводі з диску (при читанні з файлу) дані розміщуються в буфер операційної системи, а потім побайтно або певними частинами передаються програмі користувача.

Функції бібліотеки вводу-виводу мови Сі, які підтримують обмін даними з файлами на рівні потоку, дозволяють обробляти дані різних розмірів і форматів, забезпечуючи при цьому буферизований ввід і вивід. Таким чином, потік – це файл разом з доступними засобами буферизації.

Працюючи з потоком можна виконувати наступні дії:

- відкривати і закривати потоки (звязувати вказівники на потоки з конкретними файлами);

- вводити і виводити: символ, рядок, форматовані дані, порцію даних будь-якої довжини;

- аналізувати помилки потокового вводу-виводу і умови досягнення кінця потоку (кінця файлу);

- керувати буферизацією потоку і розміром буферу;

- отримувати і встановлювати вказівник (індикатор) поточної позиції в потоці.

Для того щоб можна було використовувати функції бібліотеки вводу виводу мови Сі, в програму необхідно підключити заголовочний файл stdio.h (#include<stdio.h>), який містить прототипи функцій вводу-виводу, а також визначення констант, типів і структур, необхідних для роботи функцій обміну з потоком.

1.3. Відкриття і закриття потоку

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

При відкритті потоку в програму повертається вказівник на потік, який є вказівником на об'єкт структурного типу FILE. Цей вказівник ідентифікує потік у всіх наступних операціях.

Вказівник на потік, наприклад ff, повинен бути оголошений в програмі наступним чином:

#include<stdio.h>

FILE *ff;

Вказівнпик на потік набуває значення в результаті виконання функції відкриття потоку:

ff = fopen (імя_файлу, режим_відкриття);

Параметри імя_файлу і режим_відкритт є вказівниками на масив символів, які містять відповідно ім'я файлу, зв'язаного з потоком, і дані про режим відкриття. Також ці параметри можуть задаватися і безпосередньо у вигляді рядків при виклику функції відкриття файлу:

ff = fopen (“test.txt”,”r”);

де test.txt – ім'я деякого файлу, який зв'язаний з потоком.

r – визначення одного з режимів роботи з файлом (тип доступу до потоку).

Стандартно файл, який зв'язаний з потоком, можна відкрити в одному з нижче перелічених режимів:

“w” – новий текстовий файл відкривається для запису. Якщо файл вже існував, то попередній вміст витирається, файл створюється по новому;

“r” – існуючий текстовий файл відкривається лише для читання;

“a” – текстовий файл відкривається (або створюється, якщо файлу немає) для внесення в нього нової інформації (добавлення в кінець файлу). На відміну від режиму “w” режим “а”дозволяє відкривати вже існуючий файл, не знищуючи його попередньої версії, і записувати в кінець файлу;

“w+” – новий текстовий файл відкривається для запису і наступних багаторазових виправлень. Якщо файл вже існує, то попередній зміст витирається. Наступні після відкриття файлу записи і читання з нього не допустимі в будь-якому місці файлу, зокрема запис дозволений і в кінець файлу, тобто файл може збільшуватись («рости»);

“r+” – існуючий текстовий файл відкривається як для читання, так і для запису в будь-якому місці файлу; але в цьому режимі неможливий запис в кінець файлу, тобто неможливе збільшення розміру файлу;

“а+” – текстовий файл відкривається або створюється (якщо файлу немає) і стає доступним для змін, тобто для запису і для читання в будь-якому місці; при цьому на відміну від режиму “w+”можна відкрити існуючий файл і не знищувати його змісту; на відміну від режиму “r+” в режимі “а+” можна робити запис в кінець файлу, тобто збільшувати його розміри.

Потік можна відрити в текстовому або в двійковому (бінарному) режимі.

При відкритті потоку можуть виникати наступні помилки: вказаний файл, зв'язаний з потоком, не знайдений (для режиму «читання»); диск заповнений або диск захищений від запису і ін. Необхідно також відмітити, що при виконанні функції fopen() відбувається виділення динамічної пам'яті. При її відсутності встановлюється ознака помилки “Not enough memory” (недостатньо пам'яті). В перелічених випадках вказівник на потік в будь-якому режимі, відмінному від аварійного, ніколи не буває рівним NULL.

Наведемо типову послідовність операторів, яка використовується при відкритті файлу, зв'язаного з потоком:

if ((ff = fopen(“test.txt”, “w”)) == NULL)

{

perror(“помилка відкриття файлу test.txt \n”);

Exit(0);

}

де NULL – нульовий вказівник, визначений у файлі stdio.h.

Після того як файл відкритий, з ним можна працювати, записуючи чи зчитуючи з нього інформацію (в залежності від режиму роботи). Відкриті на диску файли після закінчення роботи з ними рекомендується закривати явно. Для цього використовується бібліотечна функція:

int fclose(вказівник_на_потік);

Відкритий файл можна відкрити повторно (наприклад, для зміни режиму роботи з ним) тільки після того, як файл буде закритий за допомогою функції fclose( ).

 

1.4. Стандартні функції для роботи з файлами.

Для вводу-виводу даних за допомогою стандартних потоків в бібліотеці мови С визначені наступні функції:

getchar()/putchar()– ввід-вивід окремого символа;

gets()/puts() –ввід-вивід рядка;

scanf()/printf() – ввід-вивід в режимі форматування даних.

При читанні з файлу за допомогою функції getchar() може бути досягнутий кінець файлу. В цьому випадку операційна система у відповідь на спробу читання символу передає функції getchar() значення EOF (end of file).

 





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