C ++

Ako používať ukazovatele C ++

Ako používať ukazovatele C ++
Pamäť počítača je dlhá séria buniek. Veľkosť každej bunky sa nazýva bajt. Bajt je priestor obsadený anglickým znakom abecedy. Objekt v bežnom zmysle je po sebe idúca sada bajtov v pamäti. Každá bunka má adresu, ktorá je celým číslom, zvyčajne napísanú v hexadecimálnom tvare. Existujú tri spôsoby prístupu k objektu v pamäti. K objektu je možné pristupovať pomocou ukazovateľa. Je k nim prístup pomocou takzvanej referencie. Stále je k nim prístup pomocou identifikátora. Tento článok sa zameriava na použitie ukazovateľov a odkazov. V C ++ je to špicatý objekt a ukazovateľový objekt. Zameraný predmet má predmet záujmu. Objekt ukazovateľa má adresu na špicatý objekt.

Musíte mať základné znalosti v jazyku C ++ vrátane jeho identifikátorov, funkcií a polí; aby som pochopil tento článok.

Ukazovateľový objekt a špicatý objekt majú každý svoj identifikátor.

Prevádzkovateľ adresy &

Toto je unárny operátor. Ak nasleduje identifikátor, vráti adresu objektu identifikátora. Zvážte nasledujúce vyhlásenie:

int ptdInt;

Nižšie je uvedený kód, nasledujúci výraz, vráti adresu identifikovanú ptdInt:

& ptdInt

Pri kódovaní nemusíte poznať presnú adresu (číslo).

Indirection Operator, *

Toto je unárny operátor v kontexte ukazovateľov. Zvyčajne sa píše pred identifikátorom. Ak sa použije v deklarácii identifikátora, potom je identifikátor ukazovateľový objekt, ktorý obsahuje iba adresu zaostreného objektu. Ak sa použije pred identifikátorom objektu ukazovateľa, aby sa niečo vrátilo, potom vrátená vec je hodnota poukázaného objektu.

Vytvorenie ukazovateľa

Prezrite si nasledujúci segment kódu:

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

Segment sa začína vyhlásením špicatého objektu, ptdFloat. ptdFloat je identifikátor, ktorý iba identifikuje plavákový objekt. Skutočný objekt (hodnota) mu mohol byť priradený, v takom prípade mu však nebolo priradené nič. Ďalej v segmente je deklarácia ukazovateľa objektu. Operátor smerovania pred týmto identifikátorom znamená, že musí obsahovať adresu zahroteného objektu. Typ objektu, float na začiatku príkazu, znamená, že zaostrený objekt je float. Ukazovateľový objekt je vždy rovnakého typu ako špicatý objekt. ptrFoat je identifikátor, ktorý iba identifikuje ukazovateľový objekt.

V poslednom výroku kódu je adrese ukazovaného objektu priradená adresa zaostreného objektu. Všimnite si použitie adresy operátora &.

Posledný výrok (riadok) vyššie ukazuje, že po vyhlásení ukazovateľa za objekt bez inicializácie nepotrebujete operátor indirection, keď ho musíte inicializovať. V skutočnosti je to syntaktická chyba, keď sa v treťom (poslednom) riadku použije indirekčný operátor.

Objekt ukazovateľa je možné deklarovať a inicializovať pomocou špicatého objektu v jednom príkaze, a to nasledovne:

float ptdFloat;
float * ptrFoat = &ptdFloat;

Prvý riadok predchádzajúceho segmentu kódu a tento je rovnaký. Druhý a tretí riadok predchádzajúceho segmentu kódu boli tu spojené do jedného vyhlásenia.

Vo vyššie uvedenom kóde si všimnite, že pri deklarovaní a inicializácii ukazovateľa sa musí použiť operátor indirection. Nepoužíva sa však, ak sa má inicializácia vykonať neskôr. Ukazovateľový objekt je inicializovaný adresou zaostreného objektu.

V nasledujúcom segmente kódu sa operátor indirection používa na vrátenie obsahu zahroteného objektu.

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

Výstup je 5.

V poslednom príkaze tu bol operátor indirection použitý na vrátenie hodnoty, na ktorú ukazovateľ smeruje, podľa identifikátora ukazovateľa. Takže keď sa použije v deklarácii, identifikátor pre operátora navádzania bude obsahovať adresu zahroteného objektu. Pri použití vo vratnom výraze v kombinácii s identifikátorom ukazovateľa vráti operátor indirection hodnotu špičatého objektu.

Priradenie nuly ukazovateľovi

Ukazovateľový objekt by mal mať vždy typ zahroteného objektu. Pri deklarovaní ukazovateľového objektu je potrebné použiť dátový typ špicatého objektu. Hodnotu desatinnej nuly je však možné priradiť ukazovateľu ako v nasledujúcom segmente kódu:

int ptdInt = 5;
int * ptrInt;
ptrInt = 0;
alebo v segmente,
int ptdInt = 5;
int * ptrInt = 0;

V obidvoch prípadoch sa ukazovateľ (identifikátor) nazýva nulový ukazovateľ; význam, to nikam nevedie. To znamená, že nemá adresu žiadneho zahroteného objektu. Tu je 0 desatinná nula a nie hexadecimálna nula. Hexadecimálna nula by ukazovala na prvú adresu pamäte počítača.

Nesnažte sa získať hodnotu, na ktorú ukazuje nulový ukazovateľ. Ak to skúsite, program sa môže kompilovať, ale nemusí sa vykonať.

Názov poľa ako konštantný ukazovateľ

Zvážte nasledujúce pole:

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

Názov poľa, arr je vlastne identifikátor, ktorý má adresu prvého prvku poľa. Nasledujúci výraz vráti prvú hodnotu v poli:

* prílet

S poľom, operátorom prírastku, sa ++ správa inak. Namiesto pridania 1 nahradí adresu ukazovateľa adresou nasledujúceho prvku v poli. Názov poľa je však konštantný ukazovateľ; čo znamená, že jeho obsah (adresu) nie je možné meniť ani zvyšovať. Aby sa teda zvyšovalo, počiatočná adresa poľa musí byť priradená nekonštantnému ukazovateľu takto:

int * ptr = arr;

Teraz možno ptr zvýšiť tak, aby ukazoval na ďalší prvok poľa. ptr bol tu deklarovaný ako ukazovateľový objekt. Bez * by to nebol ukazovateľ; išlo by o identifikátor, ktorý by obsahoval objekt int a nie adresu pamäte.

Nasledujúci segment kódu nakoniec ukazuje na štvrtý prvok:

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

Nasledujúci kód vydáva štvrtú hodnotu poľa:

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

Výstup je 300.

Názov funkcie ako identifikátor

Názov funkcie je identifikátor funkcie. Zvážte nasledujúcu definíciu funkcie:

int fn ()

cout << "seen" << '\n';
návrat 4;

fn je identifikátor funkcie. Výraz,

& fn

vráti adresu funkcie v pamäti. fn je ako zahrotený predmet. Nasledujúca deklarácia deklaruje ukazovateľ na funkciu:

int (* func) ();

Identifikátor pre špicatý objekt a identifikátor pre ukazovateľový objekt sú odlišné. func je ukazovateľ na funkciu. fn je identifikátor funkcie. Funkciu teda možno uviesť na fn takto:

func = &fn;

Hodnota (obsah) func je adresa fn. Tieto dva identifikátory mohli byť spojené s inicializačným príkazom takto:

int (* func) () = &fn;

Všimnite si rozdiely a podobnosti pri zaobchádzaní s ukazovateľmi funkcií a so skalárnymi ukazovateľmi. func je ukazovateľ na funkciu; je to zahrotený predmet; deklaruje sa inak ako skalárny ukazovateľ.

Funkciu je možné vyvolať pomocou,

fn ()
alebo
func ()

Nie je možné ho volať pomocou funkcie * func ().

Keď má funkcia parametre, druhá zátvorka má typy parametrov a nemusí mať identifikátory parametrov. Nasledujúci program to ilustruje:

#include
pomocou namespace std;
float fn (float fl, int in)

návrat fl;

int main ()

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

Výstup je 2.5.

Referencia C ++

Odkazy v C ++ sú iba spôsobom, ako vytvoriť synonymum (iný názov) pre identifikátor. Používa operátor &, ale nie rovnakým spôsobom ako & sa používa pre ukazovatele. Zvážte nasledujúci segment kódu:

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

Výstup je:

8
8

Prvý príkaz inicializuje identifikátor myInt; i.e. myInt je deklarovaný a vyrobený na udržanie hodnoty, 8. Druhé vyhlásenie vytvára nový identifikátor, yourInt je synonymom pre myInt. Za týmto účelom sa operátor & umiestni medzi údajový typ a nový identifikátor v deklarácii. Výroky cout ukazujú, že dva identifikátory sú synonymá. Ak chcete v takom prípade vrátiť hodnotu, nemusíte pred ňu uvádzať znak * . Stačí použiť identifikátor.

myInt a yourInt here, nie sú dva rôzne objekty. Sú to dva rôzne identifikátory odkazujúce (identifikujúce) na rovnaké miesto v pamäti, ktoré majú hodnotu, 8. Ak sa zmení hodnota myInt, automaticky sa zmení aj hodnota yourInt. Ak sa zmení hodnota yourInt, automaticky sa zmení aj hodnota myInt.

