Näpunäited C-programmeerimisel: mis on kursor, tüübid & Näited

Lang L: none (table-of-contents):

Anonim

Mis on osuti C-s?

Pointer C, on muutuja, mis salvestab tegeleda teise muutuja. Kursorit saab kasutada ka teise kursori funktsiooni viitamiseks. Kursorit saab suurendada / vähendada, st osutada järgmisele / eelmisele mälukohale. Osuti eesmärk on salvestada mäluruumi ja saavutada kiirem täitmisaeg.

Kuidas kasutada osuteid C.

Kui kuulutame int tüüpi muutuja v, salvestab v tegelikult väärtuse.

v on nüüd võrdne nulliga.

Igal muutujal on peale väärtuse ka oma aadress (või lihtsalt öeldes, kus see mälus asub). Aadressi saab kätte, kui panna muutuja nime ette ampersand (&).

Kui printite ekraanile muutuja aadressi, näeb see välja nagu täiesti juhuslik number (pealegi võib see olla jooksvalt erinev).

Proovime seda praktikas C-näites osutiga

Selle programmi väljund on -480613588.

Mis on osuti? Väärtuse salvestamise asemel salvestab kursor muutuja aadressi.

Kursori muutuja

Int * y = & v;

MUUTUV

POINTER

Väärtus salvestatakse nimega ladustamise / mälu aadress

Muutuja , mis osutab ladustamise / mälu aadress teise muutuja

Pointeriks kuulutamine

Nagu muutujad, tuleb ka C-programmeerimise osundajad enne nende programmis kasutamist deklareerida. Kursoreid võib nimetada ükskõik milliseks, kui nad järgivad C-i nime-eeskirju. Kursori deklaratsioonil on järgmine vorm.

data_type * pointer_variable_name;

Siin,

  • data_type on C muutujate tüübi osuti baastüüp ja näitab muutuja tüüpi, millele kursor osutab.
  • Tärn (*: sama tärn, mida kasutatakse korrutamiseks), mis on suunaoperaator, deklareerib kursori.

Vaatame selles C-näpunäidete õpetuses mõnda kehtivat kursori deklaratsiooni:

int *ptr_thing; /* pointer to an integer */int *ptr1,thing;/* ptr1 is a pointer to type integer and thing is an integer variable */double *ptr2; /* pointer to a double */float *ptr3; /* pointer to a float */char *ch1 ; /* pointer to a character */float *ptr, variable;/*ptr is a pointer to type float and variable is an ordinary float variable */

Initsialiseerige kursor

Pärast osuti deklareerimist initsialiseerime selle nagu muutujad koos muutuja aadressiga. Kui C-programmeerimise näpunäiteid ei initsialiseerita ja programmis ei kasutata, on tulemused ettearvamatud ja potentsiaalselt katastroofilised.

Muutuja aadressi saamiseks kasutame operaatorit ampersand (&), mis on paigutatud muutuja nime ette, mille aadressi vajame. Kursori lähtestamine toimub järgmise süntaksiga.

Kursori süntaks

 pointer = &variable; 

Allpool on toodud lihtne programm kursori illustreerimiseks:

#include int main(){int a=10; //variable declarationint *p; //pointer variable declarationp=&a; //store address of variable a in pointer pprintf("Address stored in a variable p is:%x\n",p); //accessing the addressprintf("Value stored in a variable p is:%d\n",*p); //accessing the valuereturn 0;}

Väljund:

Address stored in a variable p is:60ff08Value stored in a variable p is:10
Operaator Tähendus
* Teenib kahte eesmärki
  1. Kursori deklaratsioon
  2. Tagastab viidatud muutuja väärtuse
& Teenib ainult ühte eesmärki
  • Tagastab muutuja aadressi

Osutajate tüübid C-s

Järgmised on C-tüüpi eri tüüpi osutid :

Nullpointer

Nullkursori saame luua, määrates kursori deklaratsiooni ajal nullväärtuse. See meetod on kasulik, kui kursorile pole määratud ühtegi aadressi. Nullkursor sisaldab alati väärtust 0.

Järgmine programm illustreerib nullkursori kasutamist:

#include int main(){int *p = NULL; //null pointerprintf(“The value inside variable p is:\n%x”,p);return 0;}

