Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
lexzii_08 / lexs_3_Mas.doc
Скачиваний:
20
Добавлен:
17.05.2015
Размер:
120.32 Кб
Скачать

Масиви даних і покажчики.

Між покажчиками і масивами існує сильний взаємозв’язок. Будь-яка дія над елементами масивів, яке досягається індексуванням, може бути виконана і за допомогою покажчиків (посилань) і операцій над ними.

Як показують задачі на Сі, покажчики рідко використовують зі скалярними змінними, частіше – з масивами. Покажчики дають можливість використовувати адреси приблизно так, як це робиться в ЕОМ на машинному рівні. Це дозволяє ефективно організувати роботу з масивами. Будь-яку програму, яка використовує масиви, можливо написати тільки за допомогою покажчиків.

Для роботи з масивами необхідно:

  1. Визначити ім’я масиву, його розмірність (кількість вимірювань) і розмір – кількість елементів масива.

  2. Виділити оперативну пам’ять для його розміщення.

В мові Сі можливо використовувати масиви даних будь-якого типу:

    1. Статичні: з виділенням ОП до початку виконання функції; ОП виділяється в стеку або в ОП для статистичних даних;

    2. Динамічні: ОП виділяється із кучі в процесі виконання програми за допомогою функцій malloc і alloc, розглянемо пізніше.

Розмір масиву можна не вказувати, а вказати пусті границі:

  1. Якщо при визначенні ініціалізуються значення його елементів, наприклад:

Static int a[ ] = {1, 2, 3}; char b[ ] = “відповідь:”;

  1. Для масивів – формальних параметрів функції, наприклад:

int funl ( int a[ ], int n ); int fun2 ( int b[ ] [m] [n] );

  1. При посиланні на раніше визначенний зовнішній масив, наприклад:

int a[5]; // - визначення зовнішнього масиву

main ( )

{ extern int a[ ]; // - посилання на зовнішній масив

У всіх визначеннях масиву, в яких розмір масиву вказаний явно або неявно – це покажчик – константа.

Способи оголошення і звернення до елементів одновимірних масивів.

Звернення до елементів одновимірного масиву в загальному випадку виглядає так:

імя_масиву [ вираз ];

де імя_­масиву – покажчик – константа;

вираз – цілого типу – індекс; він визначає зміщення – приріст адреси заданого елементу масиву відносно адреси нульового елементу масиву. Елемент одновимірного масиву розташовуються в ОП підряд: нульовий, перший і т. ін.

Приклад оголошення масиву:

Int a[10]; int*p = a; // р отримав значення а

При цьому компілятор виділяє масиву в стеку ОП розміром ( sizeof ( тип ) розмір_масиву ) байт. В прикладі це 2 * 10 = 20 байт. При чому: а – покажчик – константа, адреса початку масива, його 0-го елемента; р – покажчик – змінна.

Змінній р можна присвоїти значення одним із засобів:

р = а; р = &a[0]; p = &a[ i ];

де &a[i] = = (a+i) – адреса і-го елемента масиву.

Операція sizeof повертає кількість байт, яка займає в памяті тип даних або вираз, що передається в якості параметра. Часто використовується для визначення кількості елементів масиву при опрацюванні в циклі.

У відповідності з правилами перетворення типів значення адреси і-го елемента масиву на машинному рівні формується у вигляді

&a[i] = a + i * sizeof (int);

справедливі також такі співвідношення:

&a = = a + 0 = = &a[0] - адреса а[0] – нульового елемента масива “а”;

a + 2 = = &a[2] - адреса а[2] – другого елемента масива “а”;

a + i = = &a[i] - адреса а[і] – і-го елемента масива “а”;

*а = = *(a+0) = = *(&a[0]) = = a[0] – значення нульового елемента масиву “а”;

*(a+2) = = a[2] - значення другого елементу масиву “а”;

*(a+i) = = a[i] - значення і-го елементу масиву “а”;

*a+2 = = a[0] + 2 - сума значень a[0] i 2;

Якщо р – покажчик на елементи типу елементів масиву а і р = а, то а і р взаємозамінні; при цьому:

p= = &a[0]= =a+0;

p+2= =&a[2]= =a+2;

*(p+2)= = *(&a[2])= =a[2]= = p[2];

*(p+i)= = *(&a[i])= =a[i]= = p[i];

Для а і з еквівалентні всі звернення до елементів масиву а в вигляді:

a[i], *(a+i), *(i+a), i[a];

p[i], *(p+i), *(i+a), i[p];

Приклад. Підрахувати кількість появи кожної літери в тексті.

#include <conio.h>

#include <stdio.h>

int k [256]; /*масив кількості появи кожного з 256 символів в файлі ініціалізуються 0*/

void main( )

{ int i, c; clrscr;

printf(“Введіть символи. Для закінчення введіть ^z:/n”);

while(c= getchar( ), c!=EOF) k[c]++; //або: (*(k+c))++;

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

{ printf (“k [%d]=%d-%c”, i, k [i], i); //виведення кількості символів.

іf(!(i%5)) printf (“\n”);

}

printf (“\n Для завершення програми натисніть любу клавішу \n”);

getch( );

}

В програмі використовуються:

- k – зовнішній масив на 256 елементів по кількості різних символів алфавіту; та як це зовнішній масив, він ініціюється 256 нулями;

k – покажчик-константа;

- с –значення символу, введеного з клавіатури; номер елементу в масиві к дорівнює значенню с, коду введеного символу.

Із вхідного потоку (з клавіатури) вводяться символи в змінну с до кінця файлу, тобто до появи ЕОF. Для формування поточного значення елементу масиву к використовувати один із двох варіантів виразу:

k[c]++; або (*(k+c))++;

В останньому випадку в виразі над покажчиком k спочатку виконується операція (k+r), в результаті цього, до значення покажчика k добавляється значення коду введеного символу с, а потім вибирається вміст за цією адресою: *(k+c). Після чого до вмісту добавляється 1 (для підрахування кількості символів) і результат розміщається за адресою (k+c).

Схематично це можливо представити в вигляді:

\( * (k + c) ) ++

&k[c] – адреса елемента масиву k[c]

*&k[c] = значення елемента k[c]

k[c]++ = ( k[c] = k[c] + 1 ); збільшення k[c] на 1.

Горізонтальні фігурні дужки обмежують частини виразів, які виконуються. Послідовність обчислень частин виразів в схемі – зверху вниз.

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

Соседние файлы в папке lexzii_08