Sie sind auf Seite 1von 9

02/07/2015

C++PointersC++ProgrammingConcepts@littledrops@thiyagaraaj.com

C++Pointers
Pointers
Wehavealreadyseenhowvariablesareseenasmemorycellsthatcanbeaccessedusingtheiridentifiers.Thisway
wedidnothavetocareaboutthephysicallocationofourdatawithinmemory,wesimplyuseditsidentifier
wheneverwewantedtorefertoourvariable.
Thememoryofyourcomputercanbeimaginedasasuccessionofmemorycells,eachoneoftheminimalsizethat
computersmanage(onebyte).Thesesinglebytememorycellsarenumberedinaconsecutiveway,soas,withinany
blockofmemory,everycellhasthesamenumberasthepreviousoneplusone.
Thisway,eachcellcanbeeasilylocatedinthememorybecauseithasauniqueaddressandallthememorycells
followasuccessivepattern.Forexample,ifwearelookingforcell1776weknowthatitisgoingtoberightbetween
cells1775and1777,exactlyonethousandcellsafter776andexactlyonethousandcellsbeforecell2776.
Referenceoperator(&)
Assoonaswedeclareavariable,theamountofmemoryneededisassignedforitataspecificlocationinmemory(its
memoryaddress).Wegenerallydonotactivelydecidetheexactlocationofthevariablewithinthepanelofcellsthat
wehaveimaginedthememorytobeFortunately,thatisataskautomaticallyperformedbytheoperatingsystem
duringruntime.However,insomecaseswemaybeinterestedinknowingtheaddresswhereourvariableisbeing
storedduringruntimeinordertooperatewithrelativepositionstoit.
Theaddressthatlocatesavariablewithinmemoryiswhatwecallareferencetothatvariable.Thisreferencetoa
variablecanbeobtainedbyprecedingtheidentifierofavariablewithanampersandsign(&),knownasreference
operator,andwhichcanbeliterallytranslatedas"addressof".Forexample:
ted=&andy;

Thiswouldassigntotedtheaddressofvariableandy,sincewhenprecedingthenameofthevariableandywiththe
referenceoperator(&)wearenolongertalkingaboutthecontentofthevariableitself,butaboutitsreference(i.e.,
itsaddressinmemory).
Fromnowonwearegoingtoassumethatandyisplacedduringruntimeinthememoryaddress1776.Thisnumber
(1776)isjustanarbitraryassumptionweareinventingrightnowinordertohelpclarifysomeconceptsinthis
tutorial,butinreality,wecannotknowbeforeruntimetherealvaluetheaddressofavariablewillhaveinmemory.
Considerthefollowingcodefragment:
andy=25;
fred=andy;
ted=&andy;

Thevaluescontainedineachvariableaftertheexecutionofthis,areshowninthefollowingdiagram:

First,wehaveassignedthevalue25toandy(avariablewhoseaddressinmemorywehaveassumedtobe1776).
Thesecondstatementcopiedtofredthecontentofvariableandy(whichis25).Thisisastandardassignment
operation,aswehavedonesomanytimesbefore.
Finally,thethirdstatementcopiestotednotthevaluecontainedinandybutareferencetoit(i.e.,itsaddress,which
wehaveassumedtobe1776).Thereasonisthatinthisthirdassignmentoperationwehaveprecededtheidentifier
andywiththereferenceoperator(&),sowewerenolongerreferringtothevalueofandybuttoitsreference(its
addressinmemory).
Thevariablethatstoresthereferencetoanothervariable(liketedinthepreviousexample)iswhatwecallapointer
data:text/htmlcharset=utf8,%3Ch3%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxhtml%22%20id%3D%22sitespagetitleheader%22%20

1/9

02/07/2015

C++PointersC++ProgrammingConcepts@littledrops@thiyagaraaj.com

