Rodyklės yra simboliniai adresų atvaizdai. Jie leidžia programoms imituoti skambutį pagal nuorodą, taip pat kurti ir valdyti dinamines duomenų struktūras. Elementų kartojimas masyvuose ar kitose duomenų struktūrose yra vienas iš pagrindinių rodyklių naudojimo būdų.
Kintamojo, su kuriuo dirbate, adresas priskiriamas žymeklio kintamajam, kuris nurodo į tą patį duomenų tipą (pvz., int arba eilutę).
tinklelio išdėstymas
Sintaksė:
datatype *var_name; int *ptr; // ptr can point to an address which holds int data>
Kaip naudoti žymeklį?
- Apibrėžkite žymeklio kintamąjį
- Kintamojo adreso priskyrimas žymekliui naudojant unarinį operatorių (&), kuris grąžina to kintamojo adresą.
- Prieiga prie vertės, saugomos adresu, naudojant unarinį operatorių (*), kuris grąžina kintamojo, esančio jo operando nurodytu adresu, reikšmę.
Priežastis, kodėl duomenų tipą susiejame su žymekliu, yra kad ji žinotų, kiek baitų saugomi duomenys . Kai padidiname žymeklį, padidiname jį duomenų tipo, į kurį jis nukreipia, dydžiu.
C++ // C++ program to illustrate Pointers #include using namespace std; void geeks() { int var = 20; // declare pointer variable int* ptr; // note that data type of ptr and var must be same ptr = &var; // assign the address of a variable to a pointer cout << 'Value at ptr = ' << ptr << '
'; cout << 'Value at var = ' << var << '
'; cout << 'Value at *ptr = ' << *ptr << '
'; } // Driver program int main() { geeks(); return 0; }> Išvestis
Value at ptr = 0x7ffe454c08cc Value at var = 20 Value at *ptr = 20>
Nuorodos ir nuorodos
Yra 3 būdai, kaip perduoti C++ argumentus funkcijai:
- Skambinimas pagal vertę
- Skambinimas pagal nuorodą su rodyklės argumentu
- Skambinimas pagal nuorodą su atskaitos argumentu
// C++ program to illustrate call-by-methods #include using namespace std; // Pass-by-Value int square1(int n) { // Address of n in square1() is not the same as n1 in // main() cout << 'address of n1 in square1(): ' << &n << '
'; // clone modified inside the function n *= n; return n; } // Pass-by-Reference with Pointer Arguments void square2(int* n) { // Address of n in square2() is the same as n2 in main() cout << 'address of n2 in square2(): ' << n << '
'; // Explicit de-referencing to get the value pointed-to *n *= *n; } // Pass-by-Reference with Reference Arguments void square3(int& n) { // Address of n in square3() is the same as n3 in main() cout << 'address of n3 in square3(): ' << &n << '
'; // Implicit de-referencing (without '*') n *= n; } void geeks() { // Call-by-Value int n1 = 8; cout << 'address of n1 in main(): ' << &n1 << '
'; cout << 'Square of n1: ' << square1(n1) << '
'; cout << 'No change in n1: ' << n1 << '
'; // Call-by-Reference with Pointer Arguments int n2 = 8; cout << 'address of n2 in main(): ' << &n2 << '
'; square2(&n2); cout << 'Square of n2: ' << n2 << '
'; cout << 'Change reflected in n2: ' << n2 << '
'; // Call-by-Reference with Reference Arguments int n3 = 8; cout << 'address of n3 in main(): ' << &n3 << '
'; square3(n3); cout << 'Square of n3: ' << n3 << '
'; cout << 'Change reflected in n3: ' << n3 << '
'; } // Driver program int main() { geeks(); }> Išvestis
address of n1 in main(): 0x7fffa7e2de64 address of n1 in square1(): 0x7fffa7e2de4c Square of n1: 64 No change in n1: 8 address of n2 in main(): 0x7fffa7e2de68 address of n2 in square2(): 0x7fffa7e2de68 Square of n2: 64 Change reflected in n2: 64 address of n3 in main(): 0x7fffa7e2de6c address of n3 in square3(): 0x7fffa7e2de6c Square of n3: 64 Change reflected in n3: 64>
C++, pagal numatytuosius nustatymus argumentai perduodami pagal reikšmę, o pakviestoje funkcijoje atlikti pakeitimai neatsispindės perduodamame kintamajame. Pakeitimai atliekami į iškviestos funkcijos sukurtą kloną. Jei norime tiesiogiai modifikuoti originalią kopiją (ypač perduodant didžiulį objektą ar masyvą) ir (arba) išvengti papildomų klonavimo išlaidų, naudojame nuorodą. Nuorodų perdavimas su nuorodos argumentais nereikalauja jokios gremėzdiškos nuorodų ir nuorodų panaikinimo sintaksės.
- Funkcijų rodyklės C
- Rodyklė į funkciją
Masyvo pavadinimas kaip rodyklės
An masyvas pavadinimas yra pirmojo masyvo elemento, kuris veikia kaip pastovi rodyklė, adresas. Tai reiškia, kad masyvo pavadinime saugomo adreso pakeisti negalima. Pavyzdžiui, jei turime masyvą pavadinimu val tada val ir &val[0] gali būti naudojami pakaitomis.
C++ // C++ program to illustrate Array Name as Pointers #include using namespace std; void geeks() { // Declare an array int val[3] = { 5, 10, 20 }; // declare pointer variable int* ptr; // Assign the address of val[0] to ptr // We can use ptr=&val[0];(both are same) ptr = val; cout << 'Elements of the array are: '; cout << ptr[0] << ' ' << ptr[1] << ' ' << ptr[2]; } // Driver program int main() { geeks(); }> Išvestis
Elements of the array are: 5 10 20>
Jei rodyklė ptr siunčiama funkcijai kaip argumentas, masyvo val galima pasiekti panašiai. Rodyklė prieš masyvą
Rodyklės išraiškos ir rodyklės aritmetika
Ribotas rinkinys aritmetika operacijas galima atlikti su rodyklėmis, kurios yra:
java konvertuoti char į eilutę
- padidintas (++)
- sumažėjo ( - )
- prie rodyklės gali būti pridėtas sveikasis skaičius (+ arba +=)
- sveikasis skaičius gali būti atimtas iš rodyklės ( – arba –= )
- skirtumas tarp dviejų rodyklių (p1-p2)
( Pastaba: Rodyklės aritmetika yra beprasmė, nebent ji atliekama masyve.)
C++ // C++ program to illustrate Pointer Arithmetic #include using namespace std; void geeks() { // Declare an array int v[3] = { 10, 100, 200 }; // declare pointer variable int* ptr; // Assign the address of v[0] to ptr ptr = v; for (int i = 0; i < 3; i++) { cout << 'Value at ptr = ' << ptr << '
'; cout << 'Value at *ptr = ' << *ptr << '
'; // Increment pointer ptr by 1 ptr++; } } // Driver program int main() { geeks(); }> Išvestis
Value at ptr = 0x7ffe5a2d8060 Value at *ptr = 10 Value at ptr = 0x7ffe5a2d8064 Value at *ptr = 100 Value at ptr = 0x7ffe5a2d8068 Value at *ptr = 200>
Išplėstinė žymeklio žymėjimas
Apsvarstykite dvimačių skaitmeninių masyvų žymeklio žymėjimą. apsvarstykite toliau pateiktą deklaraciją
int nums[2][3] = { { 16, 18, 20 }, { 25, 26, 27 } };>Apskritai skaičiai[i ][ j ] yra lygiaverčiai *(*(skaičiai+i)+j)
Rodyklės ir stygų literalai
Eilučių literalai yra masyvai, kuriuose yra nulinių ženklų sekos. Eilučių literalai yra simbolio tipo ir baigiamojo nulinio simbolio masyvai, kurių kiekvienas elementas yra const char tipo (nes eilutės simbolių keisti negalima).
>
Tai deklaruoja masyvą su pažodiniu geek atvaizdavimu, o tada žymeklis į pirmąjį jo elementą priskiriamas ptr. Jei įsivaizduosime, kad geek yra saugomas atminties vietose, kurios prasideda adresu 1800, ankstesnę deklaraciją galime pavaizduoti taip:

