Mutató (számítógépes programozás)
AdaEdit
Az Ada egy erősen tipizált nyelv, ahol minden mutató be van írva, és csak biztonságos típusú konverziók engedélyezettek. Az összes mutató alapértelmezés szerint inicializálva van: null
, és a null
mutatón keresztül történő bármilyen adatelérési kísérlet kivételt eredményez. Az adai mutatókat hozzáférési típusoknak nevezzük. Az Ada 83 nem engedélyezte az aritmetikát a hozzáférési típusoknál (bár sok fordítói gyártó nem szabványos szolgáltatásként írta elő), de az Ada 95 a System.Storage_Elements
.
BASICEdit
A BASIC több régi verziója a Windows platformhoz támogatta az STRPTR () karakterlánc címét, a VARPTR () pedig a változó. A Visual Basic 5 támogatta az OBJPTR () funkciót az objektum interfész címének visszaadásához, és az ADDRESSOF operátor számára a függvény címének visszaadását. Mindezek típusai egész számok, de értékük egyenértékű amelyeket a mutatótípusok tartanak.
A BASIC újabb dialektusai, mint például a FreeBASIC vagy a BlitzMax, kimerítő mutatókkal rendelkeznek. A FreeBASIC-ben a ANY
mutatók számtana ( egyenértékű a C-vel “s void*
) úgy kezeljük, mintha a ANY
mutató bájt szélességű lenne. A ANY
mutatókra nem lehet hivatkozni, mint a C-ben. Ezenkívül a ANY
és bármely más típusú mutató közötti öntés nem generál figyelmeztetést.
dim as integer f = 257dim as any ptr g = @fdim as integer ptr i = gassert(*i = 257)assert( (g + 4) = (@f + 1) )
C és C ++ szerkesztés
A C és C ++ mutatók olyan változók, amelyek tárolják a címeket és Lehet null. Minden mutatónak van egy típusa, amelyre mutat, de szabadon vethet a mutatótípusok között (de nem egy függvénymutató és egy objektummutató között). Egy speciális mutatótípus, az úgynevezett “void pointer”, lehetővé teszi bármely (nem -függvény) objektum, de korlátozza az a tény, hogy közvetlenül nem lehet rá hivatkozni (leadni kell). Magát a címet gyakran közvetlenül lehet manipulálni, ha mutatót kell vetni egy megfelelő méretű integrált típusba és onnan, bár az eredmények megvalósításban vannak meghatározva, és valóban meghatározhatatlan viselkedést okozhatnak; míg a korábbi C szabványoknak nem volt integrált típusa, amely garantáltan elég nagy volt, a C99 megadja a uintptr_t
typedef nevet, amelyet az <stdint.h>
fájlban definiáltak, de egy megvalósításnak nem kell megadnia.
A C ++ teljes mértékben támogatja a C mutatókat és a C típusú specifikációt. Támogatja az újfajta tipográfiai operátorok egy csoportját is, hogy segítsen néhány nem szándékos veszélyes dobást lefordítani. C ++ 11 óta a C ++ szabványos könyvtár intelligens mutatókat is biztosít (unique_ptr
, shared_ptr
és weak_ptr
), amelyek bizonyos helyzetekben a primitív C mutatók biztonságosabb alternatívájaként használhatók. A C ++ egy másik referenciaformát is támogat, amely egészen más, mint egy mutató, egyszerűen hivatkozásnak vagy referencia típusnak nevezzük.
A mutató aritmetikája, azaz a mutató célcímének aritmetikai műveletekkel történő módosítása valamint a nagyság-összehasonlítások), a nyelvi szabvány korlátozza, hogy egyetlen tömb objektum határain belül maradjon (vagy közvetlenül utána), és különben meghatározatlan viselkedésre hív fel. Mutató hozzáadása vagy kivonása a méret többszörösével mozgatja Például, ha 1-et adunk egy mutatóhoz a 4 bájtos egész számokhoz, akkor a mutató hegyes-bájtos címe 4-gyel növekszik. Ez azt eredményezi, hogy a mutató egy szomszédos elemben a következő elemre növekszik. egész szám tömb – ami gyakran a kívánt eredmény. A mutató számtana nem hajtható végre a void
mutatókon, mert a void típusnak nincs mérete, és ezért a hegyes cím nem adható hozzá, bár a gcc és más fordítók bájtos armetmetikát fognak végrehajtani a void*
nem szabványos kiterjesztésként, úgy kezelve, mintha char *
lenne.
A mutatószámtechnika a programozó számára egy a különféle típusok kezelésének egyetlen módja: a szükséges elemek számának összeadása és kivonása a tényleges eltolás helyett bájtokban. (A mutató aritmetikája a char *
mutatókkal bájteltolásokat használ, mert a sizeof(char)
definíció szerint 1.) Különösen a C definíció kifejezetten kijelenti, hogy szintaxis a
, amely a n
tömb a
tömb egyenértékű a *(a + n)
címre, amely a a + n
által mutatott elem tartalma. Ez azt jelenti, hogy a n
egyenértékű a a
-vel, és írhatunk például a
vagy 3
ugyanolyan jól érhető el egy tömb negyedik eleméhez a
.
Noha a számtechnika hatékony, a számítógépes hibák forrása lehet. Hajlamos megzavarni a kezdő programozókat, különböző kontextusokba kényszerítve őket: egy kifejezés lehet közönséges aritmetikai vagy mutatós aritmetikai, és néha könnyen összetéveszthető a másik. Erre válaszul számos modern, magas szintű számítógépes nyelv (például Java) nem teszi lehetővé a címek használatával történő közvetlen hozzáférést a memóriához. Ezenkívül a biztonságos C dialektus, a Cyclone a mutatókkal számos problémát megold. További vitát lásd a C programozási nyelvben.
A void
mutatót vagy a void*
mutatót az ANSI C támogatja, és C ++, mint általános mutatótípus. A void
mutatóra bármely objektum (nem függvény) címe tárolható, és C-ben implicit módon más objektummutató-típusokká konvertálódik a hozzárendeléskor, de ezt kifejezetten át kell önteni ha erre hivatkoznak.K & RC a char*
-t használta a “type-agnostic pointer” célra (az ANSI C előtt).
void*
implicit konvertálását más mutató típusokká, még hozzárendelésekben sem. Ez egy tervezési döntés volt a gondatlan és akár nem szándékos leadások elkerülése érdekében, bár a legtöbb fordító csak figyelmeztetéseket adott ki , nem pedig hibák, amikor más szereplőkkel találkozik.
A C ++ fájlban nincs void&
(hivatkozás void-ra), amely kiegészíti a void*
(point to void), mert a hivatkozások álnevekként viselkednek az általuk mutatott változókra, és soha nem lehet olyan változó, amelynek típusa void
.
Mutató deklaráció szintaxis áttekintésEdit
Ezek a mutató deklarációk c a mutató deklarációk legtöbb változatánál. Természetesen lehetőség van hármas mutatókra is, de a hármas mutató fő elvei már léteznek egy kettős mutatóban.
A () és magasabb prioritással bír, mint a *.
C # szerkesztés
A C # programozási nyelvben a mutatók csak bizonyos feltételek mellett támogatottak: minden kódblokkot, beleértve a mutatókat is, a unsafe
kulcsszóval kell megjelölni. Az ilyen blokkok futtatásához általában magasabb biztonsági engedélyekre van szükség. A szintaxis lényegében megegyezik a C ++ verzióval, és a jelzett cím kezelhető vagy nem kezelt memória lehet. Azonban a kezelt memóriára mutató mutatókat (bármely irányított objektumra mutató mutatót) a fixed
kulcsszóval kell deklarálni, ami megakadályozza, hogy a szemétgyűjtő a hegyes objektumot a memóriakezelés részeként mozgassa, miközben A mutató hatókörben van, így érvényben tartja a mutató címét.
Ez alól kivételt jelent a IntPtr
struktúra használata, amely egy biztonságos felügyelt megfelelője a int*
, és nem igényel nem biztonságos kódot. Ez a típus gyakran visszatér, ha a System.Runtime.InteropServices
metódusokat használja, például:
A .NET-keretrendszer számos osztályt és metódust tartalmaz a System
és System.Runtime.InteropServices
névterek (például Marshal
osztály), amelyek konvertálják a .NET típusokat (például System.String
) számos nem kezelt típushoz és mutatóhoz (például LPWSTR
vagy void*
), illetve azoktól, hogy engedélyezze kommunikáció nem kezelt kóddal. A legtöbb ilyen módszer ugyanazokkal a biztonsági engedélyekkel szemben támasztja a követelményeket, mint a nem kezelt kód, mivel ezek befolyásolhatják a memória tetszőleges helyeit.
COBOLEdit
A COBOL programozási nyelv támogatja a változókra mutató mutatókat. A program LINKAGE SECTION
ban deklarált primitív vagy csoportos (rekord) adatobjektumok eredendően mutatóalapúak, ahol a programon belül egyetlen kiosztott memória az adatcím címének ad helyet ( jellemzően egyetlen memória szó). A program forráskódjában ezeket az adatelemeket ugyanúgy használják, mint bármely más WORKING-STORAGE
változót, de azok tartalmához közvetetten, LINKAGE
mutatóik révén jutnak hozzá. .
Az egyes mutatott adatobjektumok memóriaterületét általában dinamikusan osztják ki külső CALL
utasítások használatával, vagy beágyazott kiterjesztett nyelvi konstrukciókkal, például EXEC CICS
vagy EXEC SQL
utasítások.
A COBOL kibővített verziói olyan mutatóváltozókat is tartalmaznak, amelyek USAGE
IS
POINTER
záradékok. Az ilyen mutatóváltozók értékeit a SET
és a SET
ADDRESS
utasítások segítségével állapítják meg és módosítják.
A COBOL néhány kibővített verziója PROCEDURE-POINTER
változókat is tartalmaz, amelyek képesek a futtatható kód címeinek tárolására.
PL / IEdit
A PL / I nyelv teljes körű támogatást nyújt az összes adattípusra mutató mutatókhoz (beleértve a struktúrákra mutató mutatókat is), a rekurzióhoz, a többfeladatos feladathoz, a karakterláncok kezeléséhez és a kiterjedt beépített funkciókhoz.A PL / I korai programozási nyelvekhez képest meglehetősen nagy előrelépés volt. A PL / I mutatók nincsenek beírva, és ezért nincs szükség castingra a mutató levonásához vagy hozzárendeléséhez. A mutató deklarációs szintaxisa DECLARE xxx POINTER;
, amely “xxx” nevű mutatót deklarál. A mutatókat BASED
változókkal együtt használják. Egy alapú változó deklarálható egy alapértelmezett lokátorral (DECLARE xxx BASED(ppp);
vagy anélkül (DECLARE xxx BASED;
), ahol az xxx egy alapú változó, amely lehet egy elem változó, egy szerkezet vagy egy tömb, és a ppp az alapértelmezett mutató). Az ilyen változó lehet cím kifejezett hivatkozás nélkül (xxx=1;
, vagy megcélozható kifejezett hivatkozással az alapértelmezett helymeghatározóra (ppp) vagy bármely más mutatóra (qqq->xxx=1;
).
A mutató-aritmetika nem része a PL / I szabványnak, de sok fordító megengedi a ptr = ptr±expression
formátumú kifejezéseket . Az IBM PL / I beépített PTRADD
függvénnyel is rendelkezik az aritmetika végrehajtására. A mutató-aritmetikát mindig bájtokban hajtják végre.
Az IBM Enterprise PL / I fordítóknak van egy a gépelt mutató új formája, az úgynevezett HANDLE
.
DEdit
A D programozási nyelv a C és C ++ származéka, amely teljes mértékben támogatja a C mutatók és C típusú specifikáció.
EiffelEdit
Az Eiffel objektum-orientált nyelv mutató- és aritmetika nélkül alkalmaz érték- és referenciaszemantikát. Mindazonáltal mutatóosztályok állnak rendelkezésre. memóriakezelés, int nem Eiffel szoftverrel és más funkciókkal való felújítás.
FortranEdit
A Fortran-90 egy erősen tipizált mutató képességet vezetett be. A Fortran mutatók nem csupán egyszerű memóriacímet tartalmaznak. Beépítik a tömb dimenzióinak alsó és felső határait, a lépéseket (például tetszőleges tömb szakaszok támogatására) és egyéb metaadatokat. A =>
társítási operátor segítségével egy POINTER
társítható egy olyan változóhoz, amelynek TARGET
attribútum. A Fortran-90 ALLOCATE
utasítás szintén használható mutató társításához a memória blokkjához. Például a következő kód használható egy összekapcsolt listaszerkezet meghatározására és létrehozására:
A Fortran-2003 támogatja az eljárásmutatókat. A C átjárhatósági szolgáltatás részeként a Fortran-2003 támogatja a belső funkciókat a C-stílusú mutatók Fortran-mutatóvá és vissza történő konvertálásához.
GoEdit
A Go mutatókat tartalmaz. Deklarációs szintaxisa megegyezik a C-vel, de fordítva van írva, a típussal végződve. C-vel ellentétben a Go rendelkezik szemétszállítással, és nem engedélyezi a mutató számtanát. A C ++ -hoz hasonló referenciatípusok nem léteznek. Egyes beépített típusok, például a térképek és a csatornák dobozosak (azaz belsőleg mutatók a mutálható struktúrákra), és a make
függvény segítségével inicializálódnak. A mutatók és a nem mutatók közötti egységes szintaxis megközelítésében a nyíl (->
) operátor leesett: a pointer operátor a hivatkozott objektum mezőjére vagy módszerére utal . Ez azonban csak 1 szintű indirekcióval működik.
JavaEdit
A C, C ++ vagy Pascal programmal ellentétben a mutatók nincsenek kifejezetten ábrázolva a Java-ban. Ehelyett bonyolultabb adatstruktúrák, például objektumok és tömbök, referenciák segítségével valósulnak meg. A nyelv nem tartalmaz kifejezett mutató-manipulációs operátorokat. Még mindig lehetséges, hogy a kód megpróbál elvetni egy null referenciát (null mutató), ami a futási idő kivételét eredményezi. A nem hivatkozott memóriaobjektumok által elfoglalt helyet a futás közbeni szemétgyűjtés automatikusan helyreállítja.
Modula-2Edit
A mutatók ugyanúgy megvalósulnak, mint a Pascal-ban, ahogyan a VAR
paraméterek az eljáráshívásokban. A Modula-2 még erősebben be van írva, mint Pascal, kevesebb módszerrel lehet elkerülni a típusrendszert. A Modula-2 néhány változata (például a Modula-3) szemétgyűjtést tartalmaz.
OberonEdit
A Modula-2-hez hasonlóan mutatók is rendelkezésre állnak. Még mindig kevesebb módszer van a típusrendszer kibújására, így az Oberon és változatai még mindig biztonságosabbak a mutatók szempontjából, mint a Modula-2 vagy annak változatai. A Modula-3-hoz hasonlóan a szemétgyűjtés is a nyelvi specifikáció része.
PascalEdit
Sok mutatóval rendelkező nyelvtől eltérően a szokásos ISO Pascal csak a dinamikusan létrehozott változók hivatkozására engedi meg a mutatókat. névtelenek, és nem teszik lehetővé számukra a standard statikus vagy lokális változók hivatkozását. Nincs mutatószámtana. A mutatóknak társított típussal is kell rendelkezniük, és az egyik típusra mutató mutató nem kompatibilis egy másik típusú mutatóval (például a char mutatója nem kompatibilis egy egész szám mutatójával).Ez segít kiküszöbölni a többi mutatómegvalósítással járó típusú biztonsági problémákat, különösen a PL / I vagy C esetén használtakat. Megszünteti a függő mutatók okozta kockázatokat is, de a hivatkozott terület dinamikus elengedésének képessége a dispose
szabványos eljárás (amelynek ugyanaz a hatása van, mint a C-ben található free
könyvtárfunkciónak) azt jelenti, hogy a mutatók lógásának kockázatát nem sikerült teljesen kiküszöbölni.
Egyes kereskedelmi és nyílt forráskódú Pascal (vagy származékok) fordítói megvalósításokban – például a Free Pascal, a Turbo Pascal vagy az Obbar Pascal az Embarcadero Delphi-ben – megengedett, hogy egy mutató normál statikus vagy lokális változókra hivatkozhasson, és egyik mutatótípusból a másikba dobja. Ezenkívül a mutató aritmetikája nem korlátozott: egy mutató hozzáadása vagy kivonása ezt a bájtok számával mindkét irányba elmozdítja, de a Inc
vagy Dec
standard eljárások vele mozgatja a mutatót annak az adattípusnak a méretével, amelyre deklarálva mutat. A be nem írt mutató Pointer
néven is megtalálható, amely kompatibilis más mutatótípusokkal.