PointersareaverypowerfulfeatureoftheC++languagethathasmanyusesinadvancedprogramming.Farther
ahead,wewillseehowthistypeofvariableisusedanddeclared.
Dereferenceoperator(*)
Wehavejustseenthatavariablewhichstoresareferencetoanothervariableiscalledapointer.Pointersaresaidto
"pointto"thevariablewhosereferencetheystore.
Usingapointerwecandirectlyaccessthevaluestoredinthevariablewhichitpointsto.Todothis,wesimplyhave
toprecedethepointer'sidentifierwithanasterisk(*),whichactsasdereferenceoperatorandthatcanbeliterally
translatedto"valuepointedby".
Therefore,followingwiththevaluesofthepreviousexample,ifwewrite:
beth=*ted;

(thatwecouldreadas:"bethequaltovaluepointedbyted")bethwouldtakethevalue25,sincetedis1776,andthe
valuepointedby1776is25.

Youmustclearlydifferentiatethattheexpressiontedreferstothevalue1776,while*ted(withanasterisk*
precedingtheidentifier)referstothevaluestoredataddress1776,whichinthiscaseis25.Noticethedifferenceof
includingornotincludingthedereferenceoperator(Ihaveincludedanexplanatorycommentaryofhoweachof
thesetwoexpressionscouldberead):
beth=ted;//bethequaltoted(1776)
beth=*ted;//bethequaltovaluepointedbyted(25)

Noticethedifferencebetweenthereferenceanddereferenceoperators:
&isthereferenceoperatorandcanbereadas"addressof"
*isthedereferenceoperatorandcanbereadas"valuepointedby"
Thus,theyhavecomplementary(oropposite)meanings.Avariablereferencedwith&canbedereferencedwith*.
Earlierweperformedthefollowingtwoassignmentoperations:
andy=25;
ted=&andy;

Rightafterthesetwostatements,allofthefollowingexpressionswouldgivetrueasresult:
andy==25
&andy==1776
ted==1776
*ted==25

Thefirstexpressionisquiteclearconsideringthattheassignmentoperationperformedonandywasandy=25.The
secondoneusesthereferenceoperator(&),whichreturnstheaddressofvariableandy,whichweassumedittohave
avalueof1776.Thethirdoneissomewhatobvioussincethesecondexpressionwastrueandtheassignment
operationperformedontedwasted=&andy.Thefourthexpressionusesthedereferenceoperator(*)that,aswehave
justseen,canbereadas"valuepointedby",andthevaluepointedbytedisindeed25.
So,afterallthat,youmayalsoinferthatforaslongastheaddresspointedbytedremainsunchangedthefollowing
expressionwillalsobetrue:
*ted==andy

Declaringvariablesofpointertypes
data:text/htmlcharset=utf8,%3Ch3%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxhtml%22%20id%3D%22sitespagetitleheader%22%20

2/9

02/07/2015

C++PointersC++ProgrammingConcepts@littledrops@thiyagaraaj.com

Duetotheabilityofapointertodirectlyrefertothevaluethatitpointsto,itbecomesnecessarytospecifyinits
declarationwhichdatatypeapointerisgoingpointto.Itisnotthesamethingtopointtoacharthantopointtoan
intorafloat.
Thedeclarationofpointersfollowsthisformat:
type*name
wheretypeisthedatatypeofthevaluethatthepointerisintendedtopointto.Thistypeisnotthetypeofthepointer
itself!butthetypeofthedatathepointerpointsto.Forexample:
int*number;
char*character;
float*greatnumber;

Thesearethreedeclarationsofpointers.Eachoneisintendedtopointtoadifferentdatatype,butinfactallofthem
arepointersandallofthemwilloccupythesameamountofspaceinmemory(thesizeinmemoryofapointer
dependsontheplatformwherethecodeisgoingtorun).Nevertheless,thedatatowhichtheypointtodonotoccupy
thesameamountofspacenorareofthesametype:thefirstonepointstoanint,thesecondonetoacharandthe
lastonetoafloat.Therefore,althoughthesethreeexamplevariablesareallofthempointerswhichoccupythesame
sizeinmemory,theyaresaidtohavedifferenttypes:int*,char*andfloat*respectively,dependingonthetypethey
pointto.
Iwanttoemphasizethattheasterisksign(*)thatweusewhendeclaringapointeronlymeansthatitisapointer(it
ispartofitstypecompoundspecifier),andshouldnotbeconfusedwiththedereferenceoperatorthatwehaveseena
bitearlier,butwhichisalsowrittenwithanasterisk(*).Theyaresimplytwodifferentthingsrepresentedwiththe
samesign.
Nowhavealookatthiscode:
//myfirstpointer
#include<iostream>
usingnamespacestd;