Väljund:

The value inside variable p is:0

Tühine osuti

C-programmeerimisel nimetatakse tühikut osutit ka üldiseks osutiks. Sellel pole ühtegi standardset andmetüüpi. Tühine osuti luuakse märksõna tühine abil. Seda saab kasutada mis tahes muutuja aadressi salvestamiseks.

Järgmine programm illustreerib tühise kursori kasutamist:

#include int main(){void *p = NULL; //void pointerprintf("The size of pointer is:%d\n",sizeof(p));return 0;}

Väljund:

The size of pointer is:4

Metsik osuti

Kursorit peetakse metsikuks osutajaks, kui seda millekski ei initsialiseerita. Seda tüüpi C-osutid pole tõhusad, kuna need võivad viidata mõnele tundmatule mälukohale, mis võib meie programmis probleeme tekitada ja see võib põhjustada programmi krahhi. Metsikute osutitega töötamisel peaks alati olema ettevaatlik.

Järgmine programm illustreerib metsiku kursori kasutamist:

#include int main(){int *p; //wild pointerprintf("\n%d",*p);return 0;}

Väljund

timeout: the monitored command dumped coresh: line 1: 95298 Segmentation fault timeout 10s main

Muud tüüpi tähised punktis c on järgmised:

  • Rippuv osuti
  • Kompleksne osuti
  • Lähikursor
  • Kauge näpunäide
  • Tohutu osuti

Otsene ja kaudne pöörduspunkt

C-s on muutuvale sisule juurdepääsemiseks ja sellega manipuleerimiseks kaks samaväärset viisi

  • Otsene juurdepääs: kasutame muutuja nime otse
  • Kaudne juurdepääs: kasutame muutujale osutit

Mõistame seda allpool oleva programmi abil

#include /* Declare and initialize an int variable */int var = 1;/* Declare a pointer to int */int *ptr;int main( void ){/* Initialize ptr to point to var */ptr = &var;/* Access var directly and indirectly */printf("\nDirect access, var = %d", var);printf("\nIndirect access, var = %d", *ptr);/* Display the address of var two ways */printf("\n\nThe address of var = %d", &var);printf("\nThe address of var = %d\n", ptr);/*change the content of var through the pointer*/*ptr=48;printf("\nIndirect access, var = %d", *ptr);return 0;}

Pärast programmi ilma vigadeta kompileerimist on tulemus:

Direct access, var = 1Indirect access, var = 1The address of var = 4202496The address of var = 4202496Indirect access, var = 48

Kursori aritmeetika C-s

Kursori toimingud on kokku võetud järgmisel joonisel

Kursorioperatsioonid

Prioriteetne toiming (ülimuslikkus)

C-osundajatega töötamisel peame järgima järgmisi prioriteedireegleid:

  • Operaatoritel * ja & on sama prioriteet kui unaarsetel operaatoritel (eitus!, Juurdekasv ++, dekrement--).
  • Samas väljendis hinnatakse unaaroperaatoreid *, &,!, ++, - paremalt vasakule.

Kui P-osuti osutab X muutujale, siis saab * P kasutada kõikjal, kuhu X saab kirjutada.

Järgmised väljendid on samaväärsed:

int X = 10 int * P = & Y; Ülaltoodud koodi puhul on alltoodud väljendid tõesed
Väljendus Ekvivalentne väljend
Y = * P + 1 * P = * P + 10 * P + = 2 ++ * P (* P) ​​++ Y = X + 1 X = X + 10 X + = 2 ++ X X ++

Viimasel juhul on vaja sulge: kuna unaaroperaatoreid * ja ++ hinnatakse paremalt vasakule, ilma sulgudeta suureneks kursor P, mitte objekt, millele P osutab.

Allpool olev tabel näitab aritmeetilist ja põhitoimingut, mida saab kasutada C-osuti käsitlemisel

Operatsioon Selgitus
Ülesanne int * P1, * P2 P1 = P2; P1 ja P2 osutavad samale täisarvu muutujale
Suurendamine ja vähendamine Int * P1; P1 ++; P1--;
Nihke lisamine (konstant) See võimaldab kursoril liigutada tabelis N elementi. Kursorit suurendatakse või vähendatakse N korda muutuja tüübi baitide arvu võrra. P1 + 5;

