Pekare (datorprogrammering)
AdaEdit
Ada är ett starkt skrivet språk där alla pekare skrivs och endast säkra typkonverteringar är tillåtna. Alla pekare initialiseras som standard till null
, och varje försök att komma åt data via en null
-pekare gör att ett undantag höjs. Pekare i Ada kallas åtkomsttyper. Ada 83 tillät inte aritmetik på åtkomsttyper (även om många leverantörer av kompilatorer tillhandahöll det som en icke-standardfunktion), men Ada 95 stöder ”säker” aritmetik på åtkomsttyper via paketet System.Storage_Elements
.
BASICEdit
Flera gamla versioner av BASIC för Windows-plattformen hade stöd för STRPTR () för att returnera adressen till en sträng och för VARPTR () för att returnera adressen till Visual Basic 5 hade också stöd för OBJPTR () för att returnera adressen till ett objektgränssnitt och för en ADDRESSOF-operatör att returnera adressen till en funktion. Typerna av alla dessa är heltal, men deras värden motsvarar de som innehas av pekartyper.
Nyare dialekter av BASIC, som FreeBASIC eller BlitzMax, har dock uttömmande pekareimplementeringar. I FreeBASIC är aritmetik på ANY
pekare ( motsvarande C ”s void*
) behandlas som om ANY
-pekaren var en bytebredd. ANY
pekare kan inte hänvisas till, som i C. Om du kastar mellan ANY
och andra typer av pekare genereras inga varningar.
dim as integer f = 257dim as any ptr g = @fdim as integer ptr i = gassert(*i = 257)assert( (g + 4) = (@f + 1) )
C and C ++ Edit
I C- och C ++ -pekare är variabler som lagrar adresser och kan vara noll. Varje pekare har en typ som den pekar på, men man kan fritt kasta mellan pekartyper (men inte mellan en funktionspekare och en objektpekare). En speciell pekartyp som kallas ”tomrumspekaren” gör det möjligt att peka på valfri -funktion) objekt, men är begränsat av det faktum att det inte kan hänvisas direkt (det ska gjutas). Själva adressen kan ofta manipuleras direkt genom att kasta en pekare till och från en integrerad typ av tillräcklig storlek, även om resultaten är implementeringsdefinierade och verkligen kan orsaka odefinierat beteende; medan tidigare C-standarder inte hade en integrerad typ som garanterades vara tillräckligt stor, anger C99 uintptr_t
typedef-namnet definierat i <stdint.h>
, men en implementering behöver inte tillhandahålla den.
C ++ stöder helt C-pekare och C-typecasting. Det stöder också en ny grupp av typoperatörsoperatörer för att fånga några oavsiktliga farliga casts vid sammanställningstid. Sedan C ++ 11 tillhandahåller C ++ – standardbiblioteket också smarta pekare (unique_ptr
, shared_ptr
och weak_ptr
) som kan användas i vissa situationer som ett säkrare alternativ till primitiva C-pekare. C ++ stöder också en annan typ av referens, helt annorlunda än en pekare, kallad helt enkelt en referens eller referens typ.
Pekare aritmetik, det vill säga möjligheten att ändra en pekares måladress med aritmetiska operationer (som jämförelse med storleken) är begränsad av språkstandarden för att förbli inom gränserna för ett enda arrayobjekt (eller strax efter det) och på annat sätt åberopar odefinierat beteende. Att lägga till eller subtrahera från en pekare flyttar det med en multipel av storleken Om du till exempel lägger till 1 till en pekare till 4-byte-helvärden kommer pekarens pekade till byte-adress att ökas med 4. Detta har effekten att pekaren ökas för att peka på nästa element i en sammanhängande array av heltal – vilket ofta är det avsedda resultatet. Pekare-aritmetik kan inte utföras på void
-pekare eftersom tomrumstypen inte har någon storlek och därför kan den spetsiga adressen inte läggas till, även om gcc och andra kompilatorer kommer att utföra byte-aritmetik på void*
som ett icke-standardtillägg och behandlar det som om det vore char *
.
Pekaren aritmetik ger programmeraren en ett sätt att hantera olika typer: addera och subtrahera det antal element som krävs istället för den faktiska förskjutningen i byte. (Pekare-aritmetik med char *
-pekare använder byteförskjutningar, eftersom sizeof(char)
är 1 per definition.) Speciellt C-definitionen förklarar uttryckligen att syntax a
, vilket är n
-elementet i arrayen a
till *(a + n)
, vilket är innehållet i elementet pekat av a + n
. Detta innebär att n
motsvarar a
, och man kan t.ex. skriva a
eller 3
lika bra för att komma åt det fjärde elementet i en array a
.
Medan kraftfull pekare aritmetik kan vara en källa till datorfel. Det tenderar att förvirra nybörjare och tvinga dem till olika sammanhang: ett uttryck kan vara en vanlig aritmetisk eller en pekare aritmetisk, och ibland är det lätt att misstänka varandra. Som svar på detta tillåter många moderna datorspråk på hög nivå (till exempel Java) inte direkt åtkomst till minne med adresser. Den säkra C-dialekten Cyclone tar också upp många av problemen med pekare. Se programmeringsspråk C för mer diskussion.
void
-pekaren, eller void*
, stöds i ANSI C och C ++ som en generisk pekartyp. En pekare till void
kan lagra adressen till vilket objekt som helst (inte funktion), och i C konverteras implicit till någon annan objektpekartyp vid tilldelning, men den måste uttryckligen kastas om dereferens.K & RC använde char*
för ”typ-agnostisk pekare” (före ANSI C).
C ++ tillåter inte implicit konvertering av void*
till andra pekartyper, inte ens i uppdrag. Detta var ett designbeslut för att undvika slarviga och till och med oavsiktliga gjutningar, även om de flesta kompilatorer bara ger varningar , inte fel, när andra stötar.
I C ++ finns ingen void&
(referens till ogiltig) som kompletterar void*
(pekare till ogiltig), eftersom referenser beter sig som alias till variablerna de pekar på, och det kan aldrig finnas en variabel vars typ är void
.
Syntaxöversikt över pekardeklaration Redigera
Dessa pekardeklarationer c över de flesta varianter av pekardeklarationer. Naturligtvis är det möjligt att ha trippelpekare, men huvudprinciperna bakom en trippelpekare finns redan i en dubbelpekare.
() och har högre prioritet än *.
C # Redigera
I programmeringsspråket C # stöds pekare endast under vissa förhållanden: alla kodblock inklusive pekare måste markeras med nyckelordet unsafe
. Sådana block kräver vanligtvis högre säkerhetsbehörigheter för att kunna köras. Syntaxen är i huvudsak densamma som i C ++, och den pekade adressen kan antingen hanteras eller ej hanteras. Pekare till hanterat minne (vilken pekare som helst till ett hanterat objekt) måste dock deklareras med nyckelordet fixed
, vilket förhindrar sopuppsamlaren från att flytta det spetsiga objektet som en del av minneshantering medan pekaren är inom räckvidden, vilket gör att pekarens adress är giltig.
Ett undantag från detta är från att använda IntPtr
-strukturen, vilket är en säker hanterad motsvarighet till int*
och kräver inte osäker kod. Denna typ returneras ofta när man använder metoder från System.Runtime.InteropServices
, till exempel:
.NET-ramverket innehåller många klasser och metoder i System
och System.Runtime.InteropServices
namnområden (som Marshal
-klassen) som konverterar .NET-typer (till exempel System.String
) till och från många icke-hanterade typer och pekare (till exempel LPWSTR
eller void*
) för att tillåta kommunikation med okontrollerad kod. De flesta sådana metoder har samma krav på säkerhetstillstånd som ohanterad kod, eftersom de kan påverka godtyckliga platser i minnet.
COBOLEdit
COBOL-programmeringsspråket stöder pekare till variabler. Primitiva eller grupp (post) dataobjekt som deklarerats inom LINKAGE SECTION
i ett program är i sig pekarbaserade, där det enda minnet som tilldelats inom programmet är plats för datapostens adress ( vanligtvis ett enda minnesord). I programkällkoden används dessa dataobjekt precis som alla andra WORKING-STORAGE
variabler, men deras innehåll är implicit tillgängligt indirekt via deras LINKAGE
pekare .
Minnesutrymme för varje pekat dataobjekt allokeras vanligtvis dynamiskt med hjälp av externa CALL
-uttalanden eller via inbäddade utökade språkkonstruktioner som EXEC CICS
eller EXEC SQL
uttalanden.
Utökade versioner av COBOL ger också pekvariabler som deklareras med USAGE
IS
POINTER
klausuler. Värdena för sådana pekvariabler fastställs och modifieras med SET
och SET
ADDRESS
uttalanden.
Vissa utökade versioner av COBOL tillhandahåller också PROCEDURE-POINTER
variabler som kan lagra adresserna till körbar kod.
PL / IEdit
PL / I-språket ger fullt stöd för pekare till alla datatyper (inklusive pekare till strukturer), rekursion, multitasking, stränghantering och omfattande inbyggda funktioner.PL / I var ett stort steg framåt jämfört med tidens programmeringsspråk. PL / I-pekare är otypade och därför behövs ingen gjutning för pekareherferens eller tilldelning. Deklarationssyntaxen för en pekare är DECLARE xxx POINTER;
, vilket förklarar en pekare som heter ”xxx”. Pekare används med BASED
variabler. En baserad variabel kan deklareras med en standardlokaliserare (DECLARE xxx BASED(ppp);
eller utan (DECLARE xxx BASED;
), där xxx är en baserad variabel, som kan vara en elementvariabel, en struktur eller en matris, och ppp är standardpekaren). En sådan variabel kan vara adress utan en uttrycklig pekarehänvisning (xxx=1;
, eller kan adresseras med en uttrycklig hänvisning till standardlokalisatorn (ppp) eller till någon annan pekare (qqq->xxx=1;
).
Pekarens aritmetik är inte en del av PL / I-standarden, men många kompilatorer tillåter uttryck av formuläret ptr = ptr±expression
IBM PL / I har också den inbyggda funktionen PTRADD
för att utföra aritmetiken. Pekarens aritmetik utförs alltid i byte.
IBM Enterprise PL / I-kompilatorer har en ny form av typad pekare som kallas HANDLE
.
DEdit
D-programmeringsspråket är ett derivat av C och C ++ som helt stöder C pekare och C-typberäkning.
EiffelEdit
Det objektorienterade språket Eiffel använder värde- och referenssemantik utan pekare-aritmetik. Ändå tillhandahålls pekarklasser. De erbjuder pekare-aritmetik, typecasting, explicit minneshantering, int erfacing med icke-Eiffel-programvara och andra funktioner.
FortranEdit
Fortran-90 introducerade en starkt skriven pekfunktion. Fortran-pekare innehåller mer än bara en enkel minnesadress. De kapslar också nedre och övre gränserna för arraydimensioner, steg (till exempel för att stödja godtyckliga array-sektioner) och andra metadata. En associeringsoperatör =>
används för att associera en POINTER
till en variabel som har en TARGET
attribut. Fortran-90 ALLOCATE
-uttrycket kan också användas för att associera en pekare till ett minnesblock. Följande kod kan till exempel användas för att definiera och skapa en länkad liststruktur:
Fortran-2003 lägger till stöd för procedurpekare. Som en del av C-interoperabilitetsfunktionen stöder Fortran-2003 inneboende funktioner för att konvertera pekare i C-stil till Fortran-pekare och tillbaka.
GoEdit
Go har pekare. Dess deklarationssyntax motsvarar C, men skrivs tvärtom och slutar med typen. Till skillnad från C har Go sopuppsamling och tillåter inte pekarens aritmetik. Referenstyper, som i C ++, finns inte. Vissa inbyggda typer, som kartor och kanaler, är inramade (dvs internt är de pekare till muterbara strukturer) och initialiseras med funktionen make
. I ett tillvägagångssätt för enhetlig syntax mellan pekare och icke-pekare har pilen (->
) tappats: punktoperatören på en pekare hänvisar till fältet eller metoden för det derferenserade objektet . Detta fungerar dock bara med en indirektionsnivå.
JavaEdit
Till skillnad från C, C ++ eller Pascal finns det ingen uttrycklig representation av pekare i Java. Istället implementeras mer komplexa datastrukturer som objekt och matriser med referenser. Språket tillhandahåller inga explicita operatorer för pekmanipulation. Det är fortfarande möjligt för kod att försöka dereferera en nullreferens (nullpekare), vilket resulterar i att ett körtidsundantag kastas. Utrymmet som upptas av icke-referensminneobjekt återställs automatiskt genom skräpsamling vid körning.
Modula-2Edit
Pekare implementeras väldigt mycket som i Pascal, liksom VAR
parametrar i proceduranrop. Modula-2 är ännu starkare typad än Pascal, med färre sätt att undkomma typsystemet. Några av varianterna av Modula-2 (som Modula-3) inkluderar sopuppsamling.
OberonEdit
I likhet med Modula-2 finns pekare tillgängliga. Det finns fortfarande färre sätt att undvika typsystemet och så Oberon och dess varianter är fortfarande säkrare med avseende på pekare än Modula-2 eller dess varianter. Som med Modula-3 är avfallssamling en del av språkspecifikationen.
PascalEdit
Till skillnad från många språk som har pekare tillåter standard ISO Pascal bara pekare att referera till dynamiskt skapade variabler som är anonyma och tillåter dem inte att referera till vanliga statiska eller lokala variabler. Det har inte pekare aritmetik. Pekare måste också ha en associerad typ och en pekare till en typ är inte kompatibel med en pekare till en annan typ (t.ex. är en pekare till en char inte kompatibel med en pekare till ett heltal).Detta hjälper till att eliminera de typsäkerhetsproblem som finns med andra pekareimplementeringar, särskilt de som används för PL / I eller C.Det tar också bort vissa risker orsakade av dinglande pekare, men möjligheten att dynamiskt släppa referensutrymme genom att använda dispose
standardprocedur (som har samma effekt som free
biblioteksfunktionen som finns i C) innebär att risken för dinglande pekare inte har eliminerats helt.
I vissa kommersiella och öppen källkods Pascal (eller derivat) kompilatorimplementeringar – som Free Pascal, Turbo Pascal eller Object Pascal i Embarcadero Delphi – får en pekare hänvisa till standardstatiska eller lokala variabler och kan vara cast från en pekartyp till en annan. Dessutom är pekarens aritmetik obegränsad: att lägga till eller subtrahera från en pekare flyttar den med det antalet byte i båda riktningarna, men använder Inc
eller Dec
standardprocedurer med den flyttar pekaren efter storleken på datatypen som deklareras peka på. En otypad pekare finns också under namnet Pointer
, vilket är kompatibelt med andra pekartyper.