- 1 1. Sissejuhatus
- 2 2. Nooleoperaatori põhialused ja kasutamine
- 3 3. Nooleoperaatori kasutamine praktikas
- 4 4. Nooleoperaatori sisemine tööpõhimõte
- 5 5. Nooleoperaatori kasutamisel tähelepanu ja vigade vältimine
- 6 6. Korduma kippuvad küsimused (KKK)
- 7 7. Kokkuvõte ja järgmised sammud
- 8 8. Viited ja lisamaterjalid
1. Sissejuhatus
Mis on nooleoperaator C-keeles?
C-keel on programmeerimiskeel, mida kasutatakse laialdaselt süsteemiprogrammide ja manustarkvara arendamisel. Nende seas on “nooleoperaator (->
)” väga kasulik funktsioon, kui töötatakse struktuuride osutitega.
Nooleoperaatori abil saab struktuuri liikmetele ligi pääseda lühikese ja loetava koodiga. Eriti sageli kasutatakse seda olukordades, kus andmeid hallatakse osutite kaudu, mistõttu on selle mõistmine oluline.
Artikli sihtrühm ja õpieesmärgid
See artikkel on mõeldud järgmistele lugejatele:
- Neile, kes õpivad C-keelt ning omavad põhiteadmisi struktuuridest ja osutitest.
- Neile, kes soovivad põhjalikult teada saada, kuidas nooleoperaatorit kasutada ja rakendada.
- Neile, kes tahavad parandada programmi loetavust ja efektiivsust.
Käesolevas artiklis selgitame laialdaselt nooleoperaatori põhikasutust, rakendusnäiteid, tähelepanekuid ja veakäsitlust. Selle tulemusena on eesmärk võimaldada praktiliste programmide loomist, kasutades nooleoperaatorit.

