C ++

Jak používat ukazatele C ++

Jak používat ukazatele C ++
Paměť počítače je dlouhá řada buněk. Velikost každé buňky se nazývá bajt. Bajt je prostor obsazený anglickým znakem abecedy. Objekt v běžném smyslu je po sobě jdoucí sada bajtů v paměti. Každá buňka má adresu, což je celé číslo, obvykle napsané v hexadecimálním tvaru. Existují tři způsoby přístupu k objektu v paměti. K objektu lze přistupovat pomocí takzvaného ukazatele. Lze k němu přistupovat pomocí takzvaného odkazu. Stále k němu lze přistupovat pomocí identifikátoru. Tento článek se zaměřuje na použití ukazatelů a odkazů. V C ++ je špičatý objekt a ukazatel objekt. Špičatý předmět má předmět zájmu. Objekt ukazatele má adresu na špičatý objekt.

Musíte mít základní znalosti v C ++, včetně jeho identifikátorů, funkcí a polí; porozumět tomuto článku.

Ukazatel a špičatý objekt mají každý svůj identifikátor.

Provozovatel adresy &

Toto je unární operátor. Když následuje identifikátor, vrátí adresu objektu identifikátoru. Zvažte následující prohlášení:

int ptdInt;

Níže je kód, následující výraz, vrátí adresu identifikovanou ptdInt:

& ptdInt

Při kódování nemusíte znát přesnou adresu (číslo).

Indirection Operator, *

Toto je unární operátor v kontextu ukazatelů. Obvykle se zadává před identifikátor. Pokud je použit v deklaraci identifikátoru, pak identifikátor je objekt ukazatele, který obsahuje pouze adresu špičatého objektu. Pokud se použije před identifikátor objektu ukazatele, aby se něco vrátilo, pak vrácená věc je hodnota špičatého objektu.

Vytvoření ukazatele

Podívejte se na následující segment kódu:

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

Segment začíná deklarací špičatého objektu ptdFloat. ptdFloat je identifikátor, který pouze identifikuje plovoucí objekt. Mohl mu být přiřazen skutečný objekt (hodnota), ale v tomto případě mu nebylo přiřazeno nic. Dále v segmentu je deklarace ukazatele objektu. Operátor indirection před tímto identifikátorem znamená, že musí mít adresu špičatého objektu. Typ objektu, float na začátku příkazu, znamená, že špičatým objektem je float. Objekt ukazatele je vždy stejného typu jako špičatý objekt. ptrFoat je identifikátor, který pouze identifikuje ukazatelový objekt.

V posledním příkazu kódu je adrese špičatého objektu přiřazena objekt ukazatele. Všimněte si použití adresy operátora &.

Poslední příkaz (řádek) výše ukazuje, že po deklaraci ukazatele bez inicializace nepotřebujete operátor indirection, když jej musíte inicializovat. Ve skutečnosti se jedná o syntaktickou chybu při použití operátoru indirection ve třetím (posledním) řádku.

Objekt ukazatele lze deklarovat a inicializovat špičatým objektem v jednom příkazu, a to následovně:

float ptdFloat;
float * ptrFoat = &ptdFloat;

První řádek předchozího segmentu kódu a tento jsou stejné. Druhý a třetí řádek předchozího segmentu kódu zde byly sloučeny do jednoho prohlášení.

Ve výše uvedeném kódu si všimněte, že při deklaraci a inicializaci objektu ukazatele je třeba použít operátor indirection. Nepoužívá se však, pokud má být inicializace provedena později. Objekt ukazatele je inicializován adresou špičatého objektu.

V následujícím segmentu kódu se operátor indirection používá k vrácení obsahu špičatého objektu.

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

Výstup je 5.

V posledním příkazu zde byl operátor indirection použit k vrácení hodnoty, na kterou ukazuje, identifikátor ukazatele. Takže pokud je použit v deklaraci, identifikátor pro operátor indirection bude obsahovat adresu špičatého objektu. Při použití ve návratovém výrazu v kombinaci s identifikátorem ukazatele vrátí operátor indirection hodnotu špičatého objektu.

