C ++

Kako koristiti C ++ pokazivače

Kako koristiti C ++ pokazivače
Sjećanje računala dugačak je niz stanica. Veličina svake stanice naziva se bajt. Bajt je prostor koji zauzima engleski znak abecede. Objekt u uobičajenom smislu uzastopni je niz bajtova u memoriji. Svaka ćelija ima adresu, koja je cijeli broj, obično napisana u heksadecimalnom obliku. Tri su načina pristupa objektu u memoriji. Objektu se može pristupiti pomoću onoga što je poznato kao pokazivač. Može mu se pristupiti pomoću onoga što je poznato kao referenca. Još uvijek mu se može pristupiti pomoću identifikatora. Fokus ovog članka je na korištenju pokazivača i referenci. U C ++-u postoje usmjereni objekt i objekt pokazivača. Šiljati predmet ima predmet interesa. Objekt pokazivača ima adresu usmjerenog objekta.

Morate imati osnovno znanje iz jezika C ++, uključujući njegove identifikatore, funkcije i nizove; razumjeti ovaj članak.

Objekt pokazivača i šiljati objekt imaju svaki svoj identifikator.

Adresa operatora, &

Ovo je unarni operator. Kad ga slijedi identifikator, vraća adresu objekta identifikatora. Razmotrite sljedeću izjavu:

int ptdInt;

Ispod je kôd, sljedeći izraz vratit će adresu koju je identificirao ptdInt:

& ptdInt

Ne morate znati točnu adresu (broj) dok kodirate.

Indirektni operator, *

Ovo je unarni operator u kontekstu pokazivača. Obično se upisuje ispred identifikatora. Ako se koristi u deklaraciji identifikatora, tada je identifikator objekt pokazivača koji sadrži samo adresu istaknutog objekta. Ako se koristi ispred identifikatora objekta pokazivača, da bi se nešto vratilo, tada je vraćena vrijednost vrijednost istaknutog objekta.

Stvaranje pokazivača

Pogledajte sljedeći segment koda:

plutati ptdFloat;
float * ptrFloat;
ptrFoat = &ptdFloat;

Segment započinje deklaracijom šiljatog objekta, ptdFloat. ptdFloat je identifikator, koji samo identificira plutajući objekt. Stvarni objekt (vrijednost) mogao mu je biti dodijeljen, ali u ovom slučaju nije mu dodijeljeno ništa. Sljedeća u segmentu je deklaracija pokazivačkog objekta. Indirektni operator ispred ovog identifikatora znači da mora držati adresu usmjerenog objekta. Tip objekta, plutajući na početku izjave, znači da je šiljati objekt lebdeći. Objekt pokazivača uvijek je istog tipa kao i šiljati objekt. ptrFoat je identifikator koji samo identificira pokazivački objekt.

U posljednjoj izjavi koda, objektu pokazivača dodjeljuje se adresa usmjerenog objekta. Imajte na umu upotrebu adrese operatora, &.

Posljednja izjava (redak) gore pokazuje, da nakon deklariranja pokazivačkog objekta bez inicijalizacije, ne treba vam operator indirekcije, kada ga morate inicijalizirati. Zapravo je sintaksička pogreška uporaba indirektnog operatora u trećem (posljednjem) retku.

Objekt pokazivača može se deklarirati i inicijalizirati usmjerenim objektom u jednoj naredbi, kako slijedi:

plutati ptdFloat;
float * ptrFoat = &ptdFloat;

Prvi redak prethodnog i ovog segmenta koda isti su. Drugi i treći redak prethodnog segmenta koda ovdje su kombinirani u jednu izjavu.

Primijetite u gornjem kodu da se prilikom deklariranja i inicijalizacije pokazivačkog objekta mora koristiti operator indirektnosti. Međutim, ne koristi se ako se inicijalizacija treba obaviti nakon toga. Objekt pokazivača inicijalizira se adresom usmjerenog objekta.

