Sie sind auf Seite 1von 114

2/3/2015

EmbeddedSoftwareinCforanARMCortexMValvanoandYerraballi

EmbeddedSoftwareinCforanARMCortexM
JonathanW.ValvanoandRameshYerraballi(1/2015)
Chapter1:ProgramStructure
AsampleprogramintroducesC
Cisafreefieldlanguage
Precedenceoftheoperatordeterminestheorderofoperation
Commentsareusedtodocumentthesoftware
Preprocessordirectivesarespecialoperationsthatoccurfirst
Globaldeclarationsprovidemodularbuildingblocks
Declarationsarethebasicoperations
Functiondeclarationsallowforoneroutinetocallanother
Compoundstatementsarethemorecomplexoperations
Globalvariablesarepermanentandcanbeshared
Localvariablesaretemporaryandareprivate
Sourcefilesmakeiteasiertomaintainlargeprojects
Chapter2:Tokens
ASCIIcharacters
Literalsincludenumberscharactersandstrings
Keywordsarepredefined
Namesareuserdefined
Punctuationmarks
Operators
Chapter3:Literalsincludenumberscharactersandstrings
Howarenumbersrepresentedonthecomputer
8bitunsignednumbers
8bitsignednumbers
16bitunsignednumbers
16bitsignednumbers
BigandlittleEndian
Boolean(true/false)
Decimalnumbers
Hexadecimalnumbers
Octalnumbers
Characters
Strings
Escapesequences
Chapter4:Variables
Astaticvariableexistspermanently
Astaticglobalcanbeaccessedonlyfromwithinthesamefile
Astaticlocalcanbeaccessedonlyinthefunction
WespecifyvolatilevariableswhenusinginterruptsandI/Oports
Automaticvariablesareallocatedonthestack
Wecanunderstandautomaticsbylookingattheassemblycode
Aconstantlocalcannotbechanged
Externalvariablesaredefinedelsewhere
http://users.ece.utexas.edu/~valvano/embed/toc1.htm

1/4

2/3/2015

EmbeddedSoftwareinCforanARMCortexMValvanoandYerraballi

Thescopeofavariabledefineswhereitcanbeaccessed
Variablesdeclarations
8bitvariablesaredefinedwithchar
Discussionofwhentousestaticversusautomaticvariables
Initializationofvariablesandconstants
Wecanunderstandinitializationbylookingattheassemblycode
Chapter5:Expressions
Precedenceandassociativity
Unaryoperators
Binaryoperators
Assignmentoperators
Expressiontypeandexplicitcasting
Selectionoperator
Arithmeticoverflowandunderflow
Chapter6:FlowofControl
Simplestatements
Compoundstatements
ifandifelsestatements
switchstatements
whilestatements
forstatements
dostatements
returnstatements
gotostatements
Nullstatements
Chapter7:Pointers
Definitionsofaddressandpointer
Declarationsofpointersdefinethetypeandallocatespaceinmemory
Howdoweusepointers
MemoryarchitectureoftheTM4C123andTM4C1294ARMCortexM4
Pointermath
Pointercomparisons
FIFOqueueimplementedwithpointers
I/Oportaccess
Chapter8:ArraysandStrings
ArraySubscripts
ArrayDeclarations
ArrayReferences
PointersandArrayNames
NegativeSubscripts
AddressArithmetic
StringFunctionsdefinedinstring.h
FifoQueueExample
Chapter9:Structures
StructureDeclarations
http://users.ece.utexas.edu/~valvano/embed/toc1.htm

2/4

2/3/2015

EmbeddedSoftwareinCforanARMCortexMValvanoandYerraballi

Accessingelementsofastructure
Initializationofstructuredata
Usingpointerstoaccessstructures
Passingstructuresasparameterstofunctions
ExampleofaLinearLinkedList
ExampleofaHuffmanCode
Chapter10:Functions
FunctionDeclarations
FunctionDefinitions
FunctionCalls
ParameterPassing
MakingourCprograms"looklike"C++
StackframecreatedKeiluVision
FiniteStateMachineusingFunctionPointers
Linkedlistinterpreter
Chapter11:PreprocessorDirectives
Using#definetocreatemacros
Using#ifdeftoimplementconditionalcompilation
Using#includetoloadothersoftwaremodules
AssemblerDirectives
Appendix1:CDeclarationsAShortPrimer

Chapter0ThePreface
ZeroisanappropriateplaceforabookonCtostart.ZerohasmanyspecialmeaningstotheC
programmer.OntheARMCortexM,zeroistheaddressoftheinitialstackpointerthatgetsset
onreset.Thecompilerwillinitializeallglobalvariablestozeroonstartup.Weuseazeroto
signifytheendofastring.Apointerwithazerovalueisconsideredanullpointer(doesn'tpoint
toanything).WeuseazerovaluetosignifytheBooleanfalse,andtrueisanynonzerovalue.The
arraysubscriptsinCstartwithzero.
ThisdocumentservesasanintroductiontoCprogrammingontheTexasInstrumentsTM4C123
orTM4C1294microcomputers.ItspurposeistoprovideashortintroductiontoCprogramming
inthecontextofEmbeddedSystems.Initiallywhenweusegeneral(notEmbeddedSystem
specific)Cconstructs.wewillassumeyouhaveaccesstoafreecompiler(codepad.orgisan
excellentstart).ForEmbeddedSystemdevelopmentwhereamicrocontrollerboardisusedan
IDEliketheKeiluVisionfromARM(https://www.keil.com/demo/eval/armv4.htm)isan
invaluabletooltoedit,compileanddebugyourcodeinbothsimulatedenviromentsaswellas
actualboards.
ThisdocumentdiffersfromclassicalCprogrammingbooksinitsemphasisonembedded
systems.WhilereviewingtheexistingliteratureonCprogrammingIwasstuckbythehigh
percentageofprogrammingexamplesinthesebooksthatrelyonthefunctionsscanfandprintf
toperforminput/output.WhileI/Oisextremelyimportantforembeddedsystems,rarelyisserial
I/Owithscanfandprintfanimportantaspectofanembeddedsystem.ThisHTMLdocumentis
clearlynotcomprehensiveratheritservesasashortrefresherforthoseCprogrammerswhose
skillsarealittlerusty.Thisdocumentalsoassiststheexperiencedprogrammertrainedinanother
http://users.ece.utexas.edu/~valvano/embed/toc1.htm

3/4

2/3/2015

EmbeddedSoftwareinCforanARMCortexMValvanoandYerraballi

languagelikePascalorC++,thatnowwishestoprograminCforanembeddedCortexM
system.IfthereaderininterestedinamoreclassicalapproachtoCprogrammingIsuggest:
ABookonC:ProgramminginC,byKelleyandPohl,AddisonWesley
Sendcommentsandsuggestionsaboutthisdocumentto:valvano@mail.utexas.eduor
ramesh@mail.utexas.edu
ThestyleandstructureofthisHTMLdocumentwasderivedfromASmallCCompiler:
Language,Usage,Theory,andDesign,byJamesE.Hendrix.
LegalStatement

EmbeddedSoftwareinCforanARMCortexMbyJonathanValvanoandRameshYerraballiis
licensedunderaCreativeCommonsAttributionNonCommercialNoDerivatives4.0
InternationalLicense.
Basedonaworkathttp://users.ece.utexas.edu/~valvano/arm/outline1.htm.

http://users.ece.utexas.edu/~valvano/embed/toc1.htm

4/4

2/3/2015

Chapter1:ProgramStructureValvano

Chapter1:ProgramStructure
What'sinChapter1?
AsampleprogramintroducesC
Cisafreefieldlanguage
Precedenceoftheoperatordeterminestheorderofoperation
Commentsareusedtodocumentthesoftware
Prepreocessordirectivesarespecialoperationsthatoccurfirst
Globaldeclarationsprovidemodularbuildingblocks
Declarationsarethebasicoperations
Functiondeclarationsallowforoneroutinetocallanother
Compoundstatementsarethemorecomplexoperations
Globalvariablesarepermanentandcanbeshared
Localvariablesaretemporaryandareprivate
Sourcefilesmakeiteasiertomaintainlargeprojects
ThischaptergivesabasicoverviewofprogramminginCforanembeddedsystem.Wewill
introducesomebasictermssothatyougetabasicfeelforthelanguage.Sincethisisjustthefirst
ofmanychaptersitisnotimportantyetthatyouunderstandfullytheexampleprograms.The
examplesareincludedtoillustrateparticularfeaturesofthelanguage.
CaseStudy:MicrocomputerBasedLock
Toillustratethesoftwaredevelopmentprocess,wewillimplementasimpledigitallock.The
locksystemhas7toggleswitchesandasolenoidasshowninthefollowingfigure.Ifthe7bit
binarypatternonPortAbit6tobit0becomes0100011foratleast10ms,thenthesolenoidwill
activate.The10msdelaywillcompensatefortheswitchbounce.Forinformationonswitches
andsolenoidsseeSections4.2and8.6.3ofEmbeddedSystems:IntroductiontoARMCortexM
MicrocontrollersbyJonathanW.Valvano.FornowwhatweneedtounderstandisthatPortA
bits60areinputsignalstothecomputerandPortAbit7isanoutputsignal.

BeforewewriteCcode,weneedtodevelopasoftwareplan.Softwaredevelopmentisan
iterativeprocess.Eventhoughweliststepsthedevelopmentprocessina1,2,3...order,inreality
weiterativethesestepsoverandover.
1)Webeginwithalistoftheinputsandoutputs.Wespecifytherangeofvaluesandtheir
significance.InthisexamplewewillusePORTA.Bits60willbeinputs.The7inputsignals
http://users.ece.utexas.edu/~valvano/embed/chap1/chap1.htm

1/14

2/3/2015

Chapter1:ProgramStructureValvano

representanunsignedintegerfrom0to127.PortAbit7willbeanoutput.IfPA7is1thenthe
solenoidwillactivateandthedoorwillbeunlocked.InC,weuse#defineMACROStoassigna
symbolicnamestothecorrespondingaddressesoftheports.
#defineGPIO_PORTA_DATA_R(*((volatileunsignedlong*)0x400043FC))
#defineGPIO_PORTA_DIR_R(*((volatileunsignedlong*)0x40004400))
#defineGPIO_PORTA_DEN_R(*((volatileunsignedlong*)0x4000451C))
#defineSYSCTL_PRGPIO_R(*((volatileunsignedlong*)0x400FEA08))

2)Next,wemakealistoftherequireddatastructures.Datastructuresareusedtosave
information.Ifthedataneedstobepermanent,thenitisallocatesinglobalspace.Ifthesoftware
willchangeitsvaluethenitwillbeallocatedinRAM.Inthisexampleweneeda32bitunsigned
counter.
unsignedintcnt

Ifdatastructurecanbedefinedatcompiletimeandwillremainfixed,thenitcanbeallocatedin
ROM.Inthisexamplewewilldefinean8bitfixedconstanttoholdthekeycode,whichthe
operatorneedstosettounlockthedoor.Thecompilerwillplacetheselineswiththeprogramso
thattheywillbedefinedinFlashROMmemory.
constunsignedcharkey=0x23//Thekeycode0100011(binary)

ItisnotrealclearatthispointexactlywhereinROMthisconstantwillbe,butluckilyforus,the
compilerwillcalculatetheexactaddressautomatically.Aftertheprogramiscompiled,wecan
lookinthelistingfileorinthemapfiletoseewhereinmemoryeachstructureisallocated.
3)Nextwedevelopthesoftwarealgorithm,whichisasequenceofoperationswewishto
execute.Therearemanyapproachestodescribingtheplan.Experiencedprogrammerscan
developthealgorithmdirectlyinClanguage.Ontheotherhand,mostofusneedanabstractive
methodtodocumentthedesiredsequenceofactions.Flowchartsandpseudocodearetwo
commondescriptiveformats.Therearenoformalrulesregardingpseudocode,ratheritisa
shorthandfordescribingwhattodoandwhentodoit.Wecanplaceourpseudocodeas
documentationintothecommentfieldsofourprogram.Thefollowingshowsaflowchartonthe
leftandpseudocodeandCcodeontherightforourdigitallockexample.

NormallyweplacetheprogramsinFlashROM.Typically,thecompilerwillinitializethestack
http://users.ece.utexas.edu/~valvano/embed/chap1/chap1.htm

2/14

2/3/2015

Chapter1:ProgramStructureValvano

pointertothelastlocationofRAM.OntheARMCortexM,thestackisinitializedtothe32bit
valuelocatedatROMaddress0.NextwewriteCcodetoimplementthealgorithmasillustrated
intheaboveflowchartandpseudocode.
4)Thelaststageisdebugging.ForinformationondebuggingseeSections2.6,4.6,5.8and6.9
ofEmbeddedSystems:IntroductiontoARMCortexMMicrocontrollersbyJonathanW.
Valvano.
Freefieldlanguage
Inmostprogramminglanguagesthecolumnpositionandlinenumberaffectthemeaning.Onthe
contrary,Cisafreefieldlanguage.Exceptforpreprocessorlines(thatbeginwith#,seeChapter
11),spaces,tabsandlinebreakshavethesamemeaning.Theothersituationwherespaces,tabs
andlinebreaksmatterisstringconstants.Wecannottypetabsorlinebreakswithinastring
constant.Formoreinformationseethesectiononstringsintheconstantschapter.Thismeanswe
canplacemorethanonestatementonasingleline,orplaceasinglestatementacrossmultiple
lines.Forexampleafunctioncouldhavebeenwrittenwithoutanylinebreaks
voidLock_Init(void){volatileunsignedlongdelay;SYSCTL_PRGPIO_R|=
0x01;delay=SYSCTL_PRGPIO_R;GPIO_PORTA_DIR_R=0x80;GPIO_PORTA_DEN_R=
0xFF;}

"Sincewerarelymakehardcopyprintoutsofoursoftware,itisnotnecessarytominimizethe
numberoflinebreaks."
However,wecouldhaveaddedextralinebreaksandcommentstomakeitmorereadable.
voidLock_Init(void){volatileunsignedlongdelay;
SYSCTL_PRGPIO_R|=0x01;//activateclockforPortA
delay=SYSCTL_PRGPIO_R;//allowtimeforclocktostart
GPIO_PORTA_DIR_R=0x80;//setPA7tooutputandPA60toinput
GPIO_PORTA_DEN_R=0xFF;//enabledigitalport
}

AtthispointIwillwarnthereader,justbecauseCallowsmanydifferentformsofsyntax,
propersyntaxwillhaveaprofoundimpactonthequalityofourcode.Aftermuchexperienceyou
willdevelopaprogrammingstylethatiseasytounderstand.Althoughspaces,tabs,andline
breaksaresyntacticallyequivalent,theirproperusagewillhaveaprofoundimpactonthe
readabilityofyoursoftware.FormoreinformationonprogrammingstyleseeSection5.6of
EmbeddedSystems:IntroductiontoARMCortexMMicrocontrollersbyJonathanW.Valvano.
AtokeninCcanbeauserdefinedname(e.g.,thevariableInfoandfunctionLock_Init)ora
predefinedoperation(e.g.,*,unsigned,while).Eachtokenmustbecontainedonasingleline.
Weseeintheaboveexamplethattokenscanbeseparatedbywhitespaces(space,tab,line
break)orbythespecialcharacters,whichwecansubdivideintopunctuationmarks(Table11)
andoperations(Table12).Punctuationmarks(semicolons,colons,commas,apostrophes,
quotationmarks,braces,brackets,andparentheses)areveryimportantinC.Itisoneofthemost
frequentsourcesoferrorsforboththebeginningandexperiencedprogrammers.
punctuation Meaning
;
Endofstatement
:
Definesalabel
,
Separateselementsofalist
()
Startandendofaparameterlist
{}
Startandstopofacompoundstatement
[]
Startandstopofaarrayindex
http://users.ece.utexas.edu/~valvano/embed/chap1/chap1.htm

3/14

2/3/2015

Chapter1:ProgramStructureValvano

""
''

Startandstopofastring
Startandstopofacharacterconstant

Table11:Specialcharacterscanbepunctuationmarks
Thenexttableshowsthesinglecharacteroperators.Foradescriptionoftheseoperations,see
Chapter5.
operation Meaning
=
assignmentstatement
@
addressof
?
selection
<
lessthan
>
greaterthan
!
logicalnot(truetofalse,falsetotrue)
~
1'scomplement
+
addition

subtraction
*
multiplyorpointerreference
/
divide
%
modulo,divisionremainder
|
logicalor
&
logicaland,oraddressof
^
logicalexclusiveor
.
usedtoaccesspartsofastructure
Table12:Specialcharacterscanbeoperators
Thenexttableshowstheoperatorsformedwithmultiplecharacters.Foradescriptionofthese
operations,seeChapter5.
operation Meaning
==
equaltocomparison
<=
lessthanorequalto
>=
greaterthanorequalto
!=
notequalto
<<
shiftleft
>>
shiftright
++
increment

decrement
&&
Booleanand
||
Booleanor
+=
addvalueto
=
subtractvalueto
*=
multiplyvalueto
/=
dividevalueto
|=
orvalueto
&=
andvalueto
^=
exclusiveorvalueto
<<=
shiftvalueleft
>>=
http://users.ece.utexas.edu/~valvano/embed/chap1/chap1.htm

4/14

2/3/2015

Chapter1:ProgramStructureValvano

%=
>

shiftvalueright
modulodividevalueto
pointertoastructure

Table13:Multiplespecialcharactersalsocanbeoperators
AlthoughtheoperatorswillbecoveredindetailinChapter9,thefollowingsectionillustrates
someofthecommonoperators.Webeginwiththeassignmentoperator.Noticethatintheline
x=1;xisonthelefthandsideofthe=.Thisspecifiestheaddressofxisthedestinationof
assignment.Ontheotherhand,inthelinez=x;xisontherighthandsideofthe=.Thisspecifies
thevalueofxwillbeassignedintothevariablez.Alsorememberthatthelinez=x;createstwo
copiesofthedata.Theoriginalvalueremainsinx,whilezalsocontainsthisvalue.
shortx,y,z;/*Threevariables*/
voidExample(void){
x=1;/*setthevalueofxto1*/
y=2;/*setthevalueofyto2*/
z=x;/*setthevalueofztothevalueofx(bothare1)*/
x=y=z=0;/*allallthreetozero*/
}

Listing12:SimpleprogramillustratingCarithmeticoperators
Nextwewillintroducethearithmeticoperationsaddition,subtraction,multiplicationand
division.Thestandardarithmeticprecedenceapply.Foradetaileddescriptionofthese
operations,seeChapter5.
shortx,y,z;/*Threevariables*/
voidExample(void){
x=1;y=2;/*setthevaluesofxandy*/
z=x+4*y;/*arithmeticoperation*/
x++;/*sameasx=x+1;*/
y;/*sameasy=y1;*/
x=y<<2;/*leftshiftsameasx=4*y;*/
z=y>>2;/*rightshiftsameasx=y/4;*/
y+=2;/*sameasy=y+2;*/
}

Listing13:SimpleprogramillustratingCarithmeticoperators
Nextwewillintroduceasimpleconditionalcontrolstructure.AssumePORTBisconfiguredas
anoutputport,andPORTEasaninputport.Formoreinformationoninput/outputportssee
Chapter4ofEmbeddedSystems:IntroductiontoARMCortexMMicrocontrollersbyJonathan
W.Valvano.TheexpressionPORTE&0x04willreturn0ifPORTEbit2is0andwillreturna4if
PORTEbit2is1.Theexpression(PORTE&0x04)==0willreturnTRUEifPORTEbit2is0and
willreturnaFALSEifPORTEbit2is1.Thestatementimmediatelyfollowingtheifwillbe
executediftheconditionisTRUE.Theelsestatementisoptional.
#definePORTB(*((volatileunsignedlong*)0x400053FC))
#definePORTE(*((volatileunsignedlong*)0x400243FC))
voidExample(void){
if((PORTE&0x04)==0){/*testbit2ofPORTE*/
PORTB=0;/*ifPORTEbit2is0,thenmakePORTB=0*/
}else{
PORTB=100;/*ifPORTEbit0isnot0,thenmakePORTB=100*/
}
}

Listing1.4:SimpleprogramillustratingtheCifelsecontrolstructure
http://users.ece.utexas.edu/~valvano/embed/chap1/chap1.htm

5/14

2/3/2015

Chapter1:ProgramStructureValvano

InthenextexampleletsassumethatPORTAbit3isconfiguredasanoutputpinonthe
TM4C123.Liketheifstatement,thewhilestatementhasaconditionaltest(i.e.,returnsa
TRUE/FALSE).Thestatementimmediatelyfollowingthewhilewillbeexecutedoverandover
untiltheconditionaltestbecomesFALSE.
#definePORTA(*((volatileunsignedlong*)0x400043FC))
#definePORTB(*((volatileunsignedlong*)0x400053FC))
voidExample(void){/*loopuntilPORTBequals200*/
PORTB=0;
while(PORTB!=200){
PORTA=PORTA^0x08;}/*togglePORTAbit3output*/
PORTB++;}/*incrementPORTBoutput*/
}

Listing1.5:SimpleprogramillustratingtheCwhilecontrolstructure
Theforcontrolstructurehasthreepartsandabody.for(part1;part2;part3){body;}Thefirst
partPORTB=0isexecutedonceatthebeginning.ThenthebodyPORTA=PORTA^0x08;isexecuted,
followedbythethirdpartPORTB++.ThesecondpartPORTB!=200isaconditional.Thebodyand
thirdpartarerepeateduntiltheconditionalisFALSE.Foramoredetaileddescriptionofthe
controlstructures,seeChapter6.
#definePORTB(*((volatileunsignedlong*)0x400053FC))
voidExample(void){/*loopuntilPORTBequals200*/
for(PORTB=0;PORTB!=200;PORTB++){
PORTA=PORTA^0x08;}/*togglePORTAbit3output*/
}
}

Listing1.6:SimpleprogramillustratingtheCforloopcontrolstructure

Precedence
Aswithallprogramminglanguagestheorderofthetokensisimportant.Therearetwoissuesto
considerwhenevaluatingcomplexstatements.Theprecedenceoftheoperatordetermineswhich
operationsareperformedfirst.Inthefollowingexample,the2*xisperformedfirstbecause*has
higherprecedencethan+and=.Theadditionisperformedsecondbecause+hashigher
precedencethan=.Theassignment=isperformedlast.Sometimesweuseparenthesestoclarify
themeaningoftheexpression,evenwhentheyarenotneeded.Therefore,thelinez=y+2*x
couldalsohavebeenwrittenz=2*x+yorz=y+(2*x)orz=(2*x)+y.
shortexample(shortx,shorty){shortz;
z=y+2*x;
return(z);
}

Thesecondissueistheassociativity.Associativitydeterminesthelefttorightorrighttoleft
orderofevaluationwhenmultipleoperationsoftheprecedencearecombined.Forexample+
andhavethesameprecedence,sohowdoweevaluatethefollowing?
z=y2+x;

Weknowthat+andassociatethelefttoright,thisfunctionisthesameasz=(y2)+x.Meaning
thesubtractionisperformedfirstbecauseitismoretotheleftthantheaddition.Mostoperations
associatelefttoright,butthefollowingtableillustratesthatsomeoperatorsassociaterightto
left.
http://users.ece.utexas.edu/~valvano/embed/chap1/chap1.htm

6/14

2/3/2015

Chapter1:ProgramStructureValvano

Precedence
highest

lowest

Operators
()[].>++(postfix)(postfix)
++(prefix)(prefix)!~sizeof(type)+(unary)
(unary)&(address)*(dereference)
*/%
+
<<>>
<<=>>=
==!=
&
^
|
&&
||
?:
=+==*=/=%=<<=>>=|=&=^=
,

Associativity
lefttoright
righttoleft
lefttoright
lefttoright
lefttoright
lefttoright
lefttoright
lefttoright
lefttoright
lefttoright
lefttoright
lefttoright
righttoleft
righttoleft
lefttoright

Table14:Precedenceandassociativitydeterminetheorderofoperation
"Whenconfusedaboutprecedence(andaren'tweall)addparenthesestoclarifytheexpression."
Comments
Therearetwotypesofcomments.Thefirsttypeexplainshowtousethesoftware.These
commentsareusuallyplacedatthetopofthefile,withintheheaderfile,oratthestartofa
function.Thereaderofthesecommentswillbewritingsoftwarethatusesorcallstheseroutines.
Thesecondtypeofcommentsassistsafutureprogrammer(ourselvesincluded)inchanging,
debuggingorextendingtheseroutines.Weusuallyplacethesecommentswithinthebodyofthe
functions.Thecommentsontherightofeachlineareexamplesofthesecondtype.Formore
informationonwritinggoodcommentsseeSection5.6ofEmbeddedSystems:Introductionto
ARMCortexMMicrocontrollersbyJonathanW.Valvano.
Commentsbeginwiththe/*sequenceandendwiththe*/sequence.Theymayextendover
multiplelinesaswellasexistinthemiddleofstatements.Thefollowingisthesameas
PORTA=0x80;
PORTA/*PA7isoutput*/=0x80/*turnonrelay*/;

KeiluVisiondoesallowtheuseofC++stylecomments.Thestartcommentsequenceis//and
thecommentendsatthenextlinebreakorendoffile.Thus,thefollowingtwolinesare
equivalent:
UART_Init();/*turnonUARTserialport*/
UART_Init();//turnonUARTserialport

Cdoesallowthecommentstartandstopsequenceswithincharacterconstantsandstring
constants.Forexamplethefollowingstringcontainsall7characters,notjusttheac
constcharstr[10]="a/*b*/c";

Mostcompilersunfortunatelydonotsupportcommentnesting.Thismakesitdifficultto
commentoutsectionsoflogicthatarethemselvescommented.Forexample,thefollowing
attempttocommentoutthePORTA=0x00;willresultinacompilererror.
http://users.ece.utexas.edu/~valvano/embed/chap1/chap1.htm

7/14

2/3/2015

Chapter1:ProgramStructureValvano

intmain(void){unsignedchardata;
Lock_Init();/*initializeI/Oports*/
/*
PORTA=0x00;/*outputtoportA*/
*/
while(1){
Info=PORTE;/*inputfromportE*/
PORTB=Info;}}/*outputtoportB*/

