- 1 1. Sissejuhatus
- 2 2. Struktuuride ja pointerite põhitõed
- 3 3. Mis on struktuur?
- 4 Kokkuvõte
- 5 4. Pointerite põhitõed
- 6 Kokkuvõte
- 7 5. Struktuuride ja pointerite kombinatsioon
- 8 Kokkuvõte
- 9 6. Funktsioonide ja struktuuripointerite koostöö
- 10 7. Pointerite kasutamine struktuuri sees
- 11 8. Praktiline näide: ühendatud loend
- 12 9. Levinud vead ja silumine
- 13 10. Kokkuvõte
- 14 Lõppsõna
1. Sissejuhatus
C-keelt kasutatakse laialdaselt süsteemiarenduses ja manustatud programmides. Nende seas on „struktuurid” ja „pointerid” hädavajalikud elemendid, mis võimaldavad tõhusat andmehaldust ja mäluga manipuleerimist. Käesolevas artiklis selgitame neid mõisteid põhitasemest kuni rakenduseni.
Seda artiklit lugedes mõistad struktuuride ja pointerite rolli C-keeles ning õpid nende kasutamist praktiliste koodinäidete abil. Ka algajatele on see kergesti arusaadav, kuna liigume edasi konkreetsete näidete toel.
2. Struktuuride ja pointerite põhitõed
Mis on struktuur?
Struktuur on andmestruktuur, mis koondab mitu erinevat tüüpi andmevälja üheks tervikuks. Näiteks inimese info (nimi, vanus, pikkus jne) saab hallata ühe üksusena.
Alljärgnev koodinäide näitab struktuuri põhilist definitsiooni ja kasutust.
#include <stdio.h>
// Struktuuri definitsioon
struct Person {
char name[50];
int age;
float height;
};
int main() {
struct Person person1; // Struktuuri muutuja deklareerimine
// Andmete määramine
strcpy(person1.name, "Taro");
person1.age = 20;
person1.height = 170.5;
// Andmete kuvamine
printf("Nimi: %sn", person1.name);
printf("Vanus: %dn", person1.age);
printf("Pikkus: %.1f cmn", person1.height);
return 0;
}
Selles näites defineeritakse struktuur Person
, mis ühendab kolm erinevat tüüpi andmevälja ühte struktuuri. Nii saab seotud andmeid hallata ühtselt.
Mis on pointer?
Pointer on muutuja, mis salvestab teise muutuja mäluaadressi. Seda kasutatakse programmi sees dünaamilise mälu käsitlemiseks. Allpool on pointeri põhiline näide.
#include <stdio.h>
int main() {
int a = 10;
int *p; // Pointeri deklareerimine
p = &a; // Pointerile omistatakse muutuja a aadress
printf("Muutuja a väärtus: %dn", a);
printf("Pointer p viidatav väärtus: %dn", *p);
return 0;
}
Selles näites kasutatakse pointermuutujat p
, et pääseda juurde muutuja a
väärtusele. Pointerid on võimsad mäluhalduse tööriistad, kuid valesti kasutades võivad põhjustada vigu või mälulekkeid.
Struktuuride ja pointerite seos
Kombineerides struktuurid ja pointerid, on võimalik saavutada paindlikum andmete haldus. Sellest räägime täpsemalt järgmistes osades, kuid põhitõdede mõistmine aitab edasi liikuda rakenduste poole.
3. Mis on struktuur?
Struktuuri põhialused
Struktuur on andmestruktuur, mis ühendab mitu erinevat tüüpi andmevälja üheks tervikuks. C-keeles kasutatakse seda sageli seotud info rühmitamiseks ja andmehalduse lihtsustamiseks.
Alljärgnevalt on näidatud struktuuri definitsioon.
struct Person {
char name[50];
int age;
float height;
};
Selles näites defineeritakse Person
struktuur, mis sisaldab järgmisi kolme välja:
name
: salvestab nime stringina (massiivina)age
: salvestab vanuse täisarvunaheight
: salvestab pikkuse ujukomaarvuna
Struktuuri definitsioon on „tüübi” deklaratsioon, mida kasutatakse konkreetsete muutujate loomiseks.
Struktuurimuutuja deklareerimine ja kasutamine
Struktuuri kasutamiseks tuleb kõigepealt muutuja deklareerida. Näiteks:
#include <stdio.h>
#include <string.h>
struct Person {
char name[50];
int age;
float height;
};
int main() {
struct Person person1; // Struktuuri muutuja deklareerimine
// Andmete määramine
strcpy(person1.name, "Taro");
person1.age = 20;
person1.height = 170.5;
// Andmete kuvamine
printf("Nimi: %sn", person1.name);
printf("Vanus: %dn", person1.age);
printf("Pikkus: %.1f cmn", person1.height);
return 0;
}
Selles koodis deklareeritakse struktuurimuutuja person1
ja määratakse selle liikmetele väärtused.
Struktuuri initsialiseerimine
Struktuurimuutujat saab ka deklareerimise hetkel initsialiseerida.
struct Person person2 = {"Hanako", 25, 160.0};
Nii saab väärtused korraga määrata ja koodi lihtsustada.
Struktuurimassiiv
Mitme andmeüksuse haldamiseks saab kasutada struktuuride massiivi.
struct Person people[2] = {
{"Taro", 20, 170.5},
{"Hanako", 25, 160.0}
};
for (int i = 0; i < 2; i++) {
printf("Nimi: %s, Vanus: %d, Pikkus: %.1f cmn", people[i].name, people[i].age, people[i].height);
}
Selles näites hallatakse kahe inimese andmeid massiivina ja töödeldakse neid tsükliga.
Struktuuri edastamine funktsioonile
Struktuuri saab edastada ka funktsioonile. Näiteks:
void printPerson(struct Person p) {
printf("Nimi: %s, Vanus: %d, Pikkus: %.1f cmn", p.name, p.age, p.height);
}
See funktsioon võtab argumendina struktuuri ja kuvab selle info.
Kokkuvõte
Struktuurid on väga kasulik andmetüüp, et hallata seotud andmeid terviklikult. Põhikasutuse omandamine muudab andmete korrastamise ja neile ligipääsu tõhusamaks.
4. Pointerite põhitõed
Mis on pointer?
Pointer on C-keele võimas vahend, mis võimaldab muutuja mäluaadressi otsest käsitlemist. Selles osas selgitame pointerite põhimõtteid, deklareerimist, kasutamist ja konkreetseid näiteid.
Pointeri deklareerimine ja initsialiseerimine
Pointer deklareeritakse, lisades tüübi ette *
.
int a = 10; // Tavaline muutuja
int *p; // Pointeri deklareerimine
p = &a; // p viitab muutuja a aadressile
*p
: väljendab pointeri viidatava aadressi väärtust (indirektne viide)&a
: võtab muutujaa
aadressi (aadressioperaator)
Väärtuste muutmine pointeri abil
Järgmine näide näitab väärtuste muutmist pointeri kaudu.
#include <stdio.h>
int main() {
int a = 10;
int *p = &a;
printf("a väärtus: %dn", a);
printf("a aadress: %pn", &a);
printf("p väärtus (aadress): %pn", p);
printf("p viidatav väärtus: %dn", *p);
*p = 20;
printf("a uus väärtus: %dn", a);
return 0;
}
Selles koodis muudetakse muutuja a
väärtust pointeri p
kaudu.
Massiiv ja pointerid
Ka massiivi elementidele saab ligi pointerite abil.
#include <stdio.h>
int main() {
int arr[3] = {10, 20, 30};
int *p = arr; // Viitab massiivi esimesele elemendile
printf("1. element: %dn", *p);
printf("2. element: %dn", *(p+1));
printf("3. element: %dn", *(p+2));
return 0;
}
Selles näites kasutatakse pointerit p
massiivi elementidele ligipääsuks.
Kokkuvõte
Pointerid on C-keeles väga olulised. Need võimaldavad tõhusat mäluhaldust ja paindlikku programmide ülesehitust. Järgmisena vaatleme „5. Struktuuride ja pointerite kombinatsiooni”.
5. Struktuuride ja pointerite kombinatsioon
Struktuuripointeri põhialused
Kombineerides struktuurid ja pointerid, saab andmeid hallata veelgi paindlikumalt ja tõhusamalt. Selles osas selgitame struktuuripointerite põhikasutust ja näitame rakendusi.
Allpool on lihtne näide struktuuripointerist.
#include <stdio.h>
#include <string.h>
// Struktuuri definitsioon
struct Person {
char name[50];
int age;
float height;
};
int main() {
struct Person person1 = {"Taro", 20, 170.5};
struct Person *p = &person1;
// Ligipääs andmetele pointeri abil
printf("Nimi: %sn", p->name);
printf("Vanus: %dn", p->age);
printf("Pikkus: %.1f cmn", p->height);
// Andmete muutmine pointeri kaudu
p->age = 25;
printf("Muudetud vanus: %dn", p->age);
return 0;
}
Koostöö dünaamilise mäluga
Struktuuripointerid sobivad hästi dünaamilise mäluhaldusega, mis on mugav suure hulga andmete töötlemisel.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Person {
char name[50];
int age;
float height;
};
int main() {
struct Person *p = (struct Person *)malloc(sizeof(struct Person));
strcpy(p->name, "Hanako");
p->age = 22;
p->height = 160.0;
printf("Nimi: %sn", p->name);
printf("Vanus: %dn", p->age);
printf("Pikkus: %.1f cmn", p->height);
free(p);
return 0;
}
Massiivid ja struktuuripointerid
Kombineerides massiivid ja struktuuripointerid, saab hallata mitut üksust korraga.
#include <stdio.h>
#include <string.h>
struct Person {
char name[50];
int age;
float height;
};
int main() {
struct Person people[2] = {{"Taro", 20, 170.5}, {"Hanako", 25, 160.0}};
struct Person *p = people;
for (int i = 0; i < 2; i++) {
printf("Nimi: %sn", (p + i)->name);
printf("Vanus: %dn", (p + i)->age);
printf("Pikkus: %.1f cmn", (p + i)->height);
}
return 0;
}
Kokkuvõte
Struktuuride ja pointerite ühendamine muudab andmehalduse efektiivsemaks ja annab paindlikkust mälutöötluses. Selles osas käsitlesime põhilisi kasutusviise ja dünaamilist mäluhaldust.
6. Funktsioonide ja struktuuripointerite koostöö
Struktuuri edastamise viisid
Struktuuri saab funktsioonile edastada kahel viisil:
- Väärtusena – tehakse koopia, mis võib olla ebaefektiivne suurte andmete puhul.
- Viitena (pointeriga) – edastatakse aadress, mis säästab mälu ja võimaldab originaalandmeid otse muuta.
Väärtuse edastamise näide
#include <stdio.h>
#include <string.h>
struct Person {
char name[50];
int age;
};
void printPerson(struct Person p) {
printf("Nimi: %sn", p.name);
printf("Vanus: %dn", p.age);
}
int main() {
struct Person person1 = {"Taro", 20};
printPerson(person1);
return 0;
}
Viitena (pointeriga) edastamise näide
#include <stdio.h>
#include <string.h>
struct Person {
char name[50];
int age;
};
void updateAge(struct Person *p) {
p->age += 1;
}
void printPerson(const struct Person *p) {
printf("Nimi: %sn", p->name);
printf("Vanus: %dn", p->age);
}
int main() {
struct Person person1 = {"Hanako", 25};
printf("Enne muutmist:n");
printPerson(&person1);
updateAge(&person1);
printf("Pärast muutmist:n");
printPerson(&person1);
return 0;
}
7. Pointerite kasutamine struktuuri sees
Eelis
Struktuuri sees olevad pointerid võimaldavad paindlikku mäluhaldust ja keerukamate andmestruktuuride loomist.
Näide: dünaamiline stringihaldus
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Person {
char *name;
int age;
};
void setPerson(struct Person *p, const char *name, int age) {
p->name = (char *)malloc(strlen(name) + 1);
strcpy(p->name, name);
p->age = age;
}
void printPerson(const struct Person *p) {
printf("Nimi: %sn", p->name);
printf("Vanus: %dn", p->age);
}
void freePerson(struct Person *p) {
free(p->name);
}
8. Praktiline näide: ühendatud loend
Ühendatud loend on dünaamiline andmestruktuur, kus iga element viitab järgmisele. C-keeles rakendatakse seda struktuuride ja pointerite abil.
struct Node {
int data;
struct Node *next;
};
Nii saab dünaamiliselt elemente lisada ja eemaldada.
9. Levinud vead ja silumine
- Initsialiseerimata pointerid
- Mälulekked
- Dangling pointerid
- NULL-pointeri kasutamine
Need vead võivad põhjustada tõsiseid probleeme, seetõttu tuleb pointeritega ettevaatlik olla ning kasutada tööriistu nagu valgrind
ja gdb
.
10. Kokkuvõte
Õpitu kordamine
- Struktuurid – seotud andmete rühmitamiseks
- Pointerid – mäluaadresside otsekäsitlemiseks
- Nende kombinatsioon – efektiivseks andmehalduseks
- Funktsioonidega kasutamine – andmete jagamiseks ja muutmiseks
- Praktilised rakendused – nagu ühendatud loendid
Edasised sammud
- Kohanda näidiskoodi oma projektide jaoks
- Õpi keerukamaid andmestruktuure (puud, graafid)
- Kombineeri algoritmidega (otsing, sorteerimine)
- Harjuta silumist ja optimeerimist
Lõppsõna
C-keele struktuurid ja pointerid on olulised mõisted, mis võimaldavad luua paindlikke ja tõhusaid programme. Käesolev artikkel aitas sul õppida nende põhimõtteid ja rakendusi praktiliste näidete abil. Kasuta neid teadmisi järgmiste sammude astumiseks ja oma programmeerimisoskuste arendamiseks!