firstvalueis10
secondvalueis20

intmain()
{
intfirstvalue,secondvalue;
int*mypointer;
mypointer=&firstvalue;
*mypointer=10;
mypointer=&secondvalue;
*mypointer=20;
cout<<"firstvalueis"<<firstvalue<<endl;
cout<<"secondvalueis"<<secondvalue<<endl;
return0;
}

Noticethateventhoughwehaveneverdirectlysetavaluetoeitherfirstvalueorsecondvalue,bothendupwitha
valuesetindirectlythroughtheuseofmypointer.Thisistheprocedure:
First,wehaveassignedasvalueofmypointerareferencetofirstvalueusingthereferenceoperator(&).Andthenwe
haveassignedthevalue10tothememorylocationpointedbymypointer,thatbecauseatthismomentispointingto
thememorylocationoffirstvalue,thisinfactmodifiesthevalueoffirstvalue.
InordertodemonstratethatapointermaytakeseveraldifferentvaluesduringthesameprogramIhaverepeated
theprocesswithsecondvalueandthatsamepointer,mypointer.
Hereisanexamplealittlebitmoreelaborated:
//morepointers
#include<iostream>
usingnamespacestd;

firstvalueis10
secondvalueis20

data:text/htmlcharset=utf8,%3Ch3%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxhtml%22%20id%3D%22sitespagetitleheader%22%20

3/9

02/07/2015

C++PointersC++ProgrammingConcepts@littledrops@thiyagaraaj.com

intmain()
{
intfirstvalue=5,secondvalue=15;
int*p1,*p2;
p1=&firstvalue;//p1=addressoffirstvalue
p2=&secondvalue;//p2=addressofsecondvalue
*p1=10;//valuepointedbyp1=10
*p2=*p1;//valuepointedbyp2=valuepointedbyp1
p1=p2;//p1=p2(valueofpointeriscopied)
*p1=20;//valuepointedbyp1=20

cout<<"firstvalueis"<<firstvalue<<endl;
cout<<"secondvalueis"<<secondvalue<<endl;
return0;
}

Ihaveincludedasacommentoneachlinehowthecodecanberead:ampersand(&)as"addressof"andasterisk(*)
as"valuepointedby".
Noticethatthereareexpressionswithpointersp1andp2,bothwithandwithoutdereferenceoperator(*).The
meaningofanexpressionusingthedereferenceoperator(*)isverydifferentfromonethatdoesnot:Whenthis
operatorprecedesthepointername,theexpressionreferstothevaluebeingpointed,whilewhenapointername
appearswithoutthisoperator,itreferstothevalueofthepointeritself(i.e.theaddressofwhatthepointeris
pointingto).
Anotherthingthatmaycallyourattentionistheline:
int*p1,*p2;

Thisdeclaresthetwopointersusedinthepreviousexample.Butnoticethatthereisanasterisk(*)foreachpointer,
inorderforbothtohavetypeint*(pointertoint).
Otherwise,thetypeforthesecondvariabledeclaredinthatlinewouldhavebeenint(andnotint*)becauseof
precedencerelationships.Ifwehadwritten:
int*p1,p2;

p1wouldindeedhaveint*type,butp2wouldhavetypeint(spacesdonotmatteratallforthispurpose).Thisisdue
tooperatorprecedencerules.Butanyway,simplyrememberingthatyouhavetoputoneasteriskperpointeris
enoughformostpointerusers.

Pointersandarrays
Theconceptofarrayisverymuchboundtotheoneofpointer.Infact,theidentifierofanarrayisequivalenttothe
addressofitsfirstelement,asapointerisequivalenttotheaddressofthefirstelementthatitpointsto,soinfact
theyarethesameconcept.Forexample,supposingthesetwodeclarations:
intnumbers[20];
int*p;

Thefollowingassignmentoperationwouldbevalid:
p=numbers;

