B.I.Березін,С.Б.Березін(С.83) МАСИВИ І ПОКАЖЧИКИ Раніше ми ввели типи даних в мові С, які називаються іноді базовими або вбудованими. На основі цих типів даних мова С дозволяє будувати інші типи даних і структури даних. Масив - один з найбільш простих і відомих структур даних. Під масивом в мові С розуміють набір даних одного і того ж типу, зібраних під одним ім'ям. Кожний елемент масиву визначається ім'ям масиву і порядковим номером елемента, який називається індексом. Індекс в мові С завжди ціле число. ОГОЛОШЕННЯ МАСИВУ В ПРОГРАМІ Основна форма оголошення масиву розмірності N така: тип <ім'я масиву>[размер1][размер2]...[размерН] Частіше за все використовуються одновимірні масиви: тип <ім'я масиву> [розмір] ; тип - базовий тип елементів масиву, розмір - кількість елементів одновимірного масиву. При описі двовимірного масиву оголошення має наступний вигляд: тип <ім'я масиву> [размері][размер2]; У цьому описі можна трактувати оголошення двовимірного масиву як оголошення масиву масивів, т. е. масив розміру [размер2], елементами якого є одновимірні масиви <ім'я масиву>[размер1]. Розмір масиву в мові С може задаватися константою або константним виразом. Не можна задати масив змінного розміру. Для цього існує окремий механізм, званий динамічним виділенням пам'яті. ОДНОВИМІРНІ МАСИВИ У мові С індекс завжди починається з нуля. Коли ми говоримо про перший елемент масиву, то маємо на увазі елемент з індексом 0. Еслі ми оголосили масив int a[100] ; це означає, що масив містить 100 елементів від а[0] до а[99]. Для одновимірного масиву легко підрахувати, скільки байт в пам'яті буде займати цей масив: кільк.байтів=<розмір базового типу>*<кільк.елементів>. У мові С під масив завжди виділяється безперервне місце в оперативній пам'яті. У мові С не перевіряється вихід індексу за межі масиву. Якщо масив а[100] описаний як цілочисельний масив, що має 100 елементів, а ви в програмі вкажете а[200], то повідомлення про помилку не буде видане, а як значення елемента а[200] буде видано деяке число, що займає відповідні 2 байти. Можна визначити масив будь-якого визначеного раніше типу, наприклад unsigned arr[40], long double al[1000], char ch[80]. /*поміняти місцями max з min*/ #include <iostream.h> main() { int i,j,a[10], max. nmax, min, nmin, temp; clrscr(); for (i=0; i<10; i++) сіп » a[i]; max=min=a[0]; nmax=nmin=0; for (i=0; i<10; i++) if(a[i]>max) { max=a[i]; nmax=i;} else if(a[i]<min) {min=a[i], nmin=i;} tern p= a[n m ax]; a[n max]=a[nm і n]; a[nm і n]=temp; for (i=0; i<10; i++) cout « a[i] «" "; } | // Сортування і програвання масиву #include<iostream.h> #include<dos. h> #'\ nclude<conio. h> void main() { int temp, і, j, a[ 1 0]; clrscr(); for (i=0;i<10;i++) сіп » a [ і ]; for (i=0;i<9;i++) for (j=i+1 ;j<10;j++) if (a[i]>a[j]) { temp=a[i]; a[i]=a[j]; a[j]=temp; } for (i=0;i<1 0;i++) { cout « a[i]«" "; sound(a[i]*80); delay(500); nosou nd(); } getch(); } | МАСИВИ СИМВОЛІВ. РЯДКИ Однак масиви типу char - символьні масиви - займають в мові особливе місце. У багатьох мовах е спеціальний тип даних - рядок символів (string). У мові С окремого типу рядка символів немає, а реалізована робота з рядками шляхом використання одновимірних масивів типу char. У мові С символьний рядок - це одновимірний масив типу char, що закінчується нульовим байтом. Нульовий байт - це байт, кожний біт якого рівний нулю. Для нульового байта визначена спеціальна символьна константа ' \0 ' . Це потрібно враховувати при описі відповідного масиву символів. Так, якщо рядок повинен містити N символів, то в описі масиву потрібно указати N+1 елемент. Наприклад, опис char str[11] ; передбачає, що рядок містить 10 символів, а останній байт зарезервований під нульовий байт. Звичайно, ми задали звичайний одновимірний масив, але якщо ми хочемо трактувати його як рядок символів, то це буде рядок максимум з 10 елементів. Хоча в мові С немає спеціального типу рядка, мова допускає рядкові константи. Рядкова константа - це список літер, взятих в подвійні лапки. Наприклад, "Borland C++ ", "Це рядкова константа". У кінець рядкової константи не треба ставити символ '\0'. Це зробить компілятор, і рядок "Borland C++" в пам'яті буде вигляда- Є два простих способи ввести рядок з клавіатури. Перший спосіб -скористатися функцією scanf() зі специфікатором введення %s. Треба пам'ятати, що функція scanf() вводить символи до першого пропуско-вого символа. Другий спосіб - скористатися спеціальною бібліотечною функцією gets(), оголошеною в файлі stdio.h. Функція gets() дозволяє вводити рядки, що містять пропуски. Введення закінчується натисненням клавіші Enter. Обидві функції автоматично ставлять в кінець рядка нульовий байт. Не забудьте зарезервувати для нього місце. Як параметр в цих функціях використовується просто ім'я масиву. #i ncl ude <stdio. h> void main () { char s1[80], s2[80]; scanf( %s, "s1); І" можна об'єднати 2 scanf в один s c a n f ( % s % s , " s 1 , s 2); * / scanf("%S", s2); printf("%s\n", s1); printf("%s", s2); } ввели: Hello! Good I uck! Резул ьтат: Hello! Good | #i nclude <std io. h> void main () { char s1[80], s2[80]; gets(s1); gets(s2) puts(s1); puts(s2); } ввели: Hello! Good luck! Результат: Hello! Good luck! | Виведення виробляється функціями printf() або puts(). Обидві функції виводять вміст масиву до першого нульового байта. Функція puts() додає в кінці рядка, що виводиться символ нового рядка. У функції printf() перехід на новий рядок треба передбачати в рядку формату самим. ФУНКЦІЇ ДЛЯ РОБОТИ З РЯДКАМИ Для роботи з рядками існує спеціальна бібліотека, опис якої знаходиться в файлі string.h. Найчастіше використовуються функції strcpyO, strcat(), strlenQ, strcmpO. Виклик функції strcpy() має вигляд strcpy(si, s2) ; Функція strcpy() використовується для копіювання вмісту рядка s2 в рядок s1. Масив s1 повинен бути досить великим, щоб в нього вмістився рядок s2. Якщо місця мало, компілятор не видає вказівки на помилку або попередження; це не перерве виконання програми, але може привести до псування інших даних або самої програми і неправильній роботі програми надалі. Виклик функції strcat() має вигляд strcat(sl, s2) ; Функція strcat() приєднує рядок s2 до рядка s1 і вміщує його в масив, де знаходився рядок s1, при цьому рядок s2 не змінюється. Нульовий байт, який завершував рядок s1, буде замінений першим символом рядка s2. їв функції strcpyO, і в функції strcat() рядок, що виходить, автоматично завершується нульовим байтом. Розглянемо простий приклад використання цих функцій. Резул ьтат: Hello, World! Hello, World! World! | #include <stdio.h> #і ncl ude <string . h> main () { char s1[20], s2[20]; strcpy(s1 , "Hello, "); strcpy(s2, "World!"); puts(s1); puts(s2); strcat(s1, s2); puts(s1); puts(s2); } Виклик функції strcmpO має вигляд strcmp(sl, s2); Функція strcmpO порівнює рядки si і s2 і повертає значення О, якщо рядки однакові, тобто містять одне і те ж число однакових символів. Під порівнянням рядків ми розуміємо порівняння в лексикографічному значенні, так як це відбувається, наприклад, в словнику. Звичайно, в функції відбувається посимвольне порівняння кодів символів. Код першого символа одного рядка порівнюється з кодом символа другого рядка. Якщо вони однакові, розглядаються другі символи тощо. Якщо зі лексикографічно (в значенні словника) більше s2, то функція strcmpO повертає додатне значення, якщо менше -від'ємне значення. Виклик функції strlen() має вигляд strlen(s) ; Функція strlen() повертає довжину рядка з, при цьому завершальний нульовий байт не враховується. Виклик length("Hello") поверне значення 5. Розглянемо застосування цієї функції для обчислення довжини рядка, що вводиться з клавіатури. #include <stdio.h> #incl ude <string . h > m а і n () { char s(80], printf( "Введіть рядок:"); gets(s); printf( "Рядок\п%з\п має довжину %d символів \n", s, strlen(s)); } ДВОВИМІРНІ МАСИВИ Як ми вже зазначали, мова С допускає багатовимірні масиви, найпростішою формою яких е двовимірний масив (two-dimentional array). Можна сказати, що двовимірний масив - це масив одновимірних масивів . Двовимірний масив int a[3][4] можна подати у вигляді таблички: Перший індекс а[0] [0] | а[0][1] | а[0][2] | а[0] [3] | а[1] [0] | а[1][1] | а[1][2] | а[1][3] | а[2][0] | а[2] [1] | а[2][2] | а[2] [3] | Перший індекс - номер рядка, другий індекс - номер стовпця. Кількість байт пам'яті, яке необхідне для зберігання масиву, обчислюється по формулі Кільк.байтів = <розмір типу даних>*<кільк.рядків>*<кільк.ствпців>. У пам'яті комп'ютера масив розташовується безперервно по рядках, тобто а[0][0], а[0][1], а[0][2], а[0][3], а[1][0], а[1][1], а[1] [2], а[2] [1],. ... а[2] [3] . Потрібно пам'ятати, що пам'ять для всіх масивів, які визначені як глобальні, відводиться в процесі компіляції і зберігається весь час, поки працює програма. Часто двовимірні масиви використовуються для роботи з таблицями, що містять текстову інформацію. Також дуже часто використовуються масиви рядків. ІНІЦІАЛІЗАЦІЯ МАСИВІВ Дуже важливо уміти ініціалізувати масиви, тобто привласнювати елементам масиву деякі початкові значення. У мові С для цього є спеціальні можливості. Самий простий спосіб ініціалізації наступний: в процесі оголошення масиву можна указати в фігурних дужках список ініціалізаторів: float а[6]={1.1, 2.2, 3.3, 4.0, 5, 6}; В іншому випадку така форма запису еквівалентна набору операторів: а[0]=1.1; а[1]=2.2; ... а [5] =6. Багатовимірні масиви, в тому числі і двовимірні масиви, можна ініціалізувати, розглядаючи іх як масив масивів. Ініціалізації int а[3][5]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; і int а[3][5]={{1,2,3,4,5}, {6,7,8,9,10}, {11,12,13,14,15}}; еквівалентні. Кількість ініціалізаторів не зобов'язана співпадати з кількістю елементів масиву. Якщо ініціалізаторів менше, то значення решти елементів масиву не визначені. У той же час ініціалізації int а[3][5]={1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11); і int а[3][5]={{1, 2, 3}, {4, 5, 6, 7, 8}, {9, 10, 11}}; різні. //change strings: 1-6, 2-5, 3-4 #i nclude<std io. h > | ***** Скачайте бесплатно полную версию реферата !!! *****
|