Peker (dataprogrammering)
AdaEdit
Ada er et sterkt skrevet språk der alle pekere er skrevet og bare sikre konverteringer er tillatt. Alle pekere er som standard initialisert til null
, og ethvert forsøk på å få tilgang til data gjennom en null
-peker fører til at et unntak heves. Pekere i Ada kalles tilgangstyper. Ada 83 tillot ikke aritmetikk på tilgangstyper (selv om mange kompilatørleverandører sørget for det som en ikke-standard funksjon), men Ada 95 støtter «sikker» aritmetikk på tilgangstyper via pakken System.Storage_Elements
.
BASICEdit
Flere gamle versjoner av BASIC for Windows-plattformen hadde støtte for STRPTR () for å returnere adressen til en streng, og for VARPTR () for å returnere adressen til Visual Basic 5 hadde også støtte for OBJPTR () for å returnere adressen til et objektgrensesnitt, og for en ADDRESSOF-operatør for å returnere adressen til en funksjon. Typene av alle disse er heltall, men deres verdier tilsvarer de som holdes av pekertyper.
Nyere dialekter av BASIC, som FreeBASIC eller BlitzMax, har imidlertid uttømmende pekerimplementeringer. I FreeBASIC er regning på ANY
pekere ( tilsvarende C «s void*
) behandles som om ANY
-pekeren var en bytebredde. ANY
pekere kan ikke refereres til, som i C. Dessuten vil casting mellom ANY
og andre typer pekere ikke generere noen advarsler.
dim as integer f = 257dim as any ptr g = @fdim as integer ptr i = gassert(*i = 257)assert( (g + 4) = (@f + 1) )
C og C ++ Rediger
I C og C ++ er pekere variabler som lagrer adresser og kan være null. Hver peker har en type den peker på, men man kan fritt kaste mellom pekertyper (men ikke mellom en funksjonspeker og en objektpeker). En spesiell pekertype kalt «tom pekepinn» gjør det mulig å peke på hvilken som helst (ikke -funksjon) objekt, men er begrenset av det faktum at det ikke kan refereres direkte (det skal støpes). Selve adressen kan ofte manipuleres direkte ved å kaste en peker til og fra en integrert type av tilstrekkelig størrelse, selv om resultatene er implementeringsdefinerte og faktisk kan forårsake udefinert oppførsel; mens tidligere C-standarder ikke hadde en integrert type som garantert var stor nok, spesifiserer C99 uintptr_t
typedef-navnet definert i <stdint.h>
, men en implementering trenger ikke å gi det.
C ++ støtter fullt ut C-pekere og C typecasting. Den støtter også en ny gruppe typecasting-operatører for å fange utilsiktede farlige rollebesetninger på kompileringstidspunktet. Siden C ++ 11 gir C ++ standardbiblioteket også smarte pekere (unique_ptr
, shared_ptr
og weak_ptr
) som kan brukes i noen situasjoner som et tryggere alternativ til primitive C-pekere. C ++ støtter også en annen referanseform, ganske forskjellig fra en peker, kalt bare en referanse eller referansetype.
Pekeraritmetikk, det vil si muligheten til å endre en pekers måladresse med aritmetiske operasjoner (som sammenlikning med størrelsesorden), er begrenset av språkstandarden til å forbli innenfor grensene til et enkelt array-objekt (eller like etter det), og vil ellers påberope seg udefinert oppførsel. Å legge til eller trekke fra en peker flytter det med et multiplum av størrelsen Hvis du for eksempel legger til 1 til en peker til 4-byte heltallverdier, øker pekeren som er pekt til byte-adressen med 4. Dette har den effekten at pekeren økes for å peke på neste element i en sammenhengende rekke med heltall — som ofte er det tiltenkte resultatet. Pekere aritmetikk kan ikke utføres på void
pekere fordi tomromstypen ikke har størrelse, og dermed kan den spisse adressen ikke legges til, selv om gcc og andre kompilatorer vil utføre byte-aritmetikk på void*
som en ikke-standard utvidelse, og behandler den som om den var char *
.
Pekeraritmetikk gir programmereren en enkelt måte å håndtere forskjellige typer på: å legge til og trekke antallet nødvendige elementer i stedet for den faktiske forskyvningen i byte. (Pekere aritmetisk med char *
pekere bruker byteforskyvninger, fordi sizeof(char)
per definisjon er 1.) Spesielt erklærer C-definisjonen eksplisitt at syntaks a
, som er n
-te element i matrisen a
, er ekvivalent til *(a + n)
, som er innholdet i elementet pekt av a + n
. Dette innebærer at n
tilsvarer a
, og man kan skrive f.eks. a
eller 3
like bra for å få tilgang til det fjerde elementet i en matrise a
.
Selv om kraftig, pekere aritmetikk kan være en kilde til datamaskinfeil. Det har en tendens til å forvirre nybegynnerprogrammerere, og tvinge dem inn i forskjellige sammenhenger: et uttrykk kan være en vanlig regning eller en pekere, og noen ganger er det lett å feile den ene for den andre. Som svar på dette, tillater mange moderne dataspråk på høyt nivå (for eksempel Java) ikke direkte tilgang til minne ved hjelp av adresser. Den sikre C-dialekten Cyclone adresserer også mange av problemene med pekere. Se programmeringsspråk C for mer diskusjon.
void
pekeren, eller void*
, støttes i ANSI C og C ++ som en generisk pekertype. En peker til void
kan lagre adressen til et hvilket som helst objekt (ikke funksjon), og i C konverteres det implisitt til en hvilken som helst annen objektpekertype ved tildelingen, men den må eksplisitt kastes hvis dereferenser.K & RC brukte char*
for «type agnostisk peker» -formål (før ANSI C).
C ++ tillater ikke implisitt konvertering av void*
til andre pekertyper, selv ikke i oppgaver. Dette var en designbeslutning for å unngå uforsiktig og til og med utilsiktet rollebesetning, selv om de fleste kompilatorer bare gir advarsler , ikke feil, når du støter på andre rollebesetninger.
I C ++ er det ingen void&
(referanse til ugyldig) som utfyller void*
(peker til ugyldig), fordi referanser oppfører seg som aliaser til variablene de peker på, og det kan aldri være en variabel hvis type er void
.
Syntaksoversikt over pekererklæring Rediger
Disse pekererklæringene c over de fleste varianter av pekererklæringer. Selvfølgelig er det mulig å ha trippel pekere, men hovedprinsippene bak en trippel peker eksisterer allerede i en dobbel peker.
() og har høyere prioritet enn *.
C # Rediger
På programmeringsspråket C # støttes pekere bare under visse betingelser: enhver blokk med kode inkludert pekere må merkes med unsafe
nøkkelordet. Slike blokker krever vanligvis høyere sikkerhetstillatelser for å få lov til å kjøre. Syntaksen er egentlig den samme som i C ++, og adressen som pekes kan være enten administrert eller ikke-administrert minne. Pekere til administrert minne (hvilken som helst peker til et administrert objekt) må imidlertid erklæres ved å bruke nøkkelordet fixed
, som forhindrer søppeloppsamleren fra å flytte det spisse objektet som en del av minnestyring mens pekeren er i omfang, og dermed holder pekeradressen gyldig.
Et unntak fra dette er fra å bruke IntPtr
-strukturen, som er en sikker administrert ekvivalent med int*
, og krever ikke usikker kode. Denne typen returneres ofte når du bruker metoder fra System.Runtime.InteropServices
, for eksempel:
.NET-rammeverket inkluderer mange klasser og metoder i System
og System.Runtime.InteropServices
navnerom (for eksempel Marshal
-klassen) som konverterer .NET-typer (for eksempel System.String
) til og fra mange ikke-administrerte typer og pekere (for eksempel LPWSTR
eller void*
) for å tillate kommunikasjon med ikke-administrert kode. De fleste slike metoder har de samme sikkerhetstillatelseskravene som ikke-administrert kode, siden de kan påvirke vilkårlige steder i minnet.
COBOLEdit
COBOL-programmeringsspråket støtter pekere til variabler. Primitive eller gruppe (post) dataobjekter deklarert i LINKAGE SECTION
til et program er iboende pekerbasert, hvor det eneste minnet som er tildelt i programmet er plass til adressen til dataelementet ( vanligvis et enkelt minneord). I programkildekoden brukes disse dataelementene akkurat som alle andre WORKING-STORAGE
variabler, men innholdet deres er implisitt tilgjengelig indirekte gjennom LINKAGE
pekere .
Minneplass for hvert pekte dataobjekt tildeles vanligvis dynamisk ved hjelp av eksterne CALL
-uttalelser eller via innebygde utvidede språkkonstruksjoner som EXEC CICS
eller EXEC SQL
utsagn.
Utvidede versjoner av COBOL gir også pekervariabler erklært med USAGE
IS
POINTER
klausuler. Verdiene til slike pekervariabler etableres og modifiseres ved hjelp av SET
og SET
ADDRESS
utsagn.
Noen utvidede versjoner av COBOL gir også PROCEDURE-POINTER
variabler som kan lagre adressene til den kjørbare koden.
PL / IEdit
PL / I-språket gir full støtte for pekere til alle datatyper (inkludert pekere til strukturer), rekursjon, multitasking, strenghåndtering og omfattende innebygde funksjoner.PL / I var et stort fremskritt i forhold til programmeringsspråkene på sin tid. PL / I-pekere er ikke skrevet, og det er derfor ikke behov for avstøpning for pekereferanse eller tildeling. Deklarasjonssyntaks for en peker er DECLARE xxx POINTER;
, som erklærer en peker med navnet «xxx». Pekere brukes med BASED
-variabler. En basert variabel kan deklareres med en standardlokator (DECLARE xxx BASED(ppp);
eller uten (DECLARE xxx BASED;
), der xxx er en basert variabel, som kan være en elementvariabel, en struktur eller en matrise, og ppp er standardpekeren). En slik variabel kan være adresse uten en eksplisitt pekerreferanse (xxx=1;
, eller kan adresseres med en eksplisitt referanse til standardlokatoren (ppp), eller til en hvilken som helst annen peker (qqq->xxx=1;
).
Peker-aritmetikk er ikke en del av PL / I-standarden, men mange kompilatorer tillater uttrykk for skjemaet ptr = ptr±expression
IBM PL / I har også den innebygde funksjonen PTRADD
for å utføre aritmetikken. Pekeraritmetikk utføres alltid i byte.
IBM Enterprise PL / I-kompilatorer har en ny form for skrevet peker kalt HANDLE
.
DEdit
D-programmeringsspråket er et derivat av C og C ++ som fullt ut støtter C pekere og C-typecasting.
EiffelEdit
Det Eiffel objektorienterte språket benytter verdi- og referansesemantikk uten peker-aritmetikk. Ikke desto mindre tilbys pekeklasser. De tilbyr pekere-aritmetikk, typecasting, eksplisitt minnehåndtering, int erfacing med ikke-Eiffel-programvare og andre funksjoner.
FortranEdit
Fortran-90 introduserte en sterkt skrevet pekefunksjon. Fortran-pekere inneholder mer enn bare en enkel minneadresse. De innkapsler også nedre og øvre grenser for arraydimensjoner, skritt (for eksempel for å støtte vilkårlige array-seksjoner) og andre metadata. En tilknytningsoperatør, =>
, brukes til å knytte en POINTER
til en variabel som har en TARGET
attributt. Fortran-90 ALLOCATE
uttalelsen kan også brukes til å knytte en peker til en minneblokk. For eksempel kan følgende kode brukes til å definere og opprette en koblet listestruktur:
Fortran-2003 legger til støtte for prosedyrepekere. Som en del av C-interoperabilitetsfunksjonen støtter Fortran-2003 iboende funksjoner for å konvertere pekere i C-stil til Fortran-pekere og tilbake.
GoEdit
Go har pekere. Syntaksens erklæring tilsvarer C, men skrevet omvendt og slutter med typen. I motsetning til C har Go søppeloppsamling, og tillater ikke pekere aritmetikk. Referansetyper, som i C ++, finnes ikke. Noen innebygde typer, som kart og kanaler, er bokset (dvs. internt er de pekere til foranderlige strukturer), og initialiseres ved hjelp av make
-funksjonen. I en tilnærming til enhetlig syntaks mellom pekere og ikke-pekere, har pilen (->
) operatøren blitt droppet: prikkoperatøren på en peker refererer til feltet eller metoden til det derferiserte objektet . Dette fungerer imidlertid bare med 1 indireksjonsnivå.
JavaEdit
I motsetning til C, C ++ eller Pascal er det ingen eksplisitt representasjon av pekere i Java. I stedet implementeres mer komplekse datastrukturer som objekter og matriser ved hjelp av referanser. Språket gir ingen eksplisitte operatorer for pekermanipulering. Det er fremdeles mulig for kode å forsøke å fjerne en nullreferanse (nullpeker), noe som resulterer i at et kjøretids unntak blir kastet. Plassen som er okkupert av ikke-refererte minneobjekter gjenopprettes automatisk ved søppeloppsamling under kjøretid.
Modula-2Edit
Pekere implementeres veldig mye som i Pascal, det samme er VAR
parametere i prosedyreanrop. Modula-2 er enda sterkere skrevet enn Pascal, med færre måter å unnslippe typesystemet. Noen av variantene av Modula-2 (som Modula-3) inkluderer søppeloppsamling.
OberonEdit
I likhet med Modula-2 er pekere tilgjengelige. Det er fortsatt færre måter å unngå typesystemet, og Oberon og dets varianter er fortsatt tryggere med hensyn til pekere enn Modula-2 eller dets varianter. Som med Modula-3 er søppeloppsamling en del av språkspesifikasjonen.
PascalEdit
I motsetning til mange språk som har pekere, tillater standard ISO Pascal bare pekere å referere til dynamisk opprettede variabler som er anonyme og tillater ikke dem å referere til standard statiske eller lokale variabler. Det har ikke peker-aritmetikk. Pekere må også ha en tilhørende type, og en peker til en type er ikke kompatibel med en peker til en annen type (f.eks. Er en peker til en røye ikke kompatibel med en peker til et helt tall).Dette bidrar til å eliminere typesikkerhetsproblemene som ligger i andre pekerimplementeringer, spesielt de som brukes til PL / I eller C. Det fjerner også noen risikoer forårsaket av dinglende pekere, men muligheten til å dynamisk gi slipp på referert plass ved å bruke dispose
standardprosedyre (som har samme effekt som free
biblioteksfunksjonen som finnes i C) betyr at risikoen for dinglende pekere ikke er helt eliminert.
Imidlertid, i noen kommersielle og åpen kildekode-Pascal (eller derivater) kompilatorimplementeringer – som Free Pascal, Turbo Pascal eller Object Pascal i Embarcadero Delphi – kan en peker referere til standard statiske eller lokale variabler og kan være kast fra en pekertype til en annen. Videre er pekeraritmetikk ubegrenset: å legge til eller trekke fra en peker flytter den med det antallet byte i begge retninger, men ved å bruke Inc
eller Dec
standardprosedyrer med den flytter pekeren etter størrelsen på datatypen den blir erklært å peke på. En utypet peker er også gitt under navnet Pointer
, som er kompatibel med andre pekertyper.