Theconditionalcompilationfeaturecanbeusedtotemporarilyremoveandrestoreblocksof
code.
PreprocessorDirectives
Preprocessordirectivesbeginwith#inthefirstcolumn.Asthenameimpliespreprocessor
commandsareprocessedfirst.I.e.,thecompilerpassesthroughtheprogramhandlingthe
preprocessordirectives.Althoughtherearemanypossibilities(assemblylanguage,conditional
compilation,interruptserviceroutines),IthoughtI'dmentionthetwomostimportantonesearly
inthisdocument.Wehavealreadyseenthemacrodefinition(#define)usedtodefineI/Oports
andbitfields.Asecondimportantdirectiveisthe#include,whichallowsyoutoincludeanother
entirefileatthatpositionwithintheprogram.Thefollowingdirectivewilldefineallthe
TM4C123I/Oportnames.
#include"tm4c123gh6pm.h"

Examplesof#includeareshownbelow,andmoreinChapter11.
GlobalDeclarations
Anobjectmaybeadatastructureorafunction.Objectsthatarenotdefinedwithinfunctionsare
global.ObjectsthatmaybedeclaredinKeiluVisioninclude:
integervariables(8bit16bitor32bitsignedorunsigned)
charactervariables(8bit)
arraysofintegersorcharacters
pointerstointegersorcharacters
arraysofpointers
structure(groupingofotherobjects)
unions(redefinitionsofstorage)
functions
KeiluVisionsupports64bitlonglongintegersandfloatingpoint.Inthisdocumentwewill
focuson8bit16bitand32bitobjects.ObjectcodegeneratedwithmostARMcompilersis
oftenmoreefficientusing32bitparametersratherthan8bitor16bitparameters.
DeclarationsandDefinitions
ItisimportantfortheCprogrammertodistinguishthetwotermsdeclarationanddefinition.A
functiondeclarationspecifiesitsname,itsinputparametersanditsoutputparameter.Another
nameforafunctiondeclarationisprototype.Adatastructuredeclarationspecifiesitstypeand
format.Ontheotherhand,afunctiondefinitionspecifiestheexactsequenceofoperationsto
executewhenitiscalled.Afunctiondefinitionwillgenerateobjectcode(machineinstructionsto
beloadedintomemorythatperformtheintendedoperations).Adatastructuredefinitionwill
reservespaceinmemoryforit.Theconfusingpartisthatthedefinitionwillrepeatthe
declarationspecifications.Wecandeclaresomethingwithoutdefiningit,butwecannotdefineit
withoutdeclaringit.ForexamplethedeclarationforthefunctionUART_OutCharcouldbewritten
as
http://users.ece.utexas.edu/~valvano/embed/chap1/chap1.htm

8/14

2/3/2015

Chapter1:ProgramStructureValvano

voidUART_OutChar(char);
or
voidUART_OutChar(charletter);

Wecanseethatthedeclarationshowsushowtousethefunction,nothowthefunctionworks.
BecausetheCcompilationisaonepassprocess,anobjectmustbedeclaredordefinedbeforeit
canbeusedinastatement.(Actuallythepreprocessperformsapassthroughtheprogramthat
handlesthepreprocessordirectives.)Oneapproachistofirstdeclareafunctions,useit,and
lastlydefinesthefunctions:
longadd(long,long);
intmain(void){
longx,y,z;
x=2;y=3;
z=add(x,y);
return1;
}
longadd(longa,longb){
return(a+b);
}

Anobjectmaybesaidtoexistinthefileinwhichitisdefined,sincecompilingthefileyieldsa
modulecontainingtheobject.Ontheotherhand,anobjectmaybedeclaredwithinafilein
whichitdoesnotexist.Declarationsofdatastructuresareprecededbythekeywordextern.
Thus,
longRunFlag;

defines32bitsignedintegercalledRunFlagwhereas,
externlongRunFlag;

onlydeclarestheRunFlagtoexistinanother,separatelycompiled,module.Thustheline
externvoidSysTick_Handler();

declaresthefunctionnameandtypejustlikearegularfunctiondeclaration.Theexterntellsthe
compilerthattheactualfunctionexistsinanothermoduleandthelinkerwillcombinethe
modulessothattheproperactionoccursatruntime.Thecompilerknowseverythingabout
externobjectsexceptwheretheyare.Thelinkerisresponsibleforresolvingthatdiscrepancy.
Thecompilersimplytellstheassemblerthattheobjectsareinfactexternal.Andtheassembler,
inturn,makesthisknowntothelinker.
Functions
Afunctionisasequenceofoperationsthatcanbeinvokedfromotherplaceswithinthesoftware.
Wecanpass0ormoreparametersintoafunction.ThecodegeneratedbytheKeiluVisionC
compilerpassesthefirstfourinputparametersinRegisterR0,R1,R2andR3andtheremaining
parametersarepassedonthestack.Afunctioncanhave0or1outputparameter.Thereturn
parameterisplacedinRegisterR0(8bitor16bitreturnparametersarepromotedto32bits.)
Theaddfunctionbelow(animprovementthatchecksforoverflow)hastwo16bitsignedinput
parameters,andone16bitoutputparameter.Againthenumbersinthefirstcolumnarenotpart
ofthesoftware,butaddedtosimplifyourdiscussion.
http://users.ece.utexas.edu/~valvano/embed/chap1/chap1.htm

9/14

2/3/2015

Chapter1:ProgramStructureValvano

1shortadd(shortx,shorty){shortz;
2z=x+y;
3if((x>0)&&(y>0)&&(z<0))z=32767;
4if((x<0)&&(y<0)&&(z>0))z=32768;
5return(z);}
6intmain(void){shorta,b;
7a=add(2000,2000)
8b=0
9while(1){
10b=add(b,1);
11}

Listing18:Exampleofafunctioncall
Theinterestingpartisthataftertheoperationswithinthefunctionareperformed,controlreturns
totheplacerightafterwherethefunctionwascalled.InC,executionbeginswiththemain
program.Theexecutionsequenceisshownbelow:
6intmain(void){shorta,b;
7a=add(2000,2000);/*calltoadd*/
1shortadd(shortx,shorty){shortz;
2z=x+y;/*z=4000*/
3if((x>0)&&(y>0)&&(z<0))z=32767;
4if((x<0)&&(y<0)&&(z>0))z=32768;
5return(z);}/*return4000fromcall*/
8b=0
9while(1){
10b=add(b,1);}/*calltoadd*/
1shortadd(shortx,shorty){shortz;
2z=x+y;/*z=1*/
3if((x>0)&&(y>0)&&(z<0))z=32767;
4if((x<0)&&(y<0)&&(z>0))z=32768;
5return(z);}/*return1fromcall*/
11}
9while(1){
10b=add(b,1);}/*calltoadd*/
1shortadd(shortx,shorty){shortz;
2z=x+y;/*z=2*/
3if((x>0)&&(y>0)&&(z<0))z=32767;
4if((x<0)&&(y<0)&&(z>0))z=32768;
5return(z);}/*return2fromcall*/
11}

Noticethatthereturnfromthefirstcallgoestoline8,whilealltheotherreturnsgotoline11.
Theexecutionsequencerepeatslines9,10,1,2,3,4,5,11indefinitely.
TheprogramminglanguagePascaldistinguishesbetweenfunctionsandprocedures.InPascala
functionreturnsaparameterwhileaproceduredoesnot.Celiminatesthedistinctionby
acceptingabareorvoidexpressionasitsreturnparameter.
Cdoesnotallowforthenestingofproceduraldeclarations.Inotherwordsyoucannotdefinea
functionwithinanotherfunction.Inparticularallfunctiondeclarationsmustoccurattheglobal
level.
Afunctiondeclarationconsistsoftwoparts:adeclaratorandabody.Thedeclaratorstatesthe
nameofthefunctionandthenamesofargumentspassedtoit.Thenamesoftheargumentare
onlyusedinsidethefunction.Intheaddfunctionabove,thedeclaratoris(shortx,shorty)
meaningithastwo16bitinputparameters.
Theparenthesesarerequiredevenwhentherearenoarguments.Whentherearenoinput
parametersavoidornothingcanbespecified.Thefollowingtwostatementsareequivalent:
http://users.ece.utexas.edu/~valvano/embed/chap1/chap1.htm

10/14

2/3/2015

Chapter1:ProgramStructureValvano

voidTogglePA3(void){PORTA^=0x08;}
voidTogglePA3(){PORTA^=0x08;}

Iprefertoincludethevoidbecauseitisapositivestatementthattherearenoinputparameters.
However,onemustspecifytheoutputparameter,evenifthereisnone.Formoreinformationon
functionsseeChapter10.
Thebodyofafunctionconsistsofastatementthatperformsthework.Normallythebodyisa
compoundstatementbetweena{}pair.Ifthefunctionhasareturnparameter,thenallexitpoints
mustspecifywhattoreturn.InthefollowingmedianfilterfunctionshowninListing14,there
aresixpossibleexitpathsthatallspecifyareturnparameter.
Onaresetorapowerinitialization,the32bitvalueinROMlocation0x000000004isloaded
intotheprogramcounter,PC.TheprogramscreatedusingKeiluVisionactuallybeginexecution
ataplacecalledReset_Handler,whichcanbefoundinthestart.sfile.Afterapoweronor
hardwarereset,theembeddedsystemwillinitializethestack,initializetheheap,andclearall
RAMbasedglobalvariables.Afterthisbriefinitializationsequencethefunctionnamedmain()
iscalled.Consequently,theremustbeamain()functionsomewhereintheprogram.Ifyouare
curiousaboutwhatreallyhappens,lookintheassemblyfilestart.sForprogramsnotinan
embeddedenvironment(e.g.,runningonyourPC)areturnfrommain()transferscontrolbackto
theoperatingsystem.Aswesawearlier,softwareforanembeddedsystemusuallydoesnotquit.
CompoundStatements
Acompoundstatement(orblock)isasequenceofstatements,enclosedbybraces,thatstandsin
placeofasinglestatement.Simpleandcompoundstatementsarecompletelyinterchangeableas
farasthesyntaxoftheClanguageisconcerned.Therefore,thestatementsthatcomprisea
compoundstatementmaythemselvesbecompoundthatis,blockscanbenested.Thus,itislegal
towrite
//3wide16bitsignedmedianfilter
shortmedian(shortn1,shortn2,shortn3){
if(n1>n2){
if(n2>n3)
return(n2);//n1>n2,n2>n3n1>n2>n3
else{
if(n1>n3)
return(n3);//n1>n2,n3>n2,n1>n3n1>n3>n2
else
return(n1);//n1>n2,n3>n2,n3>n1n3>n1>n2
}
}
else{
if(n3>n2)
return(n2);//n2>n1,n3>n2n3>n2>n1
else{
if(n1>n3)
return(n1);//n2>n1,n2>n3,n1>n3n2>n1>n3
else
return(n3);//n2>n1,n2>n3,n3>n1n2>n3>n1
}
}
}

Listing19:Exampleofnestedcompoundstatements.
AlthoughCisafreefieldlanguage,noticehowtheindentinghasbeenaddedtotheabove
example.Thepurposeofthisindentingistomaketheprogrameasiertoread.Ontheotherhand
sinceCisafreefieldlanguage,thefollowingtwostatementsarequitedifferent
http://users.ece.utexas.edu/~valvano/embed/chap1/chap1.htm

11/14

2/3/2015

Chapter1:ProgramStructureValvano

if(n1>100)n2=100;n3=0;
if(n1>100){n2=100;n3=0;}

Inbothcasesn2=100;isexecutedifn1>100.Inthefirstcasethestatementn3=0;isalways
executed,whileinthesecondcasen3=0;isexecutedonlyifn1>100.
GlobalVariables
Variablesdeclaredoutsideofafunction,likeCountinthefollowingexample,areproperlycalled
externalvariablesbecausetheyaredefinedoutsideofanyfunction.Whilethisisthestandard
termforthesevariables,itisconfusingbecausethereisanotherclassofexternalvariable,one
thatexistsinaseparatelycompiledsourcefile.Inthisdocumentwewillrefertovariablesinthe
presentsourcefileasglobals,andwewillrefertovariablesdefinedinanotherfileasexternals.
Therearetworeasonstoemployglobalvariables.Thefirstreasonisdatapermanence.Theother
reasonisinformationsharing.Normallywepassinformationfromonemoduletoanother
explicitlyusinginputandoutputparameters,butthereareapplicationslikeinterrupt
programmingwherethismethodisunavailable.Forthesesituations,onemodulecanstoredata
intoaglobalwhileanothermodulecanviewit.
Inthefollowingexample,wewishtomaintainacounterofthenumberoftimesPA3istoggled.
Thisdatamustexistfortheentirelifeoftheprogram.Thisexamplealsoillustratesthatwithan
embeddedsystemitisimportanttoinitializeRAMbasedglobalsatruntime.MostCcompilers
(includinguVision)willautomaticallyinitializeglobalstozeroatstartup.
unsignedlongCount;/*numberoftoggles,initializedto0*/
voidTogglePA3(void){
Count=Count+1;/*incrementedeachtimecalled*/
PORTA^=0x08;}

Listing110:Aglobalvariablecontainspermanentinformation

Althoughthefollowingtwoexamplesareequivalent,Ilikethesecondcasebecauseitsoperation
ismoreselfevident.InbothcasestheglobalisallocatedinRAM,andinitializedatthestartof
theprogramto1.
intFlag=1;
voidmain(void){
/*mainbodygoeshere*/
}

Listing111:Aglobalvariableinitializedatruntimebythecompiler
intFlag;
voidmain(void){Flag=1;
/*mainbodygoeshere*/
}

Listing112:Aglobalvariableinitializedatruntimebythecompiler
Fromaprogrammer'spointofview,weusuallytreattheI/Oportsinthesamecategoryasglobal
variablesbecausetheyexistpermanentlyandsupportsharedaccess.
LocalVariables
LocalvariablesareveryimportantinCprogramming.Theycontaintemporaryinformationthat
http://users.ece.utexas.edu/~valvano/embed/chap1/chap1.htm

12/14

2/3/2015

Chapter1:ProgramStructureValvano

isaccessibleonlywithinanarrowscope.Wecandefinelocalvariablesatthestartofa
compoundstatement.Wecalltheselocalvariablessincetheyareknownonlytotheblockin
whichtheyappear,andtosubordinateblocks.Thefollowingstatementadjustsxandysuchthat
xcontainsthesmallernumberandycontainsthelargerone.Ifaswapisrequiredthenthelocal
variablezisused.
if(x>y){shortz;/*createatemporaryvariable*/
z=x;x=y;y=z;/*swapxandy*/
}/*thendestroyz*/

Noticethatthelocalvariablezisdeclaredwithinthecompoundstatement.Unlikeglobals,which
aresaidtobestatic,localsarecreateddynamicallywhentheirblockisentered,andtheyceaseto
existwhencontrolleavestheblock.Furthermore,localnamessupersedethenamesofglobals
andotherlocalsdeclaredathigherlevelsofnesting.Therefore,localsmaybeusedfreelywithout
regardtothenamesofothervariables.Althoughtwoglobalvariablescannotusethesamename,
alocalvariableofoneblockcanusethesamenameasalocalvariableinanotherblock.
Programmingerrorsandconfusioncanbeavoidedbyunderstandingtheseconventions.
SourceFiles
Ourprogramsmayconsistofsourcecodelocatedinmorethanonefile.Thesimplestmethodof
combiningthepartstogetheristousethe#includepreprocessordirective.Anothermethodisto
compilethesourcefilesseparately,thencombinetheseparateobjectfilesastheprogramisbeing
linkedwithlibrarymodules.Thelinker/librarymethodshouldbeusedwhentheprogramsare
large,andonlysmallpiecesarechangedatatime.Ontheotherhand,mostembeddedsystem
applicationsaresmallenoughtousethesimplemethod.Inthiswaywewillcompiletheentire
systemwheneverchangesaremade.Rememberthatafunctionorvariablemustbedefinedor
declaredbeforeitcanbeused.Thefollowingexampleisonemethodofdividingoursimple
exampleintomultiplefiles.
/*****filetm4c123gh6pm.h(actuallymuchbigger)*************/
#defineGPIO_PORTA_DATA_R(*((volatileunsignedlong*)0x400043FC))
#defineGPIO_PORTA_DIR_R(*((volatileunsignedlong*)0x40004400))
#defineGPIO_PORTA_DEN_R(*((volatileunsignedlong*)0x4000451C))
#defineSYSCTL_PRGPIO_R(*((volatileunsignedlong*)0x400FEA08))

Listing113:HeaderfileforPortAI/Oports
/*****fileLOCK.h*************/
voidLock_Init(void);
voidLock_Set(intflag);
unsignedlongLock_Input(void);

Listing114:HeaderfileforthePortAfunctions
/*****fileLock.C*************/
#include"tm4c123gh6pm.h"
voidLock_Init(void){volatileunsignedlongdelay;
SYSCTL_PRGPIO_R|=0x01;//activateclockforPortA
delay=SYSCTL_PRGPIO_R;//allowtimeforclocktostart
GPIO_PORTA_DIR_R=0x80;//setPA7tooutputandPA60toinput
GPIO_PORTA_DEN_R=0xFF;//enabledigitalport
}
voidLock_Set(intflag){
if(flag){
GPIO_PORTA_DATA_R=0x80;
}else{
GPIO_PORTA_DATA_R=0;
}
http://users.ece.utexas.edu/~valvano/embed/chap1/chap1.htm

13/14

2/3/2015

Chapter1:ProgramStructureValvano

}
unsignedlongLock_Input(void){
returnGPIO_PORTA_DATA_R&0x7F;//0to127
}

Listing115:ImplementationfileforthePortAinterface
/*****filemain.c*************/
constunsignedcharkey=0x23//Thekeycode0100011(binary)
#include"Lock.h"
voidmain(void){unsignedcharinput;unsignedlongcnt;
Lock_Init();//initializelock
cnt=4000;
while(1){
key=Lock_Input();//input8bitsfromparallelportA
if(key==input){
cnt;//debounceswitches
if(cnt==0){//donebouncing
Lock_Set(1);//unlockdoor
}
}else{
Lock_Set(0);//lockthedoor
cnt=4000;
}
}
}
#include"Lock.c"

Listing116:Mainprogramfileforthissystem
WithKeiluVision,wedonotneedthe#include"Lock.c"becauseLock.cwillbeincludedin
theproject.Imakethefollowinggeneralstatementaboutgoodprogrammingstyle.
"Ifthesoftwareiseasytounderstand,debug,andchange,thenitiswrittenwithgoodstyle"
WhilethemainfocusofthisdocumentisonCsyntax,itwouldbeimpropertoneglectallstyle
issues.Thissystemwasdividedusingthefollowingprinciples:
DefinetheI/Oportsinatm4c123gh6pm.hheaderfile
Foreachmoduleplacetheusercallableprototypesina*.hheaderfile
Foreachmoduleplacetheimplementationsina*.cprogramfile
Inthemainprogramfile,includetheheaderfilesfirst
Inthemainprogramfile,includetheimplementationfileslast
Breakingasoftwaresystemintofileshasalotofadvantages.Thefirstreasoniscodereuse.
Considerthecodeinthisexample.IfaLockoutputfunctionisneededinanotherapplication,
thenitwouldbeasimplemattertoreusethelock.handlock.cfiles.Thenextadvantageis
clarity.Becausethedetailshavebeenremoved,theoverallapproachiseasiertounderstand.The
nextreasontobreaksoftwareintofilesisparalleldevelopment.Asthesoftwaresystemgrowsit
willbeeasiertodivideupasoftwareprojectintosubtasks,andtorecombinethemodulesintoa
completesystemifthesubtaskshaveseparatefiles.Thelastreasonisupgrades.Consideran
upgradeinoursimpleexamplewherethePortAisreplacedwithPortB.Forthiskindof
upgradeweimplementthePortBfunctionsintheLock.cfilewiththenewversion.Ifweplan
appropriately,weshouldbeabletomakethisupgradewithoutchangestothefileslock.hand
main.c.
GotoChapter2onTokensReturntoTableofContents
http://users.ece.utexas.edu/~valvano/embed/chap1/chap1.htm

14/14

2/3/2015

Chapter2:TokensValvano

Chapter2:Tokens
What'sinChapter2?
ASCIIcharacters
Literalsincludenumberscharactersandstrings
Keywordsarepredefined
Namesareuserdefined
Punctuationmarks
Operators
ThischapterdefinesthebasicbuildingblocksofaCprogram.Understandingtheconceptsinthis
chapterwillhelpeliminatethesyntaxbugsthatconfuseeventheveteranCprogrammer.A
simplesyntaxerrorcangenerate100'sofobscurecompilererrors.Inthischapterwewill
introducesomeofthesyntaxofthelanguage.
TounderstandthesyntaxofaCprogram,wedivideitintotokensseparatedbywhitespacesand
punctuation.Rememberthewhitespacesincludespace,tab,carriagereturnsandlinefeeds.A
tokenmaybeasinglecharacterorasequenceofcharactersthatformasingleitem.Thefirststep
ofacompileristoprocesstheprogramintoalistoftokensandpunctuationmarks.The
followingexampleincludespunctuationmarksof(){};Thecompilerthenchecksfor
propersyntax.And,finally,itcreatesobjectcodethatperformstheintendedoperations.Inthe
followingexample:
voidmain(void){longz;
z=0;
while(1){
z=z+1;
}
}

Listing21:Exampleofafunctioncall
Thefollowingsequenceshowsthetokensandpunctuationmarksfromtheabovelisting:
voidmain(void){longz;z=0;while(1){z=z+1;}}

Sincetokensarethebuildingblocksofprograms,webeginourstudyofClanguagebydefining
itstokens.

ASCIICharacterSet
LikemostprogramminglanguagesCusesthestandardASCIIcharacterset.Thefollowingtable
showsthe128standardASCIIcode.Oneormorewhitespacecanbeusedtoseparatetokensand
orpunctuationmarks.ThewhitespacecharactersinCincludehorizontaltab(9=0x09),the
carriagereturn(13=0x0D),thelinefeed(10=0x0A),space(32=0x20).
BITS4to6

NUL

DLE

SP

B
I
T

1
2
3

SOH
STX
ETX

DC1
DC2
DC3

!
"
#

1
2
3

A
B
C

Q
R
S

a
b
c

q
r
s

http://users.ece.utexas.edu/~valvano/embed/chap2/chap2.htm

1/9

2/3/2015

Chapter2:TokensValvano

T
O

4
5

EOT
ENQ

DC4
NAK

$
%

4
5

D
E

T
U

d
e

t
u

6
7

ACK
BEL

SYN
ETB

&
'

6
7

F
G

V
W

f
g

v
w

8
9
A

BS
HT
LF

CAN
EM
SUB

(
)
*

8
9
:

H
I
J

X
Y
Z

h
i
j

x
y
z

B
C

VT
FF

ESC
FS

+
,

;
<

K
L

[
\

k
l

{
|

CR

GS

SO

RS

>

S1

US

DEL

Table21.ASCIICharactercodes.
Thefirst32(values0to31or0x00to0x1F)andthelastone(127=0x7F)areclassifiedas
controlcharacters.Codes32to126(or0x20to0x7E)includethe"normal"characters.Normal
charactersaredividedinto
thespacecharacter(32=0x20),
thenumericdigits0to9(48to57or0x30to0x39),
theuppercasealphabetAtoZ(65to90or0x41to0x5A),
thelowercasealphabetatoz(97to122or0x61to0x7A),and
thespecialcharacters(alltherest).
Literals
Numericliteralsconsistofanuninterruptedsequenceofdigitsdelimitedbywhitespacesor
specialcharacters(operatorsorpunctuation).AlthoughMetrowerksdoessupportfloatingpoint,
thisdocumentwillnotcoverit.Theuseoffloatingpointrequiresasubstantialaboutofprogram
memoryandexecutiontime,thereforemostapplicationsshouldbeimplementedusinginteger
math.Consequentlytheperiodwillnotappearinnumbersasdescribedinthisdocument.For
moreinformationaboutnumbersseethesectionsondecimals,octals,orhexadecimalsin
Chapter3.
CharacterliteralsarewrittenbyenclosinganASCIIcharacterinapostrophes(singlequotes).
Wewouldwrite'a'foracharacterwiththeASCIIvalueofthelowercasea(97).Thecontrol
characterscanalsobedefinedasconstants.Forexample'\t'isthetabcharacter.Formore
informationaboutcharacterliteralsseethesectiononcharactersinChapter3.
StringliteralsarewrittenasasequenceofASCIIcharactersboundedbyquotationmarks(double
quotes).Thus,"ABC"describesastringofcharacterscontainingthefirstthreelettersofthe
alphabetinuppercase.Formoreinformationaboutstringliteralsseethesectiononstringsin
Chapter3.
Keywords
Therearesomepredefinedtokens,calledkeywords,thathavespecificmeaninginCprograms.
Thereservedwordswewillcoverinthisdocumentare:
keyword meaning
Specifiesavariableasautomatic(createdon
auto
thestack)
break
Causestheprogramcontrolstructuretofinish
case
Onepossibilitywithinaswitchstatement
http://users.ece.utexas.edu/~valvano/embed/chap2/chap2.htm

2/9

2/3/2015

Chapter2:TokensValvano

char
const

8bitinteger
DefinesglobalparameterasconstantinROM,
anddefinesalocalparameterasfixedvalue
continue Causestheprogramtogotobeginningofloop
default Usedinswitchstatementforallothercases
do
Usedforcreatingprogramloops
double Specifiesvariableasdoubleprecision
floatingpoint
else
Alternativepartofaconditional
extern Definedinanothermodule
float
Specifiesvariableassingleprecision
floatingpoint
for
Usedforcreatingprogramloops
goto
Causesprogramtojumptospecifiedlocation
if
Conditionalcontrolstructure
int
32bitinteger(sameaslongon

theARM)Itshouldbeavoidedin
mostcasesbecausethe
implementationwillvaryfrom
compilertocompiler.

long
32bitinteger
register Specifieshowtoimplementalocal
return Leavefunction
short
16bitinteger
signed Specifiesvariableassigned(default)
sizeof Builtinfunctionreturnsthesizeofan
object
static Storedpermanentlyinmemory,accessedlocally
struct Usedforcreatingdatastructures
switch Complexconditionalcontrolstructure
typedef Usedtocreatenewdatatypes
unsigned Alwaysgreaterthanorequaltozero
void
Usedinparameterlisttomeannoparameter
volatile Canchangeimplicitlyoutsidethedirect
actionofthesoftware.Itdisablescompiler
optimization,forcingthecompilertofetcha
newvalueeachtime
while
Usedforcreatingprogramloops

Table22.Keywordshavepredefinedmeanings.
DidyounoticethatallofthekeywordsinCarelowercase?Noticealsothatasamatterofstyle,I
usedamixtureofupperandlowercaseforthenamesIcreated,andalluppercasefortheI/O
ports.Itisagoodprogrammingpracticenottousethesekeywordsforyourvariableorfunction
names.
Names
Weusenamestoidentifyourvariables,functions,andmacros.Namesmustbeginwithaletter
orunderscoreandtheremainingcharactersmustbeeitherlettersordigits.Wecanuseamixture
ofupperandlowercaseortheunderscorecharactertocreateselfexplainingsymbols.E.g.,
time_of_daygo_left_then_stop
TimeOfDayGoLeftThenStop

Thecarefulselectionofnamesgoesalongwaytomakingourprogramsmorereadable.Names
maybewrittenwithbothupperandlowercaseletters.Thenamesarecasesensitive.Therefore
http://users.ece.utexas.edu/~valvano/embed/chap2/chap2.htm

3/9

2/3/2015

Chapter2:TokensValvano

thefollowingnamesaredifferent:
thetemperature
THETEMPERATURE
TheTemperature

Thepracticeofnamingmacrosinuppercasecallsattentiontothefactthattheyarenotvariable
namesbutdefinedsymbols.RemembertheI/Oportnamesareimplementedasmacrosinthe
headerfiletm4c123gh6pm.h.
Wecanusethemapfiletogettheabsoluteaddressesfortheselabels,thenusethedebuggerto
observeandmodifytheircontents.
Developinganamingconventionwillavoidconfusion.Possibleideastoconsiderinclude:
1.Starteveryvariablenamewithitstype.E.g.,
bmeansBooleantrue/false
s8means8bitsignedinteger
u8means8bitunsignedinteger
s16means16bitsignedinteger
u16means16bitunsignedinteger
s32means32bitsignedinteger
u32means32bitunsignedinteger
cmeans8bitASCIIcharacter
smeansnullterminatedASCIIstring
2.Starteverylocalvariablewith"the"or"my"
3.Starteveryglobalvariableandfunctionwithassociatedfileormodulename.Inthefollowing
examplethenamesallbeginwithBit_.Noticehowsimilarthisnamingconventionrecreatesthe
lookandfeelofthemodularityachievedbyclassesinC++.E.g.,
/***********file=Bit.c*************
PointerimplementationoftheaBit_Fifo
Theseroutinescanbeusedtosave(Bit_Put)and
recall(Bit_Get)binarydata1bitatatime(bitstreams)
Informationissaved/recalledinafirstinfirstoutmanner
Bit_FifoSizeisthenumberof16bitwordsintheBit_Fifo
TheBit_Fifoisfullwhenithas16*Bit_FifoSize1bits*/
#defineBit_FifoSize4
//16*41=31bitsofstorage
unsignedshortBit_Fifo[Bit_FifoSize];//storageforBitStream
structBit_Pointer{
unsignedshortMask;//0x8000,0x4000,...,2,1
unsignedshort*WPt;};//Pointertowordcontainingbit
typedefstructBit_PointerBit_PointerType;
Bit_PointerTypeBit_PutPt;//Pointerofwheretoputnext
Bit_PointerTypeBit_GetPt;//Pointerofwheretogetnext
/*Bit_FIFOisemptyifBit_PutPt==Bit_GetPt*/
/*Bit_FIFOisfullifBit_PutPt+1==Bit_GetPt*/
shortBit_Same(Bit_PointerTypep1,Bit_PointerTypep2){
if((p1.WPt==p2.WPt)&&(p1.Mask==p2.Mask))
return(1);//yes
return(0);}//no
voidBit_Init(void){
Bit_PutPt.Mask=Bit_GetPt.Mask=0x8000;
Bit_PutPt.WPt=Bit_GetPt.WPt=&Bit_Fifo[0];/*Empty*/
}
//returnsTRUE=1ifsuccessful,
http://users.ece.utexas.edu/~valvano/embed/chap2/chap2.htm

4/9

2/3/2015

Chapter2:TokensValvano

//FALSE=0iffullanddatanotsaved
//inputisbooleanFALSEifdata==0
shortBit_Put(shortdata){Bit_PointerTypemyPutPt;
myPutPt=Bit_PutPt;
myPutPt.Mask=myPutPt.Mask>>1;
if(myPutPt.Mask==0){
myPutPt.Mask=0x8000;
if((++myPutPt.WPt)==&Bit_Fifo[Bit_FifoSize])
myPutPt.WPt=&Bit_Fifo[0];//wrap
}
if(Bit_Same(myPutPt,Bit_GetPt))
return(0);/*Failed,Bit_Fifowasfull*/
else{
if(data)
(*Bit_PutPt.WPt)|=Bit_PutPt.Mask;//setbit
else
(*Bit_PutPt.WPt)&=~Bit_PutPt.Mask;//clearbit
Bit_PutPt=myPutPt;
return(1);
}
}
//returnsTRUE=1ifsuccessful,
//FALSE=0ifemptyanddatanotremoved
//outputisboolean0meansFALSE,nonzeroistrue
shortBit_Get(unsignedshort*datapt){
if(Bit_Same(Bit_PutPt,Bit_GetPt))
return(0);/*Failed,Bit_Fifowasempty*/
else{
*datapt=(*Bit_GetPt.WPt)&Bit_GetPt.Mask;
Bit_GetPt.Mask=Bit_GetPt.Mask>>1;
if(Bit_GetPt.Mask==0){
Bit_GetPt.Mask=0x8000;
if((++Bit_GetPt.WPt)==&Bit_Fifo[Bit_FifoSize])
Bit_GetPt.WPt=&Bit_Fifo[0];//wrap
}
return(1);
}
}

Listing22:ThisnamingconventioncancreatemodularitysimilartoclassesinC++.

Punctuation
Punctuationmarks(semicolons,colons,commas,apostrophes,quotationmarks,braces,brackets,
andparentheses)areveryimportantinC.Itisoneofthemostfrequentsourcesoferrorsforboth
thebeginningandexperiencedprogrammers.
Semicolons
Semicolonsareusedasstatementterminators.Strangeandconfusingsyntaxerrorsmaybe
generatedwhenyouforgetasemicolon,sothisisoneofthefirstthingstocheckwhentryingto
removesyntaxerrors.InthisexampleweassumethatPortBhasbeeninitializedasanoutput.
Noticethatonesemicolonisplacedattheendofeverysimplestatementinthefollowing
example
#definePORTB(*((volatileunsignedlong*)0x400053FC))
voidStep(void){
PORTB=10;
PORTB=9;
PORTB=5;
http://users.ece.utexas.edu/~valvano/embed/chap2/chap2.htm

5/9

2/3/2015

Chapter2:TokensValvano

PORTB=6;
}

Listing23:Semicolonsareusedtoseparateonestatementfromthenext.
PreprocessordirectivesdonotendwithasemicolonsincetheyarenotactuallypartoftheC
languageproper.Preprocessordirectivesbegininthefirstcolumnwiththe#andconcludeatthe
endoftheline.ThefollowingexamplewillfillthearrayDataBufferwithdatareadfromthe
inputport(PORTB).WeassumeinthisexamplethatPortBhasbeeninitializedasaninput.
Semicolonsarealsousedintheforloopstatement(seealsoChapter6),asillustratedby
voidFill(void){shortj;
for(j=0;j<100;j++){
DataBuffer[j]=PORTB;
}
}

Listing24:Semicolonsareusedtoseparatethreefieldsoftheforstatement.

Colons
Wecandefinealabelusingthecolon.AlthoughChasagotostatement,Istronglydiscourageits
use.Ibelievethesoftwareiseasiertounderstandusingtheblockstructuredcontrolstatements
(if,ifelse,for,while,dowhile,andswitchcase.)Thefollowingexamplewillreturnafterthe
PortBinputreadsthesamevalue100timesinarow.Inthisexample,weassumePortBhas
beeninitializedasaninput.NoticethateverytimethecurrentvalueonPortBisdifferentfrom
thepreviousvaluethecounterisreinitialized.
charDebounce(void){shortCnt;unsignedcharLastData;
Start:Cnt=0;/*numberoftimesPortCisthesame*/
LastData=PORTB;
Loop:if(++Cnt==100)gotoDone;/*samething100times*/
if(LastData!=PORTB)gotoStart;/*changed*/
gotoLoop;
Done:return(LastData);
}

Listing24:Colonsareusedtodefinelabels(placeswecanjumpto)
Colonsalsoterminatecase,anddefaultprefixesthatappearinswitchstatements.Formore
informationseethesectiononswitchinChapter6.Inthefollowingexample,thenextstepper
motoroutputisfound(thepropersequenceis10,9,5,6).Thedefaultcaseisusedtorestartthe
pattern.
unsignedcharNextStep(unsignedcharstep){unsignedchartheNext;
switch(step){
case10:theNext=9;break;
case9:theNext=5;break;
case5:theNext=6;break;
case6:theNext=10;break;
default:theNext=10;
}
return(theNext);
}

Listing25:Colonsarealsousedtowiththeswitchstatement
Forbothapplicationsofthecolon(gotoandswitch),weseethatalabeliscreatedthatisa
http://users.ece.utexas.edu/~valvano/embed/chap2/chap2.htm

6/9

2/3/2015

Chapter2:TokensValvano

potentialtargetforatransferofcontrol.
Commas
Commasseparateitemsthatappearinlists.Wecancreatemultiplevariablesofthesametype.
E.g.,
unsignedshortbeginTime,endTime,elapsedTime;

Listsarealsousedwithfunctionshavingmultipleparameters(bothwhenthefunctionisdefined
andcalled):
shortadd(shortx,shorty){shortz;
z=x+y;
if((x>0)&&(y>0)&&(z<0))z=32767;
if((x<0)&&(y<0)&&(z>0))z=32768;
return(z);
}
voidmain(void){shorta,b;
a=add(2000,2000)
b=0
while(1){
b=add(b,1);
}

Listing26:Commasseparatetheparametersofafunction
Listscanalsobeusedingeneralexpressions.Sometimesitaddsclaritytoaprogramifrelated
variablesaremodifiedatthesameplace.Thevalueofalistofexpressionsisalwaysthevalueof
thelastexpressioninthelist.Inthefollowingexample,firstthetimeisincremented,thedateis
decremented,thenxissettok+2.
x=(thetime++,thedate,k+2);

Apostrophes
Apostrophesareusedtospecifycharacterliterals.Formoreinformationaboutcharacterliterals
seethesectiononcharactersinChapter3.AssumingthefunctionOutCharwillprintasingle
ASCIIcharacter,thefollowingexamplewillprintthelowercasealphabet:
voidAlphabet(void){unsignedcharmych;
for(mych='a';mych<='z';mych++){
OutChar(mych);/*Printnextletter*/
}
}

Listing27:Apostrophesareusedtospecifycharacters
Quotationmarks
Quotationmarksareusedtospecifystringliterals.Formoreinformationaboutstringliteralssee
thesectiononstringsinChapter3.Example
unsignedconstcharMsg[12]="HelloWorld";
/*Msghas11charactersandtermination*/
voidPrintHelloWorld(void){
UART_OutString("HelloWorld");
UART_OutString(Msg);
}
http://users.ece.utexas.edu/~valvano/embed/chap2/chap2.htm

7/9

2/3/2015

Chapter2:TokensValvano

Listing28:Quotationmarksareusedtospecifystrings
ThecommandLetter='A';placestheASCIIcode(65)intothevariableLetter.Thecommand
pt="A";createsanASCIIstringandplacesapointertoitintothevariablept.
Braces
Braces{}areusedthroughoutCprograms.Themostcommonapplicationisforcreatinga
compoundstatement.Eachopenbrace{mustbematchedwithaclosingbrace}.Oneapproach
thathelpstomatchupbracesistouseindenting.Eachtimeanopenbraceisused,thesource
codeistabbedover.Inthisway,itiseasytoseeataglancethebracepairs.Examplesofthis
approachtotabbingaretheBit_PutfunctionwithinListing22andthemedianfunctionin
Listing14.
Brackets
Squarebracketsenclosearraydimensions(indeclarations)andsubscripts(inexpressions).Thus,
shortFifo[100];

declaresanintegerarraynamedFifoconsistingof80wordsnumberedfrom0through99,and
PutPt=&Fifo[0];

assignsthevariablePutPttotheaddressofthefirstentryofthearray.
Parentheses
Parenthesesencloseargumentliststhatareassociatedwithfunctiondeclarationsandcalls.They
arerequiredeveniftherearenoarguments.
Aswithallprogramminglanguages,Cusesparenthesestocontroltheorderinwhichexpressions
areevaluated.Thus,(11+3)/2yields7,whereas11+3/2yields12.Parenthesesareveryimportant
whenwritingexpressions.

Operators
Thespecialcharactersusedasexpressionoperatorsarecoveredintheoperatorsectioninchapter
5.Therearemanyoperators,someofwhicharesinglecharacters
~!@%^&*+=|/:?<>,

whileothersrequiretwocharacters
++<<>><=+==*=/===|=%=&=^=||&&!=

andsomeevenrequirethreecharacters
<<=>>=

Themultiplecharacteroperatorscannothavewhitespacesorcommentsbetweenthecharacters.
TheCsyntaxcanbeconfusingtothebeginningprogrammer.Forexample
z=x+y;/*setszequaltothesumofxandy*/
z=x_y;/*setszequaltothevalueofx_y*/
http://users.ece.utexas.edu/~valvano/embed/chap2/chap2.htm

8/9

2/3/2015

Chapter2:TokensValvano

GotoChapter3onLiteralsReturntoTableofContents

http://users.ece.utexas.edu/~valvano/embed/chap2/chap2.htm

9/9

2/3/2015

Chapter3:Numbers,CharactersandStringsValvano

Chapter3:Numbers,CharactersandStrings
What'sinChapter3?
Howarenumbersrepresentedonthecomputer
8bitunsignednumbers
8bitsignednumbers
16bitunsignednumbers
16bitsignednumbers
Bigandlittleendian
Boolean(true/false)
Decimalnumbers
Hexadecimalnumbers
Octalnumbers
Characters
Strings
Escapesequences
Thischapterdefinesthevariousdatatypessupportedbythecompiler.Sincetheobjectiveof
mostcomputersystemsistoprocessdata,itisimportanttounderstandhowdataisstoredand
interpretedbythesoftware.Wedefinealiteralasthedirectspecificationofthenumber,
character,orstring.E.g.,
100'a'"HelloWorld"

areexamplesofanumberliteral,acharacterliteralandastringliteralrespectively.Wewill
discussthewaydataarestoredonthecomputeraswellastheCsyntaxforcreatingtheliterals.
TheImagecraftandMetrowerkscompilersrecognizethreetypesofliterals(numeric,character,
string).Numberscanbewritteninthreebases(decimal,octal,andhexadecimal).Althoughthe
programmercanchoosetospecifynumbersinthesethreebases,onceloadedintothecomputer,
theallnumbersarestoredandprocessedasunsignedorsignedbinary.AlthoughCdoesnot
supportthebinaryliterals,ifyouwantedtospecifyabinarynumber,youshouldhavenotrouble
usingeithertheoctalorhexadecimalformat.
Binaryrepresentation
Numbers are stored on the computer in binary form. In other words, information is
encodedasasequenceof1sand0s.Onmostcomputers,thememoryisorganizedinto8bit
bytes.Thismeanseach8bitbytestoredinmemorywillhaveaseparateaddress.Precision is
thenumberofdistinctordifferentvalues.Weexpressprecisioninalternatives,decimaldigits,
bytes,orbinarybits.Alternativesaredefinedasthetotalnumberofpossibilities.Forexample,
an 8bit number scheme can represent 256 different numbers. An 8bit digital to analog
converter can generate 256 different analog outputs. An 8bit analog to digital converter
(ADC)canmeasure256differentanaloginputs.Weusetheexpression4decimaldigitsto
meanabout20,000alternativesandtheexpression4decimaldigitstomeanmorethan20,000
alternativesbutlessthan100,000alternatives.Thedecimaldigitmeanstwicethenumberof
alternativesoroneadditionalbinarybit.Forexample,avoltmeterwitharangeof0.00to9.99V
has a three decimal digit precision. Let the operation [[x]] be the greatest integer of x. E.g.,
[[2.1]]isroundedupto3.Tables3.1aand3.1billustratevariousrepresentationsofprecision.
Binarybits
8
10
12

Bytes
1

http://users.ece.utexas.edu/~valvano/embed/chap3/chap3.htm

Alternatives
256
1024
4096
1/14

2/3/2015

Chapter3:Numbers,CharactersandStringsValvano

16
2
65536
20

1,048,576
24
3
16,777,216
30

1,073,741,824
32
4
4,294,967,296
n
[[n/8]]
2n
Table31a.Relationshipsbetweenvariousrepresentationsofprecision.

Decimaldigits Alternatives
3
1000
3
2000
3
4000
4
10000
4
20000
4
40000
5
100000
n
10n
Table31b.Relationshipsbetweenvariousrepresentationsofprecision.
Observation:Agoodruleofthumbtorememberis210nisabout103n.
Forlargenumbersweuseabbreviations,asshowninthefollowingtable.Forexample,16K
means16*1024whichequals16384.Computerengineersusethesamesymbolsasother
scientists,butwithslightlydifferentvalues.

abbreviation
K

pronunciation ComputerEngineering
Value
"kay"
2101024

Scientific
Value
103

M
G
T
P
E

"meg"
"gig"
"tera"
"peta"
"exa"

106
109
1012
1015
1018

2201,048,576
2301,073,741,824
2401,099,511,627,776
2501,125,899,906,843,624
260
1,152,921,504,606,846,976

Table32.Commonabbreviationsforlargenumbers.

8bitunsignednumbers
Abytecontains8bits

http://users.ece.utexas.edu/~valvano/embed/chap3/chap3.htm

2/14

2/3/2015

Chapter3:Numbers,CharactersandStringsValvano

whereeachbitb7,...,b0isbinaryandhasthevalue1or0.Wespecifyb7asthemostsignificant
bitorMSB,andb0astheleastsignificantbitorLSB.Ifabyteisusedtorepresentanunsigned
number,thenthevalueofthenumberis
N=128b7+64b6+32b5+16b4+8b3+4b2+2b1+b0
Thereare256differentunsigned8bitnumbers.Thesmallestunsigned8bitnumberis0andthe
largestis255.Forexample,000010102is8+2or10.Otherexamplesareshowninthefollowing
table.
binary
00000000
01000001
00010110
10000111
11111111

hex
0x00
0x41
0x16
0x87
0xFF

Calculation
decimal

0
64+1
65
16+4+2
22
128+4+2+1
135
128+64+32+16+8+4+2+1 255

Table33.Exampleconversionsfromunsigned8bitbinarytohexadecimalandtodecimal.

Thebasisofanumbersystemisasubsetfromwhichlinearcombinationsofthebasiselements
canbeusedtoconstructtheentireset.Fortheunsigned8bitnumbersystem,thebasisis
{1,2,4,8,16,32,64,128}
Onewayforustoconvertadecimalnumberintobinaryistousethebasiselements.Theoverall
approachistostartwiththelargestbasiselementandworktowardsthesmallest.Onebyonewe
askourselveswhetherornotweneedthatbasiselementtocreateournumber.Ifwedo,thenwe
setthecorrespondingbitinourbinaryresultandsubtractthebasiselementfromournumber.If
wedonotneedit,thenweclearthecorrespondingbitinourbinaryresult.Wewillworkthrough
thealgorithmwiththeexampleofconverting100to8bitbinary.Wewiththelargestbasis
element(inthiscase128)andaskwhetherornotweneedtoincludeittomake100.Sinceour
numberislessthan128,wedonotneeditsobit7iszero.Wegothenextlargestbasiselement,
64andaskdoweneedit.Wedoneed64togenerateour100,sobit6isoneandsubtract100
minus64toget36.Nextwegothenextbasiselement,32andaskdoweneedit.Againwedo
need32togenerateour36,sobit5isoneandwesubtract36minus32toget4.Continuing
along,weneedbasiselement4butnot1682or1,sobits43210are00100respectively.Putting
ittogetherweget011001002(whichmeans64+32+4).

Observation:Iftheleastsignificantbinarybitiszero,thenthenumberiseven.

Observation:Iftherightmostnbits(leastsignificant)arezero,thenthenumberis
divisibleby2n.

Number
100
100
36

Basis
128
64
32

Needit
no
yes
yes

bit
bit7=0
bit6=1
bit5=1

http://users.ece.utexas.edu/~valvano/embed/chap3/chap3.htm

Operation
none
subtract10064
subtract3632
3/14

2/3/2015

Chapter3:Numbers,CharactersandStringsValvano

4
4
4
0
0

16
8
4
2
1

no
no
yes
no
no

bit4=0
bit3=0
bit2=1
bit1=0
bit0=0

none
none
subtract44
none
none

Table34.Exampleconversionfromdecimaltounsigned8bitbinarytohexadecimal.
Wedefineanunsigned8bitnumberusingtheunsignedcharformat.Whenanumberisstored
intoanunsignedcharitisconvertedto8bitunsignedvalue.Forexample
unsignedchardata;//0to255
unsignedcharfunction(unsignedcharinput){
data=input+1;
returndata;}

8bitsignednumbers
Ifabyteisusedtorepresentasigned2scomplementnumber,thenthevalueofthenumberis
N=128b7+64b6+32b5+16b4+8b3+4b2+2b1+b0
Therearealso256differentsigned8bitnumbers.Thesmallestsigned8bitnumberis128and
thelargestis127.Forexample,100000102is128+2or126.Otherexamplesareshowninthe
followingtable.
binary
00000000
01000001
00010110
10000111
11111111

hex
0x00
0x41
0x16
0x87
0xFF

Calculation
decimal

0
64+1
65
16+4+2
22
128+4+2+1
121
128+64+32+16+8+4+2+1 1

Table35.Exampleconversionsfromsigned8bitbinarytohexadecimalandtodecimal.
Forthesigned8bitnumbersystemthebasisis
{1,2,4,8,16,32,64,128}

Observation:Themostsignificantbitina2scomplementsignednumberwillspecifythe
sign.

Noticethatthesamebinarypatternof111111112couldrepresenteither255or1.Itisvery
importantforthesoftwaredevelopertokeeptrackofthenumberformat.Thecomputercannot
determinewhetherthe8bitnumberissignedorunsigned.You,astheprogrammer,will
determinewhetherthenumberissignedorunsignedbythespecificassemblyinstructionsyou
selecttooperateonthenumber.Someoperationslikeaddition,subtraction,andshiftleft
(multiplyby2)usethesamehardware(instructions)forbothunsignedandsignedoperations.On
theotherhand,multiply,divide,andshiftright(divideby2)requireseparatehardware
(instruction)forunsignedandsignedoperations.Thecompilerwillautomaticallychoosethe
properimplementation.
http://users.ece.utexas.edu/~valvano/embed/chap3/chap3.htm

4/14

2/3/2015

Chapter3:Numbers,CharactersandStringsValvano

Itisalwaysgoodprogrammingpracticetohaveclearunderstandingofthedatatypeforeach
number,variable,parameter,etc.Forsomeoperationsthereisadifferencebetweenthesigned
andunsignednumberswhileforothersitdoesnotmatter.
/%
*
>
<
>=
<=
>>

signeddifferentfromunsigned
division
multiplication
greaterthan
lessthan
greaterthanorequalto
lessthanorequalto
rightshift

==
|
&
^
<<

signedsameasunsigned
addition
subtraction
isequalto
logicalor
logicaland
logicalexclusiveor
leftshift

Table36.Operationseitherdependordon'tdependonwhetherthenumberissigned/unsigned.

Thepointisthatcaremustbetakenwhendealingwithamixtureofnumbersofdifferentsizes
andtypes.
Similartotheunsignedalgorithm,wecanusethebasistoconvertadecimalnumberintosigned
binary.Wewillworkthroughthealgorithmwiththeexampleofconverting100to8bitbinary.
Wewiththelargestbasiselement(inthiscase128)anddecidedoweneedtoincludeittomake
100.Yes(without128,wewouldbeunabletoaddtheotherbasiselementstogethertogetany
negativeresult),sowesetbit7andsubtractthebasiselementfromourvalue.Ournewvalueis
100minus128,whichis28.Wegothenextlargestbasiselement,64andaskdoweneedit.
Wedonotneed64togenerateour28,sobit6iszero.Nextwegothenextbasiselement,32and
askdoweneedit.Wedonotneed32togenerateour28,sobit5iszero.Nowweneedthebasis
element16,sowesetbit4,andsubtract16fromournumber28(2816=12).Continuingalong,
weneedbasiselements8and4butnot21,sobits3210are1100.Puttingittogetherweget
100111002(whichmeans128+16+8+4).

Number
100
28
28
28
12
4
0
0

Basis
128
64
32
16
8
4
2
1

Needit
yes
no
no
yes
yes
yes
no
no

bit
bit7=1
bit6=0
bit5=0
bit4=1
bit3=1
bit2=1
bit1=0
bit0=0

Operation
subtract100128
none
none
subtract2816
subtract128
subtract44
none
none

Table37.Exampleconversionfromdecimaltosigned8bitbinarytohexadecimal.

Observation:Totakethenegativeofa2scomplementsignednumberwefirstcomplement
(flip)allthebits,thenadd1.

http://users.ece.utexas.edu/~valvano/embed/chap3/chap3.htm

5/14

2/3/2015

Chapter3:Numbers,CharactersandStringsValvano

Asecondwaytoconvertnegativenumbersintobinaryistofirstconvertthemintounsigned
binary,thendoa2scomplementnegate.Forexample,weearlierfoundthat+100is011001002.
The2scomplementnegateisatwostepprocess.Firstwedoalogiccomplement(flipallbits)to
get100110112.Thenaddonetotheresulttoget100111002.
Athirdwaytoconvertnegativenumbersintobinaryistofirstsubtractthenumberfrom256,
thenconverttheunsignedresulttobinaryusingtheunsignedmethod.Forexample,tofind100,
wesubtract256minus100toget156.Thenweconvert156tobinaryresultingin100111002.
Thismethodworksbecausein8bitbinarymathadding256tonumberdoesnotchangethe
value.E.g.,256100isthesamevalueas100.
CommonError:Anerrorwilloccurifyouusesignedoperationsonunsignednumbers,or
useunsignedoperationsonsignednumbers.
MaintenanceTip:Toimprovetheclarityofoursoftware,alwaysspecifytheformatofyour
data(signedversusunsigned)whendefiningoraccessingthedata.
Wedefineasigned8bitnumberusingthecharformat.Whenanumberisstoredintoacharitis
convertedto8bitsignedvalue.Forexample
chardata;//128to127
charfunction(charinput){
data=input+1;
returndata;}

16bitunsignednumbers
Ahalfwordordoublebytecontains16bits.Awordcontains32bits.

whereeachbitb15,...,b0isbinaryandhasthevalue1or0.Ifawordisusedtorepresentan
unsignednumber,thenthevalueofthenumberis
N=32768b15+16384b14+8192b13+4096b12
+2048b11+1024b10+512b9+256b8
+128b7+64b6+32b5+16b4+8b3+4b2+2b1+b0
Thereare65,536differentunsigned16bitnumbers.Thesmallestunsigned16bitnumberis0
andthelargestis65535.Forexample,0010,0001,1000,01002or0x2184is8192+256+128+4or
8580.Otherexamplesareshowninthefollowingtable.

binary

hex

decimal

0000,0000,0000,0000 0x0000

Calculation

0000,0100,0000,0001 0x0401
0000,1100,1010,0000 0x0CA0
1000,1110,0000,0010 0x8E02

1024+1
2048+1024+128+32
32768+2048+1024+512+2

1025
3232
36354

http://users.ece.utexas.edu/~valvano/embed/chap3/chap3.htm

6/14

2/3/2015

Chapter3:Numbers,CharactersandStringsValvano

1111,1111,1111,1111 0xFFFF

32768+16384+8192+4096+2048+1024 65535
+512+256+128+64+32+16+8+4+2+1

Table38.Exampleconversionsfromunsigned16bitbinarytohexadecimalandtodecimal.

Fortheunsigned16bitnumbersystemthebasisis
{1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768}
Ifawordisusedtorepresentasigned2scomplementnumber,thenthevalueofthenumberis
N=32768b15+16384b14+8192b13+4096b12
+2048b11+1024b10+512b9+256b8
+128b7+64b6+32b5+16b4+8b3+4b2+2b1+b0
Wedefineanunsigned16bitnumberusingtheunsignedshortformat.Whenanumberisstored
intoanunsignedshortitisconvertedto16bitunsignedvalue.Forexample
unsignedshortdata;//0to65535
unsignedshortfunction(unsignedshortinput){
data=input+1;
returndata;}

16bitsignednumbers
Therearealso65,536differentsigned16bitnumbers.Thesmallestsigned16bitnumberis
32768andthelargestis32767.Forexample,1101,0000,0000,01002or0xD004is
32768+16384+4096+4or12284.Otherexamplesareshowninthefollowingtable.
binary

hex

Calculation

0000,0000,0000,0000
0000,0100,0000,0001
0000,1100,1010,0000
1000,0100,0000,0010
1111,1111,1111,1111

0x0000
0x0401
0x0CA0
0x8402
0xFFFF

0
1024+1
1025
2048+1024+128+32
3232
32768+1024+2
31742
32768+16384+8192+4096+2048+1024 1
+512+256+128+64+32+16+8+4+2+1

decimal

Table39.Exampleconversionsfromsigned16bitbinarytohexadecimalandtodecimal.

Forthesigned16bitnumbersystemthebasisis
{1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768}
MaintenanceTip:Toimprovethequalityofoursoftware,weshouldalwaysspecifythe
precisionofourdatawhendefiningoraccessingthedata.
Wedefineasigned16bitnumberusingtheshortformat.Whenanumberisstoredintoashort
itisconvertedto16bitsignedvalue.Forexample
shortdata;//23768to32767
http://users.ece.utexas.edu/~valvano/embed/chap3/chap3.htm

7/14

2/3/2015

Chapter3:Numbers,CharactersandStringsValvano

shortfunction(shortinput){
data=input+1;
returndata;}

BigandLittleEndian
Whenwestore16bitdataintomemoryitrequirestwobytes.Sincethememorysystemsonmost
computersarebyteaddressable(auniqueaddressforeachbyte),therearetwopossiblewaysto
storeinmemorythetwobytesthatconstitutethe16bitdata.Freescalemicrocomputers
implementthebigendianapproachthatstoresthemostsignificantpartfirst.TheARMCortexM
processorsimplementthelittleendianapproachthatstorestheleastsignificantpartfirst.Some
ARMprocessorsarebiendian,becausetheycanbeconfiguredtoefficientlyhandlebothbigand
littleendian.Forexample,assumewewishtostorethe16bitnumber1000(0x03E8)atlocations
0x50,0x51,then

Wealsocanuseeitherthebigorlittleendianapproachwhenstoring32bitnumbersinto
memorythatisbyte(8bit)addressable.Ifwewishtostorethe32bitnumber0x12345678at
locations0x500x53then

Intheabovetwoexampleswenormallywouldnotpickoutindividualbytes(e.g.,the0x12),but
rathercapturetheentiremultiplebytedataasonenondivisablepieceofinformation.Onthe
otherhand,ifeachbyteinamultiplebytedatastructureisindividuallyaddressable,thenboththe
bigandlittleendianschemesstorethedatainfirsttolastsequence.Forexample,ifwewishto
storethe4ASCIIcharacters6811whichis0x36383131atlocations0x500x53,thenthe
ASCII6=0x36comesfirstinbothbigandlittleendianschemes.

Theterm"BigEndian"comesfromJonathanSwiftssatireGulliversTravels.InSwiftsbook,a
http://users.ece.utexas.edu/~valvano/embed/chap3/chap3.htm

8/14

2/3/2015

Chapter3:Numbers,CharactersandStringsValvano

BigEndianreferstoapersonwhocrackstheireggonthebigend.TheLilliputiansconsidered
thebigendiansasinferiors.ThebigendiansfoughtalongandsenselesswarwiththeLilliputians
whoinsisteditwasonlypropertobreakaneggonthelittleend.

CommonError:AnerrorwilloccurwhendataisstoredinBigEndianbyonecomputer
andreadinLittleEndianformatonanother.

Booleaninformation
Abooleannumberishastwostates.Thetwovaluescouldrepresentthelogicaltrueorfalse.The
positivelogicrepresentationdefinestrueasa1orhigh,andfalseasa0orlow.Ifyouwere
controllingamotor,light,heaterorairconditionerthebooleancouldmeanonoroff.In
communicationsystems,werepresenttheinformationasasequenceofbooleans:markorspace.
Forblackorwhitegraphicdisplaysweusebooleanstospecifythestateofeachpixel.Themost
efficientstorageofbooleansonacomputeristomapeachbooleanintoonememorybit.Inthis
way,wecouldpack8booleansintoeachbyte.Ifwehavejustonebooleantostoreinmemory,
outofconvenienceweallocateanentirebyteorwordforit.MostCcompilersincludingKeil
uVisiondefine:
Falsebeallzeros,and
Truebeanynonzerovalue.
Manyprogrammersaddthefollowingmacros
#defineTRUE1
#defineFALSE0

DecimalNumbers
Decimalnumbersarewrittenasasequenceofdecimaldigits(0through9).Thenumbermaybe
precededbyaplusorminussignorfollowedbyaLorU.Lowercaselorucouldalsobeused.
Theminussigngivesthenumberanegativevalue,otherwiseitispositive.Theplussignis
optionalforpositivevalues.Unsigned16bitnumbersbetween32768and65535shouldbe
followedbyU.YoucanplaceaLattheendofthenumbertosignifyittobea32bitsigned
number.Therangeofadecimalnumberdependsonthedatatypeasshowninthefollowing
table.OntheKeiluVisioncompiler,thechardatatypemaybesignedorunsigneddependingon
acompileroption.
type
unsignedchar
char
unsignedint

range
0to255
128to127
0to4294967295

precision
8bits
8bits
32bits

int

2147483648
to2147483647
0to65535U

16bits

32768to32767
2147483648to
2147483647
0to4294967295

16bits
32bits

unsignedshort
short
long
unsignedlong

http://users.ece.utexas.edu/~valvano/embed/chap3/chap3.htm

16bits

32bits

examples
010123
123010+10
020002000
50000000L
100001000+20000
020002000U
50000U
100001000+20000
123456L0L
1234567L
0L12345678L
9/14

2/3/2015

Chapter3:Numbers,CharactersandStringsValvano

Table310.Therangeofdecimalnumbers.
BecausetheARMCortexmicrocomputersaremostefficientfor32bitdata(andnot64bitdata),
theunsignedintandintdatatypesare32bits.Ontheotherhand,ona9S16basedmachine,the
unsignedintandintdatatypesare16bits.Inordertomakeyoursoftwaremorecompatiblewith
othermachines,itispreferabletousetheshorttypewhenneeding16bitdataandthelongtype
for32bitdata.
type
unsignedchar
char
unsignedint
int
unsignedshort
short
long

6811/6812
8bits
8bits
16bits
16bits
16bits
16bits
32bits

CortexM
8bits
8bits
32bits
32bits
16bits
16bits
32bits

Table311.Differencesbetweena6811/6812andanARMCortexM
SincetheCortexMmicrocomputersdonothavedirectsupportof64bitnumbers,theuseof
longlongdatatypesshouldbeminimized.Ontheotherhand,acarefulobservationofthecode
generatedyieldsthefactthatthesecompilersaremoreefficientwith32bitnumbersthanwith8
bitor16bitnumbers.
Decimalnumbersarereducedtotheirtwo'scomplementorunsignedbinaryequivalentand
storedas8/16/32bitbinaryvalues.
Themannerinwhichdecimalliteralsaretreateddependsonthecontext.Forexample
shortI;
unsignedshortJ;
charK;
unsignedcharL;
longM;
voidmain(void){
I=97;/*16bits0x0061*/
J=97;/*16bits0x0061*/
K=97;/*8bits0x61*/
L=97;/*8bits0x61*/
M=97;/*32bits0x00000061*/}

OctalNumbers
Ifasequenceofdigitsbeginswithaleading0(zero)itisinterpretedasanoctalvalue.Thereare
onlyeightoctaldigits,0through7.Aswithdecimalnumbers,octalnumbersareconvertedto
theirbinaryequivalentin8bitor16bitwords.Therangeofanoctalnumberdependsonthe
datatypeasshowninthefollowingtable.
type
unsignedchar
char
unsignedshort
short

range
0to0377
0200to0177
0to0177777
0100000to077777

precision
8bits
8bits
16bits
16bits

long

020000000000to
017777777777

32bits

http://users.ece.utexas.edu/~valvano/embed/chap3/chap3.htm

examples
00100123
01230010+010
0020000150000U
01000001000
+020000
01234567L0L
01234567L

10/14

2/3/2015

Chapter3:Numbers,CharactersandStringsValvano

Table312.Therangeofoctalnumbers.
Noticethattheoctalvalues0through07areequivalenttothedecimalvalues0through7.Oneof
theadvantagesofthisformatisthatitisveryeasytoconvertbackandforthbetweenoctaland
binary.Eachoctaldigitmapsdirectlyto/from3binarydigits.
HexadecimalNumbers
Thehexadecimalnumbersystemusesbase16asopposedtoourregulardecimalnumbersystem
thatusesbase10.Liketheoctalformat,thehexadecimalformatisalsoaconvenientmechanism
forushumanstorepresentbinaryinformation,becauseitisextremelysimpleforustoconvert
backandforthbetweenbinaryandhexadecimal.Anibbleisdefinedas4binarybits.Eachvalue
ofthe4bitnibbleismappedintoauniquehexdigit.
HexDigit
0
1
2
3
4
5
6
7
8
9
Aora
Borb
Corc
Dord
Eore
Forf

DecimalValue
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

BinaryValue
0000
0001
0010
0011
0100
0101
0110
0111
1000
1001
1010
1011
1100
1101
1110
1111

Table313.Definitionofhexadecimalrepresentation.
Computerprogrammingenvironmentsuseawidevarietyofsymbolicnotationstospecifythe
numbersinvariousbases.Thefollowingtableillustratesvariousformatsfornumbers
environment

binary
hexadecimal
format
format
Freescaleassemblylanguage
%01111010 $7A
IntelandTIassemblylanguage 01111010B 7AH
Clanguage

0x7A

decimalformat
122
122
122

Table314.Varioushexadecimalformats.
Toconvertfrombinarytohexadecimalwecan:
1)dividethebinarynumberintorightjustifiednibbles
2)converteachnibbleintoitscorrespondinghexadecimaldigit.

http://users.ece.utexas.edu/~valvano/embed/chap3/chap3.htm

11/14

2/3/2015

Chapter3:Numbers,CharactersandStringsValvano

Toconvertfromhexadecimaltobinarywecan:
1)converteachhexadecimaldigitintoitscorresponding4bitbinarynibble
2)combinethenibblesintoasinglebinarynumber.

