Osoittimet C:ssä: Mikä on osoitin C-ohjelmoinnissa? Tyypit
Mikä on osoitin C:ssä?
- Osoitin C:ssä on muuttuja, joka tallentaa toisen muuttujan osoitteen. Osoittimella voidaan viitata myös toiseen osoitintoimintoon. Osoitinta voidaan kasvattaa/vähentää eli osoittaa seuraavaan/edelliseen muistipaikkaan. Osoittimen tarkoitus on säästää muistitilaa ja saavuttaa nopeampi suoritusaika.
Osoittimien käyttäminen C:ssä
Jos ilmoitamme muuttujan v, jonka tyyppi on int, v itse asiassa tallentaa arvon.
v on nyt nolla.
Jokaisella muuttujalla, paitsi arvolla, on kuitenkin myös osoite (tai yksinkertaisesti sanottuna, missä se sijaitsee muistissa). Osoite voidaan noutaa laittamalla et-merkki (&) muuttujan nimen eteen.
Jos tulostat muuttujan osoitteen näytölle, se näyttää täysin satunnaiselta numerolta (lisäksi se voi vaihdella ajoittain).
Kokeillaan tätä käytännössä osoittimella C-esimerkissä
Tämän ohjelman tulos on -480613588.
Mikä nyt on osoitin? Arvon tallentamisen sijaan osoitin tallentaa muuttujan osoitteen.
Osoitinmuuttuja
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ää ohjelmassasi. Osoittimet voidaan nimetä mitä tahansa, kunhan ne noudattavat C:n nimeämissääntöjä. Osoitinilmoituksella on seuraava muoto.
data_type * pointer_variable_name;
Täällä
- tietotyyppi on C:n muuttujatyyppien osoittimen perustyyppi ja osoittaa sen muuttujan tyypin, johon osoitin osoittaa.
- Asteriski (*: sama tähti, jota käytetään kertolaskussa), joka on epäsuora operaattori, ilmoittaa osoittimen.
Katsotaanpa joitain kelvollisia osoitinmäärityksiä tässä C-osoittimien opetusohjelmassa:
int *ptr_thing; /* pointer to an integer */ int *ptr1,thing;/* ptr1 is a pointer to type integer and thing is an integer variable */ double *ptr2; /* pointer to a double */ float *ptr3; /* pointer to a float */ char *ch1 ; /* pointer to a character */ float *ptr, variable;/*ptr is a pointer to type float and variable is an ordinary float variable */
Alusta osoitin
Osoittimen ilmoittamisen jälkeen alustamme sen kuten vakiomuuttujat muuttujaosoitteella. Jos C-ohjelmoinnin osoittimia ei ole alustettu ja niitä käytetään ohjelmassa, tulokset voivat olla arvaamattomia ja mahdollisesti tuhoisia.
Saadaksemme muuttujan osoitteen, käytämme et-merkkiä (&)-operaattoria, joka sijoitetaan sen muuttujan nimen eteen, jonka osoitteen tarvitsemme. Osoittimen alustus tehdään seuraavalla syntaksilla.
Osoittimen syntaksi
pointer = &variable;
Alla on yksinkertainen ohjelma osoittimen havainnollistamiseen:
#include <stdio.h> int main() { int a=10; //variable declaration int *p; //pointer variable declaration p=&a; //store address of variable a in pointer p printf("Address stored in a variable p is:%x\n",p); //accessing the address printf("Value stored in a variable p is:%d\n",*p); //accessing the value return 0; }
lähtö:
Address stored in a variable p is:60ff08 Value stored in a variable p is:10
OperaTor | Merkitys |
---|---|
* | Palvelee 2 tarkoitusta
|
& | Palvelee vain yhtä tarkoitusta
|
Osoittimien tyypit C:ssä
Seuraavassa on erilaisia Osoittimien tyypit C:ssä:
Nollaosoitin
Voimme luoda nollaosoittimen antamalla nolla-arvon osoittimen määrityksen aikana. Tämä menetelmä on hyödyllinen, kun osoittimelle ei ole määritetty osoitetta. Nollaosoitin sisältää aina arvon 0.
Seuraava ohjelma havainnollistaa nollaosoittimen käyttöä:
#include <stdio.h> int main() { int *p = NULL; //null pointer printf(“The value inside variable p is:\n%x”,p); return 0; }
lähtö:
The value inside variable p is: 0
Tyhjä osoitin
In C ohjelmointi, tyhjää osoitinta kutsutaan myös yleiseksi osoittimeksi. Sillä ei ole vakiotietotyyppiä. Void-osoitin luodaan avainsanalla void. Sitä voidaan käyttää minkä tahansa muuttujan osoitteen tallentamiseen.
Seuraava ohjelma havainnollistaa tyhjän osoittimen käyttöä:
#include <stdio.h> int main() { void *p = NULL; //void pointer printf("The size of pointer is:%d\n",sizeof(p)); return 0; }
lähtö:
The size of pointer is:4
Villi osoitin
Osoittimen sanotaan olevan villi osoitin, jos sitä ei alusteta mihinkään. Tämäntyyppiset C-osoittimet eivät ole tehokkaita, koska ne voivat osoittaa johonkin tuntemattomaan muistipaikkaan, mikä voi aiheuttaa ongelmia ohjelmassamme ja se voi johtaa ohjelman kaatumiseen. Villien osoittimien kanssa työskennellessä tulee aina olla varovainen.
Seuraava ohjelma havainnollistaa villin osoittimen käyttöä:
#include <stdio.h> int main() { int *p; //wild pointer printf("\n%d",*p); return 0; }
lähtö:
timeout: the monitored command dumped core sh: line 1: 95298 Segmentation fault timeout 10s main
Muut osoittimet c:ssä ovat seuraavat:
- Riippuva osoitin
- Monimutkainen osoitin
- Lähellä osoitinta
- Kaukoosoitin
- Valtava osoitin
Suorat ja epäsuorat yhteysosoittimet
C:ssä on kaksi vastaavaa tapaa käyttää ja muokata muuttuvaa sisältöä
- Suora pääsy: käytämme suoraan muuttujan nimeä
- Epäsuora pääsy: käytämme osoitinta muuttujaan
Ymmärretään tämä alla olevan ohjelman avulla
#include <stdio.h> /* Declare and initialize an int variable */ int var = 1; /* Declare a pointer to int */ int *ptr; int main( void ) { /* Initialize ptr to point to var */ ptr = &var; /* Access var directly and indirectly */ printf("\nDirect access, var = %d", var); printf("\nIndirect access, var = %d", *ptr); /* Display the address of var two ways */ printf("\n\nThe address of var = %d", &var); printf("\nThe address of var = %d\n", ptr); /*change the content of var through the pointer*/ *ptr=48; printf("\nIndirect access, var = %d", *ptr); return 0;}
Kun ohjelma on käännetty ilman virheitä, tulos on:
Direct access, var = 1 Indirect access, var = 1 The address of var = 4202496 The address of var = 4202496 Indirect access, var = 48
Osoittimen aritmetiikka C:ssä
Osoitintoiminnot on yhteenveto seuraavassa kuvassa
Ensisijainen toiminto (ennensijaisuus)
Kun työskentelet C-osoittimien kanssa, meidän on noudatettava seuraavia prioriteettisääntöjä:
- Operaattoreilla * ja & on sama prioriteetti kuin unaarisilla operaattoreilla (negataatio!, inkrementaatio++, dekrementti–).
- Samassa lausekkeessa unaarioperaattorit *, &,!, ++, – lasketaan oikealta vasemmalle.
Jos P-osoitin osoittaa X-muuttujaan, * P:tä voidaan käyttää kaikkialla, missä X voidaan kirjoittaa.
Seuraavat ilmaisut ovat vastaavia:
int X =10 int *P = &Y; For the above code, below expressions are true
Ilmaisu | Vastaava ilmaisu |
---|---|
Y=*P+1
*P=*P+10 *P+=2 ++*P (*P)++ |
Y=X+1
X = X+10 X+=2 ++X X++ |
Jälkimmäisessä tapauksessa tarvitaan sulkuja: koska unaarioperaattorit * ja ++ lasketaan oikealta vasemmalle, ilman sulkuja osoitin P kasvaisi, ei objekti, johon P osoittaa.
Alla oleva taulukko näyttää aritmeettiset ja perustoiminnot, joita voidaan käyttää käsiteltäessä C-osoittimia
OperaTUKSEN | Selitys |
---|---|
Toimeksianto | int *P1,*P2 P1 = P2; P1 ja P2 osoittavat samaan kokonaislukumuuttujaan |
Lisäys ja vähentäminen | Int *P1; P1++;P1– ; |
Siirron lisääminen (vakio) | Näin osoitin voi siirtää N elementtiä taulukossa. Osoitin kasvaa tai pienenee N kertaa muuttujan tyypin tavumäärä. P1+5; |
C Osoittimet ja taulukot esimerkkeineen
Perinteisesti käytämme taulukon elementtejä sen indeksin avulla, mutta tämä menetelmä voidaan poistaa käyttämällä osoittimia. Osoittimet helpottavat jokaisen taulukon elementin käyttöä.
#include <stdio.h> int main() { int a[5]={1,2,3,4,5}; //array initialization int *p; //pointer declaration /*the ptr points to the first element of the array*/ p=a; /*We can also type simply ptr==&a[0] */ printf("Printing the array elements using pointer\n"); for(int i=0;i<5;i++) //loop for traversing array elements { printf("\n%x",*p); //printing array elements p++; //incrementing to the next element, you can also write p=p+1 } return 0; }
lähtö:
1 2 3 4 5
Tietyn luvun lisääminen osoittimeen siirtää osoittimen sijainnin summaustoiminnolla saatuun arvoon. Oletetaan, että p on osoitin, joka tällä hetkellä osoittaa muistipaikkaan 0, jos suoritamme seuraavan summausoperaation, p+1, niin se suoritetaan tällä tavalla:
Koska p osoittaa tällä hetkellä sijaintiin 0 luvun 1 lisäämisen jälkeen, arvosta tulee 1, ja siten osoitin osoittaa muistipaikkaan 1.
C Osoittimet ja merkkijonot esimerkein
Merkkijono on joukko char-objekteja, jotka päättyvät nollamerkkiin \ 0. Voimme käsitellä merkkijonoja osoittimilla. Tämä osoitin C-esimerkissä selittää tämän osan
#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); printf("Printing all the characters in a string\n"); p=str; //reset the pointer for(int i=0;i<strlen(str);i++) { printf("%c\n",*p); p++; } return 0; }
lähtö:
First character is:H Next character is:e Printing all the characters in a string H e l l o G u r u 9 9 !
Toinen tapa käsitellä merkkijonoja on käyttää osoittimia, kuten seuraavassa ohjelmassa:
#include <stdio.h> int main(){ char *materials[ ] = { "iron", "copper", "gold"}; printf("Please remember these materials :\n"); int i ; for (i = 0; i < 3; i++) { printf("%s\n", materials[ i ]);} return 0;}
lähtö:
Please remember these materials: iron copper gold
Osoittimien edut C:ssä
- Osoittimet ovat hyödyllisiä muistipaikkojen hakemisessa.
- Osoittimet tarjoavat tehokkaan tavan päästä käsiksi taulukkorakenteen elementteihin.
- Osoittimia käytetään dynaamiseen muistin varaamiseen ja purkamiseen.
- Osoittimia käytetään monimutkaisten tietorakenteiden muodostamiseen, kuten linkitetty lista, kaavio, puu jne.
Osoittimien haitat C:ssä
- Osoittimet ovat hieman monimutkaisia ymmärtää.
- Osoittimet voivat johtaa erilaisiin virheisiin, kuten segmentointivirheisiin, tai voivat käyttää muistipaikkaa, jota ei tarvita ollenkaan.
- Jos osoittimelle annetaan väärä arvo, se voi aiheuttaa muistin vioittumista.
- Osoittimet ovat myös vastuussa muistivuotoja.
- Osoittimet ovat verrattain hitaampia kuin muuttujat.
- Ohjelmoijien on erittäin vaikea työskennellä osoittimien kanssa; siksi ohjelmoijan vastuulla on käsitellä osoitinta huolellisesti.
Yhteenveto
- Osoitin ei ole muuta kuin muistipaikka, johon tiedot tallennetaan.
- Osoittimella päästään muistipaikkaan.
- On olemassa erilaisia osoittimia, kuten nollaosoitin, villi osoitin, tyhjä osoitin ja muun tyyppisiä osoittimia.
- Osoittimia voidaan käyttää taulukon ja merkkijonon kanssa elementtien käyttämiseksi tehokkaammin.
- Voimme luoda funktioosoittimia kutsuaksemme funktiota dynaamisesti.
- Aritmeettisia operaatioita voidaan tehdä osoittimella, joka tunnetaan osoitinaritmetiikkana.
- Osoittimet voivat myös osoittaa toimintoon, mikä helpottaa eri funktioiden kutsumista, kun määritellään osoittimien joukko.
- Kun haluat käsitellä erilaisia muuttujan tietotyyppejä, voit käyttää typecast void -osoitinta.