Osoittimet C:ssä: Mikä on osoitin C-ohjelmoinnissa? Tyypit
⚡ Älykäs yhteenveto
C-kielen osoittimet ovat muuttujia, jotka tallentavat toisen muuttujan muistiosoitteen. Ne mahdollistavat dynaamisen muistin allokoinnin, tehokkaan taulukoiden ja merkkijonojen käsittelyn sekä monimutkaiset tietorakenteet käyttämällä address-of- ja dereference-operaattoreita arvojen lukemiseen tai muokkaamiseen.

Mikä on osoitin C-kielessä?
A osoitin C-kielessä on muuttuja, joka tallentaa toisen muuttujan osoitteen. Osoitin voi myös viitata toiseen osoittimeen tai funktioon. Osoitinta voidaan kasvattaa tai vähentää osoittamaan seuraavaan tai edelliseen muistipaikkaan. Osoittimen tarkoituksena on säästää muistitilaa ja saavuttaa nopeampi suoritusaika.
Osoittimien käyttäminen C:ssä
Jos deklaroimme int-tyyppisen muuttujan v, v tallentaa arvon. Jokaisella muuttujalla on arvon lisäksi myös osoite, eli se sijainti muistissa. Osoitteen saa selville lisäämällä et-merkin (&) muuttujan nimen eteen. Jos tulostat muuttujan osoitteen, se näyttää satunnaisluvulta, joka voi vaihdella suoritusajasta toiseen.
Arvon tallentamisen sijaan osoitin tallentaa muuttujan osoitteen. Esimerkiksi:
int *y = &v;
| MUUTTAVA | OSOITIN |
|---|---|
| A arvo varastoitu a nimeltään tallennus-/muistiosoite. | A muuttuja että pisteet tallennus-/muistiosoite toinen muuttuja. |
Osoittimen ilmoittaminen
Kuten muuttujat, osoittimet sisään C ohjelmointi on ilmoitettava ennen kuin niitä voidaan käyttää. Osoitinilmoitus on seuraavan muotoinen:
data_type *pointer_variable_name;
Täällä tietotyyppi on osoittimen perustyyppi ja ilmaisee muuttujan tyypin, johon osoitin osoittaa. Tähti (*), sama symboli kuin kertolaskussa, on epäsuora operaattori, joka määrittää osoittimen. Joitakin kelvollisia osoittimen määrittelyjä ovat:
int *ptr_thing; /* pointer to an integer */ int *ptr1, thing; /* ptr1 points to an int; thing is an int */ double *ptr2; /* pointer to a double */ float *ptr3; /* pointer to a float */ char *ch1; /* pointer to a character */
Osoittimen alustaminen
Osoittimen määrittämisen jälkeen alustamme sen muuttujaosoitteella. Jos osoitinta ei ole alustattu, tulokset voivat olla arvaamattomia ja mahdollisesti katastrofaalisia. Saadaksesi muuttujan osoitteen, käytä et-merkkiä (&) muuttujan nimen edessä:
pointer = &variable;
Yksinkertainen ohjelma, joka havainnollistaa osoittimen toimintaa, on annettu alla:
#include <stdio.h> int main() { int a = 10; // variable declaration int *p; // pointer variable declaration p = &a; // store address of a in pointer p printf("Address stored in p is: %x\n", p); // access the address printf("Value stored in p is: %d\n", *p); // access the value return 0; }
lähtö:
Address stored in p is: 60ff08 Value stored in p is: 10
| OperaTor | Merkitys |
|---|---|
| * | Palvelee kahta tarkoitusta: määrittää osoittimen ja palauttaa viitatun muuttujan arvon (dereferenssi). |
| & | Palvelee yhtä tarkoitusta: palauttaa muuttujan osoitteen. |
Osoittimien tyypit C:ssä
Nollaosoitin
Luomme null-osoittimen antamalla sille arvon NULL määrittelyn aikana. Tämä on hyödyllistä, kun osoittimelle ei ole vielä annettu osoitetta. Null-osoitin sisältää aina arvon 0:
#include <stdio.h> int main() { int *p = NULL; // null pointer printf("The value inside variable p is: %x", p); return 0; }
Tyhjä osoitin
Tyhjäosoitin, jota kutsutaan myös yleiseksi osoittimeksi, ei ole varustettu standarditietotyypillä. Se luodaan avainsanalla void ja se voi tallentaa minkä tahansa muuttujan osoitteen:
#include <stdio.h> int main() { void *p = NULL; // void pointer printf("The size of pointer is: %d\n", sizeof(p)); return 0; }
Villi osoitin
Osoitinta kutsutaan villiksi osoittimeksi, jos sitä ei ole alustettu mihinkään. Nämä osoittimet eivät ole tehokkaita, koska ne saattavat osoittaa tuntemattomaan muistipaikkaan, mikä voi aiheuttaa ongelmia ja kaataa ohjelman. Ole aina varovainen villien osoittimien kanssa:
#include <stdio.h> int main() { int *p; // wild pointer printf("%d", *p); return 0; }
Muita C-kielen osoittimien tyyppejä ovat roikkuva osoitin, kompleksiosoitin, lähiosoitin, kaukoosoitin ja valtava osoitin.
Suorat ja epäsuorat yhteysosoittimet
C-kielessä muuttujan sisällön käyttämiseen ja muokkaamiseen on kaksi samanarvoista tapaa. Suora käyttö käyttää muuttujan nimeä suoraan, kun taas epäsuora käyttö käyttää osoitinta muuttujaan:
#include <stdio.h> int var = 1; /* declare and initialize an int variable */ int *ptr; /* declare a pointer to int */ int main(void) { ptr = &var; /* point ptr to var */ printf("\nDirect access, var = %d", var); printf("\nIndirect access, var = %d", *ptr); *ptr = 48; /* change var through the pointer */ printf("\nIndirect access, var = %d", *ptr); return 0; }
Osoittimen aritmetiikka C:ssä
Kun työskentelet osoittimien kanssa, noudata seuraavia prioriteettisääntöjä. Operaattoreilla * ja & on sama prioriteetti kuin unaarioperaattoreilla (negaatio !, lisäys ++, vähennys –). Samassa lausekkeessa unaarioperaattorit *, &, !, ++ ja — arvioidaan oikealta vasemmalle. Jos osoitin P osoittaa muuttujaan X, niin *P:tä voidaan käyttää kaikkialla, missä X voidaan kirjoittaa. Seuraavat lausekkeet ovat samanarvoisia:
| Ilmaisu | Vastaava ilmaisu |
|---|---|
| Y = *P + 1 | Y = X + 1 |
| *P = *P + 10 | X = X + 10 |
| *P + = 2 | X + = 2 |
| ++*P | ++X |
| (*P)++ | X++ |
Viimeisessä tapauksessa sulkeet ovat pakollisia: koska unaarioperaattorit * ja ++ lasketaan oikealta vasemmalle, ilman sulkeita osoitin P kasvatettaisiin, ei sen osoittamaa objektia. Osoittimille käytettävissä olevat aritmeettiset operaatiot ovat sijoitus, lisäys ja vähennys sekä yhteen- tai alalasku.trackokonaislukuoffsetin asettaminen, joka siirtää osoitinta kyseisen määrän elementtejä (jokainen askel on yhtä suuri kuin perustyypin koko tavuina).
C-osoittimet ja taulukot esimerkkeineen
Perinteisesti taulukon alkioihin päästään indeksin avulla, mutta osoittimet tekevät tästäkin helppoa. Taulukon nimeen asetettu osoitin osoittaa ensimmäiseen alkioon:
#include <stdio.h> int main() { int a[5] = {1, 2, 3, 4, 5}; // array initialization int *p; // pointer declaration p = a; // p points to the first element; same as &a[0] for (int i = 0; i < 5; i++) { printf("%d\n", *p); // print element p++; // move to the next element } return 0; }
Luvun lisääminen osoittimeen siirtää sitä tietyn määrän alkioita eteenpäin. Jos p osoittaa muistipaikkaan 0, niin p + 1 siirtää osoittimen osoittamaan muistipaikkaan 1.
C Osoittimet ja merkkijonot esimerkein
Merkkijono on taulukko char-objekteja, jotka päättyvät null-merkkiin '\0'. Voimme käsitellä merkkijonoja osoittimien avulla:
#include <stdio.h> #include <string.h> int main() { char str[] = "Hello Guru99!"; char *p; p = str; printf("First character is: %c\n", *p); p = p + 1; printf("Next character is: %c\n", *p); p = str; // reset the pointer for (int i = 0; i < strlen(str); i++) { printf("%c\n", *p); p++; } return 0; }
Toinen tapa käsitellä merkkijonoja on osoittimien taulukon avulla:
#include <stdio.h> int main() { char *materials[] = {"iron", "copper", "gold"}; for (int i = 0; i < 3; i++) printf("%s\n", materials[i]); return 0; }
Osoittimien edut C:ssä
- Osoittimet ovat hyödyllisiä muistipaikkojen suoraan käyttämiseen.
- Ne tarjoavat tehokkaan tavan käyttää taulukon elementtejä.
- Niitä käytetään dynaamiseen muistin allokointiin ja vapauttamiseen.
- Niitä käytetään monimutkaisten tietorakenteiden, kuten linkitettyjen listojen, graafien ja puiden, muodostamiseen.
Osoittimien haitat C:ssä
- Osoittimet ovat hieman monimutkaisia ymmärtää.
- Ne voivat aiheuttaa virheitä, kuten segmentointivirheitä tai pääsyä tahattomaan muistipaikkaan.
- Osoittimelle annettu väärä arvo voi aiheuttaa muistin vioittumista.
- Osoittimet ovat myös vastuussa muistivuotoista, jos muistia ei vapauteta.
- Ohjelmoijan vastuulla on käsitellä osoitinta huolellisesti.