Ifasequenceofdigitsbeginswith0xor0Xthenitistakenasahexadecimalvalue.Inthiscase
theworddigitsreferstohexadecimaldigits(0throughF).Aswithdecimalnumbers,
hexadecimalnumbersareconvertedtotheirbinaryequivalentin8bitbytesor16bitwords.The
rangeofahexadecimalnumberdependsonthedatatypeasshowninthefollowingtable.
type
unsigned
char
char
unsigned
short
short
long

range

precision examples

0x00to0xFF

8bits

0x010x3a0xB3

0x80to0x7F

8bits

0x010x3a0x7B

0x0000to0xFFFF

16bits

0x220Xabcd0xF0A6

0x8000to0x7FFF
0x80000000to
0x7FFFFFFF

16bits

0x12340x0+0x7abc
0x1234567
0xABCDEF

32bits

Table315.Therangeofhexadecimalnumbers.

CharacterLiterals
Characterliteralsconsistofoneortwocharacterssurroundedbyapostrophes.Themannerin
whichcharacterliteralsaretreateddependsonthecontext.Forexample
shortI;
unsignedshortJ;
charK;
unsignedcharL;
longM;
voidmain(void){
I='a';/*16bits0x0061*/
J='a';/*16bits0x0061*/
K='a';/*8bits0x61*/
L='a';/*8bits0x61*/
M='a';/*32bits0x00000061*/}

AllstandardASCIIcharactersarepositivebecausethehighorderbitiszero.Inmostcasesit
doesn'tmatterifwedeclarecharactervariablesassignedorunsigned.Ontheotherhand,we
haveseenearlierthatthecompilertreatssignedandunsignednumbersdifferently.Unlessa
charactervariableisspecificallydeclaredtobeunsigned,itshighorderbitwillbetakenasasign
bit.Therefore,weshouldnotexpectacharactervariable,whichisnotdeclaredunsigned,to
compareequaltothesamecharacterliteralifthehighorderbitisset.Formoreonthissee
Chapter4onVariables.
http://users.ece.utexas.edu/~valvano/embed/chap3/chap3.htm

12/14

2/3/2015

Chapter3:Numbers,CharactersandStringsValvano

StringLiterals
Strictlyspeaking,Cdoesnotrecognizecharacterstrings,butitdoesrecognizearraysof
charactersandprovidesawaytowritecharacterarrays,whichwecallstrings.Surroundinga
charactersequencewithquotationmarks,e.g.,"Jon",setsupanarrayofcharactersand
generatestheaddressofthearray.Inotherwords,atthepointinaprogramwhereitappears,a
stringliteralproducestheaddressofthespecifiedarrayofcharacterliterals.Thearrayitselfis
locatedelsewhere.Metrowerkswillplacestringsintothetextarea.I.e.,thestringliteralsare
consideredconstantandwillbedefinedintheROMofanembeddedsystem.Thisisvery
importanttoremember.Noticethatthisdiffersfromacharacterliteralwhichgeneratesthevalue
oftheliteraldirectly.JusttobesurethatthisdistinctfeatureoftheClanguageisnotoverlooked,
considerthefollowingexample:
char*pt;
externvoidFoo(char*p);
voidmain(void){
pt="Jon";/*pointertothestring*/
Foo(pt);/*passesthepointernotthedataitself*/
}

Notethatthepointer,pt,isallocatedinRAMandthestringisstoredinROM.Theassignment
statementpt="Jon";copiestheaddressnotthedata.First,theaddressofthestringisassignedto
thecharacterpointerpt(KeiluVisionusesthe32bitRegisterR0forthefirstparameter).Unlike
otherlanguages,thestringitselfisnotassignedtopt,onlyitsaddressis.Afterall,ptisa32bit
objectand,therefore,cannotholdthestringitself.
Sincestringsmaycontainasfewasoneortwocharacters,theyprovideanalternativewayof
writingcharacterliteralsinsituationswheretheaddress,ratherthanthecharacteritself,is
needed.
ItisaconventioninCtoidentifytheendofacharacterstringwithanull(zero)character.
Therefore,Ccompilersautomaticallysuffixcharacterstringswithsuchaterminator.Thus,the
string"Jon"setsupanarrayoffourcharacters('J','o','n',andzero)andgeneratestheaddress
ofthefirstcharacter,forusebytheprogram.
Rememberthat'A'isdifferentfrom"A",considerthefollowingexample:
charletter,*pt;
voidmain(void){
pt="A";/*pointertothestring*/
letter='A';/*thedataitself('A'ASCII65=$41)*/
}

EscapeSequences
Sometimesitisdesirabletocodenongraphiccharactersinacharacterorstringliteral.Thiscan
bedonebyusinganescapesequenceasequenceoftwoormorecharactersinwhichthefirst
(escape)characterchangesthemeaningofthefollowingcharacter(s).Whenthisisdonethe
entiresequencegeneratesonlyonecharacter.Cusesthebackslash(\)fortheescapecharacter.
ThefollowingescapesequencesarerecognizedbytheMetrowerkscompiler:
sequence
\n
\t
\b

name
newline,linefeed
tab
backspace

http://users.ece.utexas.edu/~valvano/embed/chap3/chap3.htm

value
0x0A=10
0x09=9
0x08=8
13/14

2/3/2015

Chapter3:Numbers,CharactersandStringsValvano

\f
\a
\r
\v
\0
\"
\\
\'

formfeed
bell
return
verticaltab
null
ASCIIquote
ASCIIbackslash
ASCIIsinglequote

0x0C=12
0x07=7
0x0D=13
0x0B=11
0x00=0
0x22=34
0x5C=92
0x27=39

Table316.TheescapesequencessupportedbyKeiluVision.

Othernonprintingcharacterscanalsobedefinedusingthe\ooooctalformat.Thedigitsooocan
defineany8bitoctalnumber.Thefollowingthreelinesareequivalent:
printf("\tJon\n");
printf("\11Jon\12");
printf("\011Jon\012");

Thetermnewlinereferstoasinglecharacterwhich,whenwrittentoanoutputdevice,startsa
newline.SomehardwaredevicesusetheASCIIcarriagereturn(13)asthenewlinecharacter
whileothersusetheASCIIlinefeed(10).Itreallydoesn'tmatterwhichisthecaseaslongaswe
write\ninourprograms.AvoidusingtheASCIIvaluedirectlysincethatcouldproduce
compatibilityproblemsbetweendifferentcompilers.
Thereisoneothertypeofescapesequence:anythingundefined.Ifthebackslashisfollowedby
anycharacterotherthantheonesdescribedabove,thenthebackslashisignoredandthe
followingcharacteristakenliterally.Sothewaytocodethebackslashisbywritingapairof
backslashesandthewaytocodeanapostropheoraquoteisbywriting\'or\"respectively.
GotoChapter4onVariablesReturntoTableofContents

http://users.ece.utexas.edu/~valvano/embed/chap3/chap3.htm

14/14

2/3/2015

Chapter4:VariablesandConstantsValvano

Chapter4:VariablesandConstants
What'sinChapter4?
Astaticvariableexistspermanently
Astaticglobalcanbeaccessedonlyfromwithinthesamefile
Astaticlocalcanbeaccessedonlyinthefunction
WespecifyvolatilevariableswhenusinginterruptsandI/Oports
Automaticvariablesareallocatedonthestack
Wecanunderstandautomaticsbylookingattheassemblycode
Aconstantlocalcannotbechanged
Externalvariablesaredefinedelsewhere
Thescopeofavariabledefineswhereitcanbeaccessed
Variablesdeclarations
8bitvariablesaredefinedwithchar
Discussionofwhentousestaticversusautomaticvariables
Initializationofvariablesandconstants
Wecanunderstandinitializationbylookingattheassemblycode
Thepurposeofthischapteristoexplainhowtocreateandaccessvariablesandconstants.The
storageandretrievalofinformationarecriticaloperationsofanycomputersystem.Thischapter
willalsopresenttheCsyntaxandresultingassemblycodegeneratedbytheKeiluVision
compiler.
AvariableisanamedobjectthatresidesinRAMmemoryandiscapableofbeingexaminedand
modified.Avariableisusedtoholdinformationcriticaltotheoperationoftheembedded
system.Aconstantisanamedobjectthatresidesinmemory(usuallyinROM)andisonly
capableofbeingexamined.Aswesawinthelastchapteraliteralisthedirectspecificationofa
numbercharacterorstring.Thedifferencebetweenaliteralandaconstantisthatconstantsare
givennamessothattheycanbeaccessedmorethanonce.Forexample
shortMyVariable;/*variableallowsread/writeaccess*/
constshortMyConstant=50;/*constantallowsonlyreadaccess*/
#definefifty50
voidmain(void){
MyVariable=50;/*writeaccesstothevariable*/
OutSDec(MyVariable);/*readaccesstothevariable*/
OutSDec(MyConstant);/*readaccesstotheconstant*/
OutSDec(50);/*"50"isaliteral*/
OutSDec(fifty);/*fiftyisalsoaliteral*/
}

Listing41:Exampleshowingavariable,aconstantandsomeliterals
Theoptionsonmanycompilerscanbeusedtoselecttheprecisionofeachofthedataformats
(int,shortetc.)
Theconceptsofprecisionandtype(unsignedvs.signed)developedfornumbersinthelast
chapterapplytovariablesandconstantsaswell.Inthischapterwewillbeginthediscussionof
variablesthatcontainintegersandcharacters.Eventhoughpointersaresimilarinmanywaysto
32bitunsignedintegers,pointerswillbetreatedindetailinChapter7.Althougharraysand
structuresfitalsothedefinitionofavariable,theyareregardedascollectionsofvariablesand
willbediscussedinChapter8andChapter9.
Thetermstorageclassreferstothemethodbywhichanobjectisassignedspaceinmemory.
TheMetrowerkscompilerrecognizesthreestorageclassesstatic,automatic,andexternal.In
http://users.ece.utexas.edu/~valvano/embed/chap4/chap4.htm

1/11

2/3/2015

Chapter4:VariablesandConstantsValvano

thisdocumentwewillusethetermglobalvariabletomeanaregularstaticvariablethatcanbe
accessedbyallotherfunctions.Similarlywewillusethetermlocalvariabletomeanan
automaticvariablethatcanbeaccessedonlybythefunctionthatcreatedit.Aswewillseeinthe
followingsectionsthereareotherpossibilitieslikeastaticglobalandstaticlocal.
Statics
Staticvariablesaregivenspaceinmemoryatsomefixedlocationwithintheprogram.Theyexist
whentheprogramstartstoexecuteandcontinuetoexistthroughouttheprogram'sentirelifetime.
Thevalueofastaticvariableisfaithfullymaintaineduntilwechangeitdeliberately(orremove
powerfromthememory).Aconstant,whichwedefinebyaddingthemodifierconst,canberead
butnotchanged.
InanembeddedsystemwenormallywishtoplaceallvariablesinRAMandconstantsinROM.
Thefollowingexamplesetsaglobal,calledTheGlobal,tothevalue1000.Thisglobalcanbe
referencedbyanyfunctionfromanyfileinthesoftwaresystem.Itistrulyglobal.
longTheGlobal;/*aregularglobalvariable*/
voidmain(void){
TheGlobal=1000;
}

Listing42:Exampleshowingaregularglobalvariable
TheARMcodegeneratedbytheuVisioncompilerisasfollows(registerusewillvary)
LDRR0,=1000
LDRR1,=TheGlobal
STRR0,[R1]

Thefactthatthesetypesofvariablesexistinpermanentlyreservedmemorymeansthatstatic
variablesexistfortheentirelifeoftheprogram.Whenthepowerisfirstappliedtoanembedded
computer,thevaluesinitsRAMareusuallyundefined.Therefore,initializingglobalvariables
requiresspecialruntimesoftwareconsideration.Seethesectiononinitializationformoreabout
initializingvariablesandconstants.
Astaticglobalisverysimilartoaregularglobal.Inbothcases,thevariableisdefinedinRAM
permanently.Theassemblylanguageaccessisidentical.Theonlydifferenceisthescope.The
staticglobalcanonlybeaccessedwithinthefilewhereitisdefined.Thefollowingexamplealso
setsaglobal,calledTheGlobal,tothevalue1000.Thisglobalcannotbereferencedbymodules
inotherfiles.
staticshortTheGlobal;/*astaticglobalvariable*/
voidmain(void){
TheGlobal=1000;
}

Listing43:Exampleshowingastaticglobalvariable
Thecodegeneratedbythecompileristhesameasaregularglobal.Thecompilerdoesproperly
limittheaccessonlytothestaticglobaltofunctionsdefinedinthisfile.

Astaticlocalissimilartothestaticglobal.Justaswiththeotherstatics,thevariableisdefined
inRAMpermanently.Theassemblylanguagecodegeneratedbythecompilerthataccessesthe
variableisidentical.Theonlydifferenceisthescope.Thestaticlocalcanonlybeaccessed
http://users.ece.utexas.edu/~valvano/embed/chap4/chap4.htm

2/11

2/3/2015

Chapter4:VariablesandConstantsValvano

withinthefunctionwhereitisdefined.Thefollowingexamplesetsastaticlocal,called
TheLocal,tothevalue1000.Thecompilerlimitstheaccesstothestaticlocal,sothatthis
variablecannotbeaccessedbyotherfunctionsinthisfileorinotherfiles.Noticethatthe
assemblylanguagenameofthestaticlocalisauniquecompilergeneratedname(L2inthis
example.)Thisnamingmethodallowsotherfunctionstoalsodefineastaticlocalorautomatic
localwiththesamename.
voidmain(void){
staticstortTheLocal;/*astaticlocalvariable*/
TheLocal=1000;
}

Listing44:Exampleshowingastaticlocalvariable
Againthecodegeneratedbythecompileristhesameasaregularglobal.Thecompilerdoes
properlylimittheaccessonlytothestaticlocaltothefunctioninwhichitisdefined.

Astaticlocalcanbeusedtosaveinformationfromoneinstanceofthefunctioncalltothenext.
Assumeeachfunctionwishedtoknowhowmanytimesithasbeencalled.Rememberupon
reset,thecompilerwillinitializeallstaticstozero(includingstaticlocals).Thefollowing
functionsmaintainsuchacount,andthesecountscannotbeaccessedbyotherfunctions.Even
thoughthenamesarethesame,thetwostaticlocalsareinfactdistinct.
voidfunction1(void){
staticshortTheCount;
TheCount=TheCount+1;
}
voidfunction2(void){
staticshortTheCount;
TheCount=TheCount+1;
}

Listing45:Exampleshowingtwostaticlocalvariableswiththesamename
Volatile
Weaddthevolatilemodifiertoavariablethatcanchangevalueoutsidethescopeofthe
function.Usuallythevalueofaglobalvariablechangesonlyasaresultofexplicitstatementsin
theCfunctionthatiscurrentlyexecuting.Theparadigmresultswhenasingleprogramexecutes
fromstarttofinish,andeverythingthathappensisanexplicitresultofactionstakenbythe
program.Therearetwosituationsthatbreakthissimpleparadigminwhichthevalueofa
memorylocationmightchangeoutsidethescopeofaparticularfunctioncurrentlyexecuting:
1)interruptsand
2)input/outputports.
Aninterruptisahardwarerequestedsoftwareaction.Considerthefollowingmultithreaded
interruptexample.Thereisaforegroundthreadcalledmain(),whichwesetupastheusualmain
programthatallCprogramshave.Then,thereisabackgroundthreadcalled
SysTick_Handler(),whichwesetuptobeexecutedonaperiodicbasis(e.g.,every16ms).Both
threadsaccesstheglobalvariable,Time.Theinterruptthreadincrementstheglobalvariable,and
theforegroundthreadwaitsfortimetoreach100.NoticethatTimechangesvalueoutsidethe
influenceofthemain()program.
volatileunsignedlongTime;
voidSysTick_Handler(void){/*every16ms*/
http://users.ece.utexas.edu/~valvano/embed/chap4/chap4.htm

3/11

2/3/2015

Chapter4:VariablesandConstantsValvano

Time=Time+1;
}
voidmain(void){
SysTick_Init();
Time=0;
while(Time<100){};/*waitfor100countsofthe16mstimer*/
}

Listing46:Anexampleshowingsharedaccesstoacommonglobalvariable
Withoutthevolatilemodifierthecompilermightlookatthetwostatements:
Time=0;
while(Time<100){};

andconcludethatsincethewhileloopdoesnotmodifyTime,itcouldneverreach100.Some
compilersmightattempttomovethereadTimeoperation,performingitoncebeforethewhile
loopisexecuted.Thevolatilemodifierdisablestheoptimization,forcingtheprogramtofetcha
newvaluefromthevariableeachtimethevariableisaccessed.
Inthenextexample,assumePORTAisaninputportcontainingthecurrentstatusofsome
importantexternalsignals.Theprogramwishestocollectstatusversustimedataofthese
externalsignals.
unsignedchardata[100];
#defineGPIO_PORTA_DATA_R(*((volatileunsignedlong*)0x400043FC))
voidCollect(void){shorti;
for(i=0;i<100;i++){/*collect100measurements*/
data[i]=GPIO_PORTA_DATA_R;/*collectithmeasurement*/
}
}

Listing47:Exampleshowedsharedaccesstoacommonglobalvariable
WithoutthevolatilemodifierinthePORTAdefinition,thecompilermightoptimizetheforloop,
readingPORTAonce,thenstoring100identicalcopiesintothedataarray.I/Oportswillbe
handledinmoredetailinChapter7onpointers.
Automatics
Automaticvariables,ontheotherhand,donothavefixedmemorylocations.Theyare
dynamicallyallocatedwhentheblockinwhichtheyaredefinedisentered,andtheyare
discardeduponleavingthatblock.Whenthereareafewvariables,theyareallocatedinregisters.
However,whentherearealotoflocalvariables,theyareallocatedonthestackbysubtracting4
fromtheSPforeach32bitvariable.Sinceautomaticobjectsexistonlywithinblocks,theycan
onlybedeclaredlocally.Automaticvariablescanonlybereferenced(readorwrite)bythe
functionthatcreatedit.Inthisway,theinformationisprotectedorlocaltothefunction.
Whenalocalvariableiscreatedithasnodependableinitialvalue.Itmustbesettoaninitial
valuebymeansofanassignmentoperation.Cprovidesforautomaticvariablestobeinitialized
intheirdeclarations,likeglobals.Itdoesthisbygenerating"hidden"codethatassignsvalues
automaticallyaftervariablesareallocatedspace.
Itistemptingtoforgetthatautomaticvariablesgoawaywhentheblockinwhichtheyare
definedexits.ThissometimesleadsnewCprogrammerstofallintothe"danglingreference"trap
inwhichafunctionreturnsapointertoalocalvariable,asillustratedby
int*BadFunction(void){
http://users.ece.utexas.edu/~valvano/embed/chap4/chap4.htm

4/11

2/3/2015

Chapter4:VariablesandConstantsValvano

intz;
z=1000;
return(&z);
}

Listing48:Exampleshowinganillegalreferencetoalocalvariable
Whencallersusethereturnedaddressofztheywillfindthemselvesmessingaroundwiththe
stackspacethatzusedtooccupy.ThistypeoferrorisNOTflaggedasasyntaxerror,butrather
willcauseunexpectedbehaviorduringexecution.