Afterthat,pandnumberswouldbeequivalentandwouldhavethesameproperties.Theonlydifferenceisthatwe
couldchangethevalueofpointerpbyanotherone,whereasnumberswillalwayspointtothefirstofthe20elements
oftypeintwithwhichitwasdefined.Therefore,unlikep,whichisanordinarypointer,numbersisanarray,andan
arraycanbeconsideredaconstantpointer.Therefore,thefollowingallocationwouldnotbevalid:
numbers=p;

data:text/htmlcharset=utf8,%3Ch3%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxhtml%22%20id%3D%22sitespagetitleheader%22%20

4/9

02/07/2015

C++PointersC++ProgrammingConcepts@littledrops@thiyagaraaj.com

Becausenumbersisanarray,soitoperatesasaconstantpointer,andwecannotassignvaluestoconstants.
Duetothecharacteristicsofvariables,allexpressionsthatincludepointersinthefollowingexampleareperfectly
valid:
//morepointers
#include<iostream>
usingnamespacestd;

10,20,30,40,50,

intmain()
{
intnumbers[5];
int*p;
p=numbers;*p=10;
p++;*p=20;
p=&numbers[2];*p=30;
p=numbers+3;*p=40;
p=numbers;*(p+4)=50;
for(intn=0;n<5;n++)
cout<<numbers[n]<<",";
return0;
}

Inthechapteraboutarraysweusedbrackets([])severaltimesinordertospecifytheindexofanelementofthe
arraytowhichwewantedtorefer.Well,thesebracketsignoperators[]arealsoadereferenceoperatorknown
asoffsetoperator.Theydereferencethevariabletheyfollowjustas*does,buttheyalsoaddthenumberbetween
bracketstotheaddressbeingdereferenced.Forexample:
a[5]=0;//a[offsetof5]=0
*(a+5)=0;//pointedby(a+5)=0

Thesetwoexpressionsareequivalentandvalidbothifaisapointerorifaisanarray.
Pointerinitialization
Whendeclaringpointerswemaywanttoexplicitlyspecifywhichvariablewewantthemtopointto:
intnumber;
int*tommy=&number;

Thebehaviorofthiscodeisequivalentto:
intnumber;
int*tommy;
tommy=&number;

Whenapointerinitializationtakesplacewearealwaysassigningthereferencevaluetowherethepointerpoints
(tommy),neverthevaluebeingpointed(*tommy).Youmustconsiderthatatthemomentofdeclaringapointer,the
asterisk(*)indicatesonlythatitisapointer,itisnotthedereferenceoperator(althoughbothusethesamesign:*).
Remember,theyaretwodifferentfunctionsofonesign.Thus,wemusttakecarenottoconfusethepreviouscode
with:
intnumber;
int*tommy;
*tommy=&number;

thatisincorrect,andanywaywouldnothavemuchsenseinthiscaseifyouthinkaboutit.
Asinthecaseofarrays,thecompilerallowsthespecialcasethatwewanttoinitializethecontentatwhichthe
pointerpointswithconstantsatthesamemomentthepointerisdeclared:
char*terry="hello";

Inthiscase,memoryspaceisreservedtocontain"hello"andthenapointertothefirstcharacterofthismemory
data:text/htmlcharset=utf8,%3Ch3%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxhtml%22%20id%3D%22sitespagetitleheader%22%20

5/9

02/07/2015

C++PointersC++ProgrammingConcepts@littledrops@thiyagaraaj.com

blockisassignedtoterry.Ifweimaginethat"hello"isstoredatthememorylocationsthatstartataddresses1702,
wecanrepresentthepreviousdeclarationas:

Itisimportanttoindicatethatterrycontainsthevalue1702,andnot'h'nor"hello",although1702indeedisthe
addressofbothofthese.
Thepointerterrypointstoasequenceofcharactersandcanbereadasifitwasanarray(rememberthatanarrayis
justlikeaconstantpointer).Forexample,wecanaccessthefifthelementofthearraywithanyofthesetwo
expression:
*(terry+4)
terry[4]

