Osoitin (tietokoneohjelmointi)
AdaEdit
Ada on voimakkaasti kirjoitettu kieli, jossa kaikki osoittimet kirjoitetaan ja vain turvallisten tyyppien muunnokset ovat sallittuja. Kaikki osoittimet alustetaan oletusarvoisesti arvoon null
, ja kaikki yritykset käyttää tietoja null
-osoittimen kautta aiheuttavat poikkeuksen. Adan osoittimia kutsutaan pääsytyypeiksi. Ada 83 ei sallinut aritmeettista käyttöoikeustyyppiä (vaikka monet kääntäjän toimittajat tarjosivat sen epätyypilliseksi ominaisuudeksi), mutta Ada 95 tukee ”turvallista” aritmeettisuutta pääsytyypeissä paketin System.Storage_Elements
.
BASICEdit
Usealla Windows-alustan BASICin vanhalla versiolla oli tuki STRPTR (): lle merkkijonon osoitteen palauttamiseksi ja VARPTR (): n palauttamiseksi osoitteen muuttuja. Visual Basic 5: llä oli myös tuki OBJPTR: lle () objektirajapinnan osoitteen palauttamiseksi ja ADDRESSOF-operaattorille funktion osoitteen palauttamiseksi. Näiden kaikkien tyypit ovat kokonaislukuja, mutta niiden arvot vastaavat osoitintyyppien omistamat.
BASICin uudemmilla murteilla, kuten FreeBASIC tai BlitzMax, on kuitenkin tyhjentävä osoitintoteutus. FreeBASIC: ssa ANY
osoittimien aritmeettinen ( vastaa C: tä ”s void*
) käsitellään ikään kuin ANY
osoitin olisi tavun leveys. ANY
-osoittimista ei voida poiketa, kuten kohdassa C. Myöskään ANY
– ja muun tyyppisten osoittimien välinen suoratoisto ei luo varoituksia.
dim as integer f = 257dim as any ptr g = @fdim as integer ptr i = gassert(*i = 257)assert( (g + 4) = (@f + 1) )
C ja C ++ Muokkaa
C- ja C ++ -osoittimissa ovat muuttujia, jotka tallentavat osoitteita ja voi olla nolla. Jokaisella osoittimella on tyyppi, johon se osoittaa, mutta voi vapaasti heittää osoittimityyppien välillä (mutta ei funktion osoittimen ja objektiosoittimen välillä). Erityinen osoitintyyppi, nimeltään ”void pointer”, sallii osoittamisen mihin tahansa (ei -toiminto) esine, mutta sitä rajoittaa se, että siihen ei voida suoraan viitata (se on valettava). Osoitetta itse voidaan usein manipuloida heittämällä osoitin riittävän kokoiseen integraalityyppiin ja sieltä, vaikka tulokset olisivatkin toteutuksen määrittelemiä ja saattavat todellakin aiheuttaa määrittelemätöntä käyttäytymistä; Vaikka aikaisemmissa C-standardeissa ei ollut integraalityyppiä, jonka taattiin olevan riittävän suuri, C99 määrittää uintptr_t
typedef-nimen, joka on määritelty kohdassa <stdint.h>
, mutta toteutuksen ei tarvitse antaa sitä.
C ++ tukee täysin C-osoittimia ja C-tyypin määritystä. Se tukee myös uutta tyyppikilpailuoperaattoreiden ryhmää auttamaan tahattomien vaarallisten heittojen saamisessa käännösaikana. Koska C ++ 11, C ++ -standardikirjasto tarjoaa myös älykkäitä osoittimia (unique_ptr
, shared_ptr
ja weak_ptr
), jota voidaan käyttää joissakin tilanteissa turvallisempana vaihtoehtona primitiivisille C-osoittimille. C ++ tukee myös toista viitemuotoa, aivan erilaista kuin osoitin, jota kutsutaan yksinkertaisesti viitteeksi tai viitetyypiksi.
Osoittimen aritmeettinen eli kyky muokata osoittimen kohdeosoitetta aritmeettisilla operaatioilla (kuten sekä suuruusvertailut), kielistandardi rajoittaa sen pysymään yhden matriisiobjektin rajoissa (tai heti sen jälkeen) ja muuten vetoaa määrittelemättömään käyttäytymiseen. Osoittimen lisääminen tai vähentäminen siirtää sitä koon kerrannaisena Esimerkiksi lisäämällä 1 osoittimeen 4-tavuisiin kokonaislukuarvoihin, osoittimen osoitettu tavu-osoite kasvaa 4: llä. Tämä johtaa siihen, että osoitinta lisätään osoittamaan vierekkäisen seuraavan elementin kohdalle. joukko kokonaislukuja – mikä on usein tarkoitettu tulos. Osoittimen aritmeettisuutta ei voida suorittaa void
-osoittimilla, koska tyhjätyypillä ei ole kokoa, joten terävää osoitetta ei voida lisätä, vaikka gcc ja muut kääntäjät suorittavat tavujen aritmeettisen kohdan void*
epätyypillisenä laajennuksena, käsittelemällä sitä ikään kuin se olisi char *
.
Osoittimen aritmeikka antaa ohjelmoijalle yksi tapa käsitellä erityyppisiä tyyppejä: lisäämällä ja vähentämällä vaadittujen elementtien määrä tavujen tosiasiallisen siirtymän sijasta. (Osoittimen aritmeettinen char *
-osoittimien kanssa käytetään tavujen siirtymiä, koska sizeof(char)
on määritelmän mukaan 1.) Erityisesti C-määritelmä ilmoittaa nimenomaisesti, että syntaksi a
, joka on taulukon n
-elementti a
, on vastaava kohtaan *(a + n)
, joka on a + n
osoittaman elementin sisältö. Tämä tarkoittaa, että n
vastaa a
ja voi kirjoittaa esimerkiksi a
tai 3
yhtä hyvin päästäksesi matriisin a
neljänteen elementtiin.
Vaikka osoitinaritmeettinen on tehokas, se voi olla tietokonevikojen lähde. Se pyrkii hämmentämään aloittelijoita ohjelmoijia pakottaen heidät erilaisiin yhteyksiin: lauseke voi olla tavallinen aritmeettinen tai osoittimen aritmeettinen, ja joskus on helppo erehtyä toiseen. Vastauksena tähän monet modernit korkean tason tietokonekielet (esimerkiksi Java) eivät salli suoraa pääsyä muistiin osoitteita käyttämällä. Myös turvallinen C-murre Cyclone ratkaisee monia asioita osoittimilla. Katso lisätietoja C-ohjelmointikielestä.
ANSI C tukee void
-osoitinta tai void*
ja C ++ yleisenä osoitintyyppinä. void
-osoitin voi tallentaa minkä tahansa objektin (ei funktion) osoitteen, ja C-muodossa se muunnetaan implisiittisesti mihin tahansa muuhun objektiosoitintyyppiin tehtävässä, mutta se on nimenomaisesti valettava jos siitä on viitattu.K & RC käytti char*
-tyyppiä ”tyyppi-agnostinen osoitin” (ennen ANSI C: tä).
C ++ ei salli void*
: n implisiittistä muuntamista muiksi osoitintyypeiksi, jopa tehtävissä. Tämä oli suunnittelupäätös, jolla vältettiin huolimaton ja jopa tahaton suoratoisto, vaikka useimmat kääntäjät antavat vain varoituksia. , ei virheitä, kun kohtaat muita heittoja.
C ++: ssa ei ole void&
(viittaus voidiin) täydentämään void*
(osoitin mitätölle), koska viittaukset käyttäytyvät aliaksina muuttujiin, joihin ne osoittavat, eikä koskaan voi olla muuttujaa, jonka tyyppi on void
.
Osoittimen ilmoituksen syntaksin yleiskatsausMuokkaa
Nämä osoittimen ilmoitukset c useimmissa osoitinilmoitusten muunnoksissa. Tietysti on mahdollista saada kolmoisosoittimia, mutta kolmoisosoittimen pääperiaatteet ovat jo kaksoisosoittimessa.
() ja niillä on korkeampi prioriteetti kuin *.
C # muokkaus
C # -ohjelmointikielellä osoittimia tuetaan vain tietyissä olosuhteissa: kaikki koodilohkot, mukaan lukien osoittimet, on merkittävä unsafe
avainsanalla. Tällaiset lohkot edellyttävät yleensä korkeampia suojausoikeuksia, jotta niiden voidaan suorittaa. Syntaksi on olennaisesti sama kuin C ++: ssa, ja osoitettu osoite voi olla joko hallittu tai hallitsematon muisti. Ohjatun muistin osoittimet (kaikki osoitteet hallitulle objektille) on kuitenkin ilmoitettava käyttämällä fixed
avainsanaa, joka estää roskakorin siirtämästä terävää objektia osana muistin hallintaa, kun osoitin on laajuudessa, joten osoitinosoite pysyy kelvollisena.
Poikkeus tähän on IntPtr
-rakenteen käyttäminen, joka on turvallisesti hallittu vastine int*
, eikä vaadi vaarallista koodia. Tämä tyyppi palautetaan usein, kun käytetään System.Runtime.InteropServices
-metodeja, esimerkiksi:
.NET-kehys sisältää monia luokkia ja menetelmiä kohdassa System
ja System.Runtime.InteropServices
nimitilat (kuten luokka Marshal
), jotka muuntavat .NET-tyypit (esimerkiksi System.String
) monista hallitsemattomista tyypeistä ja osoittimista (esimerkiksi LPWSTR
tai void*
) sallimaan kommunikointi hallitsemattomalla koodilla. Useimmilla tällaisilla menetelmillä on samat suojausoikeusvaatimukset kuin hallitsemattomalla koodilla, koska ne voivat vaikuttaa mielivaltaisiin paikkoihin muistissa.
COBOLEdit
COBOL-ohjelmointikieli tukee muuttujien osoittimia. Ohjelman LINKAGE SECTION
sisällä ilmoitetut primitiiviset tai ryhmä (tietue) dataobjektit ovat luonnostaan osoitinpohjaisia, jolloin ainoa ohjelmassa allokoitu muisti on tilaa tieto kohteen osoitteelle ( tyypillisesti yksi muistisana). Ohjelman lähdekoodissa näitä dataelementtejä käytetään aivan kuten mitä tahansa muuta WORKING-STORAGE
-muuttujaa, mutta niiden sisältöön pääsee epäsuorasti epäsuorasti niiden LINKAGE
-osoittimien kautta .
Jokaisen osoitetun dataobjektin muistitila varataan tyypillisesti dynaamisesti käyttämällä ulkoisia CALL
-lausekkeita tai upotettujen laajennettujen kielirakenteiden, kuten tai EXEC SQL
lauseet.
COBOLin laajennetut versiot tarjoavat myös osoitemuuttujia, jotka on ilmoitettu USAGE
IS
POINTER
-lausekkeet. Tällaisten osoitinmuuttujien arvot määritetään ja muokataan SET
– ja SET
ADDRESS
-lausekkeilla.
Jotkin laajennetut COBOL-versiot tarjoavat myös PROCEDURE-POINTER
-muuttujia, jotka pystyvät tallentamaan suoritettavan koodin osoitteita.
PL / IEdit
PL / I-kieli tukee kaikkia osoitetyyppejä kaikilla tietotyypeillä (mukaan lukien viitteet rakenteille), rekursiota, moniajoa, merkkijonojen käsittelyä ja laajoja sisäänrakennettuja toimintoja.PL / I oli varsin harppaus eteenpäin verrattuna aikansa ohjelmointikieliin. PL / I-osoittimia ei ole kirjoitettu, ja siksi osoitinta ei tarvitse ohjata osoittamiseen tai osoittamiseen. Osoittimen lausekkeen syntaksin on DECLARE xxx POINTER;
, joka julistaa osoittimen nimeltä ”xxx”. Osoittimia käytetään BASED
-muuttujien kanssa. Perustainen muuttuja voidaan ilmoittaa oletuspaikannuslaitteella (DECLARE xxx BASED(ppp);
tai ilman (DECLARE xxx BASED;
), missä xxx on perustainen muuttuja, joka voi olla elementtimuuttuja, rakenne tai taulukko ja ppp on oletusosoitin). Tällainen muuttuja voi olla osoite ilman nimenomaista osoittimen viittausta (xxx=1;
, tai se voidaan osoittaa nimenomaisella viitteellä oletuspaikantimeen (ppp) tai mihin tahansa muuhun osoittimeen (qqq->xxx=1;
).
Osoittimen aritmeikka ei ole osa PL / I-standardia, mutta monet kääntäjät sallivat lausekkeita muodossa ptr = ptr±expression
. IBM PL / I: llä on myös sisäänrakennettu funktio PTRADD
aritmeettisen suorituksen suorittamiseksi. Osoittimen aritmeettinen suoritus suoritetaan aina tavuina.
IBM Enterprise PL / I -koostajilla on uusi muoto kirjoitetusta osoittimesta nimeltä HANDLE
.
DEdit
D-ohjelmointikieli on johdannainen C: stä ja C ++: sta, joka tukee täysin C: tä osoittimet ja C-tyypin määritys.
EiffelEdit
Eiffel-objektikielinen kieli käyttää arvo- ja viitesemantiikkaa ilman osoittimen aritmeettista. Siitä huolimatta tarjotaan osoitinluokat. Ne tarjoavat osoittimen aritmeettisen, tyyppikokoisen, nimenomaisen muistin hallinta, sis muilla kuin Eiffel-ohjelmistoilla ja muilla ominaisuuksilla.
FortranEdit
Fortran-90 esitteli voimakkaasti kirjoitetun osoitinominaisuuden. Fortran-osoittimet sisältävät enemmän kuin vain yksinkertaisen muistiosoitteen. Ne myös kapseloivat matriisimittojen ala- ja ylärajat, askeleet (esimerkiksi mielivaltaisten taulukko-osien tukemiseksi) ja muut metatiedot. Assosiaatio-operaattoria =>
käytetään liittämään POINTER
muuttujaan, jolla on TARGET
attribuutti. Fortran-90 ALLOCATE
-käskyä voidaan käyttää myös osoittimen liittämiseen muistilohkoon. Esimerkiksi seuraavaa koodia voidaan käyttää linkitetyn luettelorakenteen määrittelemiseen ja luomiseen:
Fortran-2003 lisää tuen prosessiosoittimille. Lisäksi osana C-yhteentoimivuusominaisuutta Fortran-2003 tukee sisäisiä toimintoja C-tyylisten osoittimien muuntamiseksi Fortran-osoittimiksi ja takaisin.
GoEdit
Go sisältää osoittimia. Sen ilmoitussyntaksi vastaa C: n vastaavaa, mutta kirjoitettu päinvastoin, päättyen tyyppiin. Toisin kuin C, Go: lla on roskien keräys ja se estää osoittimen aritmeettisen toiminnan. Viitetyyppejä, kuten C ++: ssa, ei ole. Jotkut sisäänrakennetut tyypit, kuten kartat ja kanavat, on ruudussa (ts. Ne ovat sisäisesti viitteitä muuttuviin rakenteisiin), ja ne alustetaan make
-toiminnon avulla. Lähestyttäessä osoittimien ja ei-osoittimien välistä yhtenäistä syntaksia, nuoli (->
) -operaattori on pudonnut: osoittimen pisteoperaattori viittaa viitatun objektin kenttään tai menetelmään . Tämä toimii kuitenkin vain yhdellä epäsuoralla tasolla.
JavaEdit
Toisin kuin C, C ++ tai Pascal, Java-ohjelmassa ei ole nimenomaista osoittimia. Sen sijaan monimutkaisemmat tietorakenteet, kuten objektit ja taulukot, toteutetaan viitteiden avulla. Kieli ei tarjoa mitään nimenomaista osoittimen manipulaatiooperaattoria. Koodilla on silti mahdollista yrittää jättää tyhjä viittaus (nollaosoitin), mikä johtaa ajonaikaisen poikkeuksen heittämiseen. Viittaamattomien muistikohteiden viemät tilat palautetaan automaattisesti roskakoriin suorituksen aikana.
Modula-2Edit
Osoittimet toteutetaan paljon kuin Pascalissa, samoin kuin VAR
-parametrit menettelykutsussa. Modula-2 on jopa voimakkaammin kirjoitettu kuin Pascal, ja vähemmän tapoja paeta tyyppijärjestelmästä. Jotkut Modula-2: n muunnelmista (kuten Modula-3) sisältävät roskien keräyksen.
OberonEdit
Aivan kuten Modula-2: n kohdalla, osoittimet ovat käytettävissä. Tyyppijärjestelmän kiertämiseen on vielä vähemmän tapoja, joten Oberon ja sen variantit ovat edelleen turvallisempia osoittimien suhteen kuin Modula-2 tai sen variantit. Kuten Modula-3: ssa, roskien keräys on osa kielimäärittelyä.
PascalEdit
Toisin kuin monet kielet, joissa on osoittimia, standardi ISO Pascal sallii osoittimilla viitata vain dynaamisesti luotuihin muuttujiin, jotka ovat nimettömiä eivätkä salli niiden viitata vakiomuotoisiin staattisiin tai paikallisiin muuttujiin. Sillä ei ole osoittimen aritmeettisuutta. Osoittimilla on myös oltava liitetty tyyppi, ja yhden tyypin osoitin ei ole yhteensopiva toisen tyyppisen osoittimen kanssa (esim. Osoittimen osoittava merkki ei ole yhteensopiva kokonaislukun osoittimen kanssa).Tämä auttaa poistamaan tyypin tietoturvaongelmat, jotka ovat ominaisia muille osoittimen toteutuksille, etenkin niille, joita käytetään PL / I: ssä tai C: ssä. Se poistaa myös joitain roikkuvien osoittimien aiheuttamia riskejä, mutta kyky vapauttaa viitattu tila dynaamisesti käyttämällä ”3d8ad5a9fe”> vakiomenettely (jolla on sama vaikutus kuin C: n kirjastofunktiolla free
) tarkoittaa, että osoittimien roikkumisen riskiä ei ole kokonaan poistettu.
Joissakin kaupallisissa ja avoimen lähdekoodin Pascal (tai johdannaiset) kääntäjän toteutuksissa – kuten Free Pascal, Turbo Pascal tai Obbar Pascal Embarcadero Delphissä – osoitin saa kuitenkin viitata vakioihin staattisiin tai paikallisiin muuttujiin, ja se voidaan valettu yhdestä osoitintyypistä toiseen. Lisäksi osoittimen aritmeettinen käyttö on rajoittamatonta: osoittimen lisääminen tai vähentäminen siirtää sitä tavujen lukumäärällä kumpaankin suuntaan, mutta käyttämällä Inc
tai Dec
vakiomenettelyt sen kanssa liikuttavat osoitinta sen tietotyypin koon mukaan, johon sen ilmoitetaan osoittavan. Kirjoittamaton osoitin annetaan myös nimellä Pointer
, joka on yhteensopiva muiden osoitintyyppien kanssa.