Omfattning i C ++

Scope C



En enhet i C ++ har ett namn som kan deklareras och/eller definieras. En deklaration är en definition, men en definition är inte nödvändigtvis en deklaration. En definition tilldelar minne för den namngivna enheten, men en deklaration kan eller inte tilldela minne för den namngivna enheten. En deklarativ region är den största delen av ett program där namnet på en enhet (variabel) är giltigt. Den regionen kallas en omfattning eller en potentiell omfattning. Denna artikel förklarar omfattning i C ++. Dessutom behövs grundläggande kunskaper i C ++ för att förstå denna artikel.

Artikelinnehåll

Deklarativ region och omfattning

En deklarativ region är den största delen av en programtext där namnet på en enhet är giltigt. Det är regionen där det okvalificerade namnet kan användas (ses) för att hänvisa till samma enhet. Tänk på följande korta program:







#omfatta
använder sig av namnrymdtimmar;

tomhetfn()
{
intvar= 3;
om (1==1)
{
kosta<<var<<' n';
}
}

inthuvud()
{
fn();
lämna tillbaka 0;
}

Funktionen fn () har två block: ett inre block för if-tillståndet och ett yttre block för funktionskroppen. Identifieraren, var, introduceras och ses i det yttre blocket. Det ses också i det inre blocket, med cout -uttalandet. De yttre och inre blocken är båda omfattningen för namnet, var.



Namnet var kan dock fortfarande användas för att deklarera en annan enhet, till exempel en flottör i det inre blocket. Följande kod illustrerar detta:



#omfatta
använder sig av namnrymdtimmar;

tomhetfn()
{
intvar= 3;
om (1==1)
{
flytavar= 7.5;
kosta<<var<<' n';
}
}

inthuvud()
{
fn();
lämna tillbaka 0;
}

Utgången är 7,5. I det här fallet kan namnet, var, inte längre användas i det inre blocket för att hänvisa till heltalet av värde 3, som infördes (deklareras) i det yttre blocket. Sådana inre block kallas potentiellt utrymme för enheter som deklareras i det yttre blocket.





Obs! En enhet av samma typ, som den i det yttre blocket, kan fortfarande deklareras i det inre blocket. Men i detta fall är det som är giltigt i det inre blocket den nya deklarationen och dess innebörd, medan den gamla deklarationen och dess betydelse utanför det inre blocket förblir giltig i det yttre blocket.

En deklaration med samma namn i ett inre block åsidosätter normalt deklarationen med samma namn utanför det inre blocket. Inre block kan häcka andra inre block.



Globalt omfång

När en programmerare bara börjar skriva en fil, är det det globala omfånget. Följande korta program illustrerar detta:

#omfatta
använder sig av namnrymdtimmar;

flytavar= 9.4;

inthuvud()
{
kosta <<var<<' n';
kosta <<::var<<' n';

lämna tillbaka 0;
}

Utgången är:
9.4
9.4

I det här fallet börjar den deklarativa regionen eller omfattningen för var från deklarationspunkten för var, fortsätter nedåt till slutet av filen (översättningsenhet).

Blocket för huvudfunktionen () är ett annat omfång; det är ett kapslat utrymme för det globala omfånget. För att komma åt en enhet av det globala omfånget, från ett annat omfång, används identifieraren direkt eller föregås av operatören för omfångsupplösning, ::.

Obs! Enheten, main (), deklareras också i den globala omfattningen.

Blockera omfattning

If, while, do, for, eller switch -satsen kan var och en definiera ett block. Ett sådant uttalande är ett sammansatt uttalande. Namnet på en variabel som deklareras i ett block har ett blocks omfattning. Dess omfattning börjar vid dess deklarationspunkt och slutar i slutet av blocket. Följande korta program illustrerar detta för variabeln, ident:

#omfatta
använder sig av namnrymdtimmar;

inthuvud()
{
om (1==1)
{
/*några uttalanden*/
intident= 5;
kosta<<ident<<' n';
/*några uttalanden*/
}
lämna tillbaka 0;
}

En variabel, såsom ident, deklarerad vid blockomfång är en lokal variabel.

En variabel som deklareras utanför blockets omfattning och över den kan ses i blockets rubrik (t.ex. villkor för if-block) och även inom blocket. Följande korta program illustrerar detta för variabeln, identifier:

#omfatta
använder sig av namnrymdtimmar;

inthuvud()
{
intidentifiera= 8;

om (identifiera== 8)
{
kosta<<identifiera<<' n';
}
lämna tillbaka 0;
}

Utdata är 8. Det finns två blockomfång här: blocket för funktionen main () och det kapslade if-compound-satsen. Det kapslade blocket är det potentiella omfånget för huvudfunktionsblocket ().

En deklaration som införs i en blockomfång kan inte ses utanför blocket. Följande korta program, som inte sammanställer, illustrerar detta med variabeln, variab:

#omfatta
använder sig av namnrymdtimmar;

