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.