Markør (computerprogrammering)
AdaEdit
Ada er et stærkt indtastet sprog, hvor alle markører er skrevet, og kun konverteringer af sikker type er tilladt. Alle markører er som standard initialiseret til null
, og ethvert forsøg på at få adgang til data gennem en null
-markør medfører, at en undtagelse hæves. Markører i Ada kaldes adgangstyper. Ada 83 tillod ikke aritmetik på adgangstyper (selvom mange compiler-leverandører sørgede for det som en ikke-standardfunktion), men Ada 95 understøtter “sikker” aritmetik på adgangstyper via pakken System.Storage_Elements
.
BASICEdit
Flere gamle versioner af BASIC til Windows-platformen understøttede STRPTR () for at returnere adressen på en streng og for VARPTR () for at returnere adressen på Visual Basic 5 understøttede også OBJPTR () for at returnere adressen på et objektgrænseflade, og for en ADDRESSOF-operatør for at returnere adressen til en funktion. Typerne af alle disse er heltal, men deres værdier svarer til dem, der holdes af markørtyper.
Nyere dialekter af BASIC, såsom FreeBASIC eller BlitzMax, har dog udtømmende markørimplementeringer. I FreeBASIC er aritmetik på ANY
-pegere ( svarende til C “s void*
) behandles som om ANY
-markøren var en bytebredde. ANY
pegepinde kan ikke henvises til, som i C. Også casting mellem ANY
og andre typer pegepunkter vil ikke generere nogen 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 markører variabler, der gemmer adresser og kan være nul. Hver markør har en type, den peger på, men man kan frit kaste mellem markørtyper (men ikke mellem en funktionsmarkør og en objektmarkør). En speciel markørtype kaldet “ugyldig markør” gør det muligt at pege på enhver (ikke -funktion) objekt, men er begrænset af det faktum, at det ikke kan dirigeres direkte (det skal støbes). Selve adressen kan ofte manipuleres direkte ved at kaste en markør til og fra en integreret type af tilstrækkelig størrelse, selvom resultaterne er implementeringsdefinerede og faktisk kan forårsage udefineret adfærd; mens tidligere C-standarder ikke havde en integreret type, der garanteret var stor nok, specificerer C99 uintptr_t
typedef-navnet defineret i <stdint.h>
, men en implementering behøver ikke at give det.
C ++ understøtter fuldt ud C-markører og C-typecasting. Det understøtter også en ny gruppe af typecasting-operatører, der hjælper med at fange nogle utilsigtede farlige rollebesætninger på kompileringstidspunktet. Siden C ++ 11 giver C ++ standardbiblioteket også smarte pointer (unique_ptr
, shared_ptr
og weak_ptr
), som kan bruges i nogle situationer som et sikrere alternativ til primitive C-markører. C ++ understøtter også en anden form for reference, der adskiller sig meget fra en markør, kaldet simpelthen en reference eller referencetype.
Markøraritmetik, det vil sige evnen til at ændre en markørs måladresse med aritmetiske operationer (som samt størrelses-sammenligninger), er begrænset af sprogstandarden til at forblive inden for rammerne af et enkelt array-objekt (eller lige efter det) og på anden måde påberåbe sig udefineret adfærd. Tilføjelse eller fratrækning fra en markør flytter det med et multiplum af størrelsen for eksempel at tilføje 1 til en markør til 4-byte heltal værdier vil forøge markørens pegede til byte-adresse med 4. Dette har den effekt, at markøren forøges til at pege på det næste element i en sammenhængende række af heltal – hvilket ofte er det tilsigtede resultat. Markørregning kan ikke udføres på void
-pegere, fordi tomrumstypen ikke har nogen størrelse, og den spidse adresse kan derfor ikke føjes til, selvom gcc og andre kompilatorer udfører byte-aritmetik på void*
som en ikke-standard udvidelse, der behandles som om det var char *
.
Markørregning giver programmøren en enkelt måde at håndtere forskellige typer på: tilføje og trække antallet af krævede elementer i stedet for den faktiske forskydning i byte. (Markørregning med char *
-pegere bruger byteforskydninger, fordi sizeof(char)
er 1 pr. Definition.) Specielt erklærer C-definitionen eksplicit, at syntaks a
, som er n
-th element i arrayet a
, er ækvivalent til *(a + n)
, som er indholdet af elementet peget af a + n
. Dette antyder, at n
svarer til a
, og man kan f.eks. Skrive a
eller 3
lige så godt for at få adgang til det fjerde element i et array a
.
Selvom det er stærkt, kan markørregning være en kilde til computerfejl. Det har en tendens til at forvirre uerfarne programmerere og tvinge dem ind i forskellige sammenhænge: et udtryk kan være en almindelig aritmetisk eller en pointer aritmetisk, og nogle gange er det let at tage fejl af hinanden. Som svar på dette tillader mange moderne computersprog på højt niveau (f.eks. Java) ikke direkte adgang til hukommelse ved hjælp af adresser. Den sikre C-dialekt Cyclone løser også mange af problemerne med henvisninger. Se programmeringssprog C for mere diskussion.
void
-markøren eller void*
understøttes i ANSI C og C ++ som en generisk markørtype. En markør til void
kan gemme adressen på ethvert objekt (ikke funktion), og i C konverteres det implicit til enhver anden objektmarkørtype ved tildelingen, men den skal udtrykkeligt kastes hvis dereferences.K & RC brugte char*
til formålet “type agnostisk pointer” (før ANSI C).
C ++ tillader ikke implicit konvertering af void*
til andre markørtyper, selv ikke i opgaver. Dette var en designbeslutning for at undgå skødesløs og endog utilsigtet rollebesætning, selvom de fleste kompilatorer kun udsender advarsler , ikke fejl, når man støder på andre rollebesætninger.
I C ++ er der ingen void&
(henvisning til ugyldighed), der supplerer void*
(pointer til ugyldig), fordi referencer opfører sig som aliaser til de variabler, de peger på, og der kan aldrig være en variabel, hvis type er void
.
Syntaksoversigt over pointererklæring Rediger
Disse markørerklæringer c over de fleste varianter af markørerklæringer. Det er selvfølgelig muligt at have tredobbelte markører, men hovedprincipperne bag en tredobbelt markør findes allerede i en dobbeltmarkør.
() og har en højere prioritet end *.
C # Rediger
På programmeringssprog C # understøttes markører kun under visse betingelser: enhver blok af kode inklusive markører skal markeres med nøgleordet unsafe
. Sådanne blokke kræver normalt højere sikkerhedstilladelser for at kunne køre. Syntaksen er stort set den samme som i C ++, og den pegede adresse kan enten være administreret eller ikke-administreret hukommelse. Markører til administreret hukommelse (enhver markør til et administreret objekt) skal dog erklæres ved hjælp af fixed
nøgleordet, som forhindrer skraldopsamleren i at flytte det spidse objekt som en del af hukommelsesadministration, mens pointer er inden for rækkevidde, hvilket holder markørens adresse gyldig.
En undtagelse herfra er fra at bruge IntPtr
-strukturen, hvilket er en sikker administreret ækvivalent med int*
og kræver ikke usikker kode. Denne type returneres ofte, når der bruges metoder fra System.Runtime.InteropServices
, for eksempel:
.NET-rammen inkluderer mange klasser og metoder i System
og System.Runtime.InteropServices
navneområder (såsom klassen Marshal
), der konverterer .NET-typer (for eksempel System.String
) til og fra mange ikke-administrerede typer og pekere (f.eks. LPWSTR
eller void*
) for at tillade kommunikation med ikke-administreret kode. De fleste af disse metoder har de samme krav til sikkerhedstilladelse som ikke-administreret kode, da de kan påvirke vilkårlige steder i hukommelsen.
COBOLEdit
COBOL-programmeringssproget understøtter markeringer til variabler. Primitive eller gruppe (optage) dataobjekter, der er erklæret inden for LINKAGE SECTION
i et program, er i sagens natur pointerbaseret, hvor den eneste hukommelse, der er allokeret i programmet, er plads til dataelementets adresse ( typisk et enkelt hukommelsesord). I programkildekoden bruges disse dataelementer ligesom enhver anden WORKING-STORAGE
-variabel, men deres indhold er implicit tilgængelig indirekte gennem deres LINKAGE
-pegere .
Hukommelsesplads til hvert pegede dataobjekt tildeles typisk dynamisk ved hjælp af eksterne CALL
udsagn eller via indlejrede udvidede sprogkonstruktioner såsom EXEC CICS
eller EXEC SQL
udsagn.
Udvidede versioner af COBOL giver også markørvariabler erklæret med USAGE
IS
POINTER
klausuler. Værdierne for sådanne markørvariabler etableres og ændres ved hjælp af SET
og SET
ADDRESS
udsagn.
Nogle udvidede versioner af COBOL indeholder også PROCEDURE-POINTER
variabler, der er i stand til at gemme adresserne på den eksekverbare kode.
PL / IEdit
PL / I-sproget giver fuld understøttelse af pekere til alle datatyper (inklusive pegepunkter til strukturer), rekursion, multitasking, strenghåndtering og omfattende indbyggede funktioner.PL / I var et stort spring fremad i forhold til programmets sprog på sin tid. PL / I-pegepinde er ikke skrevet, og der kræves derfor ingen casting til pointerderferference eller tildeling. Erklæringens syntaks for en markør er DECLARE xxx POINTER;
, som erklærer en markør ved navn “xxx”. Markører bruges med BASED
variabler. En baseret variabel kan deklareres med en standardlokator (DECLARE xxx BASED(ppp);
eller uden (DECLARE xxx BASED;
), hvor xxx er en baseret variabel, som kan være en elementvariabel, en struktur eller en matrix, og ppp er standardmarkøren). En sådan variabel kan være adresse uden en eksplicit pointerreference (xxx=1;
eller kan adresseres med en eksplicit henvisning til standardlokalisatoren (ppp) eller til en hvilken som helst anden markør (qqq->xxx=1;
).
Markørregning er ikke en del af PL / I-standarden, men mange compilere tillader udtryk for formen ptr = ptr±expression
IBM PL / I har også den indbyggede funktion PTRADD
til at udføre aritmetikken. Pointer-aritmetik udføres altid i bytes.
IBM Enterprise PL / I-kompilatorer har en ny form for indtastet markør kaldet en HANDLE
.
DEdit
D-programmeringssproget er et derivat af C og C ++, der fuldt ud understøtter C pointers og C typecasting.
EiffelEdit
Det Eiffel objektorienterede sprog anvender værdi og reference semantik uden pointer-aritmetik. Ikke desto mindre leveres pointerklasser. De tilbyder pointer aritmetik, typecasting, eksplicit hukommelsesstyring, int erfacing med ikke-Eiffel-software og andre funktioner.
FortranEdit
Fortran-90 introducerede en stærkt indtastet markørfunktion. Fortran-markører indeholder mere end bare en simpel hukommelsesadresse. De indkapsler også de nedre og øvre grænser for arraydimensioner, skridt (for eksempel for at understøtte vilkårlige array-sektioner) og andre metadata. En tilknytningsoperator, =>
, bruges til at knytte en POINTER
til en variabel, der har en TARGET
attribut. Fortran-90 ALLOCATE
udsagnet kan også bruges til at knytte en markør til en hukommelsesblok. For eksempel kan følgende kode bruges til at definere og oprette en sammenkædet listestruktur:
Fortran-2003 tilføjer understøttelse af proceduremarkører. Som en del af C-interoperabilitetsfunktionen understøtter Fortran-2003 iboende funktioner til konvertering af C-stilmarkører til Fortran-markører og tilbage.
GoEdit
Go har markører. Dens erklæringssyntaks svarer til C, men skrevet omvendt og slutter med typen. I modsætning til C har Go affaldssamling og tillader ikke markørregning. Referencetyper, som i C ++, findes ikke. Nogle indbyggede typer, som kort og kanaler, er indrammet i boks (dvs. internt er de peger på mutable strukturer) og initialiseres ved hjælp af make
-funktionen. I en tilgang til samlet syntaks mellem markører og ikke-markører er pilen (->
) operatøren blevet droppet: prikoperatoren på en markør henviser til feltet eller metoden for det derferences objekt . Dette fungerer dog kun med 1 indirektionsniveau.
JavaEdit
I modsætning til C, C ++ eller Pascal er der ingen eksplicit repræsentation af markører i Java. I stedet implementeres mere komplekse datastrukturer som objekter og arrays ved hjælp af referencer. Sproget indeholder ikke eksplicitte markørmanipulationsoperatorer. Det er stadig muligt for kode at forsøge at fjerne en null-reference (null pointer), hvilket resulterer i, at en undtagelse for kørsel bliver kastet. Pladsen, der er optaget af hukommelsesobjekter, der ikke er henvist til, gendannes automatisk ved affaldsindsamling ved kørselstid.
Modula-2Edit
Markører implementeres meget som i Pascal, ligesom VAR
parametre i procedureopkald. Modula-2 er endnu stærkere skrevet end Pascal, med færre måder at undslippe typesystemet. Nogle af varianterne af Modula-2 (såsom Modula-3) inkluderer affaldssamling.
OberonEdit
Meget som med Modula-2 er der råd til markører. Der er stadig færre måder at undgå typesystemet, og så er Oberon og dets varianter stadig sikrere med hensyn til markører end Modula-2 eller dets varianter. Som med Modula-3 er affaldssamling en del af sprogspecifikationen.
PascalEdit
I modsætning til mange sprog, der indeholder pegepinde, tillader standard ISO Pascal kun pegepinde at henvise til dynamisk oprettede variabler, der er anonyme og tillader dem ikke at henvise til standardstatiske eller lokale variabler. Det har ikke pointer aritmetik. Markører skal også have en tilknyttet type, og en markør til en type er ikke kompatibel med en markør til en anden type (f.eks. Er en markør til en char ikke kompatibel med en markør til et heltal).Dette hjælper med at eliminere typesikkerhedsproblemer, der er forbundet med andre markørimplementeringer, især dem, der bruges til PL / I eller C.Det fjerner også nogle risici forårsaget af dinglende markører, men evnen til dynamisk at give slip på det refererede rum ved hjælp af “3d8ad5a9fe”> standardprocedure (som har samme effekt som free
biblioteksfunktionen, der findes i C) betyder, at risikoen for dinglende markører ikke er helt elimineret.
I nogle kommercielle og open source Pascal (eller derivater) compilerimplementeringer – som Free Pascal, Turbo Pascal eller Object Pascal i Embarcadero Delphi – kan en markør henvise til standard statiske eller lokale variabler og kan være kastet fra en markørtype til en anden. Desuden er pointeraritmetik ubegrænset: at tilføje eller trække fra en markør flytter det med det antal bytes i begge retninger, men ved hjælp af Inc
eller Dec
standardprocedurer flytter markøren med størrelsen på den datatype, det erklæres for at pege på. En utypet markør findes også under navnet Pointer
, hvilket er kompatibelt med andre markørtyper.