Přiřazení nuly ukazateli

Objekt ukazatele by měl mít vždy typ špičatého objektu. Při deklarování objektu ukazatele je třeba použít datový typ špičatého objektu. Hodnotu desítkové nuly však lze přiřadit ukazateli jako v následujícím segmentu kódu:

int ptdInt = 5;
int * ptrInt;
ptrInt = 0;
nebo v segmentu,
int ptdInt = 5;
int * ptrInt = 0;

V obou případech se ukazatel (identifikátor) nazývá nulový ukazatel; to znamená, že to nikam nevede. To znamená, že nemá adresu žádného špičatého objektu. Zde je 0 desetinná nula a ne hexadecimální nula. Hexadecimální nula by ukazovala na první adresu paměti počítače.

Nepokoušejte se získat hodnotu, na kterou ukazuje nulový ukazatel. Pokud to zkusíte, program se může zkompilovat, ale nemusí se spustit.

Název pole jako konstantní ukazatel

Zvažte následující pole:

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

Název pole, arr je ve skutečnosti identifikátor, který má adresu prvního prvku pole. Následující výraz vrací první hodnotu v poli:

* příjezd

S maticí, operátorem přírůstku, se ++ chová odlišně. Místo přidání 1 nahradí adresu ukazatele adresou dalšího prvku v poli. Název pole je však konstantní ukazatel; což znamená, že jeho obsah (adresu) nelze měnit ani zvyšovat. Chcete-li tedy zvýšit, počáteční adresa pole musí být přiřazena nekonstantnímu ukazateli následujícím způsobem:

int * ptr = arr;

Nyní lze ptr zvýšit tak, aby ukazoval na další prvek pole. ptr zde byl deklarován jako objekt ukazatele. Bez * zde by to nebyl ukazatel; byl by to identifikátor, který by držel objekt int a ne držel adresu paměti.

Následující segment kódu nakonec ukazuje na čtvrtý prvek:

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

Následující kód vypíše čtvrtou hodnotu pole:

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

Výstup je 300.

Název funkce jako identifikátor

Název funkce je identifikátor funkce. Zvažte následující definici funkce:

int fn ()

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

fn je identifikátor funkce. Výraz,

& fn

vrací adresu funkce v paměti. fn je jako špičatý předmět. Následující deklarace deklaruje ukazatel na funkci:

int (* func) ();

Identifikátor špičatého objektu a identifikátor objektu ukazatele se liší. func je ukazatel na funkci. fn je identifikátor funkce. Funkci lze tedy nastavit tak, aby ukazovala na fn takto:

func = &fn;

Hodnota (obsah) func je adresa fn. Tyto dva identifikátory mohly být spojeny s inicializačním příkazem takto:

int (* func) () = &fn;

Všimněte si rozdílů a podobností při zpracování ukazatelů funkcí a skalárních ukazatelů. func je ukazatel na funkci; je to špičatý předmět; deklaruje se odlišně od skalárního ukazatele.

Funkci lze vyvolat pomocí,

fn ()
nebo
func ()

Nelze jej volat pomocí * func ().

Když má funkce parametry, druhá závorka má typy parametrů a nemusí mít identifikátory parametrů. Ilustruje to následující program:

#zahrnout
pomocí jmenného prostoru 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.

C ++ reference

Odkazování v C ++ je jen způsob, jak vytvořit synonymum (jiný název) pro identifikátor. Používá operátor &, ale ne stejným způsobem jako & se používá pro ukazatele. Zvažte následující segment kódu:

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

Výstupem je:

8
8

První příkaz inicializuje identifikátor myInt; i.E. myInt je deklarován a vytvořen tak, aby udržel hodnotu, 8. Druhý příkaz vytvoří nový identifikátor, yourInt synonymum pro myInt. K dosažení tohoto cíle je operátor & umístěn v deklaraci mezi datovým typem a novým identifikátorem. Příkazy cout ukazují, že dva identifikátory jsou synonyma. Chcete-li v tomto případě vrátit hodnotu, nemusíte před ní předcházet * . Stačí použít identifikátor.