U sljedećem segmentu koda, indirektni operator koristi se za vraćanje sadržaja usmjerenog objekta.

int ptdInt = 5;
int * ptrInt = &ptdInt;
cout << *ptrInt << '\n';

Izlaz je 5.

U posljednjoj izjavi ovdje, posredni operator je korišten za vraćanje vrijednosti na koju upućuje identifikator pokazivača. Dakle, kada se koristi u deklaraciji, identifikator indirektnog operatora zadržava adresu usmjerenog objekta. Kada se koristi u povratnom izrazu, u kombinaciji s identifikatorom pokazivača, operator indirekcije vraća vrijednost usmjerenog objekta.

Dodjeljivanje nule pokazivaču

Objekt pokazivača uvijek treba imati tip šiljatog objekta. Pri deklariranju pokazivačkog objekta mora se koristiti vrsta podataka usmjerenog objekta. Međutim, vrijednost decimalne nule može se dodijeliti pokazivaču kao u sljedećem segmentu koda:

int ptdInt = 5;
int * ptrInt;
ptrInt = 0;
ili u segmentu,
int ptdInt = 5;
int * ptrInt = 0;

U oba slučaja, pokazivač (identifikator) naziva se null pokazivač; što znači, nigdje ne upućuje. Odnosno, nema adresu niti jednog šiljatog predmeta. Ovdje je 0 decimalna nula, a ne heksadecimalna nula. Heksadecimalna nula ukazivala bi na prvu adresu računalne memorije.

Ne pokušavajte dobiti vrijednost na koju ukazuje null pokazivač. Ako to pokušate, program se može kompajlirati, ali se možda neće izvršiti.

Ime niza kao konstantni pokazivač

Razmotrite sljedeći niz:

int arr [] = 000, 100, 200, 300, 400;

Ime niza, arr je zapravo identifikator koji ima adresu prvog elementa niza. Sljedeći izraz vraća prvu vrijednost u polju:

* dolazak

S nizom, operator prirasta, ++ ponaša se drugačije. Umjesto dodavanja 1, zamjenjuje adresu pokazivača adresom sljedećeg elementa u polju. Međutim, ime niza je stalni pokazivač; što znači da se njegov sadržaj (adresa) ne može mijenjati ili povećavati. Dakle, za povećanje, početna adresa niza mora se dodijeliti nestalnom pokazivaču na sljedeći način:

int * ptr = arr;

Sada se ptr može povećati kako bi ukazao na sljedeći element niza. ptr je ovdje deklariran kao objekt pokazivača. Bez * ovdje, to ne bi bio pokazivač; to bi bio identifikator koji sadrži int objekt, a ne memorijsku adresu.

Sljedeći segment koda napokon upućuje na četvrti element:

++ptr;
++ptr;
++ptr;

Sljedeći kod daje četvrtu vrijednost niza:

int arr [] = 000, 100, 200, 300, 400;
int * ptr = arr;
++ptr;
++ptr;
++ptr;
cout << *ptr << '\n';

Izlaz je 300.

Naziv funkcije kao identifikator

Ime funkcije je identifikator funkcije. Razmotrite sljedeću definiciju funkcije:

int fn ()

cout << "seen" << '\n';
povratak 4;

fn je identifikator funkcije. Izraz,

& fn

vraća adresu funkcije u memoriju. fn je poput šiljatog predmeta. Sljedeća deklaracija deklarira pokazivač na funkciju:

int (* func) ();

Identifikator za šiljasti objekt i identifikator za pokazivački objekt različiti su. func je pokazivač na funkciju. fn je identifikator funkcije. I tako, func se može usmjeriti na fn kako slijedi:

func = &fn;

Vrijednost (sadržaj) func je adresa fn. Dva identifikatora mogla su se povezati s inicijalizacijskom izjavom kako slijedi:

int (* func) () = &fn;

