Uppräknad typ (förkortad uppräkning , eng. uppräkning, uppräknad typ ) - i programmeringsdatatyp , vars uppsättning värden är en begränsad lista med identifierare.
En uppräknad typ definieras som en uppsättning identifierare som ur språksynpunkt spelar samma roll som vanliga namngivna konstanter, men som är associerade med den typen. Den klassiska beskrivningen av en uppräkningstyp i Pascal är följande:
typ Cardsuit = ( klöver , ruter , hjärter , spader ) ;Här deklareras Cardsuit-datatypen, vars värden kan vara vilken som helst av de fyra listade konstanterna. En typvariabel Cardsuitkan ta ett av värdena clubs, diamonds, hearts, spades, det är tillåtet att jämföra värden av uppräkningstypen för likhet eller olikhet, samt använda dem i urvalssatser (i Pascal - case) som värden som identifierar alternativ.
Användningen av uppräkningar gör det möjligt att göra källkoderna för program mer läsbara, eftersom de tillåter att ersätta "magiska siffror" som kodar vissa värden med läsbara namn.
På grundval av uppräkningar på vissa språk kan typuppsättningar skapas . I sådana fall förstås (och beskrivs) en uppsättning som en oordnad samling av unika värden av en enumtyp.
En uppräknad typ kan användas i deklarationer av variabler och formella parametrar för funktioner (procedurer, metoder). Värden av en uppräknad typ kan tilldelas motsvarande variabler och passeras genom parametrar för motsvarande typer i funktioner. Dessutom stöds alltid jämförelse av uppräknade värden för jämlikhet och ojämlikhet. Vissa språk stöder även andra jämförelseoperatorer för värden av uppräknade typer. Resultatet av att jämföra två uppräknade värden i sådana fall bestäms som regel av ordningen på dessa värden i typdeklarationen - värdet som förekommer tidigare i typdeklarationen anses vara "mindre" än värdet som inträffar senare. Ibland kan en uppräknad typ eller något värdeintervall av en uppräknad typ också användas som en indextyp för en matris. I det här fallet finns det ett element i arrayen för varje värde i det valda intervallet, och den faktiska ordningen på elementen motsvarar ordningen på värdena i typdeklarationen.
Normalt, under kompilering, representeras uppräkningsvärden med hjälp av heltal. Beroende på det specifika programmeringsspråket kan en sådan representation antingen vara helt dold för programmeraren eller tillgänglig för honom med hjälp av vissa "lösningar" (till exempel påtvingad konvertering av ett enumtypvärde till ett "heltalstypvärde"), eller till och med kontrolleras av programmeraren (i sådana fall har programmeraren möjlighet att uttryckligen ange vilka siffror alla eller vissa värden av enum-typen kommer att kodas med. Alla alternativ har sina positiva och negativa egenskaper. Å ena sidan berövar möjligheten att använda de numeriska värdena för konstanterna som utgör uppräkningstypen, särskilt när den missbrukas, användningen av dessa typer och skapar risken för fel (när man använder numeriska värden för som det inte finns några motsvarande konstanter i typen). Å andra sidan ger explicit värdehantering några ytterligare funktioner. Till exempel tillåter det att använda enumtyper när du organiserar ett gränssnitt med moduler skrivna på andra språk, om de använder eller returnerar heltalskodade värden från någon fördefinierad uppsättning.
En annan möjlighet som uppräknade typer tillhandahåller på språkimplementeringsnivån är minnesbesparing. Med en liten mängd enumtyp räcker några bitar för att lagra ett värde av denna typ (ovan typ Cardsuitkräver endast två bitar per värde, medan ett standardheltal på de flesta använda arkitekturer tar 32 bitar - 16 gånger mer), och kompilatorn kan använda detta faktum för att kompaktera lagring av data i minnet. Detta kan vara särskilt viktigt om flera värden av enumtyper lagras i en enda post - komprimering av poster vid bearbetning av ett stort antal av dem kan frigöra mycket minne. Kompilatorer implementerar vanligtvis inte den här funktionen, åtminstone inte på senare tid när datorminnet har blivit mycket billigare.
Uppräkningstypen är traditionell för utvecklade programmeringsspråk, används ganska brett och tas ofta för given. Men denna typ är inte heller utan kritik från teoretiker och praktiker av programmering. Så när man utvecklade programmeringsspråket Oberon inkluderades uppräknade typer i listan över funktioner som togs bort från språket. Niklaus Wirth , formgivaren av språket, citerade följande skäl:
Å andra sidan, till exempel i Java , som till en början inte innehöll en uppräknad typ, introducerades denna typ senare av inte bara bekvämlighetsskäl, utan också av tillförlitlighet: problemet med att använda grupper av namngivna konstanter istället för uppräkningar är att det finns Det finns ingen kontroll från kompilatorn vad gäller unikheten hos värdekonstanter, såväl som möjligheten att slumpmässigt tilldela värden till variabler som inte motsvarar någon av dessa konstanter.
I Ada-språket specificeras uppräkningar med ett nyckelord isföljt av en kommaseparerad lista med värden:
typ Cardsuit är ( klöver , ruter , hjärter , spader );Den ursprungliga K&R -dialekten av C hade inte uppräknade typer, men de lades till i ANSI C- standarden .
enum cardsuit { KLUBBAR , DIAMANTER , HJÄRTA , SPADER };Dynamiska, svagt skrivna språk med C-liknande syntax (som perl eller JavaScript ) har i allmänhet inga uppräkningar.
C++C++ enums ärver direkt beteendet hos C enums, förutom att den uppräknade typen i C++ är en riktig typ, och nyckelordet enumanvänds bara när man deklarerar en sådan typ. Om, vid bearbetning av en parameter som är en uppräkning, något värde från uppräkningen inte behandlas (till exempel glömdes ett av uppräkningselementen att behandlas i konstruktionen switch), då kan kompilatorn utfärda en varning om det glömda värdet. [2]
C++11 tillhandahåller en andra, typsäker enumtyp som inte är implicit konverterbar till en integraltyp. Detta definieras av frasen "enum-klass". Till exempel:
enum klass Färg { Röd , Grön , Blå };En bastyp är en implementering av en viss integraltyp som är tillräckligt stor för att hålla alla listade värden (det behöver inte vara den minsta möjliga typen!). I C++ kan du ange bastypen direkt. Detta tillåter "vidarebefordran" av enums:
enum klass Färg : lång { Röd , Grön , Blå }; // måste matcha storleken och layouten för minnestypen "lång" enum- klass Shapes : char ; // preliminär förklaring. Om värden senare definieras som inte passar i 'char' är detta ett fel. C# enum Cardsuit { klöver , ruter , spader , hjärter } JavaI den ursprungliga Java fanns det inga uppräkningar, istället föreslogs det att använda klasser med statiska konstanter. Eftersom version 5 (1.5) uppräkningar har införts i språket är de en fullfjädrad klass där du kan lägga till ett godtyckligt antal fält och metoder. Enums infördes för att förbättra typsäkerhetskontrollen. [3]
enum Cardsuit { klöver , ruter , spader , hjärter } Kotlin uppräkningsklass Riktning { NORD , SYD , VÄST , ÖST } _I vissa programmeringsspråk (t.ex. Haskell) kan uppräkningar emuleras med hjälp av algebraiska typer . Till exempel är en boolesk typ som innehåller två identifierare för att representera sanningsvärden kodad så här:
data Bool = Falskt | Sann
Datatyper | |
---|---|
Otolkbart | |
Numerisk | |
Text | |
Referens | |
Sammansatt | |
abstrakt | |
Övrig | |
Relaterade ämnen |