C Näidikud ja massiivid

Traditsiooniliselt pääseme massiivi elementidele juurde selle indeksi abil, kuid selle meetodi saab kõrvaldada osutite abil. Osutitega on igale massiivi elemendile juurdepääs lihtne.

#include int main(){int a[5]={1,2,3,4,5}; //array initializationint *p; //pointer declaration/*the ptr points to the first element of the array*/p=a; /*We can also type simply ptr==&a[0] */printf("Printing the array elements using pointer\n");for(int i=0;i<5;i++) //loop for traversing array elements{printf("\n%x",*p); //printing array elementsp++; //incrementing to the next element, you can also write p=p+1}return 0;}

Väljund

12345

Kindla numbri lisamine kursorile viib kursori asukoha lisamistoiminguga saadud väärtuseni. Oletame, et p on osuti, mis näitab hetkel mälu asukohta 0, kui teostame järgmise liitmisoperatsiooni p + 1, siis ta täidab seda järgmiselt:

Kursori lisamine / juurdekasv

Kuna p osutab pärast 1 lisamist praegu asukohale 0, saab väärtuseks 1 ja seega osutab kursor mälu asukohale 1.

C Näpunäited ja stringid

String on tähemärkide massiiv, mis lõpeb nullmärgiga '\ 0'. Stringidega saame manipuleerida osutite abil. See näide C näites selgitab seda jaotist

#include #include int main(){char str[]="Hello Guru99!";char *p;p=str;printf("First character is:%c\n",*p);p =p+1;printf("Next character is:%c\n",*p);printf("Printing all the characters in a string\n");p=str; //reset the pointerfor(int i=0;i

Väljund

First character is:HNext character is:ePrinting all the characters in a stringHelloGuru99!

Teine võimalus stringide käsitlemiseks on mitmete osutitega, nagu järgmises programmis:

#include int main(){char *materials[ ] = { "iron", "copper", "gold"};printf("Please remember these materials :\n");int i ;for (i = 0; i < 3; i++) {printf("%s\n", materials[ i ]);}return 0;}

Väljund:

Please remember these materials:ironcoppergold

Näitajate eelised C.

  • Kursorid on kasulikud mälupunktide juurde pääsemiseks.
  • Osutajad pakuvad tõhusat juurdepääsu massiivstruktuuri elementidele.
  • Kursoreid kasutatakse nii dünaamilise mälu jaotamiseks kui ka tehingute paigutamiseks.
  • Kursoreid kasutatakse keerukate andmestruktuuride, näiteks lingitud loendi, graafiku, puu jms moodustamiseks.

Osutajate puudused C-s

  • Näpunäiteid on mõistmiseks veidi keeruline.
  • Kursorid võivad põhjustada mitmesuguseid vigu, näiteks segmenteerimisvead, või pääsevad juurde mälupesale, mida pole üldse vaja.
  • Kui osutile antakse vale väärtus, võib see põhjustada mälu rikkumist.
  • Osutajad vastutavad ka mälu lekke eest.
  • Osutajad on suhteliselt aeglasemad kui muutujad.
  • Programmeerijatel on osutitega töötamine väga keeruline; seetõttu on programmeerija kohustus kursoriga hoolikalt manipuleerida.

Kokkuvõte

  • Kursor pole midagi muud kui mälu asukoht, kuhu andmed salvestatakse.
  • Mälu asukohta pääsemiseks kasutatakse kursorit.
  • Näppe on mitmesuguseid, nagu nullkursor, metsik kursor, tühine osuti ja muud tüüpi osutid.
  • Elementidele tõhusamaks juurdepääsemiseks saab osuteid kasutada massiivi ja stringidega.
  • Funktsiooni dünaamiliseks esilekutsumiseks saame luua funktsioonijuhiseid.
  • Aritmeetilisi toiminguid saab teha osuti abil, mida nimetatakse osuti aritmeetikaks.
  • Osutajate massiivi määratlemise korral saavad osutid osutada ka funktsioonidele, mis hõlbustavad erinevate funktsioonide kutsumist.
  • Kui soovite tegeleda erineva muutuva andmetüübiga, võite kasutada tüpecast void pointerit.