Obratite pažnju na razlike i sličnosti u rukovanju pokazivačima na funkcije i skalarnim pokazivačima. func je pokazivač na funkciju; to je šiljasti objekt; deklarira se drugačije od skalarnog pokazivača.

Funkcija se može nazvati pomoću,

fn ()
ili
func ()

Ne može se nazvati s * func ().

Kada funkcija ima parametre, druge zagrade imaju vrste parametara i ne moraju imati identifikatore parametara. Sljedeći program to ilustrira:

#include
pomoću prostora imena std;
float fn (float fl, int in)

povratak fl;

int main ()

float (* func) (float, int) = &fn;
float val = func (2.5, 6);
cout << val << '\n';
return 0;

Izlaz je 2.5.

C ++ referenca

Upućivanje na C ++ samo je način da se sinonim (drugo ime) proizvede za identifikator. Koristi operator &, ali ne na isti način na koji se & koristi za pokazivače. Razmotrite sljedeći segment koda:

int myInt = 8;
int & yourInt = myInt;
cout << myInt << '\n';
cout << yourInt << '\n';

Izlaz je:

8
8

Prva naredba inicijalizira identifikator, myInt; ja.e. myInt je deklariran i stvoren da zadrži vrijednost, 8. Druga izjava čini novi identifikator, yourInt sinonimom za myInt. Da bi se to postiglo, operator & postavlja se između vrste podataka i novog identifikatora u deklaraciji. Izjave cout-a pokazuju da su dva identifikatora sinonimi. Da biste vratili vrijednost u ovom slučaju, ne trebate joj prethoditi sa * . Samo upotrijebite identifikator.

myInt i yourInt ovdje nisu dva različita objekta. To su dva različita identifikatora koji upućuju (identificiraju) isto mjesto u memoriji čija je vrijednost 8. Ako se vrijednost myInt promijeni, vrijednost yourInt također će se automatski promijeniti. Ako se vrijednost yourInt promijeni, vrijednost myInt također će se automatski promijeniti.

Reference su istog tipa.

Upućivanje na funkciju

Kao što možete imati referencu na skalara, tako možete imati referencu na funkciju. Međutim, kodiranje reference na funkciju razlikuje se od kodiranja reference na skalar. Sljedeći program to ilustrira:

#include
pomoću prostora imena std;
float fn (float fl, int in)

povratak fl;

int main ()

float (& func) (float, int) = fn;
float val = func (2.5, 6);
cout << val << '\n';
return 0;

Izlaz je 2.5.

Obratite pažnju na prvu izjavu u glavnoj funkciji, koja func čini sinonimom fn. Oboje upućuju na istu funkciju. Imajte na umu jednokratnu upotrebu i položaj &. Dakle & je ovdje referentni operator, a ne adresa-operatora. Da biste pozvali funkciju, samo upotrijebite bilo koje ime.

Referentni identifikator nije isto što i identifikator pokazivača.

Funkcija koja vraća pokazivač

U sljedećem programu funkcija vraća pokazivač koji je adresa istaknutog objekta:

#include
pomoću prostora imena std;
float * fn (float fl, int in)

plutajuće * fll = &fl;
povratak fll;

int main ()

float * val = fn (2.5, 6);
cout << *val << '\n';
return 0;

Izlaz je 2.5

Prva izjava u funkciji, fn () postoji samo za stvaranje objekta pokazivača. Obratite pažnju na jednokratnu upotrebu i položaj * u potpisu funkcije. Također imajte na umu kako je pokazivač (adresa) primljen u funkciji main () od drugog pokazivačkog objekta.

Funkcija koja vraća referencu

U sljedećem programu funkcija vraća referencu:

#include
pomoću prostora imena std;
float & fn (float fl, int in)

plutati & frr = fl;
povratak frr;

int main ()

float & val = fn (2.5, 6);
cout << val << '\n';
return 0;

Izlaz je 2.5.

Prva izjava u funkciji, fn () postoji samo za stvaranje reference. Obratite pažnju na jednokratnu upotrebu i položaj & u potpisu funkcije. Također imajte na umu kako je referenca primljena u funkciji main () drugom referencom.

Prosljeđivanje pokazivača na funkciju

U sljedećem programu, pokazivač, koji je zapravo adresa plutajućeg objekta, šalje se kao argument funkciji:

#include
pomoću prostora imena std;
float fn (float * fl, int in)

povratak * fl;

int main ()

plutajuće v = 2.5;
plutajuća val = fn (& v, 6);
cout << val << '\n';
return 0;

Izlaz je 2.5

Obratite pažnju na upotrebu i položaj * za parametar float u potpisu funkcije. Čim započne procjena funkcije fn (), daje se sljedeća izjava:

plutajuće * fl = & v;

I fl i & v pokazuju na isti šiljati objekt koji drži 2.5. * fl u povratnoj izjavi nije izjava; to znači, vrijednost usmjerenog objekta na koji pokazuje pokazivački objekt.

Prosljeđivanje reference na funkciju

U sljedećem programu referenca se šalje kao argument funkciji:

#include
pomoću prostora imena std;
float fn (float & fl, int in)

povratak fl;

int main ()

plutajuće v = 2.5;
plutajuća val = fn (v, 6);
cout << val << '\n';
return 0;

Izlaz je 2.5

Obratite pažnju na upotrebu i položaj & za parametar float u potpisu funkcije. Čim započne procjena funkcije fn (), daje se sljedeća izjava:

plutati & fl = v;

Prosljeđivanje niza funkciji

Sljedeći program pokazuje kako proslijediti niz funkciji:

#include
pomoću prostora imena std;
int fn (int arra [])

return arra [2];

int main ()

int arr [] = 000, 100, 200, 300, 400;
int val = fn (arr);
cout << val << '\n';
return 0;

Izlaz je 200.

U ovom programu prenosi se niz. Imajte na umu da parametar potpisa funkcije ima praznu deklaraciju niza. Argument u pozivu funkcije samo je ime stvorenog niza.

Može li funkcija C ++ vratiti niz?

Funkcija u C ++ može vratiti vrijednost niza, ali ne može vratiti niz. Sastavljanje sljedećeg programa rezultira porukom pogreške:

#include
pomoću prostora imena std;
int fn (int arra [])

return arra;

int main ()

int arr [] = 000, 100, 200, 300, 400;
int val = fn (arr);
return 0;

Pokazivač pokazivača

Pokazivač može ukazati na drugi pokazivač. Odnosno, pokazivački objekt može imati adresu drugog pokazivačkog objekta. Još uvijek moraju biti iste vrste. Sljedeći segment koda to ilustrira:

int ptdInt = 5;
int * ptrInt = &ptdInt;
int ** ptrptrInt = &ptrInt;
cout << **ptrptrInt << '\n';

Izlaz je 5.

U deklaraciji pokazivača na pokazivač koristi se double *. Da bi se vratila vrijednost konačnog šiljatog objekta, i dalje se koristi double *.

Niz pokazivača

Sljedeći program pokazuje kako kodirati niz pokazivača:

#include
pomoću prostora imena std;
int main ()

int num0 = 000, num1 = 100, num2 = 200, num3 = 300, num4 = 400;
int * no0 = & num0, * no1 = & num1, * no2 = & num2, * no3 = & num3, * no4 =&num4;
int * arr [] = no0, no1, no2, no3, no4;
cout << *arr[4] << '\n';
return 0;

Izlaz je:

400

Obratite pažnju na upotrebu i položaj * u deklaraciji niza. Obratite pažnju na upotrebu * prilikom vraćanja vrijednosti u polju. Kod pokazivača pokazivača uključena su dva *. U slučaju niza pokazivača, jedan * je već zbrinut, jer je identifikator niza pokazivač.

Niz žica promjenjive duljine

Znakovni niz je konstanta koja vraća pokazivač. Niz nizova promjenjive duljine niz je pokazivača. Svaka vrijednost u polju je pokazivač. Pokazivači su adrese memorijskih mjesta i iste su veličine. Nizovi različitih duljina nalaze se drugdje u memoriji, a ne u nizu. Sljedeći program ilustrira upotrebu:

#include
pomoću prostora imena std;
int main ()

const char * arr [] = "žena", "dječak", "djevojčica", "odrasla osoba";
cout << arr[2] << '\n';
return 0;

Rezultat je "djevojka".

Deklaracija niza započinje rezerviranom riječju, "const" za konstantu; nakon čega slijedi "char" za znak, a zatim zvjezdica, * da označi da je svaki element pokazivač. Da bi se niz vratio iz niza, * se ne koristi zbog implicitne prirode pokazivača svakog niza. Ako se koristi *, vratit će se prvi element niza.

Pokazivač na funkciju koja vraća pokazivač

Sljedeći program ilustrira kako je kodiran pokazivač na funkciju koja vraća pokazivač:

#include
pomoću prostora imena std;
int * fn ()

int broj = 4;
int * inter = #
return inter;

int main ()

int * (* func) () = &fn;
int val = * func ();
cout << val << '\n';
return 0;

Izlaz je 4.

Deklaracija pokazivača na funkciju koja vraća pokazivač slična je deklaraciji pokazivača na uobičajenu funkciju, ali joj prethodi zvjezdica. To ilustrira prva izjava u funkciji main (). Da biste pozvali funkciju pomoću pokazivača, stavite je ispred *.

Zaključak

Da biste stvorili pokazivač na skalar, učinite nešto slično,

plovak zašiljen;
plutajući * pokazivač = &pointed;

* ima dva značenja: u deklaraciji označava pokazivač; vratiti nešto, to je za vrijednost šiljatog predmeta.

Ime niza stalni je pokazivač na prvi element niza.

Možete stvoriti pokazivač na funkciju,

int (* func) () = &fn;

gdje je fn () funkcija definirana negdje drugdje, a func pokazivač.

& ima dva značenja: u deklaraciji označava referencu (sinonim) na isti objekt kao i drugi identifikator; kad nešto vraćate, to znači adresu.

Možete stvoriti referencu na funkciju,

float (& refFunc) (float, int) = fn;

gdje je fn () funkcija definirana drugdje, a refFunc referenca.

Kada funkcija vraća pokazivač, vraćenu vrijednost mora primiti pokazivač. Kad funkcija vraća referencu, vraćena vrijednost mora primiti referencu.

Prilikom prosljeđivanja pokazivača na funkciju, parametar je deklaracija, dok je argument adresa usmjerenog objekta. Kad prosljeđuje referencu funkciji, parametar je deklaracija, dok je argument referenca.

Prilikom prosljeđivanja polja funkciji, parametar je deklaracija, dok je argument ime polja bez []. Funkcija C ++ ne vraća niz.

Pointer za pokazivač treba dva * umjesto jednog, gdje je to prikladno.

Chrys

Kako preuzeti i igrati Sid Meier's Civilization VI na Linuxu
Uvod u igru Civilization 6 moderan je pogled na klasični koncept predstavljen u seriji igara Age of Empires. Ideja je bila prilično jednostavna; započ...
Kako instalirati i igrati Doom na Linuxu
Uvod u Doom Serija Doom nastala je 90-ih nakon izlaska originalnog Dooma. To je bio trenutni hit i od tog vremena nadalje igraća serija dobila je broj...
Vulkan za korisnike Linuxa
Sa svakom novom generacijom grafičkih kartica vidimo da programeri igara pomiču granice grafičke vjernosti i dolaze na korak od fotorealizma. No, bez ...