Implementationofautomaticvariables
ForinformationonhowlocalvariablesareimplementedontheARMCortexMseeChapter7of
EmbeddedSystems:IntroductiontoARMCortexMMicrocontrollersbyJonathanW.Valvano.
Iflocalsaredynamicallyallocatedatunspecifiedmemory(stack)locations,thenhowdoesthe
programfindthem?Thisisdonebyusingthestackpointer(SP)todesignateastackframefor
thecurrentlyactivefunction.
voidfun(void){longy1,y2,y3;/*3localvariables*/
y1=1000;
y2=2000;
y3=y1+y2;
}
funSUBSP,#12;allocate3localvariables
;y1=1000
LDRR0,=1000
STRR0,[SP,#0]
;y2=2000
LDRR0,=2000
STRR0,[SP,#4]
;y3=y1+y2
LDRR0,[SP,#0];y1
LDRR1,[SP,#4];y2
ADDR2,R0,R1
STRR2,[SP,#8];sety3
ADDSP,#12;deallocate
BXLR

Listing49:Exampleshowingthreelocalvariables

Aconstantlocalissimilartotheregularlocal.Justaswiththeotherlocals,theconstantis
definedtemporarilyonthestack.Thedifferenceisthattheconstantlocalcannotbechanged.
Theassemblylanguagecodegeneratedbythecompilerthataccessestheconstantlocalis
identicaltotheregularlocal.
shortTheGlobal;/*aregularglobalvariable*/
voidmain(void){
constshortTheConstant=1000;/*aconstantlocal*/
TheGlobal=TheConstant;
}

Listing410:Exampleshowingaconstantlocal
Externals
http://users.ece.utexas.edu/~valvano/embed/chap4/chap4.htm

5/11

2/3/2015

Chapter4:VariablesandConstantsValvano

Objectsthataredefinedoutsideofthepresentsourcemodulehavetheexternalstorageclass.
Thismeansthat,althoughthecompilerknowswhattheyare(signed/unsigned,8bit16bit32bit
etc.),ithasnoideawheretheyare.Itsimplyreferstothembynamewithoutreservingspacefor
them.Thenwhenthelinkerbringstogethertheobjectmodules,itresolvesthese"pending"
referencesbyfindingtheexternalobjectsandinsertingtheiraddressesintotheinstructionsthat
refertothem.Thecompilerknowsanexternalvariablebythekeywordexternthatmustprecede
itsdeclaration.
Onlyglobaldeclarationscanbedesignatedexternandonlyglobalsinothermodulescanbe
referencedasexternal.
Thefollowingexamplesetsanexternalglobal,calledExtGlobal,tothevalue1000.Thisglobal
canbereferencedbyanyfunctionfromanyfileinthesoftwaresystem.Itistrulyglobal.
externshortExtGlobal;/*anexternalglobalvariable*/
voidmain(void){
ExtGlobal=1000;
}

Listing411:Exampleshowinganexternalglobal

Scope
Thescopeofavariableistheportionoftheprogramfromwhichitcanbereferenced.Wemight
saythatavariable'sscopeisthepartoftheprogramthat"knows"or"sees"thevariable.Aswe
shallsee,differentrulesdeterminethescopesofglobalandlocalobjects.
Whenavariableisdeclaredglobally(outsideofafunction)itsscopeisthepartofthesourcefile
thatfollowsthedeclarationanyfunctionfollowingthedeclarationcanrefertoit.Functionsthat
precedethedeclarationcannotrefertoit.MostCcompilerswouldissueanerrormessageinthat
case.
Thescopeoflocalvariablesistheblockinwhichtheyaredeclared.Localdeclarationsmustbe
groupedtogetherbeforethefirstexecutablestatementintheblockattheheadoftheblock.This
isdifferentfromC++thatallowslocalvariablestobedeclaredanywhereinthefunction.It
followsthatthescopeofalocalvariableeffectivelyincludesalloftheblockinwhichitis
declared.Sinceblockscanbenested,italsofollowsthatlocalvariablesareseeninallblocksthat
arecontainedintheonethatdeclaresthevariables.
Ifwedeclarealocalvariablewiththesamenameasaglobalobjectoranotherlocalinasuperior
block,thenewvariabletemporarilysupersedesthehigherleveldeclarations.Considerthe
followingprogram.
unsignedcharx;/*aregularglobalvariable*/
voidsub(void){
x=1;
{unsignedcharx;/*alocalvariable*/
x=2;
{unsignedcharx;/*alocalvariable*/
x=3;
PORTA=x;}
PORTA=x;}
PORTA=x;}
}

Listing412:Anexampleshowingthescopeoflocalvariables
http://users.ece.utexas.edu/~valvano/embed/chap4/chap4.htm

6/11

2/3/2015

Chapter4:VariablesandConstantsValvano

Thisprogramdeclaresvariableswiththenamex,assignsvaluestothem,andoutputsthemto
PORTAwithinsuchawaythat,whenweconsideritsoutput,thescopeofitsdeclarations
becomesclear.Whenthisprogramruns,itoutputs321.Thisonlymakessenseifthexdeclared
intheinnermostblockmasksthehigherleveldeclarationssothatitreceivesthevalue'3'
withoutdestroyingthehigherlevelvariables.Likewisethesecondxisassigned'2'whichit
retainsthroughouttheexecutionoftheinnermostblock.Finally,theglobalx,whichisassigned
'1',isnotaffectedbytheexecutionofthetwoinnerblocks.Notice,too,thattheplacementofthe
lasttwoPORTA=xstatementsdemonstratesthatleavingablockeffectivelyunmasksobjects
thatwerehiddenbydeclarationsintheblock.ThesecondPORTA=xseesthemiddlexandthe
lastPORTA=xseestheglobalx.
Thismaskingofhigherleveldeclarationsisanadvantage,sinceitallowstheprogrammerto
declarelocalvariablesfortemporaryusewithoutregardforotherusesofthesamenames.
OneofthemistakesaC++programmermakeswhenwritingCcodeistryingtodefinelocal
variablesinthemiddleofablock.InClocalvariablesmustbedefinedatthebeginningofa
block.ThefollowingexampleisproperC++code,butresultsinasyntaxerrorinC.
voidsub(void){intx;/*avalidlocalvariabledeclaration*/
x=1;
inty;/*Thisdeclarationisimproper*/
y=2;
}

Listing413:Exampleshowinganillegallocalvariabledeclaration

Declarations
UnlikeBASICandFORTRAN,whichwillautomaticallydeclarevariableswhentheyarefirst
used,everyvariableinCmustbedeclaredfirst.Thismayseemunnecessary,butwhenwe
considerhowmuchtimeisspentdebuggingBASICandFORTRANprogramssimplybecause
misspelledvariablenamesarenotcaughtforus,itbecomesobviousthatthetimespentdeclaring
variablesbeforehandistimewellspent.Declarationsalsoforceustoconsidertheprecision(8
bit,16bitetc.)andformat(unsignedvs.signed)ofeachvariable.
AswesawinChapter1,describingavariableinvolvestwoactions.Thefirstactionisdeclaring
itstypeandthesecondactionisdefiningitinmemory(reservingaplaceforit).Althoughboth
ofthesemaybeinvolved,werefertotheCconstructthataccomplishesthemasadeclaration.
Aswesawabove,ifthedeclarationisprecededbyexternitonlydeclaresthetypeofthe
variables,withoutreservingspaceforthem.Insuchcases,thedefinitionmustexistinanother
sourcefile.Failuretodoso,willresultinanunresolvedreferenceerroratlinktime.
Table41containsexamplesoflegitimatevariabledeclarations.Noticethatthedeclarationsare
introducedbyoneortypekeywordsthatstatesthedatatypeofthevariableslisted.Thekeyword
chardeclares8bitvalues,intdeclares16bitvalues,shortdeclares16bitvaluesandlong
declares32bitvalues.Unlessthemodifierunsignedispresent,thevariablesdeclaredbythese
statementsareassumedbythecompilertocontainsignedvalues.Youcouldaddthekeyword
signedbeforethedatatypetoclarifyitstype.
Whenmorethanonevariableisbeingdeclared,theyarewrittenasalistwiththeindividual
namesseparatedbycommas.EachdeclarationisterminatedwithasemicolonasareallsimpleC
statements.
Declaration

Comment

http://users.ece.utexas.edu/~valvano/embed/chap4/chap4.htm

Range
7/11

2/3/2015

Chapter4:VariablesandConstantsValvano

unsignedcharuc
charc1,c2,c3
unsignedintui
inti1,i2
unsignedshortus
shorts1,s2
longl1,l2,l3,l4
unsignedlongui
floatf1,f2
doubled1,d2

8bitunsignednumber
three8bitsignednumbers
32bitunsignednumber
two32bitsignednumbers
16bitunsignednumber
two16bitsignednumbers
foursigned32bitintegers
32bitunsignednumber
two32bitfloatingnumbers
two64bitfloatingnumbers

0to+255
128to+127
0to+4294967296
2147483648Lto2147483647L
0to+65535
32768to+32767
2147483648Lto2147483647L
0to+4294967296
notrecommended
notrecommended

Table41:VariableDeclarations

Thecompilerallowstheregistermodifierforautomaticvariables,butitmaystilldefines
registerlocalsonthestack.Thekeywordscharintshortlongspecifytheprecisionofthe
variable.Thefollowingtablesshowstheavailablemodifiersforvariables.
Modifier
auto
extern
static
register

Comment
automatic,allocatedonthestack
definedinsomeotherprogramfile
permanentlyallocated
attempttoimplementanautomaticusingaregisterinsteadofonthe
stack

Table42:Variablestorageclasses

Modifier
volatile
const
unsigned
signed

Comment
canchangevaluebymeansotherthanthecurrentprogram
fixedvalue,definedinthesourcecodeandcannotbechanged
duringexecution
rangestartswith0includesonlypositivevalues
rangeincludesbothnegativeandpositivevalues

Table43Variablemodifiers
RefertotheAppendix1:CDeclarationsAShortPrimerforabriefPrimeronhowtoreadand
writedeclarationsinC.
Inallcasesconstmeansthevariablehasafixedvalueandcannotbechanged.Whendefininga
constantglobalonanembeddedsystemliketheCortexM,theparameterwillbeallocatedin
ROM.Inthefollowingexample,RetisallocatedinROM.Whenconstisaddedtoaparameter
oralocalvariable,itmeansthatparametercannotbemodifiedbythefunction.Itdoesnot
changewheretheparameterisallocated.Forexample,thisexampleislegal.
unsignedcharconstRet=13
voidLegalFuntion(shortin){
while(in){
UART_OutChar(Ret)
in
}
}
Ontheotherhand,thisexampleisnotlegalbecausethefunctionattemptstomodifytheinput
parameter.ininthisexamplewouldhavebeenallocatedonthestackorinaregister.
http://users.ece.utexas.edu/~valvano/embed/chap4/chap4.htm

8/11

2/3/2015

Chapter4:VariablesandConstantsValvano

voidNotLegalFuntion(constshortin){
while(in){
UART_OutChar(13)
in//thisoperationisillegal
}
}
Similarly,thisexampleisnotlegalbecausethefunctionattemptstomodifythelocalvariable.
countinthisexamplewouldhavebeenallocatedonthestackorinaregister.
voidNotLegalFuntion2(void){constshortcount=5
while(count){
UART_OutChar(13)
count//thisoperationisillegal
}
}
Asweshallsee,asimilarsyntaxisusedtodeclarepointers,arrays,andfunctions(Chapters7,8,
and10).
CharacterVariables
Charactervariablesarestoredas8bitquantities.Whentheyarefetchedfrommemory,theyare
alwayspromotedautomaticallyto32bitintegers.Unsigned8bitvaluesarepromotedbyadding
24zerosintothemostsignificantbits.Signedvaluesarepromotedbycopingthesignbit(bit7)
intothe24mostsignificantbits.
Thereisaconfusionwhensignedandunsignedvariablesaremixedintothesameexpression.It
isgoodprogrammingpracticetoavoidsuchconfusions.Aswithintegers,whenasigned
characterentersintoanoperationwithanunsignedquantity,thecharacterisinterpretedas
thoughitwasunsigned.Theresultofsuchoperationsisalsounsigned.Whenasignedcharacter
joinswithanothersignedquantity,theresultisalsosigned.
charx;/*signed8bitglobal*/
unsignedshorty;/*unsignedsigned16bitglobal*/
voidsub(void){
y=y+x;
/*xtreatedasunsignedeventhoughdefinedassigned*/
}

Listing413:Anexampleshowingthemixtureofsignedandunsignedvariables
Thereisalsoaneedtochangethesizeofcharacterswhentheyarestored,sincetheyare
representedintheCPUas32bitvalues.Inthiscase,however,itmattersnotwhethertheyare
signedorunsigned.Obviouslythereisonlyonereasonablewaytoputa32bitquantityintoan
8bitlocation.Whenthehighorder24bitsarechoppedoff,anerrormightoccur.Itisthe
programmer'sresponsibilitytoensurethatsignificantbitsarenotlostwhencharactersarestored.
WhenDoWeUseAutomaticsVersusStatics?
Becausetheircontentsareallowedtochange,allvariablesmustbeallocatedinRAMandnot
ROM.Anautomaticvariablecontainstemporaryinformationusedonlybyonesoftware
module.Aswesaw,automaticvariablesaretypicallyallocated,used,thendeallocatedfromthe
stack.Sinceaninterruptwillsaveregistersandcreateitsownstackframe,theuseofautomatic
variablesisimportantforcreatingreentrantsoftware.Automaticvariablesprovideprotection
limitingthescopeofaccessinsuchawaythatonlytheprogramthatcreatedthelocalvariable
canaccessit.Theinformationstoredinanautomaticvariableisnotpermanent.Thismeansifwe
storeavalueintoanautomaticvariableduringoneexecutionofthemodule,thenexttimethat
http://users.ece.utexas.edu/~valvano/embed/chap4/chap4.htm

9/11

2/3/2015

Chapter4:VariablesandConstantsValvano

moduleisexecutedthepreviousvalueisnotavailable.Typicallyweuseautomaticsforloop
counters,temporarysums.Weuseanautomaticvariabletostoredatathatistemporaryinnature.
Insummary,reasonswhyweplaceautomaticvariablesonthestackinclude
dynamicallocationreleaseallowsforreuseofmemory
limitedscopeofaccessprovidesfordataprotection
canbemadereentrant.
limitedscopeofaccessprovidesfordataprotection
sinceabsoluteaddressingisnotused,thecodeisrelocatable
thenumberofvariablesisonlylimitedbythesizeofthestackallocation.
Astaticvariableisinformationsharedbymorethanoneprogrammodule.E.g.,weuseglobals
topassdatabetweenthemain(orforeground)processandaninterrupt(orbackground)process.
Staticvariablesarenotdeallocated.Theinformationtheystoreispermanent.Wecanusestatic
variablesforthetimeofday,date,username,temperature,pointerstoshareddata.The
Metrowerkscompilerusesabsoluteaddressing(directorextended)toaccessthestaticvariables.
Initializationofvariablesandconstants
Mostprogramminglanguagesprovidewaysofspecifyinginitialvaluesthatis,thevaluesthat
variableshavewhenprogramexecutionbegins.WesawearlierthattheMetrowerkscompiler
willinitiallysetallstaticvariablestozero.Constantsmustbeinitializedatthetimetheyare
declared,andwehavetheoptionofinitializingthevariables.
Specifyinginitialvaluesissimple.Initsdeclaration,wefollowavariable'snamewithanequal
signandaconstantexpressionforthedesiredvalue.Thus
shortTemperature=55;

declaresTemperaturetobea16bitsignedinteger,andgivesitaninitialvalueof55.Character
constantswithbackslashescapesequencesarepermitted.Thus
charLetter='\t';

declaresLettertobeacharacter,andgivesitthevalueofthetabcharacter.Ifarrayelementsare
beinginitialized,alistofconstantexpressions,separatedbycommasandenclosedinbraces,is
written.Forexample,
constunsignedshortSteps[4]={10,9,6,5};

declaresStepstobeanunsigned16bitconstantintegerarray,andgivesitselementsthevalues
10,9,6,and5respectively.Ifthesizeofthearrayisnotspecified,itisdeterminedbythe
numberofinitializers.Thus
charWaveform[]={28,27,60,30,40,50,60};

declaresWaveformtobeasigned8bitarrayof7elementswhichareinitializedtothe
28,27,60,30,40,50,60.Ontheotherhand,ifthesizeofthearrayisgivenandifitexceedsthe
numberofinitializers,theleadingelementsareinitializedandthetrailingelementsdefaultto
zero.Therefore,
charWaveform[100]={28,27,60,30,40,50,60};

declaresWaveformtobeanintegerarrayof100elements,thefirst7elementsofwhichare
initializedtothe28,27,60,30,40,50,60andtheotherstozero.Finally,ifthesizeofanarrayis
givenandtherearetoomanyinitializers,thecompilergeneratesanerrormessage.Inthatcase,
http://users.ece.utexas.edu/~valvano/embed/chap4/chap4.htm

10/11

2/3/2015

Chapter4:VariablesandConstantsValvano

theprogrammermustbeconfused.
Characterarraysandcharacterpointersmaybeinitializedwithacharacterstring.Inthesecases,
aterminatingzeroisautomaticallygenerated.Forexample,
charName[4]="Jon";

declaresNametobeacharacterarrayoffourelementswiththefirstthreeinitializedto'J','o',and
'n'respectively.Thefourthelementcontainszero.Ifthesizeofthearrayisnotgiven,itwillbe
settothesizeofthestringplusone.Thuscain
charName[]="Jon";

alsocontainsthesamefourelements.Ifthesizeisgivenandthestringisshorter,trailing
elementsdefaulttozero.Forexample,thearraydeclaredby
charName[6]="Jon";

containszeroesinitslastthreeelements.Ifthestringislongerthanthespecifiedsizeofthe
array,thearraysizeisincreasedtomatch.Ifwewrite
char*NamePt="Jon";

theeffectisquitedifferentfrominitializinganarray.Firstaword(16bits)issetasideforthe
pointeritself.Thispointeristhengiventheaddressofthestring.Then,beginningwiththatbyte,
thestringanditszeroterminatorareassembled.TheresultisthatNamePtcontainstheaddressof
thestring"Jon".TheImagecraftandMetrowerkscompilersacceptinitializersforcharacter
variables,pointers,andarrays,andforintegervariablesandarrays.Theinitializersthemselves
maybeeitherconstantexpressions,listsofconstantexpressions,orstrings.
Implementationoftheinitialization
ThecompilerinitializesstaticconstantssimplybydefiningitsvalueinROM.Inthefollowing
example,Jisastaticconstant(actuallyKisaliteral)
shortI;/*16bitglobal*/
constshortJ=96;/*16bitconstant*/
#defineK97;
voidmain(void){
I=J;
I=K;}

Listing414:Anexampleshowingtheinitializationofastaticconstant
Eventhoughthefollowingtwoapplicationsofglobalvariablearetechnicallyproper,theexplicit
initializationofglobalvariablesinmyopinionisabetterstyle.
/*poorstyle*//*goodstyle*/
intI=95;intI;
voidmain(void){voidmain(void){
I=95;
}}

Opinion:Ifirmlybelieveagoodunderstandingoftheassemblycodegeneratedbyourcompiler
makesusbetterprogrammers.
GotoChapter5onExpressionsReturntoTableofContents
http://users.ece.utexas.edu/~valvano/embed/chap4/chap4.htm

11/11

2/3/2015

Chapter5:ExpressionsValvano

Chapter5:Expressions
What'sinChapter5?
Precedenceandassociativity
Unaryoperators
Binaryoperators
Assignmentoperators
Expressiontypeandexplicitcasting
Selectionoperator
Arithmeticoverflowandunderflow
Mostprogramminglanguagessupportthetraditionalconceptofanexpressionasacombinationofconstants,variables,arrayelements,andfunctioncalls
joinedbyvariousoperators(+,,etc.)toproduceasinglenumericvalue.Eachoperatorisappliedtooneortwooperands(thevaluesoperatedon)to
produceasinglevaluewhichmayitselfbeanoperandforanotheroperator.ThisideaisgeneralizedinCbyincludingnontraditionaldatatypesandarich
setofoperators.Pointers,unsubscriptedarraynames,andfunctionnamesareallowedasoperands.And,asTables51through56illustrate,many
operatorsareavailable.Alloftheseoperatorscanbecombinedinanyusefulmannerinanexpression.Asaresult,Callowsthewritingverycompactand
efficientexpressionswhichatfirstglancemayseemabitstrange.AnotherunusualfeatureofCisthatanywherethesyntaxcallsforanexpression,alistof
expressions,withcommaseparators,mayappear.
Precedenceandassociativity
Thebasicprobleminevaluatingexpressionsisdecidingwhichpartsofanexpressionaretobeassociatedwithwhichoperators.Toeliminateambiguity,
operatorsaregiventhreeproperties:operandcount,precedence,andassociativity.
Operandcountreferstotheclassificationofoperatorsasunary,binary,orternaryaccordingtowhethertheyoperateonone,two,orthreeoperands.The
unaryminussign,forinstance,reversesthesignofthefollowingoperand,whereasthebinaryminussignsubtractsoneoperandfromanother.
Thefollowingexampleconvertsthedistancexininchestoadistanceyincm.Withoutparenthesesthefollowingstatementseemsambiguous
y=254*x/100;

Ifwedividefirst,thenycanonlytakeonvaluesthataremultiplesof254(e.g.,0254508etc.)Sothefollowingstatementisincorrect.
y=254*(x/100);

Theproperapproachistomultiplyfirstthendivide.Tomultiplyfirstwemustguaranteethattheproduct254*xwillnotoverflowtheprecisionofthe
computer.Howdoweknowwhatprecisionthecompilerusedfortheintermediateresult254*x?Toanswerthisquestion,wemustobservetheassembly
codegeneratedbythecompiler.Sincemultiplicationanddivisionassociatelefttoright,thefirststatementwithoutparenthesesalthoughambiguouswill
actuallycalculatethecorrectanswer.Itisgoodprogrammingstyletouseparenthesestoclarifytheexpression.Sothislaststatementhasbothgoodstyle
andpropercalculation.
y=(254*x)/100;

TheissuesofprecedenceandassociativitywereexplainedinChapter1.Precedencedefinestheevaluationorder.Forexampletheexpression3+4*2willbe
11becausemultiplicationasprecedenceoveraddition.Associativitydeterminestheorderofexecutionforoperatorsthathavethesameprecedence.For
example,theexpression1032willbe5,becausesubtractionassociateslefttoright.Ontheotherhand,ifxandyareinitially10,thentheexpression
x+=y+=1willfirstmakey=y+1(11),thenmakex=x+y(21)becausetheoperator+=associatesrighttoleft.Thetablefromchapter1isrepeatedforyour
convenience.
Precedence
highest

Operators
()[].>++(postfix)(postfix)
++(prefix)(prefix)!~sizeof(type)+(unary)(unary)&(address)*
(dereference)
*/%
+
<<>>
<<=>>=
==!=
&
^
|
&&
||
?:
=+==*=/=%=<<=>>=|=&=^=
,

lowest

Associativity
lefttoright
righttoleft
lefttoright
lefttoright
lefttoright
lefttoright
lefttoright
lefttoright
lefttoright
lefttoright
lefttoright
lefttoright
righttoleft
righttoleft
lefttoright

Table14:Precedenceandassociativitydeterminetheorderofoperation
Unaryoperators
Webeginwiththeunaryoperators,whichtakeasingleinputandgiveasingleoutput.Inthefollowingexamples,assumeallnumbersare16bitsigned
(short).Thefollowingvariablesarelisted
shortdata;/*32767to+32767*/
short*pt;/*pointertomemory*/
shortflag;/*0isfalse,notzeroistrue*/
operator

meaning

~
!

binarycomplement
logicalcomplement
addressof
negate
positive
preincrement
predecrement

&

+
++

example
~0x1234
!flag
&data
100
+100
++data
data

http://users.ece.utexas.edu/~valvano/embed/chap5/chap5.htm

result
0xEDCB
flip0to1andnotzeroto0
addressinmemorywheredataisstored
negative100
100
data=data+1,thenresultisdata
data=data1,thenresultisdata
1/7

2/3/2015

Chapter5:ExpressionsValvano
*

reference

*pt

16bitinformationpointedtobypt

Table5.1:Unaryprefixoperators.
operator

meaning

++

postincrement
postdecrement

example
data++
data

result
resultisdata,thendata=data+1
resultisdata,thendata=data+1

Table5.2:Unarypostfixoperators.

Binaryoperators
Nextwelistthebinaryarithmeticoperators,whichoperateontwonumberinputsgivingasinglenumberresult.Theoperationsofaddition,subtractionand
shiftleftarethesameindependentofwhetherthenumbersaresignedorunsigned.Aswewillseelater,overflowandunderflowafteranaddition,
subtractionandshiftleftaredifferentforsignedandunsignednumbers,buttheoperationitselfisthesame.Ontheotherhandmultiplication,division,and
shiftrighthavedifferentfunctionsdependingonwhetherthenumbersaresignedorunsigned.Itwillbeimportant,therefore,toavoidmultiplyingor
dividinganunsignednumberwithasignednumber.
operator

meaning

addition
subtraction
multiplication
division
remainder
shiftleft
shiftright

*
/
%
<<
>>

example
100+300
100300
10*300
123/10
123%10
102<<2
102>>2

result
400
200
3000
12
3
408
25

Table5.3:Binaryarithmeticoperators.

Thebinarybitwiselogicaloperatorstaketwoinputsandgiveasingleresult.
operator

meaning

&

bitwiseand
bitwiseor
bitwiseexclusiveor

|
^

example
0x1234&0x00FF
0x1234|0x00FF
0x1234^0x00FF

result
0x0034
0x12FF
0x12CB

Table5.4:Binarybitwiselogicaloperators.

ThebinaryBooleanoperatorstaketwoBooleaninputsandgiveasingleBooleanresult.
operator meaning
&&
||

and
or

example
0&&1
0||1

result
0(false)
1(true)

Table5.5:BinaryBooleanoperators.

ManyprogrammersconfusethelogicaloperatorswiththeBooleanoperators.Logicaloperatorstaketwonumbersandperformabitwiselogicaloperation.
BooleanoperatorstaketwoBooleaninputs(0andnotzero)andreturnaBoolean(0or1).Intheprogrambelow,theoperationc=a&b;willperformabitwise
logicalandof0x0F0Fand0xF0F0resultingin0x0000.Inthed=a&&b;expression,thevalueaisconsideredasatrue(becauseitisnotzero)andthevalue
balsoisconsideredatrue(notzero).TheBooleanoperationoftrueandtruegivesatrueresult(1).
shorta,b,c,d;
intmain(void){a=0x0F0F;b=F0F0;
c=a&b;/*logicalresultcwillbe0x0000*/
d=a&&b;/*Booleanresultdwillbe1(true)*/
return1;
}

Listing51:IllustrationofthedifferencebetweenlogicalandBooleanoperators
ThebinaryrelationaloperatorstaketwonumberinputsandgiveasingleBooleanresult.
example
equal
100==200
notequal
100!=200
lessthan
100<200
lessthanorequal 100<=200
greaterthan
100>200
greaterthanorequal 100>=200

operator meaning
==
!=

<
<=
>
>=

result
0(false)
1(true)
1(true)
1(true)
0(false)
0(false)

Table5.6:Binaryrelationaloperators.
Someprogrammersconfuseassignmentequalswiththerelationalequals.Inthefollowingexample,thefirstifwillexecutethesubfunction()ifaisequal
tozero(aisnotmodified).Inthesecondcase,thevariablebissettozero,andthesubfunction()willneverbeexecutedbecausetheresultoftheequals
assignmentisthevalue(inthiscasethe0meansfalse).
shorta,b;
voidprogram(void){
if(a==0)subfunction();/*executesubfunctionifaiszero*/
if(b=0)subfunction();/*setbtozero,neverexecutesubfunction*/
}

Listing52:Illustrationofthedifferencebetweenrelationalandassignmentequals
http://users.ece.utexas.edu/~valvano/embed/chap5/chap5.htm

2/7

2/3/2015

Chapter5:ExpressionsValvano

BeforelookingatthekindsofexpressionswecanwriteinC,wewillfirstconsidertheprocessofevaluatingexpressionsandsomegeneralpropertiesof
operators.
AssignmentOperators
Theassignmentoperatorisusedtostoredataintovariables.Thesyntaxisvariable=expression;wherevariablehasbeenpreviouslydefined.Atruntime,
theresultoftheexpressionissavedintothevariable.Ifthetypeoftheexpressionisdifferentfromthevariable,thentheresultisautomaticallyconverted.
Formoreinformationabouttypesandconversion,seeexpressiontypeandexplicitcasting.Theassignmentoperationitselfhasaresult,sotheassignment
operationcanbenested.
shorta,b;
voidinitialize(void){
a=b=0;/*setbothvariablestozero*/
}

Listing53:Exampleofanestedassignmentoperation
Theread/modifywriteassignmentoperatorsareconvenient.Examplesareshownbelow.
shorta,b;
voidinitialize(void){
a+=b;/*sameasa=a+b*/
a=b;/*sameasa=ab*/
a*=b;/*sameasa=a*b*/
a/=b;/*sameasa=a/b*/
a%=b;/*sameasa=a%b*/
a<<=b;/*sameasa=a<<b*/
a<<=b;/*sameasa=a<<b*/
a>>=b;/*sameasa=a>>b*/
a|=b;/*sameasa=a|b*/
a&=b;/*sameasa=a&b*/
a^=b;/*sameasa=a^b*/
}

Listing54Listofallread/modify/writeassignmentoperations
Mostcompilerswillproducethesamecodefortheshortandlongversionoftheoperation.Thereforeyoushouldusetheread/modify/writeoperationsonly
insituationsthatmakethesoftwareeasiertounderstand.
voidfunction(void){
PORTA|=0x01;/*setPA0high*/
PORTB&=~0x80;/*clearPB7low*/
PORTC^=0x40;/*togglePC6*/
}

Listing55Goodexamplesofread/modify/writeassignmentoperations
ExpressionTypesandExplicitCasting
Wesawearlierthatnumbersarerepresentedinthecomputerusingawiderangeofformats.AlistoftheseformatsisgiveninTable5.7.Noticethatforthe
CortexM,theintandlongtypesarethesame.OntheotherhandwiththeFreescale9S12,theintandshorttypesarethesame.Thisdifferencemaycause
confusion,whenportingcodefromonesystemtoanother.Isuggestyouusetheinttypewhenyouareinterestedinefficiencyanddon'tcareabout
precision,andusetheshorttypewhenyouwantavariablewitha16bitprecision.
type
unsignedchar
char
unsignedint
int
unsignedshort
short
long
unsignedlong

range
precision
0to255
8bits
128to127
8bits
0to4294967295
32bits
2147483648to2147483647 32bits
0to65535U
16bits
32768to32767
16bits
2147483648to2147483647 32bits
0to4294967295
32bits

examplevariable
unsignedcharuc
charsc
unsignedintui
intsi
unsignedshortus
shortss
longsl
unsignedlongui

Table57.Availablenumberformatsforthecompiler
Anobviousquestionarises,whathappenswhentwonumbersofdifferenttypesareoperatedon?Beforeoperation,theCcompilerwillfirstconvertoneor
bothnumberssotheyhavethesametype.Theconversionofonetypeintoanotherhasmanynames:
automaticconversion,
implicitconversion,
coercion,
promotion,or
widening.
Therearethreewaystoconsiderthisissue.Thefirstwaytothinkaboutthisisiftherangeofonetypecompletelyfitswithintherangeoftheother,thenthe
numberwiththesmallerrangeisconverted(promoted)tothetypeofthenumberwiththelargerrange.Inthefollowingexamples,anumberoftype1is
addedtoanumberoftype2.Ineachcase,thenumberrangeoftype1fitsintotherangeoftype2,sotheparameteroftype1isfirstpromotedtotype2before
theaddition.
type1

type2

unsignedchar
unsignedchar
unsignedchar
char
char
unsignedshort
short

fitsinside
fitsinside
fitsinside
fitsinside
fitsinside
fitsinside
fitsinside

unsignedshort
short
long
short
long
long
long

example
uc+usisoftypeunsignedshort
uc+ssisoftypeshort
uc+slisoftypelong
sc+ssisoftypeshort
sc+slisoftypelong
us+slisoftypelong
ss+slisoftypelong

Table58.Whentherangeofonetypefitsinsidetherangeofanother,thenconversionissimple
Thesecondwaytoconsidermixedprecisionoperationsisthatinmostcasesthecompilerwillpromotethenumberwiththesmallerprecisionintotheother
typebeforeoperation.Ifthetwonumbersareofthesameprecision,thenthesignednumberisconvertedtounsigned.Theseautomaticconversionsmaynot
yieldcorrectresults.Thethirdandbestwaytodealwithmixedtypeoperationsistoperformtheconversionsexplicitlyusingthecastoperation.Wecan
forcethetypeofanexpressionbyexplicitlydefiningitstype.Thisapproachallowstheprogrammertoexplicitlychoosethetypeoftheoperation.Consider
http://users.ece.utexas.edu/~valvano/embed/chap5/chap5.htm

3/7

2/3/2015

Chapter5:ExpressionsValvano

thefollowingdigitalfilterwithmixedtypeoperations.Inthisexample,weexplicitlyconvertxandytosigned16bitnumbersandperform16bitsigned
arithmetic.Notethattheassignmentoftheresultintoy,willrequireademotionofthe16bitsignednumberinto8bitsigned.Unfortunately,Cdoesnot
provideanysimplemechanismsforerrordetection/correction(seeoverflowandunderflow.)
chary;//outputofthefilter
unsignedcharx;//inputofthefilter
voidfilter(void){
y=(12*(short)x+56*(short)y)/100;
}

Listing56:Examplesoftheselectionoperator
Weapplyanexplicitcastsimplybyprecedingthenumberorexpressionwithparenthesessurroundingthetype.Inthisnextdigitalfilterallnumbersareof
thesametype.Evenso,weareworriedthattheintermediateresultofthemultiplicationsandadditionsmightoverflowthe16bitarithmetic.Weknow
fromdigitalsignalprocessingthatthefinalresultwillalwaysfitintothe16bitvariable.Formoreinformationonthedesignandanalysisofdigitalfilters,
seeChapter5ofEmbeddedSystems:RealTimeOperatingSystemsforARMCortexMMicrocontrollersbyJonathanW.Valvano.Inthisexample,the
cast(long)willspecifythecalculationsbeperformedin32bitprecision.
//y(n)=[113*x(n)+113*x(n2)98*y(n2)]/128,channelspecifiestheA/Dchannel
shortx[3],y[3];//MACQscontainingcurrentandprevious
voidSysTick_Handler(void){
y[2]=y[1];y[1]=y[0];//shiftMACQ
x[2]=x[1];x[1]=x[0];
x[0]=A2D(channel);//newdata
y[0]=(113*((long)x[0]+(long)x[2])98*(long)y[2])>>7;}

Listing57:Wecanuseacasttoforcehigherprecisionarithmetic

WesawinChapter1,castingwasusedtoassignasymbolicnametoanI/Oport.Inparticularthefollowingdefinecaststhenumber0x400043FCasa
pointertype,whichpointstoanunsigned32bitdata.MoreaboutpointerscanbefoundinChapter7.
#defineGPIO_PORTA_DATA_R(*((volatileunsignedlong*)0x400043FC))

Selectionoperator
Theselectionoperatortakesthreeinputparametersandyieldsoneoutputresult.Theformatis
Expr1?Expr2:Expr3
Thefirstinputparameterisanexpression,Expr1,whichyieldsaboolean(0forfalse,notzerofortrue).Expr2andExpr3returnvaluesthatareregular
numbers.TheselectionoperatorwillreturntheresultofExpr2ifthevalueofExpr1istrue,andwillreturntheresultofExpr3ifthevalueofExpr1isfalse.
ThetypeoftheexpressionisdeterminedbythetypesofExpr2andExpr3.IfExpr2andExpr3havedifferenttypes,thentheusualpromotionisapplied.
Theresultingtimeisdeterminedatcompiletime,inasimilarmannerastheExpr2+Expr3operation,andnotatruntimedependingonthevalueofExpr1.
Thefollowingtwosubroutineshaveidenticalfunctions.
shorta,b;
voidsub1(void){
a=(b==1)?10:1;
}
voidsub2(void){
if(b==1)
a=10;
else
a=1;
}

Listing58:Examplesoftheselectionoperator

ArithmeticOverflowandUnderflow
Animportantissuewhenperformingarithmeticcalculationsonintegervaluesistheproblemofunderflowandoverflow.Arithmeticoperationsinclude
addition,subtraction,multiplication,divisionandshifting.Overflowandunderflowerrorscanoccurduringalloftheseoperations.Inassemblylanguage
theprogrammeriswarnedthatanerrorhasoccurredbecausetheprocessorwillsetconditioncodebitsaftereachoftheseoperations.Unfortunately,theC
compilerprovidesnodirectaccesstotheseerrorcodes,sowemustdevelopcarefulstrategiesfordealingwithoverflowandunderflow.Itisimportantto
rememberthatarithmeticoperations(addition,subtraction,multiplication,division,andshifting)haveconstraintswhenperformedwithfiniteprecisionon
amicrocomputer.Anoverflowerroroccurswhentheresultofanarithmeticoperationcannotfitintothefiniteprecisionoftheresult.Wewillstudy
additionandsubtractionoperationsindetail,butthetechniquesfordealingwithoverflowandunderflowwillapplytotheotherarithmeticoperationsas
well.Wewillconsidertwoapproaches
avoidingtheerror
detectingtheerrorthencorrectingtheresult
Forexamplewhentwo8bitnumbersareadded,thesummaynotfitbackintothe8bitresult.Wesawearlierthatthesamedigitalhardware(instructions)
couldbeusedtoaddandsubtractunsignedandsignednumbers.Unfortunately,wewillhavetodesignseparateoverflowdetectionforsignedandunsigned
additionandsubtraction.
Allmicrocomputershaveaconditioncoderegisterwhichcontainbitswhichspecifythestatusofthemostrecentoperation.Inthissection,wewill
introduce4conditioncodebitscommontomostmicrocomputers.Ifthetwoinputstoanadditionorsubtractionoperationareconsideredasunsigned,then
theCbit(carry)willbesetiftheresultdoesnotfit.Inotherwords,afteranunsignedaddition,theCbitissetiftheansweriswrong.Ifthetwoinputstoan
additionorsubtractionoperationareconsideredassigned,thentheVbit(overflow)willbesetiftheresultdoesnotfit.Inotherwords,afterasigned
addition,theVbitissetiftheansweriswrong.TheFreescale6805doesnothaveaVbit,thereforeitwillbedifficulttocheckforerrorsafteranoperation
onsignednumbers.
bitnamemeaningafteradditionorsubtraction
Nnegativeresultisnegative
Zzeroresultiszero
Voverflowsignedoverflow

http://users.ece.utexas.edu/~valvano/embed/chap5/chap5.htm

4/7

2/3/2015

Chapter5:ExpressionsValvano
Ccarryunsignedoverflow

Table5.9.Conditioncodebitscontainthestatusofthepreviousarithmeticorlogicaloperation.
Foran8bitunsignednumber,thereareonly256possiblevalues,0to255.Wecanthinkofthenumbersaspositionsalongacircle.Thereisadiscontinuity
atthe0|255interface,everywhereelseadjacentnumbersdifferby&plusmn1.Ifweaddtwounsignednumbers,westartatthepositionofthefirstnumber
amoveinaclockwisedirectionthenumberofstepsequaltothesecondnumber.Forexample,if96+64isperformedin8bitunsignedprecision,the
correctresultof160isobtained.Inthiscase,thecarrybitwillbe0signifyingtheansweriscorrect.Ontheotherhand,if224+64isperformedin8bit
unsignedprecision,theincorrectresultof32isobtained.Inthiscase,thecarrybitwillbe1,signifyingtheansweriswrong.

Figure51:8bitunsignedaddition.
Forsubtraction,westartatthepositionofthefirstnumberamoveinacounterclockwisedirectionthenumberofstepsequaltothesecondnumber.For
example,if16064isperformedin8bitunsignedprecision,thecorrectresultof96isobtained(carrybitwillbe0.)Ontheotherhand,if3264is
performedin8bitunsignedprecision,theincorrectresultof224isobtained(carrybitwillbe1.)

Figure52:8bitunsignedsubtraction.
Ingeneral,weseethatthecarrybitissetwhenwecrossoverfrom255to0whileaddingorcrossoverfrom0to255whilesubtracting.
Observation:Thecarrybit,C,issetafteranunsignedaddorsubtractwhentheresultisincorrect.
Foran8bitsignednumber,thepossiblevaluesrangefrom128to127.Againthereisadiscontinuity,butthistimeitexistsatthe128|127interface,
everywhereelseadjacentnumbersdifferby&plusmn1.Themeaningsofthenumberswithbit7=1aredifferentfromunsigned,butweaddandsubtract
signednumbersonthenumberwheelinasimilarway(e.g.,additionofapositivenumbermovesclockwise.)Addinganegativenumberisthesameas
subtractingapositivenumberhencethisoperationwouldcauseacounterclockwisemotion.Forexample,if32+64isperformed,thecorrectresultof32is
obtained.Inthiscase,theoverflowbitwillbe0signifyingtheansweriscorrect.Ontheotherhand,if96+64isperformed,theincorrectresultof96is
obtained.Inthiscase,theoverflowbitwillbe1signifyingtheansweriswrong.

Figure53:8bitsignedaddition.
Forsubtractingsignednumbers,weagainmoveinacounterclockwisedirection.Subtractinganegativenumberisthesameasaddingapositivenumber
hencethisoperationwouldcauseaclockwisemotion.Forexample,if3264isperformed,thecorrectresultof32isobtained(overflowbitwillbe0.)On
theotherhand,if9664isperformed,theincorrectresultof96isobtained(overflowbitwillbe1.)

Figure54:8bitsignedsubtraction.
Ingeneral,weseethattheoverflowbitissetwhenwecrossoverfrom127to128whileaddingorcrossoverfrom128to127whilesubtracting.
Observation:Theoverflowbit,V,issetafterasignedaddorsubtractwhentheresultisincorrect.
Anotherwaytodeterminetheoverflowbitafteranadditionistoconsiderthecarryoutofbit6.TheVbitwillbesetofthereisacarryoutofbit6(intobit
7)butnocarryoutofbit7(intotheCbit).Itisalsosetifthereisnocarryoutofbit6butthereisacarryoutofbit7.LetX7,X6,X5,X4,X3,X2,X1,X0and
http://users.ece.utexas.edu/~valvano/embed/chap5/chap5.htm

5/7

2/3/2015

Chapter5:ExpressionsValvano

M7,M6,M5,M4,M3,M2,M1,M0betheindividualbinarybitsofthetwo8bitnumberswhicharetobeadded,andletR7,R6,R5,R4,R3,R2,R1,R0be
individualbinarybitsofthe8bitsum.Then,the4conditioncodebitsafteranadditionareshowninTable5.10.

Table5.10.Conditioncodebitsafteran8bitadditionoperation.
LettheresultRbetheresultofthesubtractionXM.Then,the4conditioncodebitsareshowninTable5.11.

Table511.Conditioncodebitsafteran8bitsubtractionoperation.
CommonError:Ignoringoverflow(signedorunsigned)canresultinsignificanterrors.
Observation:Microcomputershavetwosetsofconditionalbranchinstructions(ifstatements)whichmakeprogramdecisionsbasedoneithertheCor
Vbit.
CommonError:Anerrorwilloccurifyouunsignedconditionalbranchinstructions(ifstatements)afteroperatingonsignednumbers,andviceversa.
Therearesomeapplicationswherearithmeticerrorsarenotpossible.Forexampleifwehadtwo8bitunsignednumbersthatweknewwereintherangeof
0to100,thennooverflowispossiblewhentheyareaddedtogether.
Typicallythenumbersweareprocessingareeithersignedorunsigned(butnotboth),soweneedonlyconsiderthecorrespondingCorVbit(butnotboth
theCandVbitsatthesametime.)Inotherwords,ifthetwonumbersareunsigned,thenwelookattheCbitandignoretheVbit.Conversely,ifthetwo
numbersaresigned,thenwelookattheVbitandignoretheCbit.Therearetwoappropriatemechanismstodealwiththepotentialforarithmeticerrors
whenaddingandsubtracting.Thefirstmechanism,usedbymostcompilers,iscalledpromotion.Promotioninvolvesincreasingtheprecisionoftheinput
numbers,andperformingtheoperationatthathigherprecision.Anerrorcanstilloccuriftheresultisstoredbackintothesmallerprecision.Fortunately,
theprogramhastheabilitytotesttheintermediateresulttoseeifitwillfitintothesmallerprecision.Topromoteanunsignednumberweaddzerostothe
leftside.Inapreviousexample,weaddedtheunsigned8bit224to64,andgotthewrongresultof32.Withpromotionwefirstconvertthetwo8bit
numbersto16bits,thenadd.
Wecancheckthe16bitintermediateresult(e.g.,228)toseeiftheanswerwillfitbackintothe8bitresult.Inthefollowingflowchart,XandMare8bit
unsignedinputs,X16,M16,andR16are16bitintermediatevalues,andRisan8bitunsignedoutput.Theovalsymbolrepresentstheentryandexitpoints,
therectangleisusedforcalculations,andthediamondshowsadecision.Laterinthebookwewilluseparallelogramsandtrapezoidstoperform
input/outputfunctions.

Figure55:Promotioncanbeusedtoavoidoverflowandunderflow.
Topromoteasignednumber,weduplicatethesignbitasweaddbinarydigitstotheleftside.Earlier,weperformedthe8bitsignedoperation9664and
gotasignedoverflow.Withpromotionwefirstconvertthetwonumbersto16bits,thensubtract.

Wecancheckthe16bitintermediateresult(e.g.,160)toseeiftheanswerwillfitbackintothe8bitresult.Inthefollowingflowchart,XandMare8bit
signedinputs,X16,M16,andR16are16bitsignedintermediatevalues,andRisan8bitsignedoutput.

http://users.ece.utexas.edu/~valvano/embed/chap5/chap5.htm

6/7

2/3/2015

Chapter5:ExpressionsValvano

Figure56:Promotioncanbeusedtoavoidoverflowandunderflow.

Theothermechanismforhandlingadditionandsubtractionerrorsiscalledceilingandfloor.Itisanalogoustomovementsinsidearoom.Ifwetrytomove
up(addapositivenumberorsubtractanegativenumber)theceilingwillpreventusfromexceedingtheboundsoftheroom.Similarly,ifwetrytomove
down(subtractapositivenumberoraddanegativenumber)thefloorwillpreventusfromgoingtoolow.Forour8bitadditionandsubtraction,wewill
preventthe0to255and255to0crossoversforunsignedoperationsand128to+127and+127to128crossoversforsignedoperations.Theseoperations
aredescribedbythefollowingflowcharts.Ifthecarrybitissetafteranunsignedadditiontheresultisadjustedtothelargestpossibleunsignednumber
(ceiling).Ifthecarrybitissetafteranunsignedsubtraction,theresultisadjustedtothesmallestpossibleunsignednumber(floor.)

Figure57:Inassemblylanguagewecandetectoverflowandunderflow.

Iftheoverflowbitissetafterasignedoperationtheresultisadjustedtothelargest(ceiling)orsmallest(floor)possiblesignednumberdependingon
whetheritwasa128to127crossover(N=0)or127to128crossover(N=1).Noticethatafterasignedoverflow,bit7oftheresultisalwayswrong
becausetherewasacrossover.

Figure58:Inassemblylanguagewecandetectoverflowandunderflow.

GotoChapter6onStatementsReturntoTableofContents

http://users.ece.utexas.edu/~valvano/embed/chap5/chap5.htm

7/7

2/3/2015

Chapter6:FlowofControlValvano

Chapter6:FlowofControl
What'sinChapter6?
Simplestatements
Compoundstatements
ifandifelsestatements
switchstatements
whilestatements
forstatements
dostatements
returnstatements
gotostatements
Nullstatements
Missingstatements
Everyprocedurallanguageprovidesstatementsfordeterminingtheflowofcontrolwithin
programs.Althoughdeclarationsareatypeofstatement,inCtheunqualifiedwordstatement
usuallyreferstoproceduralstatementsratherthandeclarations.Inthischapterweareconcerned
onlywithproceduralstatements.
IntheClanguage,statementscanbewrittenonlywithinthebodyofafunctionmore
specifically,onlywithincompoundstatements.Thenormalflowofcontrolamongstatementsis
sequential,proceedingfromonestatementtothenext.However,asweshallsee,mostofthe
statementsinCaredesignedtoalterthissequentialflowsothatalgorithmsofarbitrary
complexitycanbeimplemented.Thisisdonewithstatementsthatcontrolwhetherornotother
statementsexecuteand,ifso,howmanytimes.Furthermore,theabilitytowritecompound
statementspermitsthewritingasequenceofstatementswhereverasingle,possiblycontrolled,
statementisallowed.Thesetwofeaturesprovidethenecessarygeneralitytoimplementany
algorithm,andtodoitinastructuredway.
SimpleStatements
TheClanguageusessemicolonsasstatementterminators.Asemicolonfollowseverysimple
(noncompound)statement,eventhelastoneinasequence.
Whenonestatementcontrolsotherstatements,aterminatorisappliedonlytothecontrolled
statements.Thuswewouldwrite
if(x>5)x=0;else++x;

withtwosemicolons,notthree.Perhapsonegoodwaytorememberthisistothinkofstatements
thatcontrolotherstatementsas"super"statementsthat"contain"ordinary(simpleand
compound)statements.Thenrememberthatonlysimplestatementsareterminated.Thisimplies,
asstatedabove,thatcompoundstatementsarenotterminatedwithsemicolons.Thus
while(x<5){func();++x;}

isperfectlycorrect.Noticethateachofthesimplestatementswithinthecompoundstatementis
terminated.

CompoundStatements
http://users.ece.utexas.edu/~valvano/embed/chap6/chap6.htm

1/9

2/3/2015

Chapter6:FlowofControlValvano

Thetermscompoundstatementandblockbothrefertoacollectionofstatementsthatare
enclosedinbracestoformasingleunit.Compoundstatementshavetheform
{ObjectDeclaration?...Statement?...}

ObjectDeclaration?...isanoptionalsetoflocaldeclarations.Ifpresent,Crequiresthatthey
precedethestatementsinotherwords,theymustbewrittenattheheadoftheblock.
Statement?...isaseriesofzeroormoresimpleorcompoundstatements.Noticethatthereisnot
asemicolonattheendofablocktheclosingbracesufficestodelimittheend.Inthisexample
thelocalvariabletempisonlydefinedwithintheinnercompoundstatement.
intmain(void){shortn1,n2;
n1=1;n2=2;
{shorttemp;
temp=n1;n1=n2;n2=temp;/*switchn1,n2*/
}
return1;
}

Listing6.1:Examplesofacompoundstatements
Thepowerofcompoundstatementsderivesfromthefactthatonemaybeplacedanywherethe
syntaxcallsforastatement.Thusanystatementthatcontrolsotherstatementsisabletocontrol
unitsoflogicofanycomplexity.
Whencontrolpassesintoacompoundstatement,twothingshappen.First,spaceisreservedon
thestackforthestorageoflocalvariablesthataredeclaredattheheadoftheblock.Thenthe
executablestatementsareprocessed.
OneimportantlimitationinCisthatablockcontaininglocaldeclarationsmustbeentered
throughitsleadingbrace.Thisisbecausebypassingtheheadofablockeffectivelyskipsthe
logicthatreservesspaceforlocalobjects.Sincethegotoandswitchstatements(below)could
violatethisrule.

TheIfStatement
Ifstatementsprovideanoniterativechoicebetweenalternatepathsbasedonspecified
conditions.Theyhaveeitheroftwoforms
if(ExpressionList)Statement1

or
if(ExpressionList)Statement1
elseStatement2

ExpressionListisalistofoneormoreexpressionsandStatementisanysimpleorcompound
statement.First,ExpressionListisevaluatedandtested.Ifmorethanoneexpressionisgiven,
theyareevaluatedfromlefttorightandtherightmostexpressionistested.Iftheresultistrue
(nonzero),thentheStatement1isexecutedandtheStatement2(ifpresent)isskipped.Ifitis
false(zero),thenStatement1isskippedandStatement2(ifpresent)isexecuted.Inthisfirst
example,thefunctionisGreater()isexecutedifG2islargerthan100.
if(G2>100)isGreater();

http://users.ece.utexas.edu/~valvano/embed/chap6/chap6.htm

2/9

2/3/2015

Chapter6:FlowofControlValvano

Figure6.1:Exampleifstatement.
A3widemedianfiltercanbedesignedusingifelseconditionalstatements.
shortMedian(shortu1,shortu2,shortu3){shortresult;
if(u1>u2)
if(u2>u3)result=u2;//u1>u2,u2>u3u1>u2>u3
else
if(u1>u3)result=u3;//u1>u2,u3>u2,u1>u3u1>u3>u2
elseresult=u1;//u1>u2,u3>u2,u3>u1u3>u1>u2
else
if(u3>u2)result=u2;//u2>u1,u3>u2u3>u2>u1
else
if(u1>u3)result=u1;//u2>u1,u2>u3,u1>u3u2>u1>u3
elseresult=u3;//u2>u1,u2>u3,u3>u1u2>u3>u1
return(result):}

Listing6.2:A3widemedianfunction.
Formoreinformationonthedesignandanalysisofdigitalfilters,seeChapter5ofEmbedded
Systems:RealTimeOperatingSystemsforARMCortexMMicrocontrollersbyJonathanW.
Valvano
ComplexconditionaltestingcanbeimplementedusingtherelationalandBooleanoperators
describedinthelastchapter.
if((G2==G1)||(G4>G3))True();elseFalse();

TheSwitchStatement
Switchstatementsprovideanoniterativechoicebetweenanynumberofpathsbasedon
specifiedconditions.Theycompareanexpressiontoasetofconstantvalues.Selectedstatements
arethenexecuteddependingonwhichvalue,ifany,matchestheexpression.Switchstatements
havetheform
switch(ExpressionList){Statement?...}

whereExpressionListisalistofoneormoreexpressions.Statement?...representsthestatements
tobeselectedforexecution.Theyareselectedbymeansofcaseanddefaultprefixesspecial
labelsthatareusedonlywithinswitchstatements.Theseprefixeslocatepointstowhichcontrol
jumpsdependingonthevalueofExpressionList.Theyaretotheswitchstatementwhatordinary
labelsaretothegotostatement.Theymayoccuronlywithinthebracesthatdelimitthebodyofa
http://users.ece.utexas.edu/~valvano/embed/chap6/chap6.htm

3/9

2/3/2015

Chapter6:FlowofControlValvano

switchstatement.
Thecaseprefixhastheform
caseConstantExpression:

andthedefaultprefixhastheform
default:

Theterminatingcolonsarerequiredtheyheightentheanalogytoordinarystatementlabels.Any
expressioninvolvingonlynumericandcharacterconstantsandoperatorsisvalidinthecase
prefix.
AfterevaluatingExpressionList,asearchismadeforthefirstmatchingcaseprefix.Controlthen
goesdirectlytothatpointandproceedsnormallyfromthere.Othercaseprefixesandthedefault
prefixhavenoeffectonceacasehasbeenselectedcontrolflowsthroughthemjustasthough
theywerenoteventhere.Ifnomatchingcaseisfound,controlgoestothedefaultprefix,ifthere
isone.Intheabsenceofadefaultprefix,theentirecompoundstatementisignoredandcontrol
resumeswithwhateverfollowstheswitchstatement.Onlyonedefaultprefixmaybeusedwith
eachswitch.
Ifitisnotdesirabletohavecontrolproceedfromtheselectedprefixallthewaytotheendofthe
switchblock,breakstatementsmaybeusedtoexittheblock.Breakstatementshavetheform
break;

Someexamplesmayhelpclarifytheseideas.AssumePortAisspecifiedasanoutput,andbits
3,2,1,0areconnectedtoasteppermotor.TheswitchstatementwillfirstreadPortAandthedata
with0x0F(GPIO_PORTA_DATA_R&0x0F).Iftheresultis5,thenPortAissetto6andcontrolis
passedtotheendoftheswitch(becauseofthebreak).Similarlyfortheother3possibilities
#defineGPIO_PORTA_DATA_R(*((volatileunsignedlong*)0x400043FC))
voidstep(void){/*turnsteppermotoronestep*/
switch(GPIO_PORTA_DATA_R&0x0F){
case0x05:
GPIO_PORTA_DATA_R=0x06;//6follows5;
break;
case0x06:
GPIO_PORTA_DATA_R=0x0A;//10follows6;
break;
case0x0A:
GPIO_PORTA_DATA_R=0x09;//9follows10;
break;
case0x09:
GPIO_PORTA_DATA_R=0x05;//5follows9;
break;
default:
PORTA=0x05;//startat5
}
}

Listing6.3:Exampleoftheswitchstatement.
Formoreinformationonsteppermotors,seeSection8.8ofEmbeddedSystems:Introductionto
ARMCortexMMicrocontrollersorSection6.5ofEmbeddedSystems:RealTimeInterfacing
toARMCortexMMicrocontrollersbyJonathanW.Valvano..
Thisnextexampleshowsthatthemultipletestscanbeperformedforthesamecondition.
http://users.ece.utexas.edu/~valvano/embed/chap6/chap6.htm

4/9

2/3/2015

Chapter6:FlowofControlValvano

//ASCIItodecimaldigitconversion
unsignedcharconvert(unsignedcharletter){unsignedchardigit;
switch(letter){
case'A':
case'B':
case'C':
case'D':
case'E':
case'F':
digit=letter+10'A';
break;
case'a':
case'b':
case'c':
case'd':
case'e':
case'f':
digit=letter+10'a';
break;
default:
digit=letter'0';
}
returndigit;}

Listing6.4:Exampleoftheswitchstatement.
Thebodyoftheswitchisnotanormalcompoundstatementsincelocaldeclarationsarenot
allowedinitorinsubordinateblocks.ThisrestrictionenforcestheCrulethatablockcontaining
declarationsmustbeenteredthroughitsleadingbrace.
TheWhileStatement
Thewhilestatementisoneofthreestatementsthatdeterminetherepeatedexecutionofa
controlledstatement.Thisstatementaloneissufficientforallloopcontrolneeds.Theothertwo
merelyprovideanimprovedsyntaxandanexecutefirstfeature.Whilestatementshavetheform
while(ExpressionList)Statement

whereExpressionListisalistofoneormoreexpressionsandStatementisansimpleor
compoundstatement.Ifmorethanoneexpressionisgiven,therightmostexpressionyieldsthe
valuetobetested.First,ExpressionListisevaluated.Ifityieldstrue(nonzero),thenStatement
isexecutedandExpressionListisevaluatedagain.Aslongasityieldstrue,Statementexecutes
repeatedly.Whenityieldsfalse,Statementisskipped,andcontrolcontinueswithwhatever
follows.
Intheexample
i=5;
while(i)array[i]=0;

elements0through4ofarray[]aresettozero.Firstiissetto5.Thenaslongasitisnotzero,
theassignmentstatementisexecuted.Witheachexecutioniisdecrementedbeforebeingusedas
asubscript.
Itiscommontousethewhilestatementtoimplementbusywaitloops.Forinformationonthe
UARTseeSection8.2ofEmbeddedSystems:IntroductiontoARMCortexMMicrocontrollers
byJonathanW.Valvano.
//UART_InChar
//Waitfornewserialportinput
http://users.ece.utexas.edu/~valvano/embed/chap6/chap6.htm

5/9

2/3/2015

Chapter6:FlowofControlValvano

//Input:none
//Output:ASCIIcodeforkeytyped
unsignedcharUART_InChar(void){
while((UART1_FR_R&0x10)!=0)
return((unsignedchar)(UART1_DR_R&0xFF))
}
//UART_OutChar
//Output8bittoserialport
//Input:letterisan8bitASCIIcharactertobetransferred
//Output:none
voidUART_OutChar(chardata){
while((UART1_FR_R&0x20)!=0)
UART1_DR_R=data
}

Listing6.5:Examplesofthewhilestatement.
Continueandbreakstatementsarehandyforusewiththewhilestatement(alsohelpfulforthedo
andforloops).Thecontinuestatementhastheform
continue;

Itcausescontroltojumpdirectlybacktothetopoftheloopforthenextevaluationofthe
controllingexpression.Ifloopcontrollingstatementsarenested,thencontinueaffectsonlythe
innermostsurroundingstatement.Thatis,theinnermostloopstatementcontainingthecontinue
istheonethatstartsitsnextiteration.
Thebreakstatement(describedearlier)mayalsobeusedtobreakoutofloops.Itcausescontrol
topassontowhateverfollowstheloopcontrollingstatement.Ifwhile(oranylooporswitch)
statementsarenested,thenbreakaffectsonlytheinnermoststatementcontainingthebreak.That
is,itexitsonlyonelevelofnesting.

TheForStatement
Theforstatementalsocontrolsloops.Itisreallyjustanembellishedwhileinwhichthethree
operationsnormallyperformedonloopcontrolvariables(initialize,test,andmodify)arebrought
togethersyntactically.Ithastheform
for(ExpressionList?;
ExpressionList?;
ExpressionList?)Statement

Forstatementsareperformedinthefollowingsteps:
ThefirstExpressionListisevaluated.Thisisdoneonlyoncetoinitializethecontrolvariable(s).
ThesecondExpressionListisevaluatedtodeterminewhetherornottoperformStatement.If
morethanoneexpressionisgiven,therightmostexpressionyieldsthevaluetobetested.Ifit
yieldsfalse(zero),controlpassesontowhateverfollowstheforstatement.But,ifityieldstrue
(nonzero),Statementexecutes.
ThethirdExpressionLististhenevaluatedtoadjustthecontrolvariable(s)forthenextpass,and
theprocessgoesbacktostep2.E.g.,
for(J=100;J<1000;J++){process();}
http://users.ece.utexas.edu/~valvano/embed/chap6/chap6.htm

6/9

2/3/2015

Chapter6:FlowofControlValvano

Afiveelementarrayissettozero,couldbewrittenas
for(i=4;i>=0;i)array[i]=0;

oralittlemoreefficientlyas
for(i=5;i;array[i]=0);

Anyofthethreeexpressionlistsmaybeomitted,butthesemicolonseparatorsmustbekept.If
thetestexpressionisabsent,theresultisalwaystrue.Thus
for(;;){...break;...}

willexecuteuntilthebreakisencountered.
Aswiththewhilestatement,breakandcontinuestatementsmaybeusedwithequivalenteffects.
Abreakstatementmakescontroljumpdirectlytowhateverfollowstheforstatement.Anda
continueskipswhateverremainsinthecontrolledblocksothatthethirdExpressionListis
evaluated,afterwhichthesecondoneisevaluatedandtested.Inotherwords,acontinuehasthe
sameeffectastransferringcontroldirectlytotheendoftheblockcontrolledbythefor.
TheDoStatement
ThedostatementisthethirdloopcontrollingstatementinC.Itisreallyjustanexecutefirst
whilestatement.Ithastheform
doStatementwhile(ExpressionList);

Statementisanysimpleorcompoundstatement.Thedostatementexecutesinthefollowing
steps:firstStatementisexecuted.Then,ExpressionListisevaluatedandtested.Ifmorethanone
expressionisgiven,therightmostexpressionyieldsthevaluetobetested.Ifityieldstrue(non
zero),controlgoesbacktostep1otherwise,itgoesontowhateverfollows.
Aswiththewhileandforstatements,breakandcontinuestatementsmaybeused.Inthiscase,a
continuecausescontroltoproceeddirectlydowntothewhilepartofthestatementforanother
testofExpressionList.Abreakmakescontrolexittowhateverfollowsthedostatement.
I=100;do{process();I;}while(I>0);

http://users.ece.utexas.edu/~valvano/embed/chap6/chap6.htm

7/9

2/3/2015

Chapter6:FlowofControlValvano

Theexampleofthefiveelementarraycouldbewrittenas
i=4;
do{array[i]=0;i;}while(i>=0);

oras
i=4;
doarray[i]=0;while(i>=0);

oras
i=5;
doarray[i]=0;while(i);

TheReturnStatement
Thereturnstatementisusedwithinafunctiontoreturncontroltothecaller.Returnstatements
arenotalwaysrequiredsincereachingtheendofafunctionalwaysimpliesareturn.Buttheyare
requiredwhenitbecomesnecessarytoreturnfrominteriorpointswithinafunctionorwhena
usefulvalueistobereturnedtothecaller.Returnstatementshavetheform
returnExpressionList?;

ExpressionList?isanoptionallistofexpressions.Ifpresent,thelastexpressiondeterminesthe
valuetobereturnedbythefunction.Ifabsent,thereturnedvalueisunpredictable.
NullStatements
ThesimplestCstatementisthenullstatement.Ithasnotext,justasemicolonterminator.Asits
nameimplies,itdoesexactlynothing.Whyhaveastatementthatservesnopurpose?Well,asit
turnsout,statementsthatdonothingcanserveapurpose.AswesawinChapter5,expressionsin
Ccandoworkbeyondthatofsimplyyieldingavalue.Infact,inCprograms,alloftheworkis
accomplishedbyexpressionsthisincludesassignmentsandcallstofunctionsthatinvoke
operatingsystemservicessuchasinput/outputoperations.Itfollowsthatanythingcanbedoneat
anypointinthesyntaxthatcallsforanexpression.Take,forexample,thestatement
while((UART1_FR_R&0x20)!=0)/*WaitforTXFFtobeset*/

inwhichthe((UART1_FR_R&0x20)!=0)controlstheexecutionofthenullstatement
following.ThenullstatementisjustonewayinwhichtheClanguagefollowsaphilosophyof
attachingintuitivemeaningstoseeminglyincompleteconstructs.Theideaistomakethe
http://users.ece.utexas.edu/~valvano/embed/chap6/chap6.htm

8/9

2/3/2015

Chapter6:FlowofControlValvano

languageasgeneralaspossiblebyhavingtheleastnumberofdisallowedconstructs.
TheGotoStatement
Gotostatementsbreakthesequentialflowofexecutionbycausingcontroltojumpabruptlyto
designatedpoints.TheyhavethegeneralformgotoNamewhereNameisthenameofalabel
whichmustappearinthesamefunction.Itmustalsobeuniquewithinthefunction.
shortdata[10];
voidclear(void){shortn;
n=1;
loop:data[n]=0;
n++;
if(n==10)gotodone;
gotoloop;
done:
}

Listing6.6:Examplesofagotostatements
Noticethatlabelsareterminatedwithacolon.Thishighlightsthefactthattheyarenot
statementsbutstatementprefixeswhichservetolabelpointsinthelogicastargetsforgoto
statements.Whencontrolreachesagoto,itproceedsdirectlyfromtheretothedesignatedlabel.
Bothforwardandbackwardreferencesareallowed,buttherangeofthejumpislimitedtothe
bodyofthefunctioncontainingthegotostatement.
Asweobservedabove,gotostatements,cannotbeusedinfunctionswhichdeclarelocalsin
blockswhicharesubordinatetotheoutermostblockofthefunction.
Becausetheyviolatethestructuredprogrammingcriteria,gotostatementsshouldbeused
sparingly,ifatall.Overrelianceonthemisasuresignofsloppythinking.
MissingStatements
Itmaybesurprisingthatnothingwassaidaboutinput/output,programcontrol,ormemory
managementstatements.ThereasonisthatsuchstatementsdonotexistintheClanguage
proper.
Intheinterestofportabilitytheseserviceshavebeenrelegatedtoasetofstandardfunctionsin
theruntimelibrary.Sincetheydependsoheavilyontheruntimeenvironment,removingthem
fromthelanguageeliminatesamajorsourceofcompatibilityproblems.Eachimplementationof
Chasitsownlibraryofstandardfunctionsthatperformtheseoperations.Sincedifferent
compilershavelibrariesthatareprettymuchfunctionallyequivalent,programshaveveryfew
problemswhentheyarecompiledbydifferentcompilers.
GotoChapter7onPointersReturntoTableofContents

http://users.ece.utexas.edu/~valvano/embed/chap6/chap6.htm

9/9

2/3/2015

Chapter7:PointersValvano

Chapter7:Pointers
What'sinChapter7?
Definitionsofaddressandpointer
Declarationsofpointersdefinethetypeandallocatespaceinmemory
Howdoweusepointers
MemoryarchitectureoftheTM4C123
Pointermath
Pointercomparisons
FIFOqueueimplementedwithpointers
I/Oportaccess
TheabilitytoworkwithmemoryaddressesisanimportantfeatureoftheClanguage.This
featureallowsprogrammersthefreedomtoperformoperationssimilartoassemblylanguage.
Unfortunately,alongwiththepowercomesthepotentialdangerofhardtofindandseriousrun
timeerrors.Inmanysituations,arrayelementscanbereachedmoreefficientlythroughpointers
thanbysubscripting.Italsoallowspointersandpointerchainstobeusedindatastructures.
Withoutpointerstheruntimedynamicmemoryallocationanddeallocationusingtheheapwould
notbepossible.Wewillalsouseaformatsimilartopointerstodevelopmechanismsfor
accessingI/Oports.Theseaddeddegreesofflexibilityareabsolutelyessentialforembedded
systems.
AddressesandPointers
Addressesthatcanbestoredandchangedarecalledpointers.Apointerisreallyjustavariable
thatcontainsanaddress.Although,theycanbeusedtoreachobjectsinmemory,theirgreatest
advantageliesintheirabilitytoenterintoarithmetic(andother)operations,andtobechanged.
Justlikeothervariables,pointershaveatype.Inotherwords,thecompilerknowstheformat(8
bit16bit32bit,unsignedsigned)ofthedatapointedtobytheaddress.
Noteveryaddressisapointer.Forinstance,wecanwrite&varwhenwewanttheaddressofthe
variablevar.Theresultwillbeanaddressthatisnotapointersinceitdoesnothaveanameora
placeinmemory.Itcannot,therefore,haveitsvaluealtered.
Otherexamplesincludeanarrayorastructurename.AsweshallseeinChapter8,an
unsubscriptedarraynameyieldstheaddressofthearray.InChapter9,astructurenameyields
theaddressofthestructure.But,sincearraysandstructurescannotbemovedaroundinmemory,
theiraddressesarenotvariable.So,although,suchaddresseshaveaname,theydonotexistas
objectsinmemory(thearraydoes,butitsaddressdoesnot)andcannot,therefore,bechanged.
Athirdexampleisacharacterstring.Chapter3indicatedthatacharacterstringyieldsthe
addressofthecharacterarrayspecifiedbythestring.Inthiscasetheaddresshasneitheraname
oraplaceinmemory,soittooisnotapointer.

PointerDeclarations
Thesyntaxfordeclaringpointersislikethatforvariables(Chapter4)exceptthatpointersare
distinguishedbyanasteriskthatprefixestheirnames.Listing71illustratesseverallegitimate
pointerdeclarations.Notice,inthethirdexample,thatwemaymixpointersandvariablesina
singledeclaration.I.e.,thevariabledataandthepointerpt3aredeclaredinthesamestatement.
Alsonoticethatthedatatypeofapointerdeclarationspecifiesthetypeofobjecttowhichthe
pointerrefers,notthetypeofthepointeritself.Asweshallsee,allpointersontheCortexM
http://users.ece.utexas.edu/~valvano/embed/chap7/chap7.htm

1/9

2/3/2015

Chapter7:PointersValvano

contain32bitunsignedabsoluteaddresses.
short*pt1;/*definept1,declareasapointertoa16bitinteger*/
char*pt2;/*definept2,declareasapointertoan8bitcharacter*/
unsignedshortdata,*pt3;/*definedataandpt3,
declaredataasanunsigned16bitintegerand
declarept3asapointertoa16bitunsignedinteger*/
long*pt4;/*definept4,declareasapointertoa32bitinteger*/
externshort*pt5;/*declarept5asapointertoaninteger*/

Listing71:Exampleshowingapointerdeclarations

Thebestwaytothinkoftheasteriskistoimaginethatitstandsforthephrase"objectat"or
"objectpointedtoby."ThefirstdeclarationinListing71thenreads"theobjectat(pointedto
by)pt1isa16bitsignedinteger."
PointerReferencing
Wecanusethepointertoretrievedatafrommemoryortostoredataintomemory.Both
operationsareclassifiedaspointerreferences.Thesyntaxforusingpointersislikethatfor
variablesexceptthatpointersaredistinguishedbyanasteriskthatprefixestheirnames.Figures
71through74illustrateseverallegitimatepointerreferences.Inthefirstfigure,theglobal
variablescontainunknowndata(actuallyweknowthecompilerwillzeroglobalvariables).The
arrowidentifiestheexecutionlocation.Assumeaddresses0x20000000through0x20000017
existinRAM.
long*pt;//pointerto32bitdata
longdata;//32bit
longbuffer[4];//arrayof432bitnumbers
intmain(void){
pt=&buffer[1];
*pt=1234;
data=*pt;
return1;
}
addressdatacontents
0x200000000x00000000pt
0x200000040x00000000data
0x200000080x00000000buffer[0]
0x2000000C0x00000000buffer[1]
0x200000100x00000000buffer[2]
0x200000140x00000000buffer[3]

Figure71:PointerReferencing

TheCcodept=&buffer[1]willsetthepttopointtobuffer[1].Theexpression
&buffer[1]returnstheaddressofthesecond32bitelementofthebuffer(0x2000000C).
Thereforethelinept=&buffer[1]makesptpointtobuffer[1].
addressdatacontents
0x200000000x2000000Cpt
0x200000040x00000000data
0x200000080x00000000buffer[0]
0x2000000C0x00000000buffer[1]
0x200000100x00000000buffer[2]
0x200000140x00000000buffer[3]

TheCcode(*pt)=0x1234willstore0x1234intotheplacepointedtobypt.Inparticular,
itstores0x1234intobuffer[1].Whenthe*ptoccursonthelefthandsideofanassignment
http://users.ece.utexas.edu/~valvano/embed/chap7/chap7.htm

2/9

2/3/2015

Chapter7:PointersValvano

statementdataisstoredintomemoryattheaddress.Recallthe*ptmeans"the32bitsigned
integerat0x2000000C".Iliketoaddtheparentheses()toclarifythat*andptareone
object.Thereforetheline(*pt)=0x1234setsbuffer[1]to0x1234.
addressdatacontents
0x200000000x2000000Cpt
0x200000040x00000000data
0x200000080x00000000buffer[0]
0x2000000C0x00001234buffer[1]
0x200000100x00000000buffer[2]
0x200000140x00000000buffer[3]

TheCcodedata=(*pt)willreadmemoryfromaddresspointedtobypointerptintothe
placepointedtobydata.Inparticular,itstores0x1234intodata.Whenthe*ptoccurson
therighthandsideofanassignmentstatementdataisretrievedfrommemoryattheaddress.
Again,Iliketoaddtheparentheses()toclarifythat*andptareoneobject.Thereforetheline
data=(*pt)setsdatato0x1234(moreprecisely,itcopiesthe32bitinformationfrombuffer[1]
intodata.)
addressdatacontents
0x200000000x2000000Cpt
0x200000040x00001234data
0x200000080x00000000buffer[0]
0x2000000C0x00001234buffer[1]
0x200000100x00000000buffer[2]
0x200000140x00000000buffer[3]

ThefollowingCortexMassemblywasgeneratedbyKeiluVisionwhentheabovepointer
examplewascompiled.
48:pt=&buffer[1]
0x000003C44806LDRr0,[pc,#24]@0x000003E0
0x000003C64907LDRr1,[pc,#28]@0x000003E4
0x000003C86008STRr0,[r1,#0x00]
49:*pt=1234
0x000003CAF24040D2MOVWr0,#0x4D2
0x000003CE6809LDRr1,[r1,#0x00]
0x000003D06008STRr0,[r1,#0x00]
50:data=*pt
0x000003D24804LDRr0,[pc,#16]@0x000003E4
0x000003D46800LDRr0,[r0,#0x00]
0x000003D66800LDRr0,[r0,#0x00]
0x000003D84903LDRr1,[pc,#12]@0x000003E8
0x000003DA6008STRr0,[r1,#0x00]
51:return1
0x000003DC2001MOVSr0,#0x01
52:}
0x000003DE4770BXlr

MemoryAddressing
ThesizeofapointerdependsonthearchitectureoftheCPUandtheimplementationoftheC
compiler.FormoreinformationonthearchitectureoftheTM4CseeChapter3ofEmbedded
http://users.ece.utexas.edu/~valvano/embed/chap7/chap7.htm

3/9

2/3/2015

Chapter7:PointersValvano

Systems:IntroductiontoARMCortexMMicrocontrollersbyJonathanW.Valvano.

Figure72:MemorymapoftheTM4C123andTM4C1294.

Mostembeddedsystemsemployasegmentedmemoryarchitecture.Fromaphysicalstandpoint
wemighthaveamixtureofregularRAM,batterybackedupRAM,regularEEPROM,flash
EPROM,regularPROM,onetimeprogrammablePROMandROM.RAMistheonlymemory
structurethatallowstheprogrambothreadandwriteaccess.Table71showsthevarioustypes
ofmemoryavailableonmostmicrocomputers.TheRAMcontainstemporaryinformationthatis
lostwhenthepowerisshuntoff.ThismeansthatallvariablesallocatedinRAMmustbe
explicitlyinitializedatruntimebythesoftware.Iftheembeddedsystemincludesaseparate
batteryfortheRAM,theninformationisnotlostwhenthemainpowerisremoved.Some
microcomputershaveEEPROM.Thenumberoferase/programcyclesdependsonthememory
technology.EEPROMisoftenusedasthemainprogrammemoryduringproductdevelopment.
InthefinalproductwecanuseEEPROMforconfigurationconstantsandevennonvolatiledata
logging.TheonetimeprogrammablePROMisasimplenonvolatilestorageusedinsmall
volumeproductsthatcanbeprogrammedonlyoncewithinexpensiveequipment.TheROMisa
lowcostnonvolatilestorageusedinlargevolumeproductsthatcanbeprogrammedonlyonceat
thefactory.***ForthenumberofwritecyclesavailableforROMseetheappropriatedatasheet
forthatmicrocontroller.

Memory

Whenpoweris
removed

AbilitytoRead/Write

Programcycles

RAM

volatile

randomandfastaccess

infinite

batterybackedRAM nonvolatile

randomandfastaccess

infinite

EEPROM

nonvolatile

easilyreprogrammed

***

Flash

nonvolatile

easilyreprogrammed

***

OTPPROM

nonvolatile

canbeeasilyprogrammed

once

ROM

nonvolatile

programmedatthefactory

once

Table71:Varioustypesofmemoryavailableformicrontrollers.

Inanembeddedapplication,weusuallyputglobalvariables,theheap,andlocalvariablesin
RAMbecausethesetypesofinformationcanchangeduringexecution.Whensoftwareistobe
executedonaregularcomputer,themachineinstructionsareusuallyreadfromamassstorage
device(likeadisk)andloadedintomemory.Becausetheembeddedsystemusuallyhasnomass
storagedevice,themachineinstructionsandfixedconstantsmustbestoredinnonvolatile
memory.IfthereisbothEEPROMandROMonourmicrocomputer,weputsomefixed
constantsinEEPROMandsomeinROM.Ifitisinformationthatwemaywishtochangeinthe
http://users.ece.utexas.edu/~valvano/embed/chap7/chap7.htm

4/9

2/3/2015

Chapter7:PointersValvano

future,wecouldputitinEEPROM.Examplesincludelanguagespecificstrings,calibration
constants,finitestatemachines,andsystemIDnumbers.Thisallowsustomakeminor
modificationstothesystembyreprogrammingtheEEPROMwithoutthrowingthechipaway.If
ourprojectinvolvesproducingasmallnumberofdevicesthentheprogramcanbeplacedin
EPROMorEEPROM.Foraprojectwithalargevolumeitwillbecosteffectivetoplacethe
machineinstructionsinROM.

PointerArithmetic
Amajordifferencebetweenaddressesandordinaryvariablesorconstantshastodowiththe
interpretationofaddresses.Sinceanaddresspointstoanobjectofsomeparticulartype,adding
one(forinstance)toanaddressshoulddirectittothenextobject,notnecessarilythenextbyte.If
theaddresspointstointegers,thenitshouldenduppointingtothenextinteger.But,since
integersoccupytwobytes,addingonetoanintegeraddressmustactuallyincreasetheaddressby
two.Likewise,iftheaddresspointstolongintegers,thenaddingonetoanaddressshouldendup
pointingtothenextlongintegerbyincreasingtheaddressbyfour.Asimilarconsideration
appliestosubtraction.Inotherwords,valuesaddedtoorsubtractedfromanaddressmustbe
scaledaccordingtothesizeoftheobjectsbeingaddressed.Thisautomaticcorrectionsavesthe
programmeralotofthoughtandmakesprogramslesscomplexsincethescalingneednotbe
codedexplicitly.Thescalingfactorforlongintegersisfourthescalingfactorforintegersis
twothescalingfactorforcharactersisone.Therefore,characteraddressesdonotreceivespecial
handling.Itshouldbeobviousthatwhendefinestructures(seeChapter9)ofothersizes,the
appropriatefactorswouldhavetobeused.
Arelatedconsiderationariseswhenweimaginethemeaningofthedifferenceoftwoaddresses.
Sucharesultisinterpretedasthenumberofobjectsbetweenthetwoaddresses.Iftheobjectsare
integers,theresultmustbedividedbytwoinordertoyieldavaluewhichisconsistentwiththis
meaning.SeeChapter8formoreonaddressarithmetic.
Whenanaddressisoperatedon,theresultisalwaysanotheraddressofthesametype.Thus,if
ptrisasigned16bitintegerpointer,thenptr+1isalsopointstoasigned16bitinteger.
Precedencedeterminestheorderofevaluation.Seeatableofprecedence.Oneofthemost
commonmistakesresultswhentheprogrammermeglectsthefactthe*usedasaunarypointer
referencehasprecedenceoverallbinaryoperators.Thismeanstheexpression*ptr+1isthe
sameas(*ptr)+1andnot*(ptr+1).ThisisanimportantpointsoI'llmentionitagain,"When
confusedaboutprecedence(andaren'tweall)addparenthesestoclarifytheexpression."

PointerComparisons
Onemajordifferencebetweenpointersandothervariablesisthatpointersarealwaysconsidered
tobeunsigned.Thisshouldbeobvioussincememoryaddressesarenotsigned.Thispropertyof
pointers(actuallyalladdresses)ensuresthatonlyunsignedoperationswillbeperformedon
them.Itfurthermeansthattheotheroperandinabinaryoperationwillalsoberegardedas
unsigned(whetherornotitactuallyis).Inthefollowingexample,pt1andpt2[5]returnthe
currentvaluesoftheaddresses.Forinstance,ifthearraypt2[]containsaddresses,thenitwould
makesensetowrite

short*pt1;/*define16bitintegerpointer*/
short*pt2[10];/*defineten16bitintegerpointers*/
http://users.ece.utexas.edu/~valvano/embed/chap7/chap7.htm

5/9

2/3/2015

Chapter7:PointersValvano

shortdone(void){/*returnstrueifpt1ishigherthanpt2[5]*/
if(pt1>pt2[5])return(1);
return(0);
}

Listing72:Exampleshowingapointercomparisons

whichperformsanunsignedcomparisonsincept1andpt2arepointers.Thus,ifpt2[5]contains
0x2000F000andpt1contains0x20001000,theexpressionwillyieldtrue,since0x2000F000isa
higherunsignedvaluethan0x20001000.
Itmakesnosensetocompareapointertoanythingbutanotheraddressorzero.Cguaranteesthat
validaddressescanneverbezero,sothatparticularvalueisusefulinrepresentingtheabsenceof
anaddressinapointer.
Furthermore,toavoidportabilityproblems,onlyaddresseswithinasinglearrayshouldbe
comparedforrelativevalue(e.g.,whichpointerislarger).Todootherwisewouldnecessarily
involveassumptionsabouthowthecompilerorganizesmemory.Comparisonsforequality,
however,neednotobservethisrestriction,sincetheymakenoassumptionabouttherelative
positionsofobjects.Forexampleifpt1pointsintoonedataarrayandpt2pointsintoadifferent
array,thencomparingpt1topt2wouldbemeaningless.Whichpointerislargerwoulddepend
onwhereinmemorythetwoarrayswereassigned.
AFIFOQueueExample
ToillustratetheuseofpointerswewilldesignatwopointerFIFO.Thefirstinfirstoutcircular
queue(FIFO)isalsousefulfordataflowproblems.Itisaverycommondatastructureusedfor
I/Ointerfacing.Theorderpreservingdatastructuretemporarilysavesdatacreatedbythesource
(producer)beforeitisprocessedbythesink(consumer).TheclassofFIFOsstudiedinthis
sectionwillbestaticallyallocatedglobalstructures.Becausetheyareglobalvariables,itmeans
theywillexistpermanentlyandcanbesharedbymorethanoneprogram.Theadvantageof
usingaFIFOstructureforadataflowproblemisthatwecandecouplethesourceandsink
processes.WithouttheFIFOwewouldhavetoproduce1pieceofdata,thenprocessit,produce
anotherpieceofdata,thenprocessit.WiththeFIFO,thesourceprocesscancontinuetoproduce
datawithouthavingtowaitforthesinktofinishprocessingthepreviousdata.Thisdecoupling
cansignificantlyimprovesystemperformance.
GETPTpointstothedatathatwillberemovedbythenextcalltoGET,andPUTPTpointstothe

emptyspacewherethedatawillstoredbythenextcalltoPUT.IftheFIFOisfullwhenPUTis
calledthenthesubroutineshouldreturnafullerror(e.g.,V=1.)Similarly,iftheFIFOisempty
whenGETiscalled,thenthesubroutineshouldreturnanemptyerror(e.g.,V=1.)ThePUTPTand
GETPTmustbewrappedbackuptothetopwhentheyreachthebottom.

http://users.ece.utexas.edu/~valvano/embed/chap7/chap7.htm

6/9

2/3/2015

Chapter7:PointersValvano

Figure73:FifoexampleshowingthePUTPTandGETPTwrap.

TherearetwomechanismstodeterminewhethertheFIFOisemptyorfull.Asimplemethodis
toimplementacountercontainingthenumberofbytescurrentlystoredintheFIFO.GETwould
decrementthecounterandPUTwouldincrementthecounter.Thesecondmethodistoprevent
theFIFOfrombeingcompletelyfull.Forexample,iftheFIFOhad100bytesallocated,thenthe
PUTsubroutinewouldallowamaximumof99bytestobestored.Iftherewerealready99bytes
intheFIFOandanotherPUTwerecalled,thentheFIFOwouldnotbemodifiedandafullerror
wouldbereturned.InthiswayifPUTPTequalsGETPTatthebeginningofGET,thentheFIFO
isempty.Similarly,ifPUTPT+1equalsGETPTatthebeginningofPUT,thentheFIFOisfull.
BecarefultowrapthePUTPT+1beforecomparingittoGETPT.Thissecondmethoddoesnot
requirethelengthtobestoredorcalculated.
/*PointerimplementationoftheFIFO*/
#defineFifoSize10/*Numberof8bitdataintheFifo*/
char*PUTPT;/*Pointerofwheretoputnext*/
char*GETPT;/*Pointerofwheretogetnext*/
/*FIFOisemptyifPUTPT=GETPT*/
/*FIFOisfullifPUTPT+1=GETPT*/
charFifo[FifoSize];/*Thestaticallyallocatedfifodata*/
voidInitFifo(void){
PUTPT=GETPT=&Fifo[0];/*EmptywhenPUTPT=GETPT*/
}
intPutFifo(chardata){char*Ppt;/*Temporaryputpointer*/
Ppt=PUTPT;/*Copyofputpointer*/
*(Ppt++)=data;/*Trytoputdataintofifo*/
if(Ppt==&Fifo[FifoSize])Ppt=&Fifo[0];/*Wrap*/
if(Ppt==GETPT){
return(0);}/*Failed,fifowasfull*/
else{
PUTPT=Ppt;
return(1);/*Successful*/
}
}
intGetFifo(char*datapt){
if(PUTPT==GETPT){
return(0);}/*EmptyifPUTPT=GETPT*/
else{
*datapt=*(GETPT++);
if(GETPT==&Fifo[FifoSize])
GETPT=&Fifo[0];
return(1);
}
}

Listing73:Fifoqueueimplementedwithpointers
Sincetheseroutineshavereadmodifywriteaccessestoglobalvariablesthethreefunctions
(InitFifo,PutFifo,GetFifo)arethemselvesnotreentrant.Consequentlyinterruptsaretemporarily
disabled,topreventonethreadfromreenteringtheseFifofunctions.Oneadvantageofthis
pointerimplementationisthatifyouhaveasinglethreadthatcallstheGetFifo(e.g.,themain
program)andasinglethreadthatcallsthePutFifo(e.g.,theserialportreceiveinterrupthandler),
thenthisPutFifofunctioncaninterruptthisGetFifofunctionwithoutlossofdata.Sointhis
particularsituation,interruptswouldnothavetobedisabled.Itwouldalsooperateproperlyif
therewereasingleinterruptthreadcallingGetFifo(e.g.,theserialporttransmitinterrupt
handler)andasinglethreadcallingPutFifo(e.g.,themainprogram.)Ontheotherhand,ifthe
situationismoregeneral,andmultiplethreadscouldcallPutFifoormultiplethreadscouldcall
GetFifo,thentheinterruptswouldhavetobetemporarilydisabled.
http://users.ece.utexas.edu/~valvano/embed/chap7/chap7.htm

7/9

2/3/2015

Chapter7:PointersValvano

I/OPortAccess
EventhoughthemechanismtoaccessI/Oportstechnicallydoesnotfitthedefinitionofpointer,
itisincludedinthischapterbecauseitinvolvesaddresses.ThelineNVIC_ST_RELOAD_R=
delay1generatesa32bitI/Owriteoperationtotheportataddress0xE000E014.The
GPIO_PORTF_DATA_Rontherightsideofanassignmentstatementgeneratesa32bitreadfrom
address0x400253FC.TheNVIC_ST_CTRL_Rinthewhileloopgeneratesa32bitI/Oread
operationfromtheportataddress0xE000E010.
#defineNVIC_ST_CTRL_R(*((volatileunsignedlong*)0xE000E010))
#defineNVIC_ST_RELOAD_R(*((volatileunsignedlong*)0xE000E014))
#defineNVIC_ST_CURRENT_R(*((volatileunsignedlong*)0xE000E018))
#defineGPIO_PORTF_DATA_R(*((volatileunsignedlong*)0x400253FC))

//Thedelayparameterisinunitsofthe80MHzcoreclock.
(12.5ns)
voidSysTick_Wait(unsignedlongdelay){unsignedlongdata
NVIC_ST_RELOAD_R=delay1//numberofcountstowait
NVIC_ST_CURRENT_R=0//anyvaluewrittento
CURRENTclears
data=GPIO_PORTF_DATA_R;
while((NVIC_ST_CTRL_R&0x00010000)==0){//waitforcount
flag
}
}
Listing75:SampleProgramthataccessesI/Oports
TounderstandtheportdefinitionsinC,weremember#defineissimplyacopypaste.E.g.,
#definePA5(*((volatileunsignedlong*)0x40004080))
data=PA5
becomes
data=(*((volatileunsignedlong*)0x40004080))
Tounderstandwhywedefineportsthisway,letsbreakthisportdefinitionintopieces.First,
0x40004080istheaddressofPortAbit5.Ifwewritejust#definePA50x40004080itwill
create
data=0x40004080
whichdoesnotreadthecontentsofPA5asdesired.Thismeansweneedtodereferencethe
address.Ifwewrite#definePA5(*0x40004080)itwillcreate
data=(*0x40004080)
Thiswillattempttoreadthecontentsat0x40004080,butdoesntknowwhethertoread8,16,or
32bits.Sothecompilergivesasyntaxerrorbecausethetypeofdatadoesnotmatchthetypeof
(*0x40004080).TosolveatypemismatchinCwetypecast,placinga(newtype)infrontofthe
objectwewishtoconvert.Wewishforcethetypeconversiontounsigned32bits,sowemodify
thedefinitiontoincludethetypecast.
The volatileis added because the value of a port can change beyond the direct action of the
software. It forces the C compiler to read a new value each time through a loop and not rely on
the previous value.
http://users.ece.utexas.edu/~valvano/embed/chap7/chap7.htm

8/9

2/3/2015

Chapter7:PointersValvano

#definePA5(*((volatileunsignedlong*)0x40004080))
voidwait(void){
while((PA5&0x20)==0){}
}
voidwait2(void){
while(((*((volatileunsignedlong*)0x40004080))&0x20)==0)
{}
}
voidwait3(void){
volatileunsignedlong*pt
pt=((volatileunsignedlong*)0x40004080)
while(((*pt)&0x20)==0){}
}
Listing76:ProgramthataccessesI/Oportsusingpointers
Thefunctionwait3firstsetstheI/OpointerthenaccessestheI/Oportindirectlythroughthe
pointer.
GotoChapter8onArraysandStringsReturntoTableofContents

http://users.ece.utexas.edu/~valvano/embed/chap7/chap7.htm

9/9

2/3/2015

Chapter8:ArraysandStringsValvano

Chapter8:ArraysandStrings
What'sinChapter8?
ArraySubscripts
ArrayDeclarations
ArrayReferences
PointersandArrayNames
NegativeSubscripts
AddressArithmetic
StringFunctionsdefinedinstring.h
FifoQueueExample
Anarrayisacollectionoflikevariablesthatshareasinglename.Theindividualelementsofan
arrayarereferencedbyappendingasubscript,insquarebrackets,behindthename.The
subscriptitselfcanbeanylegitimateCexpressionthatyieldsanintegervalue,evenageneral
expression.Therefore,arraysinCmayberegardedascollectionsoflikevariables.Although
arraysrepresentoneofthesimplestdatastructures,ithaswidespreadusageinembedded
systems.
Stringsaresimilartoarrayswithjustafewdifferences.Usually,thearraysizeisfixed,while
stringscanhaveavariablenumberofelements.Arrayscancontainanydatatype(charshortint
evenotherarrays)whilestringsareusuallyASCIIcharactersterminatedwithaNULL(0)
character.Ingeneralweallowrandomaccesstoindividualarrayelements.Ontheotherhand,we
usuallyprocessstringssequentiallycharacterbycharacterfromstarttoend.Sincethese
differencesareamatterofsemanticsratherthanspecificlimitationsimposedbythesyntaxofthe
Cprogramminglanguage,thedescriptionsinthischapterapplyequallytodataarraysand
characterstrings.StringliteralswerediscussedearlierinChapter3inthischapterwewilldefine
datastructurestoholdourstrings.Inaddition,Chasarichsetofpredefinedfunctionsto
manipulatestrings.

ArraySubscripts
Whenanarrayelementisreferenced,thesubscriptexpressiondesignatesthedesiredelementby
itspositioninthedata.Thefirstelementoccupiespositionzero,thesecondpositionone,andso
on.Itfollowsthatthelastelementissubscriptedby[N1]whereNisthenumberofelementsin
thearray.Thestatement
data[9]=0;

forinstance,setsthetenthelementofdatatozero.Thearraysubscriptcanbeanyexpression
thatresultsina16bitinteger.Thefollowingforloopclears100elementsofthearraydatato
zero.
for(j=0;j<100;j++)data[j]=0;

Ifthearrayhastwodimensions,thentwosubscriptsarespecifiedwhenreferencing.As
programmerswemayanyassignlogicalmeaningtothefirstandsecondsubscripts.Forexample
wecouldconsiderthefirstsubscriptastherowandthesecondasthecolumn.Then,the
statement
ThePosition=position[3][5];

http://users.ece.utexas.edu/~valvano/embed/chap8/chap8.htm

1/8

2/3/2015

Chapter8:ArraysandStringsValvano

copiestheinformationfromthe4throw6thcolumnintothevariableThePosition.Ifthearray
hasthreedimensions,thenthreesubscriptsarespecifiedwhenreferencing.Againwemayany
assignlogicalmeaningtothevarioussubscripts.Forexamplewecouldconsiderthefirst
subscriptasthexcoordinate,thesecondsubscriptastheycoordinateandthethirdsubscriptas
thezcoordinate.Then,thestatement
humidity[2][3][4]=100;

setsthehumidityatpoint(2,3,4)to100.Arraysubscriptsaretreatedassigned32bitintegers.It
istheprogrammer'sresponsibilitytoseethatonlypositivevaluesareproduced,sinceanegative
subscriptwouldrefertosomepointinmemoryprecedingthearray.Onemustbeparticularly
carefulaboutassumingwhatexistingeitherinfrontoforbehindourarraysinmemory.

ArrayDeclarations
Justlikeanyvariable,arraysmustbedeclaredbeforetheycanbeaccessed.Thenumberof
elementsinanarrayisdeterminedbyitsdeclaration.Appendingaconstantexpressioninsquare
bracketstoanameinadeclarationidentifiesthenameasthenameofanarraywiththenumber
ofelementsindicated.Multidimensionalarraysrequiremultiplesetsofbrackets.Theexamples
inListing81arevaliddeclarations.
shortdata[5];/*definedata,allocatespacefor516bitintegers*/
charstring[20];/*definestring,allocatespacefor208bitcharacters*/
inttime,width[6];/*definetime,width,allocatespacefor16bitcharacters
*/
shortxx[10][5];/*definexx,allocatespacefor5016bitintegers*/
shortpts[5][5][5];/*definepts,allocatespacefor12516bitintegers*/
externcharbuffer[];/*declarebufferasanexternalcharacterarray*/

Listing81:Exampleshowingaarraydeclarations
Noticeinthethirdexamplethatordinaryvariablesmaybedeclaredtogetherwitharraysinthe
samestatement.Infactarraydeclarationsobeythesyntaxrulesofordinarydeclarations,as
describedinChapters4and7,exceptthatcertainnamesaredesignatedasarraysbythepresence
ofadimensionexpression.
Noticethesizeoftheexternalarray,buffer[],isnotgiven.Thisleadstoanimportantpointabout
howCdealswitharraysubscripts.Thearraydimensionsareonlyusedtodeterminehowmuch
memorytoreserve.Itistheprogrammer'sresponsibilitytostaywithintheproperbounds.
Inparticular,youmustnotletthesubscriptbecomenegativeforaboveN1,whereNisthesize
ofthearray.
Anothersituationinwhichanarray'ssizeneednotbespecifiediswhenthearrayelementsare
giveninitialvalues.AswewillseeinChapter9,thecompilerwilldeterminethesizeofsuchan
arrayfromthenumberofinitialvalues.

ArrayReferences
InCwemayrefertoanarrayinseveralways.Mostobviously,wecanwritesubscripted
referencestoarrayelements,aswehavealreadyseen.Cinterpretsanunsubscriptedarrayname
astheaddressofthearray.Inthefollowingexample,thefirsttwolinessetxtoequalthevalueof
thefirstelementofthearray.Thethirdandfourthlinesbothsetptequaltotheaddressofthe
array.Chapter7introducedtheaddressoperator&thatyieldstheaddressofanobject.This
http://users.ece.utexas.edu/~valvano/embed/chap8/chap8.htm

2/8

2/3/2015

Chapter8:ArraysandStringsValvano

operatormayalsobeusedwitharrayelements.Thus,theexpression&data[3]yieldstheaddress
ofthefourthelement.Noticetoothat&data[0]anddata+0anddataareallequivalent.Itshould
beclearbyanalogythat&data[3]anddata+3arealsoequivalent.
shortx,*pt,data[5];/*avariable,apointer,andanarray*/
voidSet(void){
x=data[0];/*setxequaltothefirstelementofdata*/
x=*data;/*setxequaltothefirstelementofdata*/
pt=data;/*setpttotheaddressofdata*/
pt=&data[0];/*setpttotheaddressofdata*/
x=data[3];/*setxequaltothefourthelementofdata*/
x=*(data+3);/*setxequaltothefourthelementofdata*/
pt=data+3;/*setpttotheaddressofthefourthelement*/
pt=&data[3];/*setpttotheaddressofthefourthelement*/
}

Listing82:Exampleshowingarrayreferences

PointersandArrayNames
Theexamplesinthesectionsuggestthatpointersandarraynamesmightbeused
interchangeably.And,inmanycases,theymay.Cwillletussubscriptpointersandalsouse
arraynamesasaddresses.Inthefollowingexample,thepointerptcontainstheaddressofan
arrayofintegers.Noticetheexpressionpt[3]isequivalentto*(pt+3).
short*pt,data[5];/*apointer,andanarray*/
voidSet(void){
pt=data;/*setpttotheaddressofdata*/
data[2]=5;/*setthethirdelementofdatato5*/
pt[2]=5;/*setthethirdelementofdatato5*/
*(pt+2)=5;/*setthethirdelementofdatato5*/
}

Listing83:Exampleshowingpointerstoaccessarrayelements

ItisimportanttorealizethatalthoughCacceptsunsubscriptedarraynamesataddresses,theyare
notthesameaspointers.Inthefollowingexample,wecannotplacetheunsubscriptedarray
nameonthelefthandsideofanassignmentstatement.
shortbuffer[5],data[5];/*twoarrays*/
voidSet(void){
data=buffer;/*illegalassignment*/
}

Listing84:Exampleshowinganillegalarrayassignment

Sincetheunsubscriptedarraynameisitsaddress,thestatementdata=bufferisanattemptto
changeitsaddress.Whatsensewouldthatmake?Thearray,likeanyobject,hasafixedhomein
memorytherefore,itsaddresscannotbechanged.Wesaythatarrayisnotalvaluethatis,it
cannotbeusedontheleftsideofanassignmentoperator(normayitbeoperatedonby
incrementordecrementoperators).Itsimplycannotbechanged.Notonlydoesthisassignment
makenosense,itisphysicallyimpossiblebecauseanarrayaddressisnotavariable.Thereisno
placereservedinmemoryforanarray'saddresstoreside,onlytheelements.
http://users.ece.utexas.edu/~valvano/embed/chap8/chap8.htm

3/8

2/3/2015

Chapter8:ArraysandStringsValvano

NegativeSubscripts
Sinceapointermaypointtoanyelementofanarray,notjustthefirstone,itfollowsthat
negativesubscriptsappliedtopointersmightwellyieldarrayreferencesthatareinbounds.This
sortofthingmightbeusefulinsituationswherethereisarelationshipbetweensuccessive
elementsinanarrayanditbecomesnecessarytoreferenceanelementprecedingtheonebeing
pointedto.Inthefollowingexample,dataisanarraycontainingtimedependent(orspace
dependent)information.Ifptpointstoanelementinthearray,pt[1]isthepreviouselementand
pt[1]isthefollowingone.Thefunctioncalculatesthesecondderivativeusingasimplediscrete
derivative.
short*pt,data[100];/*apointerandanarray*/
voidCalcSecond(void){shortd2Vdt2;
for(pt=data+1;pt<data+99;pt++){
d2Vdt2=(pt[1]2*pt[0]+pt[1]);
}
}

Listing85:Exampleshowingnegativearraysubscripting

AddressArithmetic
Aswehaveseen,addresses(pointers,arraynames,andvaluesproducedbytheaddressoperator)
maybeusedfreelyinexpressions.ThisonefactisresponsibleformuchofthepowerofC.
Aswithpointers(Chapter7),alladdressesaretreatedasunsignedquantities.Therefore,only
unsignedoperationsareperformedonthem.Ofallthearithmeticoperationsthatcouldbe
performedonaddressesonlytwomakesense,displacinganaddressbyapositiveornegative
amount,andtakingthedifferencebetweentwoaddresses.Allothers,thoughpermissible,yield
meaninglessresults.
Displacinganaddresscanbedoneeitherbymeansofsubscriptsorbyuseoftheplusandminus
operators,aswesawearlier.Theseoperationsshouldbeusedonlywhentheoriginaladdressand
thedisplacedaddressrefertopositionsinthesamearrayordatastructure.Anyothersituation
wouldassumeaknowledgeofhowmemoryisorganizedandwould,therefore,beilladvisedfor
portabilityreasons.
AswesawinChapter7,takingthedifferenceoftwoaddressesisaspecialcaseinwhichthe
compilerinterpretstheresultasthenumberofobjectslyingbetweentheaddresses.

StringFunctionsinstring.h
Mostcompliersimplementmanyusefulstringmanipulationfunctions.Recallthatstringsare8
bitarrayswithanulltermination.Theprototypesforthesefunctionscanbefoundinthestring.h
file.Yousimplyincludethisfilewheneveryouwishtouseanyoftheseroutines.Therestofthis
sectionexplainsthefunctionsonebyone.MostcompilersfortheARMCortexMtreateachof
thecountsasanunsigned32bitinteger.
typedefunsignedintsize_t;
void*memchr(void*,int,size_t);
intmemcmp(void*,void*,size_t);
http://users.ece.utexas.edu/~valvano/embed/chap8/chap8.htm

4/8

2/3/2015

Chapter8:ArraysandStringsValvano

void*memcpy(void*,void*,size_t);
void*memmove(void*,void*,size_t);
void*memset(void*,int,size_t);
char*strcat(char*,constchar*);
char*strchr(constchar*,int);
intstrcmp(constchar*,constchar*);
intstrcoll(constchar*,constchar*);
char*strcpy(char*,constchar*);
size_tstrcspn(constchar*,constchar*);
size_tstrlen(constchar*);
char*strncat(char*,constchar*,size_t);
intstrncmp(constchar*,constchar*,size_t);
char*strncpy(char*,constchar*,size_t);
char*strpbrk(constchar*,constchar*);
char*strrchr(constchar*,int);
size_tstrspn(constchar*,constchar*);
char*strstr(constchar*,constchar*);

Listing86:Prototypesforstringfunctions
Thefirstfivefunctionsaregeneralpurposememoryhandlingroutines.
void*memchr(void*p,intc,size_tn);

Startinginmemoryataddressp,memchrwillsearchforthefirstunsigned8bitbytethat
matchesthevalueinc.Atmostnbytesaresearched.Ifsuccessful,apointertothe8bitbyteis
returned,otherwiseaNULLpointerisreturned.
intmemcmp(void*p,void*q,size_tn);

Assumingthetwopointersaredirectedat8bitdatablocksofsizen,memcmpwillreturna
negativevalueiftheblockpointedtobypislexicographicallylessthantheblockpointedtoby
q.Thereturnvaluewillbezeroiftheymatch,andpositiveiftheblockpointedtobypis
lexicographicallygreaterthantheblockpointedtobyq.
void*memcpy(void*dst,void*src,size_tn);

Assumingthetwopointersaredirectedat8bitdatablocksofsizen,memcpywillcopythedata
pointedtobypointersrc,placingitinthememoryblockpointedtobypointerdst.Thepointer
dstisreturned.
void*memmove(void*dst,void*src,size_t);

Assumingthetwopointersaredirectedat8bitdatablocksofsizen,memmovewillcopy
thedatapointedtobypointersrc,placingitinthememoryblockpointedtobypointerdst.
Thisroutineworkseveniftheblocksoverlap.Thepointerdstisreturned.
void*memset(void*p,intc,size_tn);

Startinginmemoryataddressp,memsetwillsetn8bitbytestothe8bitvalueinc.Thepointer
pisreturned.
Theremainingfunctionsarestringhandlingroutines.
char*strcat(char*p,constchar*q);

Assumingthetwopointersaredirectedattwonullterminatedstrings,strcatwillappendacopy
ofthestringpointedtobypointerq,placingittheendofthestringpointedtobypointerp.The
pointerpisreturned.Itistheprogrammer'sresponsibilitytoensurethedestinationbufferislarge
http://users.ece.utexas.edu/~valvano/embed/chap8/chap8.htm

5/8

2/3/2015

Chapter8:ArraysandStringsValvano

enough.
char*strchr(constchar*p,intc);

Assumingthepointerisdirectedatanullterminatedstring.Startinginmemoryataddressp,
strchrwillsearchforthefirstunsigned8bitbytethatmatchesthevalueinc.Itwillsearchuntil
amatchisfoundorstopattheendofthestring.Ifsuccessful,apointertothe8bitbyteis
returned,otherwiseaNULLpointerisreturned.
intstrcmp(constchar*p,constchar*q);

Assumingthetwopointersaredirectedattwonullterminatedstrings,strcmpwillreturna
negativevalueifthestringpointedtobypislexicographicallylessthanthestringpointedtoby
q.Thereturnvaluewillbezeroiftheymatch,andpositiveifthestringpointedtobypis
lexicographicallygreaterthanthestringpointedtobyq.
char*strcpy(char*dst,constchar*src);

Weassumescrpointstoanullterminatedstringanddstpointstoamemorybufferlargeenough
toholdthestring.strcpywillcopythestring(includingthenull)pointedtobysrc,intothe
bufferpointedtobypointerdst.Thepointerdstisreturned.Itistheprogrammer'sresponsibility
toensurethedestinationbufferislargeenough.
size_tstrcspn(constchar*p,constchar*q);

Thestringfunctionstrcspnwillcomputethelengthofthemaximalinitialsubstringwithinthe
stringpointedtobypthathasnocharactersincommonwiththestringpointedtobyq.For
examplethefollowingcallreturnsthevalue5.
n=strcspn("label:ldaa10,x;comment",";:*\n\t\l");

Acommonapplicationofthisroutineisparsingfortokens.Thefirstparameterisalineoftext
andthesecondparameterisalistofdelimiters(e.g.,space,semicolon,colon,star,return,taband
linefeed).Thefunctionreturnsthelengthofthefirsttoken(i.e.,thesizeoflabel).
size_tstrlen(constchar*p);

Thestringfunctionstrlenreturnsthelengthofthestringpointedtobypointerp.Thelengthis
thenumberofcharactersinthestringnotcountingthenulltermination.
char*strncat(char*p,constchar*q,size_tn);

Thisfunctionissimilartostrcat.Assumingthetwopointersaredirectedattwonullterminated
strings,strncatwillappendacopyofthestringpointedtobypointerq,placingittheendofthe
stringpointedtobypointerp.Theparameternlimitsthenumberofcharacters,notincludingthe
nullthatwillbecopied.Thepointerpisreturned.Itistheprogrammer'sresponsibilitytoensure
thedestinationbufferislargeenough.
intstrncmp(constchar*p,constchar*q,size_tn);

Thisfunctionissimilartostrcmp.Assumingthetwopointersaredirectedattwonullterminated
strings,strncmpwillreturnanegativevalueifthestringpointedtobypislexicographicallyless
thanthestringpointedtobyq.Thereturnvaluewillbezeroiftheymatch,andpositiveifthe
stringpointedtobypislexicographicallygreaterthanthestringpointedtobyq.Theparameter
nlimitsthenumberofcharacters,notincludingthenullthatwillbecompared.Forexample,the
followingfunctioncallwillreturnazerobecausethefirst6charactersarethesame:
http://users.ece.utexas.edu/~valvano/embed/chap8/chap8.htm

6/8

2/3/2015

Chapter8:ArraysandStringsValvano

n=strncmp("TM4C123,"TM4C1294",6);

Thefollowingfunctionissimilartostrcpy.
char*strncpy(char*dst,constchar*src,size_tn);

Weassumescrpointstoanullterminatedstringanddstpointstoamemorybufferlargeenough
toholdthestring.strncpywillcopythestring(includingthenull)pointedtobysrc,intothe
bufferpointedtobypointerdst.Thepointerdstisreturned.Theparameternlimitsthenumberof
characters,notincludingthenullthatwillbecopied.Ifthesizeofthestringpointedtobysrcis
equaltoorlargerthann,thenthenullwillnotbecopiedintothebufferpointertobydst.Itisthe
programmer'sresponsibilitytoensurethedestinationbufferislargeenough.
char*strpbrk(constchar*p,constchar*q);

Thisfunction,strpbrk,iscalledpointertobreak.Thefunctionwillsearchthestringpointedto
bypforthefirstinstanceofanyofthecharactersinthestringpointedtobyq.Apointertothe
foundcharacterisreturned.Ifthesearchfailstofindanycharactersofthestringpointedtobyq
inthestringpointedtobyp,thenanullpointerisreturned.Forexamplethefollowingcall
returnsapointertothecolon.
pt=strpbrk("label:LDRR0,[R1];comment",";:*\n\t\l");

Thisfunction,likestrcspn,canbeusedforparsingtokens.
char*strrchr(constchar*p,intc);

Thefunctionstrrchrwillsearchthestringpointedtobypfromtherightforthefirstinstanceof
thecharacterinc.Fromtherightmeanssearchfrombackofthestringtowardsthefront.A
pointertothefoundcharacterisreturned.Ifthesearchfailstofindanycharacterswiththe8bit
valuecinthestringpointedtobyp,thenanullpointerisreturned.Forexamplethefollowing
callssetthept1topointtothe'R'inLDRandpt2topointtothe'R'inR1
pt1=strchr("label:LDRR0,[R1];comment",'R');
pt2=strrchr("label:LDRR0,[R1];comment",'R');

Noticethatstrchrsearchesfromtheleftwhilestrrchrsearchesfromtheright.
size_tstrspn(constchar*p,constchar*q);

Thefunctionstrspnwillreturnthelengthofthemaximalinitialsubstringinthestringpointedto
bypthatconsistsentirelyofcharactersinthestringpointedtobyq.Inthefollowingexamplethe
secondstringcontainsthevalidsetofhexadecimaldigits.Thefunctioncallwillreturn6because
thereisavalid6digithexadecimalstringatthestartoftheline.
n=strspn("A12F05+12BAD*45","01234567890ABCDEF");

char*strstr(constchar*p,constchar*q);

Thefunctionstrstrwillsearchthestringpointedtobypfromtheleftforthefirstinstanceofthe
stringpointedtobyq.Apointertothefoundsubstringwithinthefirststringisreturned.Ifthe
searchfailstofindamatch,thenanullpointerisreturned.Forexamplethefollowingcallsset
thepttopointtothe'L'inLDR.
pt=strstr("label:LDRR0,[R1];comment","LDR");
http://users.ece.utexas.edu/~valvano/embed/chap8/chap8.htm

7/8

2/3/2015

Chapter8:ArraysandStringsValvano

AFIFOQueueExampleusingindices
AnothermethodtoimplementastaticallyallocatedfirstinfirstoutFIFOistouseindices
insteadofpointers.Thismethodisnecessaryforcompilersthatdonotsupportpointers.The
purposeofthisexampleistoillustratetheuseofarraysandindices.JustlikethepreviousFIFO,
thisisusedfororderpreservingtemporarystorage.ThefunctionFifo_Putwillenterone8bit
byteintothequeue,andFifo_Getwillremoveonebyte.IfyoucallFifo_PutwhiletheFIFOis
full(SizeisequaltoFifoSize),theroutinewillreturnazero.Otherwise,Fifo_Putwillsavethe
datainthequeueandreturnaone.TheindexPutIspecifieswheretoputthenext8bitdata.The
routineFifo_Getactuallyreturnstwoparameters.Thequeuestatusistheregularfunctionreturn
parameter,whilethedataremovedfromthequeueisreturnbyreference.I.e.,thecallingroutine
passesinapointer,andFifo_Getstorestheremoveddataatthataddress.IfyoucallFifo_Get
whiletheFIFOisempty(Sizeisequaltozero),theroutinewillreturnazero.Otherwise,
Fifo_Getwillreturntheoldestdatafromthequeueandreturnaone.TheindexGetIspecifies
wheretogetthenext8bitdata.ThefollowingFIFOimplementationusestwoindicesanda
counter.BecauseofthereadmodifywritetoSize,theseroutineshaveacriticalsection.For
informationoncriticalsectionsseeSection5.3ofEmbeddedSystems:RealTimeInterfacingto
ARMCortexMMicrocontrollersbyJonathanW.Valvano.
/*Index,counterimplementationoftheFIFO*/
#defineFifoSize10/*Numberof8bitdataintheFifo*/
unsignedcharPutI;/*Indexofwheretoputnext*/
unsignedcharGetI;/*Indexofwheretogetnext*/
unsignedcharSize;/*NumbercurrentlyintheFIFO*/
/*FIFOisemptyifSize=0*/
/*FIFOisfullifSize=FifoSize*/
charFifo[FifoSize];/*Thestaticallyallocateddata*/
voidFifo_Init(void){
PutI=GetI=Size=0;/*EmptywhenSize==0*/
}
intFifo_Put(chardata){
if(Size==FifoSize)
return(0);/*Failed,fifowasfull*/
else{
Size++;
Fifo[PutI++]=data;/*putdataintofifo*/
if(PutI==FifoSize)PutI=0;/*Wrap*/
return(1);/*Successful*/
}
}
intFifo_Get(char*datapt){
if(Size==0)
return(0);/*EmptyifSize=0*/
else{
*datapt=Fifo[GetI++];
Size;
if(GetI==FifoSize)GetI=0;
return(1);}
}

Listing87:FIFOimplementedwithtwoindicesandacounter
ForinformationonFIFOqueuesseeeitherSection11.3ofEmbeddedSystems:Introductionto
ARMCortexMMicrocontrollersbyJonathanW.Valvano,orSection3.7ofEmbedded
Systems:RealTimeInterfacingtoARMCortexMMicrocontrollersbyJonathanW.Valvano.
GotoChapter9onStructuresReturntoTableofContents
http://users.ece.utexas.edu/~valvano/embed/chap8/chap8.htm

8/8

2/3/2015

Chapter9:StructuresValvano

Chapter9:Structures
What'sinChapter9?
StructureDeclarations
Accessingelementsofastructure
Initializationofstructuredata
Usingpointerstoaccessstructures
Passingstructuresasparameterstofunctions
ExampleofaLinearLinkedList
ExampleofaHuffmanCode
Astructureisacollectionofvariablesthatshareasinglename.Inanarray,eachelementhasthe
sameformat.Withstructureswespecifythetypesandnamesofeachoftheelementsor
membersofthestructure.Theindividualmembersofastructurearereferencedbytheir
subname.Therefore,toaccessdatastoredinastructure,wemustgiveboththenameofthe
collectionandthenameoftheelement.StructuresareoneofthemostpowerfulfeaturesoftheC
language.InthesamewaythatfunctionsallowustoextendtheClanguagetoincludenew
operations,structuresprovideamechanismforextendingthedatatypes.Withstructureswecan
addnewdatatypesderivedfromanaggregateofexistingtypes.
StructureDeclarations
LikeotherelementsofCprogramming,thestructuremustbedeclaredbeforeitcanbeused.The
declarationspecifiesthetagnameofthestructureandthenamesandtypesoftheindividual
members.Thefollowingexamplehasthreemembers:one8bitintegerandtwowordpointers
structtheport{
unsignedcharmask;//defineswhichbitsareactive
unsignedlongvolatile*addr;//pointertoitsaddress
unsignedlongvolatile*ddr;};//pointertoitsdirectionreg

Theabovedeclarationdoesnotcreateanyvariablesorallocateanyspace.Thereforetousea
structurewemustdefineaglobalorlocalvariableofthistype.Thetagname(theport)along
withthekeywordstructcanbeusedtodefinevariablesofthisnewdatatype:
structtheportPortA,PortB,PortE;

Theabovelinedefinesthethreevariablesandallocates9bytesforeachofvariable.Becausethe
pointerswillbe32bitalignedthecompilerwillskipthreebytesbetweenmaskandaddr,soeach
objectwilloccupy12bytes.Ifyouknewyouneededjustthreecopiesofstructuresofthistype,
youcouldhavedefinedthemas
structtheport{
unsignedcharmask;//defineswhichbitsareactive
unsignedlongvolatile*addr;
unsignedlongvolatile*ddr;}PortA,PortB,PortE;

Definitionsliketheabovearehardtoextend,sotoimprovecodereusewecanusetypedefto
actuallycreateanewdatatype(calledportintheexamplebelow)thatbehavessyntacticallylike
charintshortetc.
structtheport{
unsignedcharmask;//defineswhichbitsareactive
unsignedlongvolatile*addr;//address
unsignedlongvolatile*ddr;};//directionreg
typedefstructtheportport_t;
http://users.ece.utexas.edu/~valvano/embed/chap9/chap9.htm

1/11

2/3/2015

Chapter9:StructuresValvano

port_tPortA,PortB,PortE;

Oncewehaveusedtypedeftocreateport_t,wedon'tneedaccesstothenametheportanymore.
Consequently,someprogrammersusetofollowingshortcut:
typedefstruct{
unsignedcharmask;//defineswhichbitsareactive
unsignedlongvolatile*addr;//address
unsignedlongvolatile*ddr;}port_t;//directionreg
port_tPortA,PortB,PortE;

Similarly,Ihavealsoseenthefollowingapproachtocreatingstructuresthatusesthesame
structurenameasthetypedefname:
structport{
unsignedcharmask;//defineswhichbitsareactive
unsignedlongvolatile*addr;//address
unsignedlongvolatile*ddr;};//directionreg
typedefstructportport;
portPortA,PortB,PortE;

Mostcompilerssupportalloftheabovemethodsofdeclaringanddefiningstructures.

AccessingMembersofaStructure
Weneedtospecifyboththestructurename(nameofthevariable)andthemembernamewhen
accessinginformationstoredinastructure.Thefollowingexamplesshowaccessestoindividual
members:
PortB.mask=0xFF;//theTM4C123has8bitsonPORTB
PortB.addr=(unsignedlongvolatile*)(0x400053FC);
PortB.ddr=(unsignedlongvolatile*)(0x40005400);
PortE.mask=0x3F;//theTM4C123has6bitsonPORTE
PortE.addr=(unsignedlongvolatile*)(0x400243FC);
PortE.ddr=(unsignedlongvolatile*)(0x40024400);
(*PortE.ddr)=0;//specifyPortEasinputs
(*PortB.addr)=(*PortE.addr);//copyfromPortEtoPortB

Thesyntaxcangetalittlecomplicatedwhenamemberofastructureisanotherstructureas
illustratedinthenextexample:
structtheline{
intx1,y1;//startingpoint
intx2,y2;//startingpoint
unsignedcharcolor;};//color
typedefstructthelineline_t;
structthepath{
line_tL1,L2;//twolines
chardirection;};
typedefstructthepathpath_t;
path_tp;//global
voidSetp(void){line_tmyLine;path_tq;
p.L1.x1=5;//blacklinefrom5,6to10,12
p.L1.y1=6;
p.L1.x2=10;
p.L1.y2=12;
p.L1.color=255;
p.L2.x1=0;//whitelinefrom0,1to2,3
p.L2.y1=1;
p.L2.x2=2;
http://users.ece.utexas.edu/~valvano/embed/chap9/chap9.htm

2/11

2/3/2015

Chapter9:StructuresValvano

p.L2.y2=3;
p.L2.color=0;
p.direction=1;
myLine=p.L1;
q=p;
};

Listing91:Examplesofaccessingstructures

ThelocalvariabledeclarationlinemyLinewillallocate9bytesonthestackwhilepathqwill
allocate19bytesonthestack.InactualitymostCcompilersinanattempttomaintainaddresses
as32bitalignednumberswillactuallyallocate12and28bytesrespectively.Inparticular,the
CortexMexecutesfasterifaccessesoccuronwordalignedaddresses.Forexample,a32bit
dataaccesstoanoddaddressrequirestwobuscycles,whilea32bitdataaccesstoaword
alignedaddressrequiresonlyonebuscycle.Noticethattheexpressionp.L1.x1isofthetype
int,thetermp.L1hasthetypeline,whilejustphasthetypepath.Theexpressionq=pwill
copytheentire15bytesthatconstitutethestructurefromptoq.

InitializationofaStructure
Justlikeanyvariable,wecanspecifytheinitialvalueofastructureatthetimeofitsdefinition.
path_tthePath={{0,0,5,6,128},{5,6,10,6,128},1};
line_ttheLine={0,0,5,6,128};
port_tPortE={0x3F,
(unsignedlongvolatile*)(0x400243FC),
(unsignedlongvolatile*)(0x40024400)};

Ifweleavepartoftheinitializationblankitisfilledwithzeros.
path_tthePath={{0,0,5,6,128},};
line_tthePath={5,6,10,12,};
port_tPortE={1,(unsignedcharvolatile*)(0x100A),};

ToplaceastructureinROM,wedefineitasaglobalconstant.Inthefollowingexamplethe
structurefsm[3]willbeallocatedandinitializedinROMspace.Thelinkedstructurefinite
syatemmachineisagoodexampleofaROMbasedstructure.Formoreinformationaboutfinite
statemachinesseeeitherSection6.5ofEmbeddedSystems:IntroductiontoARMCortexM
MicrocontrollersbyJonathanW.Valvano,orSection3.5ofEmbeddedSystems:RealTime
InterfacingtoARMCortexMMicrocontrollersbyJonathanW.Valvano.
structState{
unsignedcharOut;/*OutputtoPortB*/
unsignedshortWait;/*Time(62.5nscycles)towait*/
unsignedcharAndMask[4];
unsignedcharEquMask[4];
conststructState*Next[4];};/*Nextstates*/
typedefconststructStatestate_t;
typedefstate_t*StatePtr;
#definestop&fsm[0]
#defineturn&fsm[1]
#definebend&fsm[2]
state_tfsm[3]={
{0x34,16000,//stop1ms
http://users.ece.utexas.edu/~valvano/embed/chap9/chap9.htm

3/11

2/3/2015

Chapter9:StructuresValvano

{0xFF,0xF0,0x27,0x00},
{0x51,0xA0,0x07,0x00},
{turn,stop,turn,bend}},
{0xB3,40000,//turn2.5ms
{0x80,0xF0,0x00,0x00},
{0x00,0x90,0x00,0x00},
{bend,stop,turn,turn}},
{0x75,32000,//bend2ms
{0xFF,0x0F,0x01,0x00},
{0x12,0x05,0x00,0x00},
{stop,stop,turn,stop}}};

Listing92:ExampleofinitializingastructureinROM

Usingpointerstoaccessstructures
Justlikeothervariableswecanusepointerstoaccessinformationstoredinastructure.The
syntaxisillustratedinthefollowingexamples:
voidSetp(void){path_t*ppt;
ppt=&p;//pointertoanexistingglobalvariable
ppt>L1.x1=5;//blacklinefrom5,6to10,12
ppt>L1.y1=6;
ppt>L1.x2=10;
ppt>L1.y2=12;
ppt>L1.color=255;
ppt>L2.x1=0;//whitelinefrom0,1to2,3
ppt>L2.y1=1;
ppt>L2.x2=2;
ppt>L2.y2=3;
ppt>L2.color=0;
ppt>direction=1;
(*ppt).direction=1;
};

Listing93:Examplesofaccessingastructureusingapointer
Noticethatthesyntaxppt>directionisequivalentto(*ppt).direction.Theparenthesesinthis
accessarerequired,becausealongwith()and[],theoperators.and>havethehighest
precedenceandassociatefromlefttoright.Therefore*ppt.directionwouldbeasyntaxerror
becauseppt.directioncannotbeevaluated.
Asananotherexampleofpointeraccessconsiderthefinitestatemachinecontrollerforthe
fsm[3]structureshownabove.ThestatemachineisillustratedinFigure91,andtheprogram
showninListing94.ThereisanexampleinChapter10thatextendsthismachinetoimplement
functionpointers.

http://users.ece.utexas.edu/~valvano/embed/chap9/chap9.htm

4/11

2/3/2015

Chapter9:StructuresValvano

Figure91:Statemachine

voidcontrol(void){StatePtrPt;
unsignedcharInput;unsignedinti;
SysTick_Init();
Port_Init();
Pt=stop;//InitialState
while(1){
GPIO_PORTA_DATA_R=Pt>Out;//1)output
SysTick_Wait(Pt>Wait);//2)wait
Input=GPIO_PORTB_DATA_R;//3)input
for(i=0;i<4;i++)
if((Input&Pt>AndMask[i])==Pt>EquMask[i]){
Pt=Pt>Next[i];//4)nextdependsoninput
i=4;}}};

Listing94:FinitestatemachinecontrollerforTM4C123

PassingStructurestoFunctions
Likeanyotherdatatype,wecanpassstructuresasparameterstofunctions.Becausemost
structuresoccupyalargenumberofbytes,itmakesmoresensetopassthestructurebyreference
ratherthanbyvalue.Inthefollowing"callbyvalue"example,theentire12bytestructureis
copiedonthestackwhenthefunctioniscalled.
unsignedlongInput(port_tthePort){
return(*thePort.addr);}

Whenweuse"callbyreference",apointertothestructureispassedwhenthefunctioniscalled.
typedefconststruct{
unsignedcharmask;//defineswhichbitsareactive
unsignedlongvolatile*addr;//address
unsignedlongvolatile*ddr;}port;//directionreg
port_tPortE={0x3F,
(unsignedlongvolatile*)(0x400243FC),
(unsignedlongvolatile*)(0x40024400)};
port_tPortF={0x1F,
(unsignedlongvolatile*)(0x400253FC),
(unsignedlongvolatile*)(0x40025400)};
intMakeOutput(port_t*ppt){
(*ppt>ddr)=ppt>mask;//makeoutput
return1;}
intMakeInput(port_t*ppt){
http://users.ece.utexas.edu/~valvano/embed/chap9/chap9.htm

5/11

2/3/2015

Chapter9:StructuresValvano

(*ppt>ddr)=0x00;//makeinput
return1;}
unsignedcharInput(port_t*ppt){
return(*ppt>addr);}
voidOutput(port_t*ppt,unsignedchardata){
(*ppt>addr)=data;
}
intmain(void){unsignedcharMyData;
MakeInput(&PortE);
MakeOutput(&PortF);
Output(&PortF,0);
MyData=Input(&PortE);
return1;}

Listing95:Portaccessorganizedwithadatastructure

LinearLinkedLists
Oneoftheapplicationsofstructuresinvolveslinkingelementstogetherwithpointers.Alinear
linkedlistisasimple1Ddatastructurewherethenodesarechainedtogetheroneafteranother.
Eachnodecontainsdataandalinktothenextnode.ThefirstnodeispointedtobytheHeadPt
andthelastnodehasanullpointerinthenextfield.Anodecouldbedefinedas
structnode{
unsignedshortdata;//16bitinformation
structnode*next;//pointertothenext
};
typedefstructnodenode_t;
node_t*HeadPt;

Listing98:Linearlinkedlistnodestructure

Figure93:Linearlinkedlistwith3nodes
Inordertostoremoredatainthestructure,wewillfirstcreateanewnodethenlinkitintothe
list.TheroutineStoreDatawillreturnatruevalueifsuccessful.
#include<stdlib.h>;
intStoreData(unsignedshortinfo){node_t*pt;
pt=malloc(sizeof(node_t));//createanewentry
if(pt){
pt>data=info;//storedata
pt>next=HeadPt;//linkintoexisting
HeadPt=pt;
return(1);
}
return(0);//outofmemory
};
http://users.ece.utexas.edu/~valvano/embed/chap9/chap9.htm

6/11

2/3/2015

Chapter9:StructuresValvano

Listing99:Codetoaddanodeatthebeginningofalinearlinkedlist
InordertosearchthelistwestartattheHeadPt,andstopwhenthepointerbecomesnull.The
routineSearchwillreturnapointertothenodeiffound,anditwillreturnanullpointerifthe
dataisnotfound.
node_t*Search(unsignedshortinfo){node_t*pt;
pt=HeadPt;
while(pt){
if(pt>data==info)
return(pt);
pt=pt>next;//linktonext
}
return(pt);//notfound
};

Listing910:Codetofindanodeinalinearlinkedlist
Tocountthenumberofelements,weagainstartattheHeadPt,andstopwhenthepointer
becomesnull.TheroutineCountwillreturnthenumberofelementsinthelist.
unsignedshortCount(void){node_t*pt;
unsignedshortcnt;
cnt=0;
pt=HeadPt;
while(pt){
cnt++;
pt=pt>next;//linktonext
}
return(cnt);
};

Listing911:Codetocountthenumberofnodesinalinearlinkedlist
Ifwewantedtomaintainasortedlist,thenwecaninsertnewdataattheproperplace,inbetween
dataelementssmallerandlargerthantheoneweareinserting.Inthefollowingfigureweare
insertingtheelement250inbetweenelements200and300.

Figure94:Insertinganodeinsortedorder
Incase1,thelistisinitiallyempty,andthisnewelementisthefirstandonlyone.Incase2,the
newelementisinsertedatthefrontofthelistbecauseithasthesmallestdatavalue.Case3isthe
generalcasedepictedintheabovefigure.Inthissituation,thenewelementisplacedinbetween
http://users.ece.utexas.edu/~valvano/embed/chap9/chap9.htm

7/11

2/3/2015

Chapter9:StructuresValvano

firstPtandsecondPt.Incase4,thenewelementisplacedattheendofthelistbecauseithasthe
largestdatavalue.
intInsertData(unsignedshortinfo){
node_t*firstPt,*secondPt,*newPt;
newPt=malloc(sizeof(node_t));//createanewentry
if(newPt){
newPt>data=info;//storedata
if(HeadPt==0){//case1
newPt>next=HeadPt;//onlyelement
HeadPt=newPt;
return(1);
}
if(info<=HeadPt>data){//case2
newPt>next=HeadPt;//firstelementinlist
HeadPt=newPt;
return(1);
}
firstPt=HeadPt;//searchfrombeginning
secondPt=HeadPt>next;
while(secondPt){
if(info<=secondPt>data){//case3
newPt>next=secondPt;//insertelementhere
firstPt>next=newPt;
return(1);
}
firstPt=secondPt;//searchnext
secondPt=secondPt>next;
}
newPt>next=secondPt;//case4,insertatend
firstPt>next=newPt;
return(1);
}
return(0);//outofmemory
};

Listing912:Codetoinsertanodeinasortedlinearlinkedlist
Thefollowingfunctionwillsearchandremoveanodefromthelinkedlist.Case1isthesituation
inwhichanattemptismadetoremoveanelementfromanemptylist.Thereturnvalueofzero
signifiestheattemptfailed.Incase2,thefirstelementisremoved.InthissituationtheHeadPt
mustbeupdatedtonowpointtothesecondelement.Itispossiblethesecondelementdoesnot
exist,becausethelistorginallyhadonlyoneelement.ThisisOKbecauseinthissituation
HeadPtwillbesettonullsignifyingthelistisnowempty.Case3isthegeneralsituationin
whichtheelementatsecondPtisremoved.Theelementbefore,firstPt,isnowlinkedtothe
elementafter.Case4isthesituationwheretheelementthatwasrequestedtoberemoveddidnot
exist.Inthiscase,thereturnvalueofzerosignifiestherequestfailed.
intRemove(unsignedshortinfo){
node_t*firstPt,*secondPt;
if(HeadPt==0)//case1
return(0);//emptylist
firstPt=HeadPt;
secondPt=HeadPt>next;
if(info==HeadPt>data){//case2
HeadPt=secondPt;//removefirstelementinlist
free(firstPt);//returnunneededmemorytoheap
return(1);
}
while(secondPt){
if(secondPt>data==info){//case3
firstPt>next=secondPt>next;//removethisone
http://users.ece.utexas.edu/~valvano/embed/chap9/chap9.htm

8/11

2/3/2015

Chapter9:StructuresValvano

free(secondPt);//returnunneededmemorytoheap
return(1);
}
firstPt=secondPt;//searchnext
secondPt=secondPt>next;
}
return(0);//case4,notfound
};

Listing913:Codetoremoveanodefromasortedlinearlinkedlist
ExampleofaHuffmanCode
Wheninformationisstoredortransmittedthereisafixedcostforeachbit.Datacompression
anddecompressionprovideameanstoreducethiscostwithoutlossofinformation.Ifthe
sendingcomputercompressesamessagebeforetransmissionandthereceivingcomputer
decompressesitatthedestination,theeffectivebandwidthisincreased.Inparticular,this
exampleintroducesawaytoprocessbitstreamsusingHuffmanencodinganddecoding.A
typicalapplicationisillustratedbythefollowingflowdiagram.

Figure95:DataflowdiagramshowingatypicalapplicationofHuffmanencodinganddecoding

TheHuffmancodeissimilartotheMorsecodeinthattheybothuseshortpatternsforlettersthat
occurmorefrequently.InregularASCII,allcharactersareencodedwiththesamenumberofbits
(8).Conversely,withtheHuffmancode,weassigncodeswherethenumberofbitstoencode
eachlettervaries.Inthisway,wecanuseshortcodesforletterlike"esiaton"(thathavea
higherprobabilityofoccurrence)andlongcodesforseldomusedconsonantslike"jqwz"(that
havealowerprobabilityofoccurrence).Toillustratetheencodedecodeoperations,considerthe
followingHuffmancodeforthelettersM,I,P,S.Sisencodedas"0",Ias"10",Pas"110"andM
as"111".WecanstoreaHuffmancodeasabinarytree.

Figure96:HuffmancodeforthelettersSIPM

If"MISSISSIPPI"weretobestoredinASCII,itwouldrequire10bytesor80bits.Withthis
simpleHuffmancode,thesamestringcanbestoredin21bits.
http://users.ece.utexas.edu/~valvano/embed/chap9/chap9.htm

9/11

2/3/2015

Chapter9:StructuresValvano

Figure97:HuffmanencodingforMISSISSIPPI

Ofcourse,thisHuffmancodecanonlyhandle4letters,whiletheASCIIcodehas128
possibilities,soitisnotfairtoclaimwehavean80to21bitsavings.Nevertheless,for
informationthathasawiderangeofindividualprobabilitiesofoccurrence,aHuffmancodewill
beefficient.InthefollowingimplementationthefunctionsBitPut()andBitGet()arecalledto
saveandrecoverbinarydata.Theimplementationsofthesetwofunctionswerepresentedbackin
Chapter2.

structNode{
charLetter0;//ASCIIcodeifbinary0
charLetter1;//ASCIIcodeifbinary1
//Letter1isNULL(0)ifLinkispointertoanothernode
conststructNode*Link;};//binarytreepointer
typedefconststructNodenode_t;
//Huffmantree
node_ttwentysixth={'Q','Z',0};
node_ttwentyfifth={'X',0,&twentysixth};
node_ttwentyfourth={'G',0,&twentyfifth};
node_ttwentythird={'J',0,&twentyfourth};
node_ttwentysecond={'W',0,&twentythird};
node_ttwentyfirst={'V',0,&twentysecond};
node_ttwentyth={'H',0,&twentyfirst};
node_tninteenth={'F',0,&twentyth};
node_teighteenth={'B',0,&ninteenth};
node_tseventeenth={'K',0,&eighteenth};
node_tsixteenth={'D',0,&seventeenth};
node_tfifteenth={'P',0,&sixteenth};
node_tfourteenth={'M',0,&fifteenth};
node_tthirteenth={'Y',0,&fourteenth};
node_ttwelfth={'L',0,&thirteenth};
node_televenth={'U',0,&twelfth};
node_ttenth={'R',0,&eleventh};
node_tninth={'C',0,&tenth};
node_teighth={'O',0,&ninth};
node_tseventh={'',0,&eighth};
node_tsixth={'N',0,&seventh};
node_tfifth={'I',0,&sixth};
node_tfourth={'S',0,&fifth};
node_tthird={'T',0,&fourth};
node_tsecond={'A',0,&third};
node_troot={'E',0,&second};
//********encode***************
//convertASCIIstringtoHuffmanbitsequence
//returnsbitcountifOK
//returns0ifBitFifoFull
//returns0xFFFFifillegalcharacter
intencode(char*sPt){//nullterminatedASCIIstring
intNotFound;chardata;
intBitCount=0;//numberofbitscreated
node_t*hpt;//pointerintoHuffmantree
while(data=(*sPt)){
sPt++;//nextcharacter
hpt=&root;//startsearchatroot
http://users.ece.utexas.edu/~valvano/embed/chap9/chap9.htm

10/11

2/3/2015

Chapter9:StructuresValvano

NotFound=1;//changesto0whenfound
while(NotFound){
if((hpt>Letter0)==data){
if(!BitPut(0))
return(0);//datastructurefull
BitCount++;
NotFound=0;}
else{
if(!BitPut(1))
return(0);//datastructurefull
BitCount++;
if((hpt>Letter1)==data)
NotFound=0;
else{//doesn'tmatcheitherLetter0orLetter1
hpt=hpt>Link;
if(hpt==0)return(0xFFFF);//illegal,endoftree?
}
}
}
}
returnBitCount;
}
//********decode***************
//convertHuffmanbitsequencetoASCII
//willremovefromtheBitFifountilitisempty
//returnscharactercount
intdecode(char*sPt){//nullterminatedASCIIstring
intCharCount=0;//numberofASCIIcharacterscreated
unsignedintdata;
node_t*hpt;//pointerintoHuffmantree
hpt=&root;//startsearchatroot
while(BitGet(&data)){
if(data==0){
(*sPt)=(hpt>Letter0);
sPt++;
CharCount++;
hpt=&root;}//startoverandsearchatroot
else//datais1
if((hpt>Link)==0){
(*sPt)=(hpt>Letter1);
sPt++;
CharCount++;
hpt=&root;}//startoverandsearchatroot
else{//doesn'tmatcheitherLetter0orLetter1
hpt=hpt>Link;
}
}
(*sPt)=0;//nullterminated
returnCharCount;
}

Listing914:AHuffmancodeimplementation

GotoChapter10onFunctionsReturntoTableofContents

http://users.ece.utexas.edu/~valvano/embed/chap9/chap9.htm

11/11

2/3/2015

Chapter10:FunctionsValvano

Chapter10:Functions
What'sinChapter10?
FunctionDeclarations
FunctionDefinitions
FunctionCalls
ParameterPassing
MakingourCprograms"looklike"C++
FiniteStateMachineusingFunctionPointers
Linkedlistinterpreter
Wehavebeenusingfunctionsthroughoutthisdocument,buthaveputoffformalpresentation
untilnowbecauseoftheirimmenseimportance.Thekeytoeffectivesoftwaredevelopmentis
theappropriatedivisionofacomplexprobleminmodules.Amoduleisasoftwaretaskthattakes
inputs,operatesinawelldefinedwaytocreateoutputs.InC,functionsareourwaytocreate
modules.Asmallmodulemaybeasinglefunction.Amediumsizedmodulemayconsistofa
groupoffunctionstogetherwithglobaldatastructures,collectedinasinglefile.Alargemodule
mayincludemultiplemediumsizedmodules.Ahierarchicalsoftwaresystemcombinesthese
softwaremodulesineitheratopdownorbottomupfashion.Wecanconsiderthefollowing
criteriawhenwedecomposeasoftwaresystemintomodules:
1)Wewishtomaketheoverallsoftwaresystemeasytounderstand
2)Wewishtominimizethecouplingorinteractionsbetweenmodules
3)WewishtogrouptogetherI/Oportaccessestosimilardevices
4)Wewishtominimizethesize(maximizethenumber)ofmodules
5)Modulesshouldbeabletobetestedindependently
6)Weshouldbeabletoreplace/upgradeonemodulewitheffectingtheothers
7)Wewouldliketoreusemodulesinothersituations.

Figure101:Amodulehasinputsandoutputs
AsaprogrammerwemusttakespecialcasewhendealingwithglobalvariablesandI/Oports.In
ordertoreducethecomplexityofthesoftwarewewilllimitaccesstoglobalvariablesandI/O
ports.Itisessentialtodividealargesoftwaretaskintosmaller,welldefinedandeasytodebug
modules.FormoreinformationaboutmodularprogrammingseeeitherChapter5ofEmbedded
Systems:IntroductiontoARMCortexMMicrocontrollersbyJonathanW.Valvano,orChapter
3ofEmbeddedSystems:RealTimeInterfacingtoARMCortexMMicrocontrollersbyJonathan
W.Valvano.
ThetermfunctioninCisbasedontheconceptofmathematicalfunctions.Inparticular,a
mathematicalfunctionisawelldefinedoperationthattranslatesasetofinputvaluesintoasetof
http://users.ece.utexas.edu/~valvano/embed/chap10/chap10.htm

1/11

2/3/2015

Chapter10:FunctionsValvano

outputvalues.InC,afunctiontranslatesasetofinputvaluesintoasingleoutputvalue.Wewill
developwaysforourCfunctionstoreturnmultipleoutputvaluesandforaparametertobeboth
aninputandanoutputparameter.Asasimpleexampleconsiderthefunctionthatconverts
temperatureindegreesFintotemperatureindegreesC.
shortFtoC(shortTempF){
shortTempC;
TempC=(5*(TempF32))/9;//conversion
returnTempC;}

Whenthefunction'snameiswritteninanexpression,togetherwiththevaluesitneeds,it
representstheresultthatitproduces.Inotherwords,anoperandinanexpressionmaybewritten
asafunctionnametogetherwithasetofvaluesuponwhichthefunctionoperates.Theresulting
value,asdeterminedbythefunction,replacesthefunctionreferenceintheexpression.For
example,intheexpression
FtoC(T+2)+4;//T+2degreesFahrenheitplus4degreesCentigrade

thetermFtoC(T+2)namesthefunctionFtoCandsuppliesthevariableTandtheconstant2
fromwhichFtoCderivesavalue,whichisthenaddedto4.Theexpressioneffectivelybecomes
((5*((T+2)32))/9)+4;

AlthoughFtoC(T+2)+4returnsthesameresultas((5*((T+2)32))/9)+4,theyarenotidentical.
Aswillweseelaterinthischapter,thefunctioncallrequirestheparameter(T+2)tobepassed
onthestackandasubroutinecallwillbeexecuted.
FunctionDeclarations
Similartotheapproachwithvariables,Cdifferentiatesbetweenafunctiondeclarationanda
functiondefinition.Adeclarationspecifiesthesyntax(nameandinput/outputparameters),
whereasafunctiondefinitionspecifiestheactualprogramtobeexecutedwhenthefunctionis
called.ManyCprogrammersrefertofunctiondeclarationasaprototype.SincetheCcompileris
essentialaonepassprocess(notincludingthepreprocessor),afunctionmustbedeclared(or
defined)beforeitcanbecalled.Afunctiondeclarationbeginswiththetype(format)ofthe
returnparameter.Ifthereisnoreturnparameter,thenthetypecanbeeitherspecifiedasvoidor
leftblank.Nextcomesthefunctionname,followedbytheparameterlist.Inafunction
declarationwedonothavetospecifynamesfortheinputparameters,justtheirtypes.Ifthereare
noinputparameters,thenthetypecanbeeitherspecifiedasvoidorleftblank.Thefollowing
examplesillustratethatthefunctiondeclarationspecifiesthenameofthefunctionandthetypes
ofthefunctionparameters.
//declarationinputoutput
voidRitual(void);//nonenone
charInChar(void);//none8bit
voidOutChar(char);//8bitnone
shortInSDec(void);//none16bit
voidOutSDec(short);//16bitnone
charMax(char,char);//two8bit8bit
intEMax(int,int);//two32bit32bit
voidOutString(char*);//pointerto8bitnone
char*alloc(int);//32bitpointerto8bit
intExec(void(*fnctPt)(void));//functionpointer32bit

Normallyweplacefunctiondeclarationsintheheaderfile.Weshouldaddcommentsthat
explainwhatthefunctiondoes.
http://users.ece.utexas.edu/~valvano/embed/chap10/chap10.htm

2/11

2/3/2015

Chapter10:FunctionsValvano

voidInitSCI(void);//Initialize38400bits/sec
charInChar(void);//Readsinacharacter,gadfly
voidOutChar(char);//Outputacharacter,gadfly
charUpCase(char);//Convertslowercasecharactertouppercase
voidInString(char*,unsignedint);//ReadsinaStringofmaxlength

Toillustratesomeoptionswhendeclaringfunctions,wegivealternativedeclarationsofthese
samefivefunctions:
InitSCI();
charInChar();
voidOutChar(charletter);
charUpCase(charletter);
InString(char*pt,unsignedintMaxSize);

Sometimeswewishtocallafunctionthatwillbedefinedinanothermodule.Ifwedefinea
functionasexternal,softwareinthisfilecancallthefunction(becausethecompilerknows
everythingaboutthefunctionexceptwhereitis),andthelinkerwillresolvetheunknown
addresslaterwhentheobjectcodesarelinked.
externvoidInitSCI(void);
externcharInChar(void);
externvoidOutChar(char);
externcharUpCase(char);
externvoidInString(char*,unsignedint);

OneofthepowerfeaturesofCistodefinepointerstofunctions.Asimpleexamplefollows:
int(*fp)(int);//pointertoafunctionwithinputandoutput
intfun1(intinput){
return(input+1);//thisadds1
};
intfun2(intinput){
return(input+2);//thisadds2
};
voidSetp(void){intdata;
fp=&fun1;//fppointstofun1
data=(*fp)(5);//data=fun1(5);
fp=&fun2;//fppointstofun2
data=(*fp)(5);//data=fun2(5);
};

Listing101:Exampleofafunctionpointer
Thedeclarationoffplooksabitcomplicatedbecauseithastwosetsofparenthesesandan
asterisk.Infact,itdeclaresfptobeapointertoanyfunctionthatreturnsintegers.Inotherwords,
thelineint(*fp)(int)doesn'tdefinethefunction.Asinotherdeclarations,theasteriskidentifies
thefollowingnameasapointer.Therefore,thisdeclarationreads"fpisapointertoafunction
witha32bitsignedinputparameterthatreturnsa32bitsignedoutputparameter."Usingthe
termobjectloosely,theasteriskmaybereadinitsusualwayas"objectat."Thuswecouldalso
readthisdeclarationas"theobjectatfpisafunctionwithanintinputthatreturnsanint."
Sowhythefirstsetofparentheses?BynowyouhavenoticedthatinCdeclarationsfollowthe
samesyntaxasreferencestothedeclaredobjects.And,sincetheasteriskandparentheses(after
thename)areexpressionoperators,anevaluationprecedenceisassociatedwiththem.InC,
parenthesesfollowinganameareassociatedwiththenamebeforetheprecedingasteriskis
appliedtotheresult.Therefore,
int*fp(int);
http://users.ece.utexas.edu/~valvano/embed/chap10/chap10.htm

3/11

2/3/2015

Chapter10:FunctionsValvano

wouldbetakenas
int*(fp(int));

sayingthatfpisafunctionreturningapointertoaninteger,whichisnotatalllikethe
declarationinListing101.

FunctionDefinitions
Thesecondwaytodeclareafunctionistofullydescribeitthatis,todefineit.Obviouslyevery
functionmustbedefinedsomewhere.Soifweorganizeoursourcecodeinabottomupfashion,
wewouldplacethelowestlevelfunctionsfirst,followedbythefunctionthatcallstheselow
levelfunctions.ItispossibletodefinelargeprojectinCwithouteverusingastandard
declaration(functionprototype).Ontheotherhand,mostprogrammerslikethetopdown
approachillustratedinthefollowingexample.Thisexampleincludesthreemodules:theLCD
interface,theUARTfunctions,andsomeSysTicktimerroutines.Noticethefunctionnamesare
chosentoreflectthemoduleinwhichtheyaredefined.IfyouareaC++programmer,consider
thesimilaritiesbetweenthisCfunctioncallLCD_clear()andaC++LCDclassandacalltoa
memberfunctionLCD.clear().The*.Hfilescontainfunctiondeclarationsandthe*.Cfiles
containtheimplementations.
#include"LCD.h"
#include"UART.H"
#include"SysTick.H"
voidmain(void){charletter;shortn=0;
UART_Init();
LCD_Init();
SysTick_Init()
LCD_String("ThisisaLCD");
SysTick_Wait10ms(1000);
LCD_clear();
letter='a'1;
while(1){
if(letter=='z')
letter='a';
else
letter++;
LCD_putchar(letter);
SysTick_Wait10ms(250);
if(++n==16){
n=0;
LCD_clear();
}
}
}

Listing102:Modularapproachtosoftwaredevelopment

Cfunctiondefinitionshavethefollowingform
typeName(parameterlist){
CompoundStatement
}
Justlikethefunctiondeclaration,webeginthedefinitionwithitstype.Thetypespecifiesthe
http://users.ece.utexas.edu/~valvano/embed/chap10/chap10.htm

4/11

2/3/2015

Chapter10:FunctionsValvano

functionreturnparameter.Ifthereisnoreturnparameterwecanusevoidorleaveitblank.
Nameisthenameofthefunction.Theparameterlistisalistofzeroormorenamesforthe
argumentsthatwillbereceivedbythefunctionwhenitiscalled.Boththetypeandnameofeach
inputparameterisrequired..
Althoughacharacterispassedina32bitregister,wearefreetodeclareitsformalargumentas
eithercharacterorword.Ifitisdeclaredasacharacter,onlytheloworderbyteoftheactual
argumentwillbereferenced.Ifitisdeclaredasaninteger,thenall32bitswillbereferenced.
Itisgenerallymoreefficienttoreferenceintegersthancharactersbecausethereisnoneedfora
machineinstructiontosetthehighorderbyte.Soitiscommontoseesituationsinwhicha
characterispassedtoafunctionwhichdeclarestheargumenttobeaninteger.Butthereisone
caveathere:notallCcompilerspromotecharacterargumentstointegerswhenpassingthemto
functionstheresultisanunpredictablevalueinthehighorderbyteoftheargument.Thisshould
berememberedasaportabilityissue.
SincethereisnowayinCtodeclarestrings,wecannotdeclareformalargumentsasstrings,but
wecandeclarethemascharacterpointersorarrays.Infact,aswehaveseen,Cdoesnot
recognizestrings,butarraysofcharacters.Thestringnotationismerelyashorthandwayof
writingaconstantarrayofcharacters.
Furthermore,sinceanunsubscriptedarraynameyieldsthearray'saddressandsincearguments
arepassedbyvalue,anarrayargumentiseffectivelyapointertothearray.Itfollowsthat,the
formalargumentdeclarationsarg[]and*argarereallyequivalent.Thecompilertakesbothas
pointerdeclarations.Arraydimensionsinargumentdeclarationsareignoredbythecompiler
sincethefunctionhasnocontroloverthesizeofarrayswhoseaddressesarepassedtoit.Itmust
eitherassumeanarray'ssize,receiveitssizeasanotherargument,orobtainitelsewhere.
Thelast,andmostimportant,partofthefunctiondefinitionaboveisCompoundStatement.This
iswheretheactionoccurs.Sincecompoundstatementsmaycontainlocaldeclarations,simple
statements,andothercompoundstatements,itfollowsthatfunctionsmayimplementalgorithms
ofanycomplexityandmaybewritteninastructuredstyle.Nestingofcompoundstatementsis
permittedwithoutlimit.
Asanexampleofafunctiondefinitionconsider
intadd3(intz1,intz2,intz3){inty;
y=z1+z2+z3;
return(y);}

Listing103:Examplefunctionwith3inputsandoneoutput.

Hereisafunctionnamedadd3whichtakesthreeinputarguments.

FunctionCalls
Afunctioniscalledbywritingitsnamefollowedbyaparenthesizedlistofargument
expressions.Thegeneralformis
Name(parameterlist)
whereNameisthenameofthefunctiontobecalled.Theparameterlistspecifiestheparticular
inputparametersusedinthiscall.Noticethateachinputparameterisinfactanexpression.It
http://users.ece.utexas.edu/~valvano/embed/chap10/chap10.htm

5/11

2/3/2015

Chapter10:FunctionsValvano

maybeassimpleasavariablenameoraconstant,oritmaybearbitrarilycomplex,including
perhapsotherfunctioncalls.Whateverthecase,theresultingvalueispushedontothestack
whereitispassedtothecalledfunction.
Cprogramsevaluateargumentsfromlefttoright,pushingthemontothestackinthatorder.On
return,thereturnparameterislocatedinRegR0.Theinputparametersareremovedfromthe
stackattheendoftheprogram.
Whenthecalledfunctionreceivescontrol,itreferstothefirstactualargumentusingthenameof
thefirstformalargument.Thesecondformalargumentreferstothesecondactualargument,and
soon.Inotherwords,actualandformalargumentsarematchedbypositionintheirrespective
lists.Extremecaremustbetakentoensurethattheselistshavethesamenumberandtypeof
arguments.
Itwasmentionedearlier,thatfunctioncallsappearinexpressions.But,sinceexpressionsare
legalstatements,andsinceexpressionsmayconsistofonlyafunctioncall,itfollowsthata
functioncallmaybewrittenasacompletestatement.Thusthestatement
add3(counter,time+5,3);

islegal.Itcallsadd3(),passingitthreeargumentscounter,time+5,and3.Sincethiscallisnot
partofalargerexpression,thevaluethatadd3()returnswillbeignored.Asabetterexample,
consider
y=add3(counter,time+5,3);

whichisalsoanexpression.Itcallsadd3()withthesameargumentsasbeforebutthistimeit
assignsthereturnedvaluetoy.Itisamistaketouseanassignmentstatementliketheabovewith
afunctionthatdoesnotreturnanoutputparameter.
TheabilitytopassonefunctionapointertoanotherfunctionisaverypowerfulfeatureoftheC
language.Itenablesafunctiontocallanyofseveralotherfunctionswiththecallerdetermining
whichsubordinatefunctionistobecalled.
intfun1(intinput){
return(input+1);//thisadds1
};
intfun2(intinput){
return(input+2);//thisadds2
};
intexecute(int(*fp)(int)){intdata;
data=(*fp)(5);//data=fun1(5);
return(data);
};
voidmain(void){intresult;
result=execute(&fun1);//result=fun1(5);
result=execute(&fun2);//result=fun2(5);
};

Listing104:Exampleofpassingafunctionpointer
Noticethatfpisdeclaredtobeafunctionpointer.Also,noticethatthedesignatedfunctionis
calledbywritinganexpressionofthesameformasthedeclaration.
ArgumentPassing
Nowletustakeacloserlookatthematterofargumentpassing.Withrespecttothemethodby
whichargumentsarepassed,twotypesofsubroutinecallsareusedinprogramminglanguages
http://users.ece.utexas.edu/~valvano/embed/chap10/chap10.htm

6/11

2/3/2015

Chapter10:FunctionsValvano

callbyreferenceandcallbyvalue.
Thecallbyreferencemethodpassesargumentsinsuchawaythatreferencestotheformal
argumentsbecome,ineffect,referencestotheactualarguments.Inotherwords,references
(pointers)totheactualargumentsarepassed,insteadofcopiesoftheactualarguments
themselves.Inthisscheme,assignmentstatementshaveimpliedsideeffectsontheactual
argumentsthatis,variablespassedtoafunctionareaffectedbychangestotheformal
arguments.Sometimessideeffectsarebeneficial,andsometimestheyarenot.SinceCsupports
onlyoneformaloutputparameter,wecanimplementadditionaloutputparametersusingcallby
reference.Inthiswaythefunctioncanreturnparametersbackusingthereference.Asan
examplerecallthefifoqueueprogramshownearlierinListing87.ThefunctionGetFifo,shown
below,returnstwoparameters.Theregularformalparameterisabooleanspecifyingwhetheror
nottherequestwassuccessful,andtheactualdataremovedfromthequeueisreturnedviathe
callbyreference.ThecallingprogramInCharpassestheaddressofitslocalvariabledata.The
assignmentstatement*datapt=Fifo[GetI++]withinGetFifowillstorethereturnparameterinto
alocalvariableofInChar.NormallyGetFifodoesnothavethescopetoaccesslocalvariables
ofInChar,butinthiscaseInCharexplicitlygrantedthatrightbypassingapointertoGetFifo.
intGetFifo(char*datapt){
if(Size==0)
return(0);/*EmptyifSize=0*/
else{
*datapt=Fifo[GetI++];Size;
if(GetI==FifoSize)GetI=0;
return(1);
}
}
charInChar(void){chardata;
while(GetFifo(&data)){};
return(data);}

Listing105:Multipleoutputparameterscanbeimplementedusingcallbyreference
Whenweusethecallbyvaluescheme,thevalues,notreferences,arepassedtofunctions.With
callbyvaluecopiesaremadeoftheparameters.Withinacalledfunction,referencestoformal
argumentsseecopiedvaluesonthestack,insteadoftheoriginalobjectsfromwhichtheywere
taken.AtthetimewhenthecomputerisexecutingwithinPutFifo()oftheexamplebelow,there
willbethreeseparateanddistinctcopiesofthe0x41data(main,OutCharandPutFifo).
intPutFifo(chardata){
if(Size==FifoSize){
return(0);}/*Failed,fifowasfull*/
else{
Size++;
*(PutPt++)=data;/*putdataintofifo*/
if(PutPt==&Fifo[FifoSize])PutPt=&Fifo[0];/*Wrap*/
return(1);/*Successful*/
}
}
voidOutChar(chardata){
while(PutFifo(data)){};
}
voidmain(void){chardata=0x41;
OutChar(data);
}

Listing106:Callbyvaluepassesacopyofthedata.
ThemostimportantpointtorememberaboutpassingargumentsbyvalueinCisthatthereisno
http://users.ece.utexas.edu/~valvano/embed/chap10/chap10.htm

7/11

2/3/2015

Chapter10:FunctionsValvano

connectionbetweenanactualargumentanditssource.Changestotheargumentsmadewithina
function,havenoaffectwhatsoeverontheobjectsthatmighthavesuppliedtheirvalues.They
canbechangedwithabandonandtheirsourceswillnotbeaffectedinanyway.Thisremovesa
burdenofconcernfromtheprogrammersincehemayuseargumentsaslocalvariableswithout
sideeffects.Italsoavoidstheneedtodefinetemporaryvariablesjusttopreventsideeffects.
ItispreciselybecauseCusescallbyvaluethatwecanpassexpressions,notjustvariables,as
arguments.Thevalueofanexpressioncanbecopied,butitcannotbereferencedsinceithasno
existenceinglobalmemory.Therefore,callbyvalueaddsimportantgeneralitytothelanguage.
AlthoughtheClanguageusesthecallbyvaluetechnique,itisstillpossibletowritefunctions
thathavesideeffectsbutitmustbedonedeliberately.ThisispossiblebecauseofC'sabilityto
handleexpressionsthatyieldaddresses.And,sinceanyexpressionisavalidargument,addresses
canbepassedtofunctions.
Sinceexpressionsmayincludeassignment,increment,anddecrementoperators(Chapter9),itis
possibleforargumentexpressionstoaffectthevaluesofargumentslyingtotheirright.(Recall
thatCevaluatesargumentexpressionsfromlefttoright.)Consider,forexample,
func(y=x+1,2*y);

wherethefirstargumenthasthevaluex+1andthesecondargumenthasthevalue2*(x+1).What
wouldbethevalueofthesecondargumentifargumentswereevaluatedfromrighttoleft?This
kindofsituationshouldbeavoided,sincetheClanguagedoesnotguaranteetheorderof
argumentevaluation.Thesafewaytowritethisis
y=x+1;
func(y,2*y);

Itistheprogrammer'sresponsibilitytoensurethattheparameterspassedmatchtheformal
argumentsinthefunction'sdefinition.Somemistakeswillbecaughtassyntaxerrorsbythe
compiler,butthismistakeisacommonandtroublesomeproblemforallCprogrammers.
Occasionally,theneedarisestowritefunctionsthatworkwithavariablenumberofarguments.
Anexampleisprintf()inthelibrary.InC,thisfeatureisimplementedusingmacrosdefinedin
thelibraryfileSTDARG.C.TousethesefeaturesyouincludeSTDARG.Hinyourfile.

PrivateversusPublicFunctions
Foreveryfunctiondefinition,thecompilergeneratesanassemblerdirectivedeclaringthe
function'snametobepublic.ThismeansthateveryCfunctionisapotentialentrypointandso
canbeaccessedexternally.Onewaytocreateprivate/publicfunctionsistocontrolwhich
functionshavedeclarations.ConsideragainthemainprograminListing102shownearlier.
NowletslookinsidetheTimer.HandTimer.Cfiles.ToimplementPrivateandPublicfunctions
weplacethefunctiondeclarationsofthePublicfunctionsintheTimer.Hfile.
voidSysTick_Init(void);
voidSysTick_Wait(unsignedlongdelay);

Listing107:SysTick.hheaderfilehaspublicfunctions
TheimplementationsofallfunctionsareincludedintheSysTick.cfile.Thefunction,
SysTick_Wait,isprivateandcanonlybecalledbysoftwareinsidetheSysTick.cfile.Wecan
applythissameapproachtoprivateandpublicglobalvariables.Noticethatinthiscasethe
http://users.ece.utexas.edu/~valvano/embed/chap10/chap10.htm

8/11

2/3/2015

Chapter10:FunctionsValvano

globalvariable,TimerClock,isprivateandcannotbeaccessedbysoftwareoutsidethe
SysTick.cfile.
unsignedlongstaticTimerClock;//privateglobal
voidSysTick_Init(void){
NVIC_ST_CTRL_R=0;//1)disableSysTickduringsetup
NVIC_ST_RELOAD_R=0x00FFFFFF;//2)maximumreloadvalue
NVIC_ST_CURRENT_R=0;//3)anywritetocurrentclearsit
NVIC_ST_CTRL_R=0x00000005;//4)enableSysTickwithcoreclock
}
//Thedelayparameterisinunitsofthe80MHzcoreclock.(12.5ns)
voidstaticSysTick_Wait(unsignedlongdelay){
NVIC_ST_RELOAD_R=delay1;//numberofcountstowait
NVIC_ST_CURRENT_R=0;//anyvaluewrittentoCURRENTclears
while((NVIC_ST_CTRL_R&0x00010000)==0){//waitforcountflag
}
}//10000usequals10ms
voidSysTick_Wait10ms(unsignedlongdelay){
unsignedlongi;
for(i=0;i<delay;i++){
SysTick_Wait(800000);//wait10ms
}
}

Listing108:Timer.Cimplementationfiledefinesallfunctions
FormoreinformationaboutmodularprogrammingseeeitherChapter5ofEmbeddedSystems:
IntroductiontoARMCortexMMicrocontrollersbyJonathanW.Valvano,orChapter3of
EmbeddedSystems:RealTimeInterfacingtoARMCortexMMicrocontrollersbyJonathanW.
Valvano.

FiniteStateMachineusingFunctionPointers
Nowthatwehavelearnedhowtodeclare,initializeandaccessfunctionpointers,wecancreate
veryflexiblefinitestatemachines.InthefinitestatemachinepresentedinListing92andListing
94,theoutputwasasimplenumberthatiswrittentotheoutputport.Inthisnextexample,we
willactuallyimplementtheexactsamemachine,butinawaythatsupportsmuchmore
flexibilityintheoperationsthateachstateperforms.InfactwewilldefineageneralCfunction
tobeexecutedateachstate.Inthisimplementationthefunctionsperformthesameoutputasthe
previousmachine.

Figure106:FiniteStateMachine(sameasFigure91)
http://users.ece.utexas.edu/~valvano/embed/chap10/chap10.htm

9/11

2/3/2015

Chapter10:FunctionsValvano

ComparethefollowingimplementationtoListing92,andseethattheunsignedcharOut
constantisreplacedwithavoid(*CmdPt)(void)functionpointer.Thethreegeneralfunction
DoStop()DoTurn()andDoBend()arealsoadded.
structState{
void(*CmdPt)(void)/*functiontoexecute*/
unsignedshortWait;/*Time,10mstowait*/
unsignedcharAndMask[4];
unsignedcharEquMask[4];
conststructState*Next[4];};/*Nextstates*/
typedefconststructStatestate_t;
typedefstate_t*StatePtr;
#definestop&fsm[0]
#defineturn&fsm[1]
#definebend&fsm[2]
voidDoStop(void){PORTA=0x34}
voidDoTurn(void){PORTA=0xB3}
voidDoBend(void){PORTA=0x75}
state_tfsm[3]={
{&DoStop,2000,//stop1ms
{0xFF,0xF0,0x27,0x00},
{0x51,0xA0,0x07,0x00},
{turn,stop,turn,bend}},
{&DoTurn,5000,//turn2.5ms
{0x80,0xF0,0x00,0x00},
{0x00,0x90,0x00,0x00},
{bend,stop,turn,turn}},
{&DoBend,4000,//bend2ms
{0xFF,0x0F,0x01,0x00},
{0x12,0x05,0x00,0x00},
{stop,stop,turn,stop}}};

Listing1012:LinkedfinitestatemachinestructurestoredinROM

ComparethefollowingimplementationtoListing94,andseethatthePORTH=ptOut
assignmentisreplacedwitha(*Pt>CmdPt)()functioncall.Inthisway,theappropriate
functionDoStop()DoTurn()orDoBend()willbecalled.
voidcontrol(void){StatePtrPt;
unsignedcharInput;unsignedshortstartTime;unsignedinti;
SysTick_Init()
Port_Init()

Pt=stop;//InitialState
while(1){
(*Pt>CmdPt)()//1)executefunction
SysTick_Wait10ms(Pt>Wait);//2)wait
Input=PORTB;//3)input
for(i=0;i<4;i++)
if((Input&Pt>AndMask[i])==Pt>EquMask[i]){
Pt=Pt>Next[i];//4)nextdependsoninput
i=4;}}};

Listing1013:Finitestatemachinecontroller
LinkedListInterpreterusingFunctionPointers
Inthenextexample,functionpointersarestoredinalistedlist.AninterpreteracceptsASCII
inputfromakeyboardandscansthelistforamatch.Inthisimplementation,eachnodeinthe
http://users.ece.utexas.edu/~valvano/embed/chap10/chap10.htm

10/11

2/3/2015

Chapter10:FunctionsValvano

linkedlisthasafunctiontobeexecutedwhentheoperatortypesthecorrespondingletter.The
linkedlistLLhasthreenodes.Eachnodehasaletter,afunctionandalinktothenextnode.
//LinkedListInterpreter
structNode{
unsignedcharLetter;
void(*fnctPt)(void);
conststructNode*Next;};
typedefconststructNodenode_t;
typedefnode_t*NodePtr;
voidCommandA(void){
OutString("\nExecutingCommanda");
}
voidCommandB(void){
OutString("\nExecutingCommandb");
}
voidCommandC(void){
OutString("\nExecutingCommandc");
}
node_tLL[3]={
{'a',&CommandA,&LL[1]},
{'b',&CommandB,&LL[2]},
{'c',&CommandC,0}};
voidmain(void){NodePtrPt;charstring[40];
UART_Init();//EnableSCIport
UART_OutString("\nEnterasinglelettercommandfollowedby<enter>");
while(1){
UART_OutString("\n>");
UART_InString(string,39);//firstcharacterisinterpreted
Pt=&LL[0];//firstnodetocheck
while(Pt){
if(string[0]==Pt>Letter){
Pt>fnctPt();//executefunction
break;}//leavewhileloop
else{
Pt=Pt>Next;
if(Pt==0)UART_OutString("Error");}}}}

Listing1014:Linkedlistimplementationofaninterpreter.
Comparethesyntaxofthefunctioncall,(*Pt>CmdPt)(),inListing1013,withthesyntaxin
thisexample,Pt>fnctPt().Thesetwoexpressionsbothgeneratecodethatexecutesthefunction.
GotoChapter11onPreprocessorDirectivesReturntoTableofContents

http://users.ece.utexas.edu/~valvano/embed/chap10/chap10.htm

11/11

2/3/2015

Chapter11:PreprocessorDirectivesValvano

Chapter11:PreprocessorDirectives
What'sinChapter11?
Using#definetocreatemacros
Using#ifdeftoimplementconditionalcompilation
Using#includetoloadothersoftwaremodules
Writinginlineassemblycode
Ccompilersincorporateapreprocessingphasethataltersthesourcecodeinvariouswaysbefore
passingitonforcompiling.FourcapabilitiesareprovidedbythisfacilityinC.Theyare:
macroprocessing
inclusionoftextfromotherfiles
conditionalcompiling
inlineassemblylanguage
ThepreprocessoriscontrolledbydirectiveswhicharenotpartoftheClanguageproper.Each
directivebeginswitha#characterandiswrittenonalinebyitself.Onlythepreprocessorsees
thesedirectivelinessinceitdeletesthemfromthecodestreamafterprocessingthem.
Dependingonthecompiler,thepreprocessormaybeaseparateprogramoritmaybeintegrated
intothecompileritself.Chasanintegratedpreprocessorthatoperatesatthefrontendofits
singlepassalgorithm.
MacroProcessing
Weusemacrosforthreereasons.1)Tosavetimewecandefineamacroforlongsequencesthat
wewillneedtorepeatmanytimes.2)Toclarifythemeaningofthesoftwarewecandefinea
macrogivingasymbolicnametoahardtounderstandsequence.TheI/Oport#definemacros
aregoodexamplesofthisreason.3)Tomakethesoftwareeasytochange,wecandefinea
macrosuchthatchangingthemacrodefinition,automaticallyupdatestheentiresoftware.
#defineNameCharacterString?...

definenameswhichstandforarbitrarystringsoftext.Aftersuchadefinition,thepreprocessor
replaceseachoccurrenceofName(exceptinstringconstantsandcharacterconstants)inthe
sourcetextwithCharacterString?....AsCimplementsthisfacility,thetermmacrois
misleading,sinceparameterizedsubstitutionsarenotsupported.Thatis,CharacterString?...does
notchangefromonesubstitutiontoanotheraccordingtoparametersprovidedwithNameinthe
sourcetext.
Cacceptsmacrodefinitionsonlyatthegloballevel.
TheNamepartofamacrodefinitionmustconformtothestandardCnamingconventionsas
describedinChapter2.CharacterString?...beginswiththefirstprintablecharacterfollowing
Nameandcontinuesthroughthelastprintablecharacterofthelineoruntilacommentisreached.
IfCharacterString?...ismissing,occurrencesofNamearesimplysqueezedoutofthetext.
Namematchingisbasedonthewholename(upto8characters)partofanamewillnotmatch.
Thusthedirective
#definesize10

willchange
http://users.ece.utexas.edu/~valvano/embed/chap11/chap11.htm

1/4

2/3/2015

Chapter11:PreprocessorDirectivesValvano

shortdata[size];

into
shortdata[10];

butitwillhavenoeffecton
shortdata[size1];

Replacementisalsoperformedonsubsequent#definedirectives,sothatnewsymbolsmaybe
definedintermsofprecedingones.
Themostcommonuseof#definedirectivesistogivemeaningfulnamestoconstantsi.e.,to
definesocalledmanifestconstants.However,wemayreplaceanamewithanythingatall,a
commonlyoccurringexpressionorsequenceofstatementsforinstance.TriggerPendSV()willset
bit20,triggeringaPendSV.SetPA5(0x20willsetPA5.Wait(500)willexecutetheloop500
times.
#defineTriggerPendSV(){NVIC_INT_CTRL_R=0x10000000;}
#defineSetPA5(x){GPIO_PORTA_DATA_R=(GPIO_PORTA_DATA_R&~0x20)|(x)};
#defineWait(t){intwait;for(wait=0;wait<(t);wait++){}};
#defineCONVERT4BPP(c)(((c)<<12)|((c)<<7)|((c)<<1))

Listing11.1:Exampleof#define

ConditionalCompiling
Thispreprocessingfeatureletsusdesignatepartsofaprogramwhichmayormaynotbe
compileddependingonwhetherornotcertainsymbolshavebeendefined.Inthiswayitis
possibletowriteintoaprogramoptionalfeatureswhicharechosenforinclusionorexclusionby
simplyaddingorremoving#definedirectivesatthebeginningoftheprogram.
Whenthepreprocessorencounters
#ifdefName

itlookstoseeifthedesignatednamehasbeendefined.Ifnot,itthrowsawaythefollowing
sourcelinesuntilitfindsamatching
#else

or
#endif

directive.The#endifdirectivedelimitsthesectionoftextcontrolledby#ifdef,andthe#else
directivepermitsustosplitconditionaltextintotrueandfalseparts.Thefirstpart(#ifdef...#else)
iscompiledonlyifthedesignatednameisdefined,andthesecond(#else...#endif)onlyifitis
notdefined.
Theconverseof#ifdefisthe
http://users.ece.utexas.edu/~valvano/embed/chap11/chap11.htm

2/4

2/3/2015

Chapter11:PreprocessorDirectivesValvano

#ifndefName

directive.Thisdirectivealsotakesmatching#elseand#endifdirectives.Inthiscase,however,if
thedesignatednameisnotdefined,thenthefirst(#ifndef...#else)oronly(#ifndef...#endif)
sectionoftextiscompiledotherwise,thesecond(#else...#endif),ifpresent,iscompiled.
Nestingofthesedirectivesisallowedandthereisnolimitonthedepthofnesting.Itispossible,
forinstance,towritesomethinglike
#ifdefABC
.../*ABC*/
#ifndefDEF
.../*ABCandnotDEF*/
#else
.../*ABCandDEF*/
#endif
.../*ABC*/
#else
.../*notABC*/
#ifdefHIJ
.../*notABCbutHIJ*/
#endif
.../*notABC*/
#endif

Listing11.2:Examplesonconditionalcompilation
wheretheellipsesrepresentconditionallycompiledcode,andthecommentsindicatethe
conditionsunderwhichthevarioussectionsofcodearecompiled.
Agoodapplicationofconditionalcompilationisinsertingdebugginginstrumemts.Inthis
exampletheonlypurposeofwritingtoPORTCisassistinperformancedebugging.Oncethe
systemisdebugged,wecanremoveallthedebuggingcode,simplybydeletingthe#defineDebug
1line.
#defineDebug1
intSub(intj){inti;
#ifdefDebug
PORTC|=0x80;/*PC7setwhenSubisentered*/
#endif
i=j+1;
#ifdefDebug
PORTC&=~0x80;/*PC7clearedwhenSubisexited*/
#endif
return(i);}
voidProgram(){inti;
#ifdefDebug
PORTC|=0x40;/*PC6setwhenProgramisentered*/
#endif
i=Sub(5);
while(1){PORTB=2;i=Sub(i);}}
voidProgB(){inti;
i=6;
#ifdefDebug
PORTC&=~0x40;/*PC6clearedwhenSubisexited*/
#endif
}

Listing11.3:Conditionalcompilationcanhelpinremovingalldebuggingcode

http://users.ece.utexas.edu/~valvano/embed/chap11/chap11.htm

3/4

2/3/2015

Chapter11:PreprocessorDirectivesValvano

IncludingOtherSourceFiles
Thepreprocessoralsorecognizesdirectivestoincludesourcecodefromotherfiles.Thetwo
directives
#include"Filename"
#include<Filename>

causeadesignatedfiletobereadasinputtothecompiler.Thedifferencebetweenthesetwo
directivesiswherethecompilerlooksforthefile.The<filename>versionwillsearchforthefile
inthestandardincludedirectory,whilethe"filename"versionwillsearchforthefileinthesame
directoryastheoriginalsourcefile.Thepreprocessorreplacesthesedirectiveswiththecontents
ofthedesignatedfiles.Whenthefilesareexhausted,normalprocessingresumes.
FilenamefollowsthenormalMSDOSfilespecificationformat,includingdrive,path,filename,
andextension.
InChapter10,anexampleusing#includewaspresentedthatimplementedafeaturesimilarto
encapsulatedobjectsofC++,includingprivateandpublicfunctions.

Inlineassembly
KeiluVisionusesthissyntaxtoembedassemblycodeintoCprograms
__asmvoid
Delay(unsignedlongulCount)
{
subsr0,#1
bneDelay
bxlr
}

Listing114:Exampleofanassemblyfunction
Codecomposerstudioimplementsassemblyfunctionsinasimilarmanner.
voidDelay(unsignedlongulCount){
__asm("subsr0,#1\n"
"bneDelay\n"
"bxlr\n");
}

Listing115:Exampleofanassemblyfunction.

ReturntoTableofContents

http://users.ece.utexas.edu/~valvano/embed/chap11/chap11.htm

4/4

2/3/2015

CDeclarationsAshortPrimer

CDeclarations:AShortPrimer
BasedonanarticlebyGregComeau,
publishedintheSeptember1998editionoftheMicrosoftSystemsJournal
Intheariticle"AGuidetoUnderstandingEventheMostComplexCDeclarations",GregComeaupresentsasetofrulesthatcanbeappliedtointerpret
anyCdeclarationhowevercomplexitmayseem.WhiletherulesareintuitiveandmightappealtomostadvancedCprogrammers,thebeginnermayfind
themdifficulttograsp.HedoeshoweverstartthearticlebypresentingasimplerulesettoreadandwriteKernighanandRitchie(ofthefamousbook,The
CProgammingLanguage,1978)styledeclarations.InthisPrimerIwillpresenttheserulesandelaboarteonthemwithexamples.
HereisthestandardsytaxforCDeclarations:
ThesytaxofaCdeclarationisoftheform:
storageclasstypequalifierdeclarator=initializer;
wherestorageclassisonlyoneofthefollowing:
typedef
extern
static
auto
register

Atypecouldbeoneormoreofthefollowing:
void
char
short,int,long
float,double
signed,unsigned
struct...
union...
typedeftype

Aqualifiercouldbeoneormoreofthefollowing:
const
volatile
Adeclaratorcontainsanidentifierandoneormore,ornoneatall,ofthefollowinginavarietyofcombinations:
*
()
[]

possiblygroupedwithinparenthesestocreatedifferentbindings

Thetermstorageclassreferstothemethodbywhichanobjectisassignedspaceinmemory.Chapter4oftheCPrimergivesdetaileddescriptionsofwhat
eachofthestorageclassesmean.Sufficeittosaythatunderstandingwhatisbeingdeclaredhasnobearingonthestorageclass,asitspecificallytells
youwhereitisbeingdeclaredandassignedspaceinmemory.Also,qualifiers(const,volatile)referrespectivelytothenonmodifiabilityofanentity,and
thefactthattheentityinquestionismodifiedelsewhere.Therefore,henceforthwewillignorethesetwopiecesofinformation.
Theabovedefinitionsimplysayswhatadeclarationoughttolooklike(thesyntaxthatis).Thekeyphraseintheabovedefinitionis"tocreatedifferent
bindings".Whatthismeansis,togivedifferentinterpretationstothedeclarationbasedonparenthesizingthedeclaration.Allonehastounderstandany
complexCdeclarationthen,istoknowthatthesedeclarationsarebasedontheCoperatorprecedencechart,thesameoneyouusetoevaluateexpressions
inC:
Precedence
highest

lowest

Operators
()[].>++(postfix)(postfix)
++(prefix)(prefix)!~sizeof(type)+(unary)(unary)&(address)*
(dereference)
*/%
+
<<>>
<<=>>=
==!=
&
^
|
&&
||
?:
=+==*=/=%=<<=>>=|=&=^=
,

Associativity
lefttoright
righttoleft
lefttoright
lefttoright
lefttoright
lefttoright
lefttoright
lefttoright
lefttoright
lefttoright
lefttoright
lefttoright
righttoleft
righttoleft
lefttoright

ThischartiscomplicatedbecauseitgivestheprecedenceandassociativityofallCoperators.Withdeclarations,weareonlydealingwithunarytokens
(unaryoperatorsneedonlyoneoperand)soitisalotsimplerTheoperatorsofinteresttousaremarkedinredintheabovetable.
So,herethenaretherulesforreadingandwritingCdeclarations:
1. Parenthesizedeclarationsasiftheywereexpressions.
2. Locatetheinnermostparentheses.
3. Say"identifieris"wheretheidentifieristhenameofthevariable.
a. Say"anarrayofX"ifyousee[X].
b. Say"apointerto"ifyousee*.
c. Say"Afunctionreturning"ifyousee()
4. Movetothenextsetofparentheses.
http://users.ece.utexas.edu/~valvano/embed/CDeclPrimer.html

1/3

2/3/2015

CDeclarationsAshortPrimer

5. Ifmore,gobackto3.
6. Else,say"type"fortheremainingtypeleft(suchasshortint)

Herearesomeexamplestoclarifythisprocess:
Example1:
inti;

Theparenthesizationoftheabovedeclarationis:
int(i);{1}

Applyingtherules(seeabove)totheparenthesizedexpressioncanbedoneasfollows:
Theinnermostparentesisis(i){2}
iisthevariablename,thereforewesay"iis..."{3}
Nomoreparenthesesleftsowesay"anint".{4,5,6}
Thatis,"iisanint"

Example2:
int*i;

Theparenthesizationoftheabovedeclarationis:
int(*(i));{1}

Applyingtherules(seeabove)totheparenthesizedexpressioncanbedoneasfollows:
Theinnermostparentesisis(i){2}
iisthevariablename,thereforewesay"iis..."{3}
Movetothenextsetofparenthesis:(*(i)){4}
Gobacktostep3.{5}
Wesay"apointerto"sinceweseea*{3.b}
Nomoreparenthesesleftsowesay"anint".{4,5,6}
Thatis,"iisapointertoanint"

Example3:
int*i[3];

Theparenthesizationoftheabovedeclarationis:
int(*((i)[3]));{1}//Notethat()and[]havethesame
//precedencebutwedealwiththemfromlefttoright.

Applyingtherules(seeabove)totheparenthesizedexpressioncanbedoneasfollows:
Theinnermostparentesisis(i){2}
iisthevariablename,thereforewesay"iis..."{3}
Movetothenextsetofparenthesis:((i)[3]){4}
Gobacktostep3.{5}
Wesay"anarrayof3..."sinceweseea[3]{3.a}
Movetothenextsetofparenthesis:(*((i)[3])){4}
Gobacktostep3.{5}
Nomoreparenthesesleftsowesay"ints".{4,5,6}
Thatis,"iisanarrayof3ints"

Example4:
int(*i)[3];

Theparenthesizationoftheabovedeclarationis:
int((*(i))[3]);{1}//Notethatparenthesesarevalidtokens
//inadeclarationandthereforemustbe
//beleftinplacewhenfindingthefinal
//parenthesization

Applyingtherules(seeabove)totheparenthesizedexpressioncanbedoneasfollows:
Theinnermostparentesisis(i){2}
iisthevariablename,thereforewesay"iis..."{3}
Movetothenextsetofparenthesis:(*(i)){4}
Gobacktostep3.{5}
Wesay"apointerto..."sinceweseea*{3.b}
Movetothenextsetofparenthesis:((*(i))[3]){4}
Gobacktostep3.{5}
Wesay"anarrayof3..."sinceweseea[3]{3.a}
Nomoreparenthesesleftsowesay"ints".{4,5,6}
Thatis,"iisapointertoanarrayof3ints"

Example5:
int*i();

Theparenthesizationoftheabovedeclarationis:
int(*((i)()));{1}//Notethat*hasalowerprecedencethan
//parentheses,()

Applyingtherules(seeabove)totheparenthesizedexpressioncanbedoneasfollows:
Theinnermostparentesisis(i){2}
//Onecouldarguethat()isalsotheinnermostparenthesisbut
//itdoesnotcontainanythingsoweknowitmustindicate
//afunction
iisthevariablename,thereforewesay"iis..."{3}
Movetothenextsetofparenthesis:((i)()){4}
Gobacktostep3.{5}
Wesay"afunctionreturning"sinceweseea(){3.c}
Movetothenextsetofparenthesis:(*((i)())){4}
Gobacktostep3.{5}
Wesay"apointerto..."sinceweseea*{3.b}
Nomoreparenthesesleftsowesay"anint".{4,5,6}
Thatis,"iisafunctionreturningapointertoanint"

Example6:
int(*i)();

Theparenthesizationoftheabovedeclarationis:
int((*(i))());{1}//Notethatparenthesesarevalidtokens
//inadeclarationandthereforemustbe
//beleftinplacewhenfindingthefinal
//parenthesization

Applyingtherules(seeabove)totheparenthesizedexpressioncanbedoneasfollows:
Theinnermostparentesisis(i){2}
iisthevariablename,thereforewesay"iis..."{3}
Movetothenextsetofparenthesis:(*(i)){4}
Gobacktostep3.{5}

http://users.ece.utexas.edu/~valvano/embed/CDeclPrimer.html

2/3

2/3/2015

CDeclarationsAshortPrimer
Wesay"apointerto"sinceweseea*{3.b}
Movetothenextsetofparenthesis:((*(i))()){4}
Gobacktostep3.{5}
Wesay"afunctionreturning"sinceweseea(){3.c}
Nomoreparenthesesleftsowesay"anint".{4,5,6}
Thatis,"iisapointertoafunctionreturninganint"

ThisistheprettymuchalloneneedstoknowtoreadandwritedeclarationsinC.

http://users.ece.utexas.edu/~valvano/embed/CDeclPrimer.html

3/3

Das könnte Ihnen auch gefallen