Kadangi rodyklės ir masyvai išraiškose elgiasi taip pat, ptr gali būti naudojamas norint pasiekti eilutės literalo simbolius. Pavyzdžiui:
char ptr = 0; char x = *(ptr+3); char y = ptr[3];>
Čia ir x, ir y yra k, saugomi 1803 (1800+3).
xd xd prasmė
Rodyklės į rodykles
C++ kalboje galime sukurti žymeklį, kuris savo ruožtu gali nurodyti duomenis ar kitą žymeklį. Sintaksė tiesiog reikalauja, kad kiekvienas netiesioginės krypties lygis būtų vienkartinis operatorius (*), deklaruojant žymeklį.
char a; char *b; char ** c; a = ’g’; b = &a; c = &b;>
Čia b nurodo simbolį, kuriame saugoma „g“, o c – žymeklį b.
Tuščios rodyklės
Tai specialus žymeklio tipas, prieinamas C++, kuris rodo tipo nebuvimą. Tuščios rodyklės yra rodyklės, nukreipiančios į vertę, kuri neturi tipo (taigi ir neapibrėžto ilgio bei neapibrėžtų nuorodų panaikinimo savybių). Tai reiškia, kad tuščiosios rodyklės turi didelį lankstumą, nes gali nurodyti bet kokį duomenų tipą. Už tokį lankstumą atsiperka. Šios nuorodos negali būti tiesiogiai atšauktos. Prieš panaikinant nuorodas, jie pirmiausia turi būti paversti kito tipo rodyklėmis, kurios nurodo konkretų duomenų tipą.
C++ // C++ program to illustrate Void Pointer #include using namespace std; void increase(void* data, int ptrsize) { if (ptrsize == sizeof(char)) { char* ptrchar; // Typecast data to a char pointer ptrchar = (char*)data; // Increase the char stored at *ptrchar by 1 (*ptrchar)++; cout << '*data points to a char' << '
'; } else if (ptrsize == sizeof(int)) { int* ptrint; // Typecast data to a int pointer ptrint = (int*)data; // Increase the int stored at *ptrchar by 1 (*ptrint)++; cout << '*data points to an int' << '
'; } } void geek() { // Declare a character char c = 'x'; // Declare an integer int i = 10; // Call increase function using a char and int address // respectively increase(&c, sizeof(c)); cout << 'The new value of c is: ' << c << '
'; increase(&i, sizeof(i)); cout << 'The new value of i is: ' << i << '
'; } // Driver program int main() { geek(); }> Išvestis
*data points to a char The new value of c is: y *data points to an int The new value of i is: 11>
Netinkamos rodyklės
Žymeklis turi nukreipti į galiojantį adresą, bet nebūtinai į galiojančius elementus (kaip masyvuose). Tai vadinama netinkamomis rodyklėmis. Neinicializuoti rodyklės taip pat yra netinkamos.
int *ptr1; int arr[10]; int *ptr2 = arr+20;>
Čia ptr1 nėra inicijuotas, todėl jis tampa netinkama rodyklė, o ptr2 yra už arr ribų, todėl jis taip pat tampa netinkama rodyklė. (Pastaba: netinkamos rodyklės nebūtinai sukelia kompiliavimo klaidas)
NULL rodyklės
A nulinis rodyklė yra rodyklė, kuri nerodo niekur, o ne tik netinkamas adresas. Toliau pateikiami 2 būdai priskirti žymeklį kaip NULL;
int *ptr1 = 0; int *ptr2 = NULL;>
Rodyklės pranašumai
- Rodyklės sumažina kodą ir pagerina našumą. Jie naudojami eilutėms, medžiams, masyvams, struktūroms ir funkcijoms gauti.
- Rodyklės leidžia mums grąžinti kelias funkcijas iš funkcijų.
- Be to, rodyklės leidžia pasiekti atminties vietą kompiuterio atmintyje.
Susiję straipsniai:
konvertuoti strin į int
- Nepermatomas rodyklė
- Netoli, toli ir didžiuliai rodyklės
Viktorinos:
- Rodyklės pagrindai
- Išplėstinė rodyklė