You are on page 1of 21

ПРОГРАМСКИ ЈАЗИК

низи
НИЗИ
 Еднодимензионалните низи претставуваат множества од повеќе елементи од
ист тип. Во C++, еднодимензионални низи се креираат и употребуваат на
сличен начин како и основните податочни типови (int, char, double, long long,
итн), со тоа што е потребно, при декларацијата, покрај името на
променливата (кое ќе го користиме за пристап до елементите од низата) и
податочниот тип (од кој тип се елементите кои ја сочинуваат низата), да го
наведеме и бројот на елементи.
 На овој начин се овозможува креирање на групи од елементи кои
соодветствуваат на множества податоци врз кои планираме да вршиме
операции. На пример, може да креираме низа од 365 (или 366) double
вредности кои ќе ја содржат измерената просечна температура за секој ден од
годината.
 Потоа, можеме да вршиме разни математички операции врз елементите од
оваа низа - да бараме минимум, максимум, просечна температура за одредени
месеци или за целата година, итн.
 Како и секоја друга променлива, така и низите мора да бидат декларирани
пред да може да се користат. Во C++, низи се декларираат на следниот начин:
tip ime[N];
 Притоа, tip го означува податочниот тип на секој елемент од низата,
N е бројот на елементи, додека ime е името на променливата преку
кое ќе пристапуваме до елементите на низата.
 На пример, за да креираме низа од 6 double вредности, треба да
напишеме: "double ime[6];". Со тоа, сме креирале променлива со
име ime, која овозможува пристап до 6 вредности од тип double.
Секоја од тие 6 вредности се нарекува елемент на низата.
 Сите елементи од низата се сместуваат на последователни
локации во меморијата (еден по друг - како што е дадено
на сликата).
 За да пристапиме до одреден елемент од низата (да ја
прочитаме неговата вредност, или да запишеме некоја
вредност) се користи операторот [p] - p го означува
индексот на елементот до кој сакаме да пристапиме.
 Индексите се движат од 0 (прв елемент) до N-1 (последен
елемент) - каде N го означува бројот на елементи во
низата!
 На пример, за да пристапиме до првиот елемент од низата
ime треба да напишеме ime[0], за да пристапиме до
вториот елемент треба да напишеме ime[1], и така натаму,
до последниот елемент ime[5] (од 0 до 5 има точно 6
елементи). Притоа, ime[0], ime[1], ..., ime[5] се однесуваат
како обични променливи од тип double и нивната
вредност може да ја читаме и/или менуваме.
 Следниве неколку наредби служат за креирање на низа
array од целобројни елементи со големина 5, и за
сместување на вредностите {0, 10, 20, 30, 40} во
елементите од таа низа:

int array[5];
array[0] = 0;
array[1] = 10;
array[2] = 20;
array[3] = array[2] + 10; //30
array[4] = array[1] + array[3]; //40

 Важно е да се напомене дека, при декларирањето на една


низа, мора да наведеме константна големина (големина
позната пред самото извршување на програмата). За
ваквите низи уште се вели дека се статички креирани.
 Следната програма користи низа arr[10] за работа со 10 цели броеви.
Притоа, броевите се читаат од стандарден влез (тастатура), а нивниот
збир се печати на стандарден излез (екран).

#include <iostream>
using namespace std;
int main()
{
int arr[10];
for (int i=0; i<10; i++)
{
cin >> arr[i]; //'i' se dvizi od 0 do 9!
}
int s = 0;
for (int i=0; i<10; i++)
s += arr[i]; //'i' se dvizi od 0 do 9!
cout << "Zbirot e: " << s << endl;
return 0;
}
 Како што може да забележите од изворниот код на програмата
дадена погоре, до елементите од низата пристапуваме преку
именување на низата (arr) и задавање на индексот на елементот до
кој сакаме да пристапиме (arr[i]).
 Операторот [p], кај еднодимензионалните низи, се користи на два
начини: за дефинирање на големина на низата (p мора да биде
константа) и за пристап до одреден елемент од низата (p може да
биде константа или променлива).
 Во C++ не е грешка (гледано синтаксички) доколку пристапите до
елемент кој не се наоѓа во границите на низата (на пример, да се
обидете да пристапите до десеттиот елемент на низа со големина
5). Но, ваквите грешки може да предизвикаат проблем за време на
извршување на програмата (т.н. runtime error). Велиме "може"
бидејќи оперативниот систем ќе ја "сруши" вашата програма само
доколку се обидете да пристапите до меморија која тој не ви ја
доделил (сакате да прочитате или запишете податок кој и припаѓа
на друга програма). Програмата може да се сруши и доколку на
таа локација во меморијата се чуваат податоци од друг тип.
ИНИЦИЈАЛИЗАЦИЈА

 По правило, откако ќе ја декларирате низата, потребно е