inthuvud()
{
om (1 == 1)
{
intvariab= femton;
}
kosta<<variab<<' n'; // fel: åtkomst utanför dess omfattning.

lämna tillbaka 0;
}

Kompilatorn producerar ett felmeddelande för variab.

En enhet som introduceras, deklarerad i rubriken till en sammansatt funktion, kan inte ses utanför (nedan) sammansatt uttalande. Följande for-loop-kod kommer inte att kompileras, vilket resulterar i ett felmeddelande:

#omfatta
använder sig av namnrymdtimmar;

inthuvud()
{
för (inti=0;i<4; ++i)
{
kosta<<i<<'';
}
kosta<<i<<'';

lämna tillbaka 0;
}

Iterationsvariabeln, i, ses inuti for-loop-blocket men inte utanför for-loop-blocket.

Funktionsomfång

En funktionsparameter visas i funktionsblocket. En enhet som deklareras i ett funktionsblock ses från deklarationspunkten till slutet av funktionsblocket. Följande korta program illustrerar detta:

#omfatta
#omfatta
använder sig av namnrymdtimmar;

sträng fn(sträng str)
{
rödingstri[] = 'bananer';
/*andra uttalanden*/
sträng totalStr=sid+stri;
lämna tillbakatotalStr;
}

inthuvud()
{
sträng totStr=fn('äter ');
kosta<<totStr<<' n';

lämna tillbaka 0;
}

Utgången är:
äta bananer

Obs! En enhet som deklareras utanför funktionen (ovanför den) kan ses i funktionsparameterlistan och även i funktionsblocket.

Märka

Omfattningen av en etikett är den funktion där den visas. Följande kod illustrerar detta:

#omfatta
använder sig av namnrymdtimmar;

tomhetfn()
{
gå tilllabl;
/*andra uttalanden*/
labl: intinte= 2;
kosta<<inte<<' n';
}

inthuvud()
{
fn();

lämna tillbaka 0;
}

Utgången är 2.

Uppräkningens omfattning

Oskalad uppräkning
Tänk på följande if-block:

om (1==1)
{
enum {a, b, c=b+2};
kosta<<till<<''<<b<<''<<c<<' n';
}

Utgången är 0 1 3.

Den första raden i blocket är en uppräkning, a, b och c är dess räknare. Räknarens omfattning börjar från deklarationspunkten till slutet av det bifogade blocket i uppräkningen.

Följande uttalande kommer inte att sammanställas eftersom punkten för deklaration av c är efter den för a:

enum {till=c+2, före Kristus};

Följande kodsegment kommer inte att kompileras eftersom räknarna nås efter det slutande blocket i uppräkningen:

om (1==1)
{
enum {a, b, c=b+2};
}
kosta<<till<<''<<b<<''<<c<<' n'; // fel: utanför tillämpningsområdet

Ovanstående uppräkning beskrivs som en oscoped uppräkning, och dess uppräknare beskrivs som oscopedräknare. Detta beror på att det bara börjar med det reserverade ordet enum. Räkningar som börjar med enum klass eller enum struct beskrivs som omfattande uppräkningar. Deras räknare beskrivs som omfattande räknare.

Omfattande uppräkning
Följande påstående är OK:

enum klassmanlig{a, b, c=b+2};

Detta är ett exempel på en omfattande uppräkning. Klassens namn är nam. Här börjar räknarens omfattning från deklarationspunkten till slutet av uppräkningsdefinitionen, och inte slutet på det bifogade blocket för uppräkningen. Följande kod kommer inte att kompileras:

om (1==1)
{
enum klassmanlig{a, b, c=b+2};
kosta<<till<<''<<b<<''<<c<<' n'; // fel: utanför tillämpningsområdet för enumklass eller enum struct
}

Klassens omfattning

Med normal omfattning börjar den deklarativa regionen från en punkt, fortsätter sedan och stannar vid en annan punkt. Omfattningen finns i en kontinuerlig region. Med klassen kan omfattningen av en enhet vara i olika regioner som inte är sammanfogade. Reglerna för kapslade block gäller fortfarande. Följande program illustrerar detta:

#omfatta
använder sig av namnrymdtimmar;

// Basklass
klassCla
{
privat:
intmemP= 5;
skyddade:
intmemPro= 9;
offentlig:
tomhetfn()
{
kosta<<memP<<' n';
}
};

// Avledad klass
klassDerCla: offentligCla
{
offentlig:
intderMem=memPro;
};
inthuvud()
{
Cla obj;
obj.fn();
DerCla derObj;
kosta<<derObj.derMem<<' n';

lämna tillbaka 0;
}

Utgången är:
5
9

I klassen Cla ses variabeln memP vid deklarationspunkten. Efter det hoppas den korta delen av skyddad över och sedan ses igen i klassmedlemsfunktionsblocket. Den härledda klassen hoppas över och ses sedan igen vid huvudfunktionens () funktionsomfång (block).

I klassen Cla ses variabeln memPro vid deklarationspunkten. Delen av den offentliga funktionen fn () hoppas över och ses sedan i det härledda klassbeskrivningsblocket. Det ses igen nere i huvudfunktionen ().

