logo

C++ rodyklės

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 žymeklis veikia C++

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.

Rodyklės C++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++
// 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.

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>
Duomenų atvaizdavimas atmintyje

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>
Duomenų atvaizdavimas atmintyje

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 žymėjimas C++

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:

Rodyklės ir eilučių raidės

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ė