2. Nooleoperaatori põhialused ja kasutamine
Mis on nooleoperaator? Süntaks ja tähendus
Nooleoperaator (->
) on C-keeles kasutatav operaator, mille abil pääseb osuti kaudu struktuuri liikmetele ligi.
Süntaks
pointer->member;
See avaldis on tähenduselt sama, mis järgmine:
(*pointer).member;
Nooleoperaatorit kasutatakse laialdaselt, kuna see on lühem ja loetavam kui sulgude ja tärni kombinatsioon.
Erinevus ja kasutusviis täppoperaatoriga (.
)
Struktuuri liikmetele pääseb ligi kahel viisil:
- Täppoperaator (
.
)
Kui kasutatakse tavalist struktuurimuutujat.
struct Person {
char name[20];
int age;
};
struct Person p = {"Alice", 25};
printf("%s
", p.name); // Kasutatakse täppoperaatorit
- Nooleoperaator (
->
)
Kui kasutatakse struktuuri osutit.
struct Person {
char name[20];
int age;
};
struct Person p = {"Alice", 25};
struct Person *ptr = &p;
printf("%s
", ptr->name); // Kasutatakse nooleoperaatorit
Erinevuste kokkuvõte
- Täppoperaatorit kasutatakse siis, kui pääsetakse otse struktuurimuutujale.
- Nooleoperaatorit kasutatakse siis, kui struktuuri liikmetele ligi pääseb osuti kaudu.
Nooleoperaatori süntaks ja põhikasutus
Näide 1: Struktuuri ja osuti põhiline kasutamine
#include <stdio.h>
#include <string.h>
// Struktuuri definitsioon
struct Person {
char name[20];
int age;
};
int main() {
// Struktuurimuutuja ja osuti loomine
struct Person p1;
struct Person *ptr;
// Osutile aadressi määramine
ptr = &p1;
// Ligipääs liikmetele nooleoperaatori abil
strcpy(ptr->name, "Alice");
ptr->age = 25;
// Väljund
printf("Name: %s
", ptr->name);
printf("Age: %d
", ptr->age);
return 0;
}
Tulem:
Name: Alice
Age: 25
Selles näites määratakse struktuuri Person
muutuja p1
aadress osutile ptr
ning nooleoperaatoriga pääsetakse struktuuri liikmetele ligi.

3. Nooleoperaatori kasutamine praktikas
Näide lingitud loendiga
Lingitud loend (linked list) on sageli kasutatav andmestruktuur. Järgmisena vaatame, kuidas seda nooleoperaatori abil hallata.
Näide 1: Ühesuunalise lingitud loendi teostus
#include <stdio.h>
#include <stdlib.h>
// Sõlme definitsioon
struct Node {
int data;
struct Node *next;
};
// Funktsioon uue sõlme loomiseks
struct Node* createNode(int data) {
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
newNode->data = data;
newNode->next = NULL;
return newNode;
}
// Funktsioon loendi kuvamiseks
void displayList(struct Node *head) {
struct Node *current = head;
while (current != NULL) {
printf("%d -> ", current->data);
current = current->next; // Kasutatakse nooleoperaatorit
}
printf("NULL
");
}
int main() {
// Sõlmede loomine
struct Node *head = createNode(10);
head->next = createNode(20); // Seotakse järgmine sõlm nooleoperaatori abil
head->next->next = createNode(30); // Järgmine sõlm lingitakse edasi
// Loendi kuvamine
displayList(head);
return 0;
}
Tulem:
10 -> 20 -> 30 -> NULL
Selles näites kasutatakse nooleoperaatorit järgmise sõlme sidumiseks, mis võimaldab hallata struktuuri osutite kaudu.
Näide puustruktuuriga
Puustruktuur on samuti üks sagedasemaid andmestruktuure, kus kasutatakse nooleoperaatorit. Järgnevalt vaatame binaarpuu (kahendpuu) näidet.
Näide 2: Sõlmede lisamine ja otsimine kahendotsingupuus
#include <stdio.h>
#include <stdlib.h>
// Sõlme definitsioon
struct TreeNode {
int data;
struct TreeNode *left;
struct TreeNode *right;
};
// Funktsioon uue sõlme loomiseks
struct TreeNode* createNode(int data) {
struct TreeNode* newNode = (struct TreeNode*)malloc(sizeof(struct TreeNode));
newNode->data = data;
newNode->left = NULL;
newNode->right = NULL;
return newNode;
}
// Funktsioon sõlme lisamiseks
struct TreeNode* insertNode(struct TreeNode* root, int data) {
if (root == NULL) {
return createNode(data);
}
if (data < root->data) {
root->left = insertNode(root->left, data); // Kasutatakse nooleoperaatorit
} else {
root->right = insertNode(root->right, data); // Kasutatakse nooleoperaatorit
}
return root;
}
// Funktsioon puu kuvamiseks preorder läbikäiguga
void preorderTraversal(struct TreeNode* root) {
if (root != NULL) {
printf("%d ", root->data);
preorderTraversal(root->left); // Vasak alampuu
preorderTraversal(root->right); // Parem alampuu
}
}
int main() {
struct TreeNode* root = NULL;
// Sõlmede lisamine
root = insertNode(root, 50);
insertNode(root, 30);
insertNode(root, 70);
insertNode(root, 20);
insertNode(root, 40);
// Väljund preorder läbikäiguga
printf("Preorder Traversal: ");
preorderTraversal(root);
printf("
");
return 0;
}
Tulem:
Preorder Traversal: 50 30 20 40 70
Selles koodis kasutatakse nooleoperaatorit vasaku ja parema sõlme sidumiseks, et ehitada kahendpuu. Nooleoperaator muudab osutitega töötamise lihtsamaks ja loetavamaks.
Dünaamilise mälu ja nooleoperaatori kombinatsioon
Nooleoperaatorit kasutatakse sageli koos dünaamilise mälu eraldamisega. Allpool on näide, kuidas dünaamiliselt luua struktuur ja sellele andmeid omistada.
Näide 3: malloc ja nooleoperaatori kasutamine
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Student {
char name[20];
int age;
};
int main() {
// Mälueraldus dünaamiliselt
struct Student *s = (struct Student*)malloc(sizeof(struct Student));
// Andmete sisestamine
printf("Enter name: ");
scanf("%s", s->name);
printf("Enter age: ");
scanf("%d", &(s->age));
// Väljund
printf("Name: %s, Age: %d
", s->name, s->age);
// Mälu vabastamine
free(s);
return 0;
}
Tulem:
Enter name: Alice
Enter age: 20
Name: Alice, Age: 20
Selles näites pääsetakse nooleoperaatori abil ligi andmetele, mis on salvestatud dünaamiliselt eraldatud mälus.

4. Nooleoperaatori sisemine tööpõhimõte
Nooleoperaatori ja täppoperaatori ekvivalentsus
Nooleoperaator (->
) on ekvivalentne järgmise väljendiga:
ptr->member;
(*ptr).member;
See tähendab, et mõlemal juhul pääseb osuti ptr
kaudu struktuuri liikmele member
ligi.
Näide
#include <stdio.h>
#include <string.h>
struct Person {
char name[20];
int age;
};
int main() {
struct Person p = {"Alice", 25};
struct Person *ptr = &p;
// Nooleoperaator
printf("%s
", ptr->name);
// Ekvivalent täppoperaatori väljend
printf("%s
", (*ptr).name);
return 0;
}
Tulem:
Alice
Alice
Nagu näha, on nooleoperaator lihtsalt lühem ja loetavam viis kirjutada (*ptr).member
. Kui osutitega töötamine on sage, parandab see koodi loetavust.
Süntaktiline suhkur
Nooleoperaator on näide nn “süntaktilisest suhkrust” (syntactic sugar). See ei muuda programmi käitumist, kuid pakub lihtsamat ja loetavamat süntaksit.
Näide:
(*ptr).member; // Tavaline süntaks (pikk)
ptr->member; // Lühike ja arusaadav süntaktiline suhkur
Süntaktiline suhkur aitab vältida vigu (nt sulgude unustamist) ja parandab koodi hooldatavust.
Ligipääs mälule ja osutite tööpõhimõte
Nooleoperaatorit kasutades tuleb täpselt mõista, millisele mäluaadressile osuti viitab.
Mälu mudeli kujutis:
Mäluaadress | Väärtus |
---|---|
0x1000 | Struktuuri alguspunkt |
0x1004 | Liige 1 (name) |
0x1020 | Liige 2 (age) |
Kui osuti viitab aadressile 0x1000
, siis nooleoperaator teostab automaatselt nihkearvutuse ja võimaldab liikmetele ligi pääseda.
Näide 4: Mälu paigutuse põhjal ligipääs
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Data {
int id;
char name[20];
};
int main() {
struct Data *ptr = (struct Data*)malloc(sizeof(struct Data));
ptr->id = 101;
strcpy(ptr->name, "Alice");
printf("ID: %d, Name: %s
", ptr->id, ptr->name);
free(ptr); // Mälu vabastamine
return 0;
}
Tulem:
ID: 101, Name: Alice
Selles koodis toimub mälu eraldamine ja andmete haldamine tõhusalt. Nooleoperaatori abil on ligipääs liikmetele lihtne ja selge.

5. Nooleoperaatori kasutamisel tähelepanu ja vigade vältimine
Levinud vead ja nende vältimine
Nooleoperaatoriga töötades tuleb olla tähelepanelik osutite ja mäluhalduse osas. Järgnevalt mõned levinud vead ja lahendused.
Viga 1: NULL-osutile viitamine
Olukord: Kui osuti viitab NULL-ile ja kasutada nooleoperaatorit, tekib jooksuaegne viga (segmentation fault).
Näide: Vigane kood
struct Data {
int id;
};
int main() {
struct Data *ptr = NULL;
ptr->id = 10; // Tekib viga
return 0;
}
Lahendus: Kontrolli alati enne kasutamist, et osuti ei oleks NULL.
Parandatud kood:
struct Data {
int id;
};
int main() {
struct Data *ptr = NULL;
if (ptr != NULL) {
ptr->id = 10;
} else {
printf("Osuti on NULL
");
}
return 0;
}
Viga 2: Mälu eraldamise ebaõnnestumine
Olukord: Kui malloc
ei suuda mälu eraldada, viitab osuti NULL-ile. Selle kasutamine nooleoperaatoriga põhjustab vea.
Näide: Vigane kood
struct Data {
int id;
};
int main() {
struct Data *ptr = (struct Data*)malloc(sizeof(struct Data));
ptr->id = 10; // Kui malloc ebaõnnestub, tekib viga
free(ptr);
return 0;
}
Lahendus: Kontrolli alati, kas mälu eraldamine õnnestus.
Parandatud kood:
struct Data {
int id;
};
int main() {
struct Data *ptr = (struct Data*)malloc(sizeof(struct Data));
if (ptr == NULL) {
printf("Mälu eraldamine ebaõnnestus.
");
return 1;
}
ptr->id = 10;
printf("ID: %d
", ptr->id);
free(ptr); // Mälu vabastamine
return 0;
}
Viga 3: Initsialiseerimata osuti kasutamine
Olukord: Kui osutit ei initsialiseerita, sisaldab see määramatut väärtust ning võib viidata ettenägematule mälualale.
Näide: Vigane kood
struct Data {
int id;
};
int main() {
struct Data *ptr; // Ei ole initsialiseeritud
ptr->id = 10; // Tekib viga
return 0;
}
Lahendus: Initsialiseeri osuti alati NULL-iga või määra sellele kehtiv mäluaadress.
Parandatud kood:
struct Data {
int id;
};
int main() {
struct Data *ptr = NULL; // Initsialiseeritud
printf("Osuti pole initsialiseeritud.
");
return 0;
}
Nipid turvalise koodi kirjutamiseks
1. Vältida mälulekkeid
- Dünaamiliselt eraldatud mälu tuleb alati
free()
abil vabastada. - Kui mälu eraldatakse funktsioonis, tuleb see vabastada enne funktsioonist väljumist.
Näide:
struct Data *ptr = (struct Data*)malloc(sizeof(struct Data));
// Kasutamise järel vabastamine
free(ptr);
2. NULL-osutite kontroll
Standardiseeri NULL-kontroll, et kood oleks turvalisem.
Näide:
if (ptr == NULL) {
printf("Viga: osuti on NULL.
");
return;
}
3. Statiilise analüüsi tööriistade kasutamine
Kasuta tööriistu, mis automaatselt kontrollivad vigu ja mälulekkeid.
Soovitatud tööriistad:
- Valgrind (mälulekke tuvastamine)
- Cppcheck (statiiline analüüs)

6. Korduma kippuvad küsimused (KKK)
K1. Kuidas eristada täppoperaatori ja nooleoperaatori kasutust?
V: Täppoperaatorit (.
) ja nooleoperaatorit (->
) kasutatakse mõlemat struktuuri liikmete juurde pääsemiseks, kuid nende kasutusviis erineb.
- Täppoperaator (
.
) — kasutatakse siis, kui struktuuri muutujaid käsitletakse otse.
struct Person {
char name[20];
int age;
};
struct Person p = {"Alice", 25};
printf("%s
", p.name); // Kasutatakse täppoperaatorit
- Nooleoperaator (
->
) — kasutatakse siis, kui struktuur on osuti kaudu hallatav.
struct Person p = {"Alice", 25};
struct Person *ptr = &p;
printf("%s
", ptr->name); // Kasutatakse nooleoperaatorit
Kasutuspõhimõtted:
- Kui töötad otse struktuurimuutujaga → täppoperaator.
- Kui töötad osuti kaudu → nooleoperaator.
K2. Kas nooleoperaatorit saab kasutada massiividega?
V: Nooleoperaator töötab ainult struktuuri osutitega. Seda ei saa kasutada otse massiividega, kuid kui massiivi elemendid on struktuurid, siis saab osutit kombineerida nooleoperaatoriga.
Näide: Massiiv ja nooleoperaator
#include <stdio.h>
#include <string.h>
struct Person {
char name[20];
int age;
};
int main() {
struct Person people[2] = {{"Alice", 25}, {"Bob", 30}};
struct Person *ptr = people;
printf("%s, %d
", ptr->name, ptr->age); // Nooleoperaator
ptr++; // Liigu järgmise elemendi juurde
printf("%s, %d
", ptr->name, ptr->age);
return 0;
}
Tulem:
Alice, 25
Bob, 30
Nagu näha, saab massiivi elementide puhul kasutada osutit koos nooleoperaatoriga.
K3. Millele tähelepanu pöörata nooleoperaatori kasutamisel?
V: Kasutades nooleoperaatorit, jälgi eelkõige järgmisi punkte:
- Väldi NULL-osuti kasutamist:
Kontrolli alati enne kasutamist, et osuti ei oleks NULL.
if (ptr != NULL) {
ptr->age = 20;
}
- Kontrolli mälu eraldamist:
Veendu, etmalloc
või muu mälufunktsioon oleks edukalt töötanud.
ptr = (struct Data*)malloc(sizeof(struct Data));
if (ptr == NULL) {
printf("Mälu eraldamine ebaõnnestus.
");
}
- Väldi mäluleke:
Vabasta alati dünaamiliselt eraldatud mälu.
free(ptr);
K4. Kuidas kasutada nooleoperaatorit, kui struktuur sisaldab osutit?
V: Kui struktuuris endas on osuti, saab sellele samuti lühidalt ligi nooleoperaatori abil.
Näide: Struktuur osutiga
#include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
struct Node *next;
};
int main() {
struct Node *head = (struct Node*)malloc(sizeof(struct Node));
head->data = 10;
head->next = NULL;
printf("Data: %d
", head->data); // Nooleoperaatori kasutamine
free(head); // Mälu vabastamine
return 0;
}
Tulem:
Data: 10
Selles näites pääsetakse struktuuris oleva osuti kaudu andmetele lihtsalt ligi nooleoperaatorit kasutades.

7. Kokkuvõte ja järgmised sammud
Nooleoperaatori peamiste punktide kordamine
Selles artiklis selgitasime põhjalikult C-keele nooleoperaatorit (->
) alates põhitõdedest kuni praktiliste rakendusteni. Toome välja olulisemad punktid:
- Nooleoperaatori roll ja kasutamine:
- Lihtne viis struktuuri liikmete juurde pääsemiseks osuti kaudu.
- Täppoperaatori (
.
) ja nooleoperaatori erinevuste mõistmine võimaldab neid õigesti kasutada.
- Praktilised näited:
- Lingitud loendid ja puustruktuurid: andmestruktuuride juures on nooleoperaator hädavajalik.
- Dünaamiline mäluhaldus: kombineerides
malloc
ja nooleoperaatori, saab luua paindlikke programme.
- Tähelepanekud ja veakäsitlus:
- NULL-osuti ja mäluleke: nägime, kuidas neid probleeme vältida.
- Turvalise koodi nipid: soovitame kasutada ka statiilise analüüsi tööriistu.
- Korduma kippuvad küsimused:
- Nooleoperaatori kasutust ja parimaid praktikaid käsitleti Q&A vormis, et toetada praktilist mõistmist.
Järgmised teemad õppimiseks
Et nooleoperaatori kasutust veelgi paremini mõista, soovitame edasi uurida järgmisi teemasid:
- Osutite ja struktuuride edasine kasutamine:
- Mitmekordsed osutid ja funktsiooni osutid keerukamate programmide loomiseks.
- Dünaamilised massiivid ja mäluhalduse täiustamine.
- C-keele mäluhaldus:
calloc
jarealloc
kasutamine mälu paindlikuks haldamiseks.- Debugimise tehnikad mäluleke ja segfault vigade vältimiseks.
- Andmestruktuurid ja algoritmid:
- Lingitud loendid, virnad, järjekorrad ja puustruktuurid.
- Sortimis- ja otsingu-algoritmid struktuuridega.
- Programmi optimeerimine:
- Koodi optimeerimise tehnikad ja jõudluse tõstmine.
- Koodi ülevaatused ja statiilise analüüsi tööriistade kasutamine.
Praktilised harjutused ja projektid
Õppimise süvendamiseks kirjuta koodi ja harjuta. Näiteks:
- Lingitud loendite haldus:
- Lisa, kustuta ja otsi elemente programmis.
- Kahendotsingupuu loomine ja otsing:
- Rakenda rekursiooni abil puu sisestamise ja otsimise algoritme.
- Järjekorra ja virna teostus:
- Ehita dünaamilise mäluhalduse abil efektiivseid andmestruktuure.
- Failihaldussüsteemi prototüüp:
- Loo lihtne andmebaasirakendus struktuuride ja osutitega.
Lõppsõna
Nooleoperaator on hädavajalik, kui kirjutad C-keeles koodi, mis ühendab struktuurid ja osutid. Selles artiklis vaatasime põhikasutust, praktilisi näiteid ja levinud veakohti.
Programmeerimisoskuse parandamiseks kirjuta koodi, lahenda vigu ja õpi kogemuse kaudu. Selle artikli põhjal saad edasi liikuda keerukamate teemade juurde, näiteks osutite laiendatud kasutus ja andmestruktuurid.
Nii kujundad tugevad praktilised oskused C-keeles.

8. Viited ja lisamaterjalid
Veebiallikad
Kui soovid C-keele ja nooleoperaatori kohta veelgi rohkem teada saada, soovitame järgmisi veebiallikaid:
- Käsiraamat ja viited
- Veebisait: cppreference.com (ingliskeelne)
- Sisu: C- ja C++ standardteegi viited, sealhulgas nooleoperaatori ja seotud funktsioonide selgitused.
- Online-kompilaatorid ja silurid
- Veebisait: OnlineGDB
- Sisu: Keskkond, kus saab brauseris C-koodi käivitada ja siluda. Kasulik testimiseks ja vigade parandamiseks.
Raamatud
Kui soovid C-keele õppimisse süvitsi minna, on abiks järgmised raamatud:
- Autor: Boyo Shibata
- Kirjeldus: Populaarne sissejuhatav raamat algajatele, hõlmab põhjalikult ka struktuure ja osuteid.
- Autor: Kazuya Maebashi
- Kirjeldus: Spetsialiseeritud raamat osutitest ja nende kasutamisest, sisaldab ka nooleoperaatori rakendusnäiteid.
- Autorid: Brian W. Kernighan, Dennis M. Ritchie
- Kirjeldus: Klassikaline C-keele õpik, mis käsitleb põhjalikult osutite ja struktuuride kasutust.
Näidiskoodi allalaadimine
Praktilised harjutussaidid
- paiza Learning
- URL: https://paiza.jp
- Sisu: Veebiplatvorm, kus saab lahendada praktilisi programmeerimisülesandeid. Sisaldab ka palju C-keele harjutusi.
- AtCoder
- URL: https://atcoder.jp
- Sisu: Võistlusprogrammeerimise keskkond, kus harjutatakse algoritme ja andmestruktuure. Ka nooleoperaatoriga seotud ülesanded.