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

Зв'язок вказівників і масивів

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

int plus[10];

то plus є вказівником на масив, точніше, на перший елемент масиву. Оператори

p1=plus;

і

p1=&plus[0];

приведуть до тому самому результату.

Для того щоб одержати значення 6-го елемента масиву plus, можна написати

plus[5] або *(р1+5).

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

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

# include <stdio.h>

# include <ctype.h>

/* Приклад 31. */

main()

{

char str[]=”String From Letters in Different Registers";

/* Рядок, що складається з Літер Різних Регистрів"; */

int i;

printf(" Рядок Буде Надрукований Заголовними Літерами");

while (str[i])

printf(“%c”, toupper(str [ i++]));

}

# include <stdio.h>

# include <ctype.h>

/* Приклад 32 б. */

main()

{

char str[]=" String From Letters in Different Register";

/* "Рядок, що складається з Літер у Різних Регистрах"/ рrintf("Рядок буде надрукований малими літера");

p=str;

while(*p)

printf(“%c”, tolower(*p++));

}

Якщо в цих прикладах замінити рядок англійською мовою на набрану російськими літерами, то ніякого перетворення літер у рядкові або, навпаки, у прописні не відбудеться. Це зв'язано з тим, що стандартні функції toupper() і tolowеr() аналізують значення аргументу і повертають те ж саме значення, якщо він не є відповідно рядковою або прописною літерою латинського алфавіту. Якщо ж аргумент є мала літера латинського алфавіту, то значенням функції toupper() буде відповідна прописна літера (точніше, код цієї літери). Функція tolower() змінює код лише прописних літер латинського алфавіту. Прототипи цих функцій знаходяться в заголовному файлі ctype. h.

Масиви вказівників

Вказівники, як і змінні будь-якого іншого типу, можуть об'єднуватися в масиви. Оголошення масиву вказівників на 10 цілих чисел має вид

int *x[10];

Кожному з елементів, масиву можна привласнити адресу; наприклад, третьому елементу привласнимо адресу цілої змінної в:

х[2]=&у;

щоб знайти значення змінної у, можна написати *х[2].

Приведемо приклад використання масиву вказівників.Частіше усього це буває зручно при опрацюванні масиву рядків.

#include <stdio.h>

#include <string.h>

#include <stlib.h>

#include <conio.h>

/* Приклад 33 */

main()

{

char ext[]={exe", "com", "dat", "c", "pas", "cpp")

char ch, s1[80];

for(;;)

{ do

{ рrintf(“Файли з розширенням:\n");

printf(“l. exe\n");

printf("2. com\n");

printf("3. dat\n");

printf("4. c\n");

printf("5. pas\n");

printf("6. cpp\n");

printf("7. guit\n");

printf("Baш вибір: \n");

ch=getche();

printf(\n);

{

while ((ch<'l'||(ch>'7'));

if (ch==’7') break;

strcp(s1, "dir*.");

strcat(s1, ext[ch-1]);

system(s1);

}

}

Тут функція system() - бібліотечна функція, що змушує операційну систему DOS виконати команду, що є аргументом цієї функції.

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

char *errors[]={"Cannot open file ",

"Cannot close file" ,

"Allocation eiror ",

"Syaem error "

};

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

Взагалі рядкова константа в мові С асоціюється з адресою початку рядка в пам'яті, тип рядка утворюється char* (вказівник на тип char). Тому можливо й активно використовується наступне присвоювання:

сhar *pc:

рс = "Hello, World ! ";

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

int **point;

Вказівник Вказівник Змінна

Адреса

------>

Адреса

------>

Значення

point має тип вказівник на вказівник на int. Відповідно, щоб одержати цілочисельне значення змінної, на якій вказує point, треба у виразі використовувати **point.

Приклад використання:

#include <sidio.h>

/* Приклад 32. */

main()

{

int i, pi, ppi;

i=7;

pi=&i;

ppi=π

printf(“i=%d pi=%р ppi=%р \n", i, pi, ppi);

*pi++;

printf(“i=%d pi=%p ppi=%p \n", i, pi, ppi);

*ppi=12;

printf("i=%d pi=%p ppi=%р \n", i, pi, ppi);

return 0;

}

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]