myInt a yourInt zde nejsou dva různé objekty. Jsou to dva různé identifikátory odkazující (identifikující) na stejné místo v paměti, které mají hodnotu, 8. Pokud se změní hodnota myInt, automaticky se změní i hodnota yourInt. Pokud se změní hodnota yourInt, automaticky se změní i hodnota myInt.

Odkazy jsou stejného typu.

Odkaz na funkci

Stejně jako můžete mít odkaz na skalár, můžete mít také odkaz na funkci. Avšak kódování odkazu na funkci se liší od kódování odkazu na skalár. Ilustruje to následující program:

#zahrnout
pomocí jmenného prostoru 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šimněte si prvního příkazu v hlavní funkci, díky kterému je func synonymem fn. Oba odkazují na stejnou funkci. Všimněte si jednorázového použití a polohy. Takže & je zde referenční operátor a nikoli operátor adresy. Chcete-li funkci zavolat, stačí použít libovolné jméno.

Identifikátor odkazu není stejný jako identifikátor ukazatele.

Funkce vrací ukazatel

V následujícím programu funkce vrátí ukazatel, který je adresou špičatého objektu:

#zahrnout
pomocí jmenného prostoru 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

První příkaz ve funkci, fn (), je tam jen proto, aby vytvořil objekt ukazatele. Všimněte si jednorázového použití a pozice * v podpisu funkce. Všimněte si také, jak byl ukazatel (adresa), přijat ve funkci main () jiným objektem ukazatele.

Funkce vrací referenci

V následujícím programu funkce vrátí odkaz:

#zahrnout
pomocí jmenného prostoru 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.

První příkaz ve funkci, fn (), je tam jen pro vytvoření odkazu. Všimněte si jednorázového použití a polohy & v podpisu funkce. Všimněte si také, jak byla reference ve funkci main () přijata jinou referencí.

Předání ukazatele na funkci

V následujícím programu je ukazatel, který je ve skutečnosti adresou plovoucího špičatého objektu, odeslán jako argument funkci:

#zahrnout
pomocí jmenného prostoru 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

Poznamenejte si použití a pozici * pro parametr float v podpisu funkce. Jakmile se spustí vyhodnocení funkce fn (), provede se následující prohlášení:

float * fl = & v;

Fl i & v ukazují na stejný špičatý objekt, který obsahuje 2.5. * fl at the return statement is not a declaration; to znamená, hodnota špičatého objektu, na kterou ukazuje objekt ukazatele.

Předání odkazu na funkci

V následujícím programu je odeslán odkaz jako argument na funkci:

#zahrnout
pomocí jmenného prostoru 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

Poznamenejte si použití a pozici & pro parametr float v podpisu funkce. Jakmile se spustí vyhodnocení funkce fn (), provede se následující prohlášení:

float & fl = v;

Předání pole funkci

Následující program ukazuje, jak předat pole funkci:

#zahrnout
pomocí jmenného prostoru std;
int fn (int arra [])

zpáteční 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 programu je předáno pole. Všimněte si, že parametr podpisu funkce má prázdnou deklaraci pole. Argument ve volání funkce je pouze název vytvořeného pole.

Může funkce C ++ vrátit pole?

Funkce v C ++ může vrátit hodnotu pole, ale nemůže ji vrátit. Při kompilaci následujícího programu se zobrazí chybová zpráva:

#zahrnout
pomocí jmenného prostoru std;
int fn (int arra [])

návratová arra;

int main ()

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

Ukazatel ukazatele

Ukazatel může ukazovat na jiný ukazatel. To znamená, že objekt ukazatele může mít adresu jiného objektu ukazatele. Stále musí být všichni stejného typu. Následující segment kódu to ilustruje:

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

Výstup je 5.

V deklaraci ukazatele na ukazatel se používá double *. Chcete-li vrátit hodnotu konečného špičatého objektu, stále se používá double *.

Pole ukazatelů

Následující program ukazuje, jak kódovat pole ukazatelů:

#zahrnout
pomocí jmenného prostoru 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ýstupem je:

400

Všimněte si použití a polohy * v deklaraci pole. Všimněte si použití * při vracení hodnoty v poli. U ukazatelů ukazatelů jsou zapojeny dva *. V případě pole ukazatelů je již o jeden * postaráno, protože identifikátor pole je ukazatel.

Pole řetězců s proměnnou délkou

Řetězcový literál je konstanta, která vrací ukazatel. Pole řetězců s proměnnou délkou je pole ukazatelů. Každá hodnota v poli je ukazatel. Ukazatele jsou adresy na paměťová místa a mají stejnou velikost. Řetězce různých délek jsou jinde v paměti, ne v poli. Následující program ilustruje použití:

#zahrnout
pomocí jmenného prostoru std;
int main ()

const char * arr [] = "žena", "chlapec", "dívka", "dospělý";
cout << arr[2] << '\n';
návrat 0;

Výstup je „dívka“.

Deklarace pole začíná vyhrazeným slovem „const“ pro konstantu; následuje znak „char“ pro znak, poté hvězdička, *, která označuje, že každý prvek je ukazatel. Chcete-li vrátit řetězec z pole, * se nepoužívá z důvodu implicitní povahy ukazatele každého řetězce. Pokud se použije *, vrátí se první prvek řetězce.

Ukazatel na funkci, která vrací ukazatel

Následující program ukazuje, jak je kódován ukazatel na funkci, která vrací ukazatel:

#zahrnout
pomocí jmenného prostoru std;
int * fn ()

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

int main ()

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

Výstup je 4.

Deklarace ukazatele na funkci vracející ukazatel je podobná deklaraci ukazatele na běžnou funkci, ale předchází jí hvězdička. Ilustruje to první příkaz ve funkci main (). Chcete-li volat funkci pomocí ukazatele, předcházejte *.

Závěr

Chcete-li vytvořit ukazatel na skalár, udělejte něco jako,

plovák ukázal;
float * pointer = &pointed;

* má dva významy: v deklaraci označuje ukazatel; vrátit něco, je to pro hodnotu špičatého objektu.

Název pole je konstantní ukazatel na první prvek pole.

Chcete-li vytvořit ukazatel na funkci, můžete to udělat,

int (* func) () = &fn;

kde fn () je funkce definovaná jinde a func je ukazatel.

& má dva významy: v deklaraci označuje odkaz (synonymum) na stejný objekt jako jiný identifikátor; když něco vracíte, znamená to adresu.

Chcete-li vytvořit odkaz na funkci, můžete to udělat,

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

kde fn () je funkce definovaná jinde a refFunc je reference.

Když funkce vrátí ukazatel, musí vrácenou hodnotu přijmout ukazatel. Když funkce vrací odkaz, musí být vrácená hodnota přijata odkazem.

Při předávání ukazatele na funkci je parametrem deklarace, zatímco argumentem je adresa špičatého objektu. Při předávání odkazu na funkci je parametrem deklarace, zatímco argument je odkaz.

Při předávání pole funkci je parametrem deklarace, zatímco argumentem je název pole bez []. Funkce C ++ nevrací pole.

Ukazatel na ukazatel potřebuje dva * místo jednoho, pokud je to vhodné.

Chrys

Trackpad a ukazatel myši AppyMouse na obrazovce pro tablety Windows
Uživatelé tabletů často postrádají ukazatel myši, zejména když obvykle používají notebooky. Dotykové smartphony a tablety mají mnoho výhod a jediným o...
Střední tlačítko myši nefunguje ve Windows 10
The prostřední tlačítko myši pomáhá procházet dlouhé webové stránky a obrazovky se spoustou dat. Pokud se to zastaví, budete nakonec používat klávesni...
Jak změnit levé a pravé tlačítko myši na počítači se systémem Windows 10
Je úplnou normou, že všechna zařízení počítačových myší jsou ergonomicky navržena pro praváky. K dispozici jsou však myší zařízení, která jsou speciál...