истата да ја иницијализирате, т.е. да им доделите вредности
на нејзините елементи.
 Како и кај основните податочни типови, вредноста на овие
елементи е неодредена - може да биде што било што се
наоѓало на таа позиција во меморијата пред стартување на
вашата програма.
 Ова правило не важи за низите кои се дефинирани глобално
(надвор од која било функција) - по правило, глобалните
низи се иницијализираат на основната вредност (целата
меморија се полни со 0).
 На елементите може да им доделиме вредност по креирање
на низата (како во примерите дадени погоре), или да им
доделиме вредност при самата декларација на низата.
 Во C++, ова се прави со набројување на вредностите:

int array[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

 Со ова сме креирале низа од 10 елементи, каде


array[0]=1, array[1]=2, ..., array[8]=9 и array[9]=10.
 Доколку не ги специфицираме вредностите на сите
елементи (на пример, декларираме низа со големина 10,
но наведеме само 5 вредности при иницијализацијата
{1,2,3,4,5}), наведените вредности ќе им се доделат на
првите елементи од низата (почнувајќи од array[0]), а на
останатите елементи ќе им се додели вредност 0. 
 Ова може да го искористиме за сместување на вредност
0 во сите елементи од одредена низа:

int array[100] = {0}; //site 100 elementi se 0

 Можно е и креирање на низи без задавање на нивна


големина (int array[]). Тогаш, компајлерот сам ќе ја
одреди големината на низата според бројот на елементи
во листата за иницијализација:

int array[] = {1, 2, 3, 4, 5}; //niza od 5 elementi

 Низите не нудат метод преку кој може да се одреди


нивната големина. 
 Во C++, можеме да го искористиме операторот sizeof()
за да откриеме колку бајти зафаќа една низа -
sizeof(array), но и од колку елементи е составена самата
таа низа - преку делење на меморијата која ја зафаќа
низата (sizeof(array)) со меморијата која ја зафаќа еден
од нејзините елементи (на пример, sizeof(array[0])).

 Бидејќи сите елементи зафаќаат иста количина на


меморија (затоа што се од ист податочен тип), оваа
едноставна математичка операција
(sizeof(array)/sizeof(array[0])) ќе го даде точниот број на
елементи во низата.
 Следната програма демонстрира некои од операциите за кои зборувавме досега:
#include <iostream>
using namespace std;

int main()
{
int arr[10] = {1, 2, 3, 4, 5};

//izlez: '1 2 3 4 5 0 0 0 0 0'


for (int i=0; i<10; i++)
cout << arr[i] << " ";

cout << endl;


double niza[] = {10.0, 15.0, 20.0, 25.0, 30.0};
cout << sizeof(niza) << endl; //pechati '40' (5 * 8)

cout << (sizeof(niza)/sizeof(niza[0])); //pechati '5'


return 0;
}
НИЗИ ОД ЗНАЦИ

 C++ овозможува работа со текстуални податоци на


неколку начини.
 Покрај со користење на класата string (за која
накратко зборувавме во претходните предавања), во
C++ е дозволена работа со текстуални податоци и
преку нивно третирање како низа од знаци - низа од
примитивниот податок char.
 Бидејќи ваквиот начин на работа со текстуални
податоци се користел и пред појавата на C++, овие
низи се среќаваат и под името "C string-ови".
 Денес, на програмерите им се препорачува да ја користат
класата string и да го избегнат директното користење на
ваквите низи од знаци.
 Низи од знаци се креираат на ист начин како и
останатите еднодимензионални низи:
char ime[N];
 Притоа, ime го означува името на променливата, додека
N го означува бројот на знаци (од колку елементи е
составена низата ime).
 Еден од овие N знаци (зависно од текстуалниот податок
кој ќе се чува во низата) ќе биде еднаков на '\0' - и ќе
претставува т.н. null знак или null terminator.
 Овој знак е потребен за да го означи крајот на
текстуалниот податок и да ни овозможи во низа со
големина N да чуваме текстуални елементи кои се
пократки од N знаци.
 На следната слика е претставен начинот на
сместување на текстуални податоци во низата од
знаци name[13]:

 На овој начин, кога сакаме да печатиме податоци,


програмата знае дека треба да печати знаци сé додека
не стигне до знакот '\0'. Сите знаци по '\0' се неважни
и не се користат.
 C++ овозможува иницијализација на овие низи од знаци на
2 начини:

 char name[] = {'D', 'a', 'r', 'k', 'o', '\0'}; //treba


da se navede '\0'
 char name[] = "Darko"; //se podrazbira '\0'
 И двата начина прикажани погоре креираат низа name со
големина 6. Низата го содржи текстуалниот податок
"Darko" и null знак '\0' за означување на крај на текстот.
Бидејќи низите имаат големина која се дефинира при
нивното креирање, не е дозволено подоцнежно менување
на нивната вредност преку користење на операторот '=' (кај
string класата ова е дозволено - таа работи со динамички
резервирана меморија).
  На пример, следниов код е погрешен:
 char name[] = "Darko";

 name = "Petar"; //GRESHKA!

 Следната програма прикажува како може да се користат низите од знаци во


комбинација со потоците cin и cout:
#include <iostream>
using namespace std;

int main()
{
char array[] = "Darko";
array[0] = 'M'; //obichna niza
cout << array << endl; //pechati 'Marko'
char text[100];
cout << "Vnesi eden zbor: ";
cin >> text; //prochitaj eden zbor
cout << text; //go pechati vneseniot zbor

return 0;
}
 Во програмата дадена погоре, наредбата cin >> text;
чита еден збор внесен од страна на корисникот и,
истиот го сместува во променливата text.
 На крајот од текстот, автоматски, се додава и null
знак.
 Бидејќи cin чита податоци до првото појавување на
празно место, tab или знак за нов ред, доколку сакаме
да прочитаме цел ред текст (наместо само еден збор
или број), потребно е да ја искористиме функцијата
cin.getline(char[], N) - слична функција како што
постоеше и за класата string.
 во C++, секогаш кога користиме наводници за креирање
на текстуален податок (cout << "Darko"), во позадина ние
всушност работиме со C string-ови (низи од знаци со null
знак). Кога креираме променлива од тип string и, преку
операторот '=', и доделуваме текстуална вредност (string
str = "Darko"), програмата автоматски го претвора
податокот од низа од знаци со null знак во string.
 Постојат 7 основни функции кои овозможуваат работа со
текстуални низи (сите дефинирани во датотеката
"<cstring>"):
 strlen(char[] niza) - ја враќа должината на низата niza (без
null знак)
 strcpy(char[] destinacija, char[] izvor) - копира текстуална
низа (од izvor во destinacija), вклучувајќи го и null знакот.
Внимавајте: низата destinacija треба да има доволна
големина за да ги собере сите знаци од izvor.
 strncpy(char[] destinacija, char[] izvor, int N) - копира најмногу N
знаци од текстуална низа (од izvor во destinacija). Знакот '\0' ќе се
ископира само доколку се појави во првите N знаци - инаку,
истиот мора да го додадеме самите. Внимавајте: низата
destinacija треба да има доволна големина за да ги собере сите
потребни знаци.
 strcmp(char[] prva, char[] vtora) - споредува две низи (резултатот е
0 ако низите се еднакви)
 strncmp(char[] prva, char[] vtora, int N) - споредува N знаци (или
помалку, ако '\0' се појави претходно) од низите prva и vtora
(резултатот е 0 ако првите N знаци од низите се еднакви)
 strcat(char[] prva, char[] vtora) - ја надоврзува низата vtora на prva.
Внимавајте: низата prva треба да има доволна големина за да ги
соберете знаците од двете низи.
 strncat(char[] prva, char[] vtora, int N) - ги надоврзува првите N
знаци (или помалку, ако '\0' се појави претходно) од низата vtora
на prva. Внимавајте: низата prva треба да има доволна големина
за да ги собере сите потребни знаци.
 Следнава програма употребува некои од функциите споменати погоре:
#include <iostream>
#include <cstring>
using namespace std;

int main()
{
char a[] = "prva niza";
char b[] = "vtora niza";

char c[] = "tekst";


char d[] = "tekst";

cout << strlen(a) << endl; //pechati '9'


cout << strlen(c) << endl; //pechati '5'

char t[100];
strcpy(t, "Nekoja vrednost"); //t="Nekoja vrednost"
strcpy(t, "Neshto drugo"); //t="Neshto drugo"

strcpy(t, a); //t="prva niza"


strncpy(t, b, 4); //t="vtor niza" (ne se kopira '\0')
t[4] = '\0'; //t="vtor"

strcat(t, b); //t="vtorvtora niza"

cout << t << endl; //pechati 'vtorvtora niza'

cout << strcmp(t, a) << endl; //pechati '1'


cout << strcmp(c, d) << endl; //pechati '0'

return 0;
}

You might also like