Operatör för omfattningsupplösning
Omfattningsupplösningsoperatören i C ++ är ::. Den används för att komma åt en statisk medlem i klassen. Följande program illustrerar detta:

#omfatta
använder sig av namnrymdtimmar;

klassCla
{
offentlig:
statisk int konstjag Jag= 5;
offentlig:
statisk tomhetfn()
{
kosta<<jag Jag<<' n';
}
};
inthuvud()
{
kosta<<Cla::jag Jag<<' n';
Cla::fn();

lämna tillbaka 0;
}

Utgången är:
5
5

De statiska delarna ses i huvudblocket () funktionsblocket, som nås med operatören för upplösning av omfång.

Mallparameter Omfattning

Det normala omfånget för ett mallparameternamn börjar från deklarationspunkten till slutet av blocket, som i följande kod:

mall<typnamnT,typnamnU> strukturÅldrar
{
T John= elva;
Du Peter= 12.3;
T Mary= 13;
U Joy= 14.6;
};

U och T ses inom blocket.

För en mallfunktionsprototyp börjar omfattningen från deklarationspunkten till slutet av funktionsparameterlistan, som i följande uttalande:

mall<typnamnT,typnamnU> tomhetfungera(Du nej, du cha,konst röding *sid);

Men när det gäller klassbeskrivningen (definitionen) kan omfattningen också ha olika delar som i följande kod:

#omfatta
använder sig av namnrymdtimmar;

mall<klassT,klassU> klassTheCla
{
offentlig:
t num;
statiskU ch;

tomhetfungera(Du far,konst röding *sid)
{
kosta << 'Det finns ' <<på ett<< 'värda böcker' <<Nej<<sid<< ' i affären.' << ' n';
}
statisk tomhetroligt(U ch)
{
om (kap== 'till')
kosta << 'Officiell statisk medlemsfunktion' << ' n';
}
};

inthuvud()
{
TheCla<int,röding>obj;
obj.på ett = 12;
obj.fungera('$','500');

lämna tillbaka 0;
}

Namn gömmer sig

Ett exempel på namn gömmer sig när namnet på samma objekttyp deklareras på nytt i ett kapslat block. Följande program illustrerar detta:

#omfatta
använder sig av namnrymdtimmar;

tomhetfn()
{
intvar= 3;
om (1==1)
{
intvar= 4;
kosta<<var<<' n';
}
kosta<<var<<' n';
}

inthuvud()
{
fn();
lämna tillbaka 0;
}

Utgången är:
4
3

Det beror på att var i det kapslade blocket gömde var i det yttre blocket.

Möjlighet att upprepa deklaration i samma omfattning

Poängen med deklarationen är där namnet introduceras (för första gången) i dess omfattning.

Funktionsprototyp
Olika enheter, även av olika slag, kan normalt inte deklareras i samma omfattning. En funktionsprototyp kan dock deklareras mer än en gång i samma omfattning. Följande program med två funktionsprototyper och motsvarande funktionsdefinition illustrerar detta:

#omfatta
använder sig av namnrymdtimmar;

tomhetfn(intpå ett);
tomhetfn(intpå ett);

tomhetfn(intpå ett)
{
kosta<<på ett<<' n';
}

inthuvud()
{
fn(5);

lämna tillbaka 0;
}

Programmet fungerar.

Överbelastade funktioner
Överbelastade funktioner är funktioner med samma namn men olika funktionssignaturer. Som ett annat undantag kan överbelastade funktioner med samma namn definieras i samma omfattning. Följande program illustrerar detta:

#omfatta
använder sig av namnrymdtimmar;

tomhetfn(intpå ett)
{
kosta<<på ett<<' n';
}

tomhetfn(flytaNej)
{
kosta<<Nej<<' n';
}

inthuvud()
{
fn(5);
flytaflt= 8.7;
fn(flt);

lämna tillbaka 0;
}

Utgången är:
5
8.7

De överbelastade funktionerna har definierats i det globala omfånget.

Namnutrymme

Namespace Scope förtjänar en egen artikel. Den nämnda artikeln har skrivits för denna webbplats, linuxhint.com. Skriv bara sökorden Namespace Scope i sökrutan på denna webbplats (sida) och klicka på OK, så får du fram artikeln.

Omfattning i olika delar

Klassen är inte det enda schemat där omfattningen kan vara i olika delar. Vänspecifikatör, vissa användningsområden för den utarbetade typspecifikatorn och användningsdirektiven är andra scheman där omfattningen finns på olika platser-för detaljer, se senare.

Slutsats

En omfattning är en deklarativ region. En deklarativ region är den största delen av en programtext där namnet på en enhet är giltigt. Den kan delas in i mer än en del i enlighet med vissa programmeringsscheman, till exempel kapslade block. De delar som inte har deklarationspunkten utgör det potentiella omfånget. Den potentiella omfattningen kan ha eller inte ha deklarationen.