Bothexpressionshaveavalueof'o'(thefifthelementofthearray).
Pointerarithmetics
Toconductarithmeticaloperationsonpointersisalittledifferentthantoconductthemonregularintegerdata
types.Tobeginwith,onlyadditionandsubtractionoperationsareallowedtobeconductedwiththem,theothers
makenosenseintheworldofpointers.Butbothadditionandsubtractionhaveadifferentbehaviorwithpointers
accordingtothesizeofthedatatypetowhichtheypoint.
Whenwesawthedifferentfundamentaldatatypes,wesawthatsomeoccupymoreorlessspacethanothersinthe
memory.Forexample,let'sassumethatinagivencompilerforaspecificmachine,chartakes1byte,shorttakes2
bytesandlongtakes4.
Supposethatwedefinethreepointersinthiscompiler:
char*mychar;
short*myshort;
long*mylong;

andthatweknowthattheypointtomemorylocations1000,2000and3000respectively.
Soifwewrite:
mychar++;
myshort++;
mylong++;

mychar,asyoumayexpect,wouldcontainthevalue1001.Butnotsoobviously,myshortwouldcontainthevalue
2002,andmylong3004,eventhoughtheyhaveeachbeenincreasedonlyonce.Thereasonisthatwhenaddingone
toapointerwearemakingittopointtothefollowingelementofthesametypewithwhichithasbeendefined,and
thereforethesizeinbytesofthetypepointedisaddedtothepointer.wouldcontain

Thisisapplicablebothwhenaddingandsubtractinganynumbertoapointer.Itwouldhappenexactlythesameifwe
write:
mychar=mychar+1;
myshort=myshort+1;
mylong=mylong+1;

Boththeincrease(++)anddecrease()operatorshavegreateroperatorprecedencethanthedereferenceoperator
(*),butbothhaveaspecialbehaviorwhenusedassuffix(theexpressionisevaluatedwiththevalueithadbefore
beingincreased).Therefore,thefollowingexpressionmayleadtoconfusion:
*p++
data:text/htmlcharset=utf8,%3Ch3%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxhtml%22%20id%3D%22sitespagetitleheader%22%20

6/9

02/07/2015

C++PointersC++ProgrammingConcepts@littledrops@thiyagaraaj.com

Because++hasgreaterprecedencethan*,thisexpressionisequivalentto*(p++).Therefore,whatitdoesisto
increasethevalueofp(soitnowpointstothenextelement),butbecause++isusedaspostfixthewholeexpression
isevaluatedasthevaluepointedbytheoriginalreference(theaddressthepointerpointedtobeforebeing
increased).
Noticethedifferencewith:
(*p)++
Here,theexpressionwouldhavebeenevaluatedasthevaluepointedbypincreasedbyone.Thevalueofp(the
pointeritself)wouldnotbemodified(whatisbeingmodifiediswhatitisbeingpointedtobythispointer).
Ifwewrite:
*p++=*q++;

Because++hasahigherprecedencethan*,bothpandqareincreased,butbecausebothincreaseoperators(++)are
usedaspostfixandnotprefix,thevalueassignedto*pis*qbeforebothpandqareincreased.Andthenbothare
increased.Itwouldberoughlyequivalentto:
*p=*q;
++p;
++q;

Likealways,Irecommendyoutouseparentheses()inordertoavoidunexpectedresultsandtogivemorelegibility
tothecode.
Pointerstopointers
C++allowstheuseofpointersthatpointtopointers,thatthese,initsturn,pointtodata(oreventootherpointers).
Inordertodothat,weonlyneedtoaddanasterisk(*)foreachlevelofreferenceintheirdeclarations:
chara;
char*b;
char**c;
a='z';
b=&a;
c=&b;

This,supposingtherandomlychosenmemorylocationsforeachvariableof7230,8092and10502,couldbe
representedas:

Thevalueofeachvariableiswritteninsideeachcellunderthecellsaretheirrespectiveaddressesinmemory.
Thenewthinginthisexampleisvariablec,whichcanbeusedinthreedifferentlevelsofindirection,eachoneof
themwouldcorrespondtoadifferentvalue:
chastypechar**andavalueof8092
*chastypechar*andavalueof7230
**chastypecharandavalueof'z'
voidpointers
Thevoidtypeofpointerisaspecialtypeofpointer.InC++,voidrepresentstheabsenceoftype,sovoidpointersare
pointersthatpointtoavaluethathasnotype(andthusalsoanundeterminedlengthandundetermineddereference
properties).
Thisallowsvoidpointerstopointtoanydatatype,fromanintegervalueorafloattoastringofcharacters.Butin
exchangetheyhaveagreatlimitation:thedatapointedbythemcannotbedirectlydereferenced(whichislogical,
data:text/htmlcharset=utf8,%3Ch3%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxhtml%22%20id%3D%22sitespagetitleheader%22%20

7/9

02/07/2015

C++PointersC++ProgrammingConcepts@littledrops@thiyagaraaj.com

sincewehavenotypetodereferenceto),andforthatreasonwewillalwayshavetocasttheaddressinthevoid
pointertosomeotherpointertypethatpointstoaconcretedatatypebeforedereferencingit.
Oneofitsusesmaybetopassgenericparameterstoafunction:
//increaser
#include<iostream>
usingnamespacestd;

y,1603

voidincrease(void*data,intpsize)
{
if(psize==sizeof(char))
{char*pchar;pchar=(char*)data;++(*pchar);}
elseif(psize==sizeof(int))
{int*pint;pint=(int*)data;++(*pint);}
}
intmain()
{
chara='x';
intb=1602;
increase(&a,sizeof(a));
increase(&b,sizeof(b));
cout<<a<<","<<b<<endl;
return0;
}

sizeofisanoperatorintegratedintheC++languagethatreturnsthesizeinbytesofitsparameter.Fornondynamic
datatypesthisvalueisaconstant.Therefore,forexample,sizeof(char)is1,becausechartypeisonebytelong.
Nullpointer
Anullpointerisaregularpointerofanypointertypewhichhasaspecialvaluethatindicatesthatitisnotpointingto
anyvalidreferenceormemoryaddress.Thisvalueistheresultoftypecastingtheintegervaluezerotoanypointer
type.
int*p;
p=0;//phasanullpointervalue

Donotconfusenullpointerswithvoidpointers.Anullpointerisavaluethatanypointermaytaketorepresentthat
itispointingto"nowhere",whileavoidpointerisaspecialtypeofpointerthatcanpointtosomewherewithouta
specifictype.Onereferstothevaluestoredinthepointeritselfandtheothertothetypeofdataitpointsto.
Pointerstofunctions
C++allowsoperationswithpointerstofunctions.Thetypicaluseofthisisforpassingafunctionasanargumentto
anotherfunction,sincethesecannotbepasseddereferenced.Inordertodeclareapointertoafunctionwehaveto
declareitliketheprototypeofthefunctionexceptthatthenameofthefunctionisenclosedbetweenparentheses()
andanasterisk(*)isinsertedbeforethename:
//pointertofunctions
#include<iostream>
usingnamespacestd;

intaddition(inta,intb)
{return(a+b);}
intsubtraction(inta,intb)
{return(ab);}
intoperation(intx,inty,int(*functocall)(int,int))
{
intg;
g=(*functocall)(x,y);
return(g);
}
data:text/htmlcharset=utf8,%3Ch3%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxhtml%22%20id%3D%22sitespagetitleheader%22%20

8/9

02/07/2015

C++PointersC++ProgrammingConcepts@littledrops@thiyagaraaj.com

intmain()
{
intm,n;
int(*minus)(int,int)=subtraction;
m=operation(7,5,addition);
n=operation(20,m,minus);
cout<<n;
return0;
}

Intheexample,minusisapointertoafunctionthathastwoparametersoftypeint.Itisimmediatelyassignedto
pointtothefunctionsubtraction,allinasingleline:
int(*minus)(int,int)=subtraction

APartOfThiyagaraajWebsites
Subpages(1): PointerExampleProgramInC++

Comments
Youdonothavepermissiontoaddcomments.

data:text/htmlcharset=utf8,%3Ch3%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxhtml%22%20id%3D%22sitespagetitleheader%22%20

9/9

Das könnte Ihnen auch gefallen