Pointer ( engelsk pointer ) är en variabel vars värdeintervall består av adresser till minnesceller eller en speciell värde- noll adress . Den senare används för att indikera att pekaren för närvarande inte hänvisar till någon av de giltiga cellerna. Pekare uppfanns av Ekaterina Logvinovna Jusjtjenko i Adressprogrammeringsspråket (1955), och inte av Harold Lawson 1964, som man länge trodde utomlands [1] . År 1955 introducerades begreppen indirekt adressering och adressering av högre rang i Address Programming Language , som täcker begreppet en pekare och dess omfattning i moderna programmeringsspråk.
Pekare används inom två områden:
Programmeringsspråk som tillhandahåller typen av pekare innehåller som regel två grundläggande operationer på dem: tilldelning och dereference .
År 1955 introducerade adressprogrammeringsspråket (USSR) "bar-operationen" (pekareavledning), som implementerades i hårdvara genom F-operationen av processorn i Kiev-datorn (1955) och senare i M-20 datorer , " Dnepr ", datorer från BESM -familjen (BESM-2, BESM-3, BESM-3M och BESM-4), familjerna Minsk och Ural, samt några andra sovjettillverkade datorer. Multipel användning av pekaravledning implementerades också i hårdvara i dessa datorer genom gruppadressuppdateringsoperationer för att påskynda arbetet med trädliknande format ( listor och andra abstrakta datatyper är ett specialfall av trädliknande format).
Den första tilldelar en viss adress till pekaren. Den andra används för att komma åt värdet i minnet som pekaren pekar på. Avlägsnande kan vara explicit eller implicit; i de flesta moderna programmeringsspråk sker dereferencing endast när det uttryckligen anges[ vad? ] .
Ett exempel på att arbeta med pekare i C- språket :
int n = 6 ; // Deklarera en variabel n av typen int och tilldela den värdet 6 int * pn = malloc ( sizeof ( int ) ); // Deklarerar pekaren pn och allokerar minne för den * pn = 5 ; // Referenspekare och tilldela värde 5 n = * pn ; // Tilldela n till värdet (5) som pekas på av pn free ( pn ); // Frigör det upptagna minnet pn = & n ; // Tilldela pekaren pn till adressen för variabel n (pekaren pekar på n) n = 7 ; // *pn blev också lika med 7Den unära operatorn &returnerar adressen till variabeln, och operatorn *används för att avreferens:
int sourceNum1 = 100 ; int sourceNum2 = 200 ; int * pNum1 = & sourceNum1 ; int * pNum2 = & sourceNum2 ; printf ( "Pekarvärde på 1-%d, 2-%d \n " , * pNum1 , * pNum2 ); pNum1 = pNum2 ; printf ( "Pekarvärde på 1-%d, 2-%d \n " , * pNum1 , * pNum2 );Om pekaren lagrar adressen till något objekt, sägs pekaren referera till eller peka på detta objekt.
Språk som tillhandahåller användning av pekare för dynamisk minnesallokering måste innehålla en operator för explicit tilldelning av variabler i minnet. På vissa språk finns det förutom denna operator även en operator för att explicit radera variabler från minnet. Båda dessa operationer tar ofta formen av inbyggda rutiner (malloc- och gratisfunktionerna i C, de nya och ta bort-operatörerna i C++, och så vidare). När du använder en enkel snarare än en smart pekare bör du alltid ta bort variabeln från minnet i tid för att undvika minnesläckor .
En void typ-pekare låter dig referera till vilken datatyp som helst , inklusive en klass . Denna teknik ligger till grund för alla typer av Boost- biblioteket .
klass A { int fält ; }; AclA ; _ void * pA = ( void * ) & clA ; // pekaren pA hänvisar till ett objekt av klass ADet finns också pekare till pekare i programmering. De lagrar minnesadresser där det finns pekare till minnet där dataobjektet finns, eller en annan pekare. Att länka en pekare till en pekare som återigen pekar på en pekare gör det möjligt för oss att introducera begreppet multipel pekareavledning (i adressprogrammeringsspråket : "adressera högre rang" ) och motsvarande åtgärd på pekare: Multipel inriktning.
int x , * p , ** q ; x = 10 ; p = & x ; q = & p ; // pekare till pekare printf ( "%d" , ** q );En nollpekare är en pekare som har ett speciellt värde som indikerar att den givna pekarvariabeln inte refererar till (pekar inte på) något objekt. I programmeringsspråk representeras den av en speciell konstant [4] :
Pekare är svåra att hantera. Det är lätt nog att skriva fel värde till en pekare, vilket kan orsaka ett svårt att återskapa fel. Till exempel ändrade du av misstag adressen till en pekare i minnet, eller felaktigt allokerat minne för information, och här kan en överraskning vänta dig: en annan mycket viktig variabel som bara används i programmet kommer att skrivas över. Att förstå exakt var felet finns och återskapa det blir inte lätt, och att eliminera sådana fel är inte alltid en trivial uppgift, ibland måste man skriva om en betydande del av programmet [6] .
För att lösa några av problemen finns det metoder för skydd och försäkring:
Ett exempel på ett fel med en oinitierad pekare:
/* programmet är ogiltigt. */ int main ( void ) { int x , * p ; // Tilldelat minne för x, men inte för *p x = 10 ; // Minnet skrivs 10 * p = x ; // 10 skrivs till en odefinierad plats i minnet, vilket kan göra att programmet kraschar. returnera 0 ; }I ett så litet program kan problemet gå obemärkt förbi. Men när programmet växer kan det plötsligt stå klart att variabeln skrivs mellan andra datablock som är viktiga för programmet. För att undvika denna situation, initiera bara [6] -pekaren .
Felaktig användning av en pekare:
#include <stdio.h> /* programmet är ogiltigt */ int main ( void ) { int x , * p ; x = 10 ; p = x ; printf ( "%d" , * p ); returnera 0 ; }Samtalet printf()visar inte värdet på х, vilket är 10, på skärmen. Istället matas ett okänt värde ut - detta är resultatet av en felaktig användning av tilldelningsoperatorn ( р = х;). Den här operatorn tilldelar värdet 10 till pekaren р, som ska innehålla adressen, inte värdet. Lyckligtvis upptäcks felet i detta program av kompilatorn - det utfärdar en varning om en ovanlig pekarkonvertering. För att åtgärda felet, skriv p = &х;[6] .
Korrekt användning av pekarenEn minnesläcka är en process för okontrollerad minskning av mängden ledigt RAM-minne (RAM) i en dator som är förknippad med fel i program som körs som inte släpper onödiga minnesområden i tid, eller med fel i systemminneskontrolltjänster.
char * pointer = NULL ; int i = 0 ; för ( i = 0 ; i < 10 ; i ++ ) { pekare = ( char * ) malloc ( 100 ); // Minnet allokeras 10 gånger } gratis ( pekare ); // A frigörs endast i det sista falletMinnesadresser som tilldelats pekare kan jämföras. Jämförelser av formen pNum1 < pNum2och pNum1 > pNum2används ofta för att sekventiellt iterera över elementen i en array i en loop : pNum1motsvarar den aktuella positionen i minnet och motsvarar pNum2 slutet av arrayen. pNum1 == pNum2kommer att returnera sant om båda pekarna pekar på samma minnesplats.
Adressaritmetik dök upp som en logisk fortsättning på idén om pekare som ärvts från assemblerspråk: i det senare är det möjligt att indikera en viss förskjutning från den nuvarande positionen.
Typiska operationer för adressaritmetik:
int * p ; // Låt oss säga att p pekar på adressen 200 p ++ ; // Efter inkrementering pekar det på 200 + sizeof(int) = 204 p -- ; // Nu pekar det tillbaka till 200.I vissa programmeringsspråk finns det klasser (oftast mallar) som implementerar pekargränssnittet med ny funktionalitet som rättar till några av de ovan nämnda bristerna.
Hjärnan använder pekare-liknande grupper av celler för att utföra några av de uppgifter som är förknippade med att komma ihåg ny information [7] .
Datatyper | |
---|---|
Otolkbart | |
Numerisk | |
Text | |
Referens | |
Sammansatt | |
abstrakt | |
Övrig | |
Relaterade ämnen |