Referencie sú rovnakého typu.

Odkaz na funkciu

Rovnako ako môžete mať odkaz na skalár, môžete mať aj odkaz na funkciu. Avšak kódovanie odkazu na funkciu sa líši od kódovania odkazu na skalár. Nasledujúci program to ilustruje:

#include
pomocou namespace std;
float fn (float fl, int in)

návrat fl;

int main ()

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

Výstup je 2.5.

Všimnite si prvé vyhlásenie v hlavnej funkcii, vďaka ktorému je func synonymom fn. Oba odkazujú na rovnakú funkciu. Všimnite si jednorazové použitie a polohu. Takže & je tu referenčný operátor a nie adresa operátora. Ak chcete funkciu zavolať, stačí použiť ľubovoľné meno.

Referenčný identifikátor nie je rovnaký ako identifikátor ukazovateľa.

Funkcia vrátenia ukazovateľa

V nasledujúcom programe funkcia vráti ukazovateľ, ktorý je adresou špicatého objektu:

#include
pomocou namespace std;
float * fn (float fl, int in)

float * fll = &fl;
návrat fll;

int main ()

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

Výstup je 2.5

Prvý príkaz vo funkcii fn () je tu len na vytvorenie ukazovateľa. Poznačte si jednorazové použitie a pozíciu * v podpisu funkcie. Všimnite si tiež, ako bol ukazovateľ (adresa) prijatý vo funkcii main () iným objektom ukazovateľa.

Funkcia vrátenia referencie

V nasledujúcom programe funkcia vráti odkaz:

#include
pomocou namespace std;
float & fn (float fl, int in)

float & frr = fl;
návrat frr;

int main ()

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

Výstup je 2.5.

Prvý príkaz vo funkcii fn () je tu len na vytvorenie referencie. Všimnite si jednorazové použitie a pozíciu & v podpisu funkcie. Všimnite si tiež, ako bol odkaz prijatý vo funkcii main () iným odkazom.

Odovzdanie ukazovateľa na funkciu

V nasledujúcom programe je ako argument funkcie odoslaný ukazovateľ, ktorý je v skutočnosti adresou objektu s pohyblivou špičkou

#include
pomocou namespace std;
float fn (float * fl, int in)

návrat * fl;

int main ()

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

Výstup je 2.5

Poznačte si použitie a pozíciu * pre parameter float v podpisu funkcie. Hneď ako sa spustí vyhodnotenie funkcie fn (), urobí sa nasledujúce vyhlásenie:

float * fl = & v;

Fl aj & v smerujú k rovnakému zahrotenému objektu, ktorý drží 2.5. * vyhlásenie o vrátení tovaru nie je vyhlásením; to znamená, hodnota namiereného objektu, na ktorú ukazuje ukazovateľový objekt.

Odovzdanie odkazu na funkciu

V nasledujúcom programe sa ako argument odošle odkaz na funkciu:

#include
pomocou namespace std;
float fn (float & fl, int in)

návrat fl;

int main ()

float v = 2.5;
float val = fn (v, 6);
cout << val << '\n';
návrat 0;

Výstup je 2.5

Poznačte si použitie a polohu parametra & pre float parameter v podpisu funkcie. Hneď ako sa spustí vyhodnotenie funkcie fn (), urobí sa nasledujúce vyhlásenie:

float & fl = v;

Rozdelenie poľa na funkciu

Nasledujúci program ukazuje, ako odovzdať pole funkcii:

#include
pomocou namespace std;
int fn (int arra [])

spätná arra [2];

int main ()

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

Výstup je 200.

V tomto programe sa odovzdáva pole. Upozorňujeme, že parameter podpisu funkcie má prázdnu deklaráciu poľa. Argumentom volania funkcie je iba názov vytvoreného poľa.

Môže funkcia C ++ vrátiť pole?

Funkcia v C ++ môže vrátiť hodnotu poľa, ale nemôže ho vrátiť. Výsledkom zostavenia nasledujúceho programu je chybové hlásenie:

#include
pomocou namespace std;
int fn (int arra [])

spätná arra;

int main ()

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

Ukazovateľ ukazovateľa

Ukazovateľ môže smerovať na iný ukazovateľ. To znamená, že ukazovateľ môže mať adresu iného ukazovateľa. Stále musia byť všetci rovnakého typu. Ilustruje to nasledujúci segment kódu:

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

Výstup je 5.

Vo vyhlásení ukazovateľ na ukazovateľ sa používa dvojitý *. Na vrátenie hodnoty konečného zaostreného objektu sa stále používa double *.

Pole ukazovateľov

Nasledujúci program ukazuje, ako kódovať pole ukazovateľov:

#include
pomocou namespace 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';
návrat 0;

Výstup je:

400

Všimnite si použitie a pozíciu * v deklarácii poľa. Všimnite si použitie * pri vracaní hodnoty v poli. Pri ukazovateľoch ukazovateľov sú zapojené dva *. V prípade poľa ukazovateľov je už o jeden * postarané, pretože identifikátor poľa je ukazovateľ.

Pole reťazcov s premenlivou dĺžkou

Reťazcový literál je konštanta, ktorá vracia ukazovateľ. Pole reťazcov s premennou dĺžkou je pole ukazovateľov. Každá hodnota v poli je ukazovateľ. Ukazovatele sú adresy na pamäťové miesta a majú rovnakú veľkosť. Reťazce rôznych dĺžok sú inde v pamäti, nie v poli. Nasledujúci program ilustruje použitie:

#include
pomocou namespace std;
int main ()

const char * arr [] = "žena", "chlapec", "dievča", "dospelý";
cout << arr[2] << '\n';
návrat 0;

Výstup je „dievča“.

Deklarácia poľa sa začína rezervovaným slovom „const“ pre konštantu; nasledovaný znakom „char“ pre znak, potom hviezdička, *, ktorá označuje, že každý prvok je ukazovateľ. Na vrátenie reťazca z poľa sa znak * nepoužíva z dôvodu implicitnej povahy ukazovateľa každého reťazca. Ak sa použije *, vráti sa prvý prvok reťazca.

Ukazovateľ na funkciu, ktorá vracia ukazovateľ

Nasledujúci program ilustruje, ako je kódovaný ukazovateľ na funkciu vracajúcu ukazovateľ:

#include
pomocou namespace std;
int * fn ()

int num = 4;
int * inter = #
návrat medzi;

int main ()

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

Výstup je 4.

Deklarácia ukazovateľa na funkciu vracajúcu ukazovateľ je podobná deklarácii ukazovateľa na bežnú funkciu, ale pred ňou je hviezdička. Ilustruje to prvý príkaz vo funkcii main (). Ak chcete funkciu zavolať pomocou ukazovateľa, vložte pred ňu znak *.

Záver

Ak chcete vytvoriť ukazovateľ na skalár, urobte niečo ako,

vznášať sa;
float * pointer = &pointed;

* má dva významy: v deklarácii označuje ukazovateľ; niečo vrátiť, je to pre hodnotu poukázaného objektu.

Názov poľa je konštantný smerník na prvý prvok poľa.

Ak chcete vytvoriť ukazovateľ na funkciu, môžete urobiť,

int (* func) () = &fn;

kde fn () je funkcia definovaná inde a func je ukazovateľ.

& má dva významy: v deklarácii označuje odkaz (synonymum) na rovnaký objekt ako iný identifikátor; pri vrátení niečoho to znamená adresu.

Ak chcete vytvoriť odkaz na funkciu, môžete urobiť,

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

kde fn () je funkcia definovaná inde a refFunc je odkaz.

Keď funkcia vráti ukazovateľ, vrátenú hodnotu musí prijať ukazovateľ. Keď funkcia vráti referenciu, vrátenú hodnotu musí prijať referencia.

Pri odovzdávaní ukazovateľa na funkciu je parametrom deklarácia, zatiaľ čo argumentom je adresa zaostreného objektu. Pri odovzdávaní odkazu na funkciu je parametrom deklarácia, zatiaľ čo argumentom je referencia.

Pri odovzdávaní poľa funkcii je parametrom deklarácia, zatiaľ čo argumentom je názov poľa bez []. Funkcia C ++ nevracia pole.

Ukazovateľ na ukazovateľ potrebuje podľa potreby dva * namiesto jedného.

Chrys

Hry Ako zobraziť počítadlo FPS v hrách Linux
Ako zobraziť počítadlo FPS v hrách Linux
Hranie na systéme Linux získalo veľký tlak, keď spoločnosť Valve v roku 2012 oznámila podporu systému Linux pre klienta Steam a ich hry. Od tej doby s...
Hry Ako sťahovať a prehrávať Sid Meier's Civilization VI v systéme Linux
Ako sťahovať a prehrávať Sid Meier's Civilization VI v systéme Linux
Úvod do hry Civilization 6 predstavuje moderné poňatie klasického konceptu predstaveného v sérii hier Age of Empires. Myšlienka bola dosť jednoduchá; ...
Hry Ako inštalovať a hrať Doom na Linuxe
Ako inštalovať a hrať Doom na Linuxe
Úvod do Doom Séria Doom vznikla v 90. rokoch po vydaní pôvodného Doomu. Bol to okamžitý hit a od tej doby herná séria získala množstvo ocenení a origi...