русс | укр

Мови програмуванняВідео уроки php mysqlПаскальСіАсемблерJavaMatlabPhpHtmlJavaScriptCSSC#DelphiТурбо Пролог

Компьютерные сетиСистемное программное обеспечениеИнформационные технологииПрограммирование


Linux Unix Алгоритмічні мови Архітектура мікроконтролерів Введення в розробку розподілених інформаційних систем Дискретна математика Інформаційне обслуговування користувачів Інформація та моделювання в управлінні виробництвом Комп'ютерна графіка Лекції


Масиви символьних рядків і масиви вказівників


Дата додавання: 2014-04-22; переглядів: 2227.


Масиви символів можна створювати двома способами: з використанням масивів і з використанням вказівників:

 

char с1[ ] = "now is the time";

char * с2 = "now is the time";

 

В цьому визначенні с1 – це масив з кількістю елементів достатньою для розміщення символів рядка ініціалізації і нульового символу. Символи масиву можуть змінюватися, с1 є константним вказівником. с2 – це вказівник, який ініціалізований таким чином, щоб посилатися на рядкову константу. Значення вказівника можна змінювати, елементи символьного рядка – ні. Розглянемо програму, яка буде копіювати один рядок в інший.

 

#include <iostream>

using namespace std;

int main() {

char c1[ 80 ] = "Good old string";

char * c2 = "Nice new string (pointer version)";

char c3[ 80 ] = "Nice new string (array version)";

char * t1, *t2;

int i;

for ( t1 = c1, t2 = c2, i = 0; t2[ i ] != '\0'; i++ )

t1[ i ] = t2[ i ];

cout << c1 << endl;

for ( t1=c1, t2=c3, i=0; ( t1[ i ] = t2[ i ] ) != 0; i++ );

cout << c1 << endl;

t1 = c1;

t2 = c2;

while ( ( * t1++ = * t2++ ) != '\0' );

cout << c1 << endl;

t1 = c1;

t2 = c3;

while ( * t1++ = * t2++ );

cout << c1 << endl;

}

 

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

 

#include <iostream>

using namespace std;

int main() {

char c[ 80 ] = "A string";

char * t;

t = c;

while (* ++t);

cout << t - c << endl;

}

 

Поширеним видом багатовимірних масивів є масиви символьних рядків, тобто масиви, кожен елемент яких – окремий символьний рядок. Наприклад, масив повідомлень про помилки можна оголосити таким чином:

 

char Error[ 3 ][ 20 ] = {

"File Write Error",

"File Read Error",

"File Open Error"

};

 

Масив Error в пам'яті буде розташований таким чином (рис. 8.1):

 

 
F i l e   W r i t e   E r r o r \0      
F i l e   R e a d   E r r o r \0        
F i l e   O p e n   E r r o r \0        

 

Рис. 8.1. Розташування елементів масиву рядків в пам'яті

 

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

 

#include <iostream>

using namespace std;

int main() {

char Error[ 3 ][ 20 ] = {

"File Write Error",

"File Read Error",

"File Open Error"

};

cout << Error[ 0 ]; // Перший рядок символів

cout << Error[ 1 ][ 0 ]; // Перший символ другого рядка

}

 

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

 

#include <iostream>

#include <ctime>

using namespace std;

int main() {

srand( unsigned( time ( NULL ) ) );

char code[ ][ 5 ] = {

"0000", "0001", "0010", "0011", "0100",

"0101", "0110", "0111", "1000", "1001"

};

for ( int i = 0, t; i < 20; i++ ) {

t = rand( ) % 100;

cout << t << "\t" << code[ t / 10 ] << " "

<< code[ t % 10 ] << endl;

}

}

 

В цьому прикладі всі рядки в масиві мають однакову довжину – 5 символів (4 символи для цифр і один символ для нуль – символу), тому всі елементи цього двовимірного масиву будуть зайняті корисною інформацією. В попередньому прикладі для збереження кожного повідомлення про помилку мі виділяли 20 символів, по розміру найбільш довгого повідомлення. Через це частина елементів декількох з рядків не використовувалась.

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

 

#include <iostream>

using namespace std;

int main() {

char * month[ ] = {

"Wrong month number",

"January", "February", "March", "April", "May",

"June", "July", "August", "September", "October",

"November", "December"

};

int t;

cin >> t;

cout << ( 1 <= t && t <= 12 ? month[ t ] : month[ 0 ] );

}

 

тут month – це масив вказівників на char, кількість елементів масиву визначається кількістю ініціалізаторів, їх 13, кожен елемент масиву – вказівник на перший елемент відповідного рядка.

Напишемо програму, яка буде визначати день року для зазначеної дати і навпаки. В цьому прикладі змінна leap має значення 0, якщо рік не високосний і 1 – якщо високосний.

 

#include <iostream>

using namespace std;

int main() {

char * month_name[ ] = {

"Wrong month number",

"January", "February", "March" , "April", "May",

"June", "July", "August", "September", "October",

"November", "Deсember"

};

char ndays[ 2 ][ 13 ] = {

{ 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},

{ 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}

};

int year = 2011, month = 3, day = 16, i, j, n;

// Номер дня для заданої дати

int leap= year % 4 == 0 && year % 100 != 0 || year % 400 == 0;

for ( i = 1, n = day; i < month; i++ )

n += ndays[ leap ][ i ];

cout << n << endl;

// Дата для номера дня і року

n = 75;

for ( i = 1; ndays[ leap ][ i ] <= n; i++ )

n -= ndays[ leap ][ i ];

cout << month_name[ i ] << " " << n << endl;

// Всі номера днів

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

for ( j = 1; j <= ndays[ leap ][ i ]; j++, n++ ) {

cout << n << "\t";

cout << month_name[ i ] << "\t";

cout << j << endl;

}

}


<== попередня лекція | наступна лекція ==>
Звертання до елементів масивів через вказівники | Динамічне виділення пам’яті


Онлайн система числення Калькулятор онлайн звичайний Науковий калькулятор онлайн