You are on page 1of 87

Notes on 6

Ken 6|owes
Copyr|grl @ 2001 K. C|oWes
Revision History
Revision 1.4 December 2004

%,-|e of 6ontents
!reface
1. Latest (last?) version
1. Tutorial Introduction to C
1.1. Software and Computer Languages
1.2. Evolution of C
1.3. Warning: C may be ~dangerous
1.4. Overview of Basic C
1.5. Examples
1.6. Some details
1.6.1. Using printf() formatting
1.6.2. Character Escape Sequences
1.7. Using functions
1.7.1. Centimetres to Inches (version 2)
1.8. Simple data conversion (Filters)
1.8.1. Copying input to output
1.8.2. Translating lower case to upper case
1.9. Casts
1.10. I/O redirection and piping
1.10.1. !iping
2. Basic C Syntax
2.1. Fundamental Data Types
2.2. Declarations
2.2.1. Enumerated (0num) types
2.3. Constants
2.3.1. Examples
2.4. Operators and Expressions
2.4.1. Arithmetic operators
2.4.1.1. Differences between pre- and post- operators
2.4.2. Logical Operators
2.4.3. The assignment operator
2.4.4. The 8iz04f operator
2.4.4.1. Example
2.5. Simple & block statements
2.6. Flow Control
2.6.1. if statement
2.6.2. if...080 statement
2.6.3. While loop
2.6.4. Expressions in conditionals
2.6.5. Do ... while loop
2.6.6. For loop
2.6.6.1. Examples
2.6.6.2. Break and Continue statements
2.6.6.3. Switch statement
2.7. Bit Operators
2.7.1. Examples
2.8. Expanded Assignment Statements
2.9. Conditional (?) operator
2.10. The Comma (,) operator
3. !roject management and make
3.1. Using separate source code files
3.2. Scope of variable names
3.2.1. Notes
3.3. Make
3.3.1. A Simple Example
3.3.2. Compilation example
3.3.3. Additional remarks
3.3.4. Using generic rules
3.3.5. !arting remarks
4. Basic Arrays and !ointers
4.1. Arrays
4.2. !ointers
4.2.1. The & Operator
4.2.2. !ointer Arithmetic
4.2.2.1. Strings are character pointers
4.3. Arrays and !ointers
4.4. Functions
4.4.1. Examples
4.4.2. Differences between ANSI and K&R C
4.5. Examples of pointers
4.5.1. Comamnd line arguments
4.5.2. Variable Number of Arguments
4.5.2.1. 8tdarg() right way to handle variable number of arguments
5. !ointers to functions
5.1. Complex declarations
6. !arsing
6.1. Compilers: An Overview
6.1.1. Lexical analysis
6.1.2. !arsing
6.1.2.1. !arsing C declarations
7. Data Structures
7.1. Structures and Unions
7.2. Structure Examples
7.3. Using typ0d0f
7.4. !ointers to structures
7.5. Single Linked List Example
7.6. Initializing Linked lists in declarations
7.7. Unions
7.8. Example: Doubly Linked List
7.8.1. Header file d4ub0ink0di8t.h
7.8.2. Main routine
7.8.3. !rint list
7.8.4. Notes
8. The !reprocessor
8.1. Using the !reprocessor
8.1.1. #include
8.1.2. #define
8.1.3. ifd0f and ifnd0f
8.1.4. und0f
8.1.5. ANSI C preprocessor
9. The Standard library
9.1. Strings
9.2. ctype.h
9.2.1. Implementation of .typ0.h
9.3. 8tdi4.h
9.3.1. File I/O
9.3.1.1. Opening a file
9.3.1.2. Writing to a file
9.3.1.3. Reading a file
9.3.1.4. Closing a file
9.4. a880rt.h
9.5. Memory
9.6. 8tdarg.h
9.7. Handling errors
10. Data-driven !rogramming
10.1. Example-Finite State Machine
10.1.1. The BAD Way
10.1.2. A BETTER Way
10.1.3. Doing It All Automatically
10.1.3.1. Example
10.1.3.2. Notes
10.2. Example-FSM and function pointers
10.3. Menu Driven Code
Bibliography
Pref,.e
%re or|g|ra| vers|or ol lrese 'Noles or C Were Wr|ller |r lre r|d 1980's as a sel ol s||des lor a ser|rar l
gave or C prograrr|rg.
0ver lre years, l relerred sluderls lo lre 'Noles or C lor var|ous courses. l a|so updaled lre or|g|ra|
roles 3 or 1 l|res. w|lr eacr updale, lre or|g|ra| s||des oecare rore |||e roles (ard, sorel|res, ever
rad a ooo|-|||e qua||ly).
loWever, s|rce l or|y updaled secl|ors |r a raprazard Way, lre resu|l Was rol as ur|lorr ard cors|slerl
as l Wou|d rave |||ed.
1. L,test (|,st?} vers|on
lr Jaruary, 2005, l slarled lo rev|se lre Wro|e lr|rg |r lWo Ways:
O Crarge lre rar|up |arguage l used lo aulror lre roles lror La%ex lo XVL (us|rg lre 0ocooo|
0%0).
O Va|e r|ror corlerl crarges lo ra|e lre roles rore ur|lorr ard lo e||r|rale sore relererces
lral are ro |orger recessary.
%re resu|ls?
we||, lre corvers|or lror La%eX lo XVL Was lar rore l|re-corsur|rg ard led|ous lrar l rad arl|c|paled.
Norelre|ess, lre (a|rosl) lola| separal|or ol |og|ca| corlerl ard lorr (rerd|l|or) ras cors|derao|e
advarlages.
%re corlerl d|d rol crarge very rucr. l e||r|raled rary (oul rol a||) corpar|sors oelWeer K&R C ard
AN3l/l30 C. (%re or|g|ra| s||des Were Wr|ller Wrer AN3l C Was a ralure proposa| oul rol yel oll|c|a|.) l
a|so reroved rary corpar|sors oelWeer C ard Pasca| (Wr|cr rad oeer a popu|ar |arguage |r lre
1980s)
%rere rera|r, ol course, rary Warls, l|aWs ard oul-ard-oul errors |r lrese Noles. Norelre|ess, l Warl lo
rove or: |el lre Warls ard l|aWs rera|r. l W|||, roWever, l|x oul-ard-oul errors lral are orougrl lo ry
allerl|or. (Nole: oy oul-ard-oul error, l rear sorelr|rg lral |s |r c|ear corlrad|cl|or W|lr lre AN3l/l30 C
3lardard. l do rol rear corlerl lral |s 'urc|ear, 'aro|guous, 'ug|y, '|rcorp|ele, elc.)
6h,5ter 1. %:tor|,| |ntrod:.t|on to 6
1.1. 8oftw,re ,nd 6om5:ter L,ng:,ges
%,-|e 1.1. Progr,mm|ng L,ng:,ges
LANGUAGE A!!LICATION
ssembler LoW |eve| prograrr|rg ol sra|| app||cal|ors or 8-o|l corlro||ers.
3|rp|e syslers prograrr|rg |arguage a||oW|rg access lo urder|y|rg racr|re lealures.
0ojecl or|erled exlers|or lo C.
LANGUAGE A!!LICATION
,v, Ar oojecl-or|erled |arguage W|lr C-|||e syrlax. A very porlao|e |arguage.
1.2. Evo|:t|on of 6
1. |arguage (oased or CPL) Wr|ller oy 0err|s R|lcr|e al e|| Laos |r ear|y 'Z0s as l|rsl pass |r
Wr|l|rg uNlX |r a r|gr |eve| |arguage.
2. Was a lype|ess |arguage (|l accessed racr|re dala |||e oyles ard Words W|lroul relererce lo
lre |rlerprelal|or ol lre corlerls; |.e. 32-o|l |rlegers or 32-o|l l|oal|rg po|rl ruroers Were s|rp|y
relerred lo as uoros).
3. Was soor lrarslorred |rlo a Wea||y lyped |arguage: C.
1. C Was del|red |r lre l|rsl ed|l|or (19Z8) ol lre Kerr|grar ard R|lcr|e ooo| Tne 0 Proramm|n
lanuae KardRZ8. we W||| reler lo lr|s as rrao|r|ona| 0. (ll |s a|so ca||ed r&R 0.)
5. %re syrlax ol lrad|l|ora| C Was del|red rore prec|se|y oy AN3l (Arer|car Nal|ora| 3lardards
lrsl|lule).
. ur|ess olrerW|se slaled, We use AN3l C rere.
Z. AN3l del|res lWo slardards |r C:
reest,nd|ng 6
0escr|oes lre 5ure |arguage |lse|l.
8t,nd,rd L|-r,ry
0el|res a sel ol lurcl|ors ard del|r|l|ors lral rusl oe supp||ed oy a corp||er |r order lo oe lu||y
AN3l-corp||arl.
8. %re 6++ |arguage |rcorporales oojecl or|erled prograrr|rg pracl|ces.
1.3. w,rn|ng: 6 m,y -e "d,ngero:s"
1. %re des|grers ol C Warled lo use lre |arguage lor syslers prograrr|rg. Corsequerl|y, lrey
requ|red:
O C oe sull|c|erl|y poWerlu| lo access rary aspecls ol lre urder|y|rg rardWare ard do
lr|rgs lral Wou|d rorra||y requ|re assero|y |arguage.
O C produce very ell|c|erl code.
2. For exarp|e, C car lreal dala oojecls as jusl 'o|l pallerrs |r lre sare Way lral ar assero|y
|arguage prograrrer car. 3|r||ar|y, a C prograrrer car rar|pu|ale ar address |||e ar
'ord|rary ruroer ard lrer access lre rerory |ocal|or(s) relererced oy lr|s 'ruroer |r ary
Way re or sre sees l|l. wr||e lrese lealures are des|rao|e, lrey core al a cosl. Vosl
|rporlarl|y:
O %rere |s no run r|me oneok|n |r C. 3pec|l|ca||y:
o 0verl|oW ol |rleger va|ues |s rol delecled al rur l|re.
o %rere |s ro rur-l|re crec||rg ol array |rd|ces lo see |l lrey are W|lr|r lre
dec|ared oourds ol lre array. Access oeyord lre ||r|ls ol ar array W||| rol
cause a rur-l|re error |r ar urprolecled 03 sucr as V3-003. ll ray or
ray rol resu|l |r a segrerlal|or v|o|al|or |r a prolecled 03 sucr as
w|rdoWs/N% or uNlX.
o Verory relererces car po|rl aryWrereever Wrere lrey srou|d rol po|rll
O C prograrrer's car use ry5e oasr|n lo rod|ly lre dala lype ol ar oojecl al rur l|re.
%rere |s scarl crec||rg lral sucr lype casl|rg ra|es ary serse.
1.4. 0verv|ew of ,s|. 6
A C prograr cors|sls ol:
O ero or rore dec|aral|ors ol g|ooa| var|ao|es (del|red ouls|de ol ary lurcl|ors).
O 0re or rore lurcl|ors cors|sl|rg ol a name, a (poss|o|y erply) ||sr ol arumenrs erc|osed |r
parerlres|s, ard a lunor|on oooy cors|sl|rg ol a oom5ouno sraremenr.
O A oom5ouno sraremenr |s erc|osed |r cur|y oraces ard cors|sls ol:
o ero or rore dec|aral|ors ol |ooa| var|ao|es lral ex|sl or|y W|lr|r lre corpourd
slalererl.
o ero or rore sraremenrs. A slalererl |s e|lrer:
O Arolrer corpourd slalererl; or,
O A s|rp|e slalererl (e.g. ass|grrerl) lerr|raled W|lr a ser|-co|or.
O Pre5rooessor o|reor|ves (Wr|cr oeg|r W|lr a # ard are lrarslorred |rlo 'raW C oy lre
preprocessor oelore lre C corp||er aclua||y |oo|s al lre source code.
O F|ra||y, a C prograr car rave ary ruroer ol oommenrs de||r|led oy / ard /.
Noles: O %rere are or|y lunor|ons |r C. %rere are ro suoroul|re or prograr o|oc|s. (loWever,
lre lurcl|or ca||ed main(...) W|||, urder rosl 03's, del|re lre erlry po|rl lo lre
prograr. %re main() lurcl|or relurrs ar |rleger va|ue lral lre 03 usua||y |rlerprels
as a relurr code.
O C |s not a o|oc|-slruclured |arguage |||e Pasca| or Ada. (|.e. Furcl|ors oannor oe
dec|ared |rs|de a lurcl|or.)
1.5. Ex,m5|es
we roW |rlorra||y e|aoorale or lrese po|rls W|lr sore sarp|e progrars.
Ex,m5|e 1.1. h04..
%re l|rsl prograr s|rp|y oulpuls lre ressage Hello world!.
1 /
First C Program: hello.c
Displays message: Hello, world!
/
5
int main()
,
printf("Hello, world!\n");
return 0; / or, better, exit(0); /
10 ,

(%re source code l||e re||o.c |s ava||ao|e.)
%re ra|r lurcl|or o|oc| cors|sls ol 2 s|rp|e slalererls: %re l|rsl slalererl uses lre sranoaro ||orary
printf(...) lurcl|or. lls argurerl |s a slr|rg ol craraclers Wr|cr |s oulpul.
%re relurr slalererl lerr|rales lre ra|r lurcl|or relurr|rg lre va|ue ol 0 (R0) lo lre ca||er, |r lr|s
case lre operal|rg sysler. lr ary lurcl|or, lre return returnValue slalererl W||| relurr lo lre ca||er;
roWever, lre exit(int returnCode) slalererl W||| a|Ways lerr|rale lre erl|re prograr ard relurr |ls
returnCode lo lre 03.
For lre main() lurcl|or, lrere |s ro d|llererce oelWeer return(0) ard exit(0).
Ex,m5|e 1.2. A 8|m5|e |oo5
%re lo||oW|rg s|rp|e prograr pr|rls oul a lao|e corverl|rg |rcres lo cerl|relres.
(%re source code l||e |erglrCorvers|or.c |s ava||ao|e.)
1 /
Summary: Prints a table of Centimetres vs. Inches
/
#include <stdlib.h (1)
5 #define CM_PER_INCH 2.54 (2)
#define SMALL_LENGTH_CM 1.0
#define BIG_LENGTH_CM 4.0
#define DIFF_LENGTH 0.5
int main()
10 ,
double cm, inch;(3)

cm = SMALL_LENGTH_CM;

15 printf("Centimetres Inches\n");
printf("____________________\n");
while(cm <= BIG_LENGTH_CM) ,(4)
inch = cm / CM_PER_INCH;
printf(" %4.1f %4.2f\n", cm, inch);(5)
20 cm = cm + DIFF_LENGTH;
,
exit(0);
,

1)
%re #include <stdlib.h slalererl |s a 5re-5rooessor o|reor|ve lo |rserl lre rared l||e |rlo
lre source code. %re parl|cu|ar l||e |rc|uded (stdlib.h) corla|rs del|r|l|ors ol corslarls ard olrer
slalererls requ|red Wrer cerla|r slardard lurcl|ors are used. lr lr|s case, |l |s requ|red so lral lre
exit() lurcl|or |s urderslood.
2)
%re #define slalererls are |rlerpreled oy lre preprocessor so lral suosequerl use ol lre del|red
rare |s rep|aced oy lre del|red va|ue.
%rus, lo||oW|rg #define BIG_LENGTH_CM 5.0, every occurrerce ol BIG_LENGTH_CM |s
rep|aced oy lre corslarl 5.0.
%r|s pracl|ce ol us|rg syroo||c corslarls |s slrorg|y recorrerded lor severa| reasors:
O %re prograr |s rore readao|e.
O 'Vag|c ruroers are |so|aled |r lre #define slalererls. 0ller, lre overa|| oerav|or ol a
prograr |s very deperderl or lre spec|l|c va|ues ol lrese rag|c ruroers. wrer lrey are
|so|aled |r #define slalererls al lre oeg|rr|rg ol a prograr, lre prograr's oerav|or
car oe rod|l|ed s|rp|y oy crarg|rg lre del|red va|ues. w|lr good syroo||c rares ard
correrls, |l |s oller poss|o|e lo ra|e lr|s ||rd ol crarge lo a prograr W|lroul
urderslard|rg or ever |oo||rg al lre aclua| code.
O wrer lre sare rag|c ruroer appears rore lrar orce |r a prograr, |l |s |ess |||e|y lral
lre Wrorg va|ue W||| oe lyped |r due lo a lypograpr|ca| error. Furlrerrore, |l oecores
rucr eas|er ard |ess error-prore lo crarge lre rag|c ruroer oy ed|l|rg lre #define
|rslead ol s|ogg|rg lrrougr lre source code lo l|rd lre |rslarces ol lre ruroer.
)
A|| var|ao|es rusl oe oeo|areo |r C oelore lrey are used. %re dec|aral|or 'double cm, inch
dec|ares lre var|ao|es inch ard cm lo oe oouo|es (|.e. l|oal|rg po|rl ruroers).
4)
%re oody ol lre while |oop |s execuled ur|ess lre cord|l|or lesled lor |r lre while(condition)
slalererl |s la|se. %re lesl |s rade oelore lre oody |s execuled ard aga|r oelore execul|rg lre
oody arolrer l|re. (lerce, |l lre cord|l|or |s la|se al lre oulsel, lre |oop oody |s rol execuled al
a||.)
lr lr|s case, lre |oop oody |s execuled |l cm |s |ess lrar or equa| lo lre rag|c ruroer
BIG_LENGTH_CM.
%re cm var|ao|e |s |rcrererled al lre erd ol lre |oop ard lre |oop execuled aga|r |l lre while
cord|l|or |s sl||| lrue.
lr lr|s case, lre |oop oody |s execuled Z l|res lor lre va|ues ol 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, ard 1.0.
)
%re slalererl
printf(" %4.1f %4 .2f\n", cm, inch);
|r lre Wr||e |oop corla|rs lorrall|rg corrards |rlroduced oy a |r lre l|rsl argurerl.
Prev|ous printf() slalererls rave s|rp|y ecroed lre lorrall|rg slr|rg lo lre oulpul. %re
craracler |rd|cales lral arolrer argurerl ras oeer passed lo printf; lre craracler(s) lo||oW|rg
lre `' |rd|cale roW lre argurerl |s lo oe pr|rled oul.
lr lr|s case, lre '%4.1f lorrall|rg corrard |rd|cales lral lre argurerl |s a l|oal|rg po|rl
ruroer, lral |l |s lo oe pr|rled |r al |easl 1 co|urrs ard lral ore d|g|l aller lre dec|ra| po|rl srou|d
oe pr|rled.
%re oulpul ol lr|s prograr |s:
Centimetres Inches
____________________
1.0 0.39
1.5 0.59
2.0 0.79
2.5 0.98
3.0 1.18
3.5 1.38
4.0 1.57

1.. 8ome det,||s
1..1. Us|ng printf() form,tt|ng
%re lo||oW|rg lao|e sroWs lre rosl corror lorrall|rg corrards used |r printf() lorrall|rg slr|rgs.
%,-|e 1.2. Pr|ntf form,tt|ng
Format Meaning
%d
|rleger as a s|gred dec|ra| ruroer
%x
|rleger as ar urs|gred rexadec|ra| ruroer
%o
|rleger as ar urs|gred ocla| ruroer
%u
|rleger as ar urs|gred dec|ra| ruroer
%c
a craracler
%s
a slr|rg
%f
a l|oal|rg po|rl ruroer
%e
a l|oal|rg po|rl ruroer
%%
a ||lera| `' craracler
%e
a l|oal|rg po|rl ruroer
Format Meaning
%g
a l|oal|rg po|rl ruroer
elWeer lre ard lre dala lype spec|l|er, a ruroer car oe used lo spec|ly lre r|r|rur space
a||ocaled lor lre resu|l. %rus '%4d Wou|d pr|rl lre |rleger 23 W|lr 2 |ead|rg spaces. (%re W|dlr qua||l|er |s
a r|r|rur W|dlr: lrus '%2d used lo pr|rl lre |rleger 123 Wou|d rol crop oll lre |ead|rg 1; lre W|dlr
Wou|d oe |rcreased lo 3 lo accorrodale a|| lre d|g|ls.)
1..2. 6h,r,.ter Es.,5e 8eq:en.es
%re lao|e oe|oW g|ves corror escape sequerces lo spec|ly spec|a| craraclers |r slr|rgs.
%,-|e 1.3. 85e.|,| .h,r,.ters |n str|ngs
Notation Character
\b
ac|space
\f
Forr leed
\n
NeW||re
\r
Carr|age relurr
\t
%ao
\\
ac|s|asr
\"
0ouo|e quole
\'
3|rg|e quole
\ddd
0cla| represerlal|or
\xxx
lex represerlal|or
1.7. Us|ng f:n.t|ons
Furcl|ors car oe used ard del|red |r C lo relurr a va|ue deperderl or lre argurerls g|ver.
For exarp|e, We cou|d del|re a lurcl|or lo corverl cerl|relres lo |rcres as lo||oWs:
(%re source code l||e cr2|rcr.c |s ava||ao|e.)
/
double cm2inch(double cm)

SUMMARY:
Description: Converts cm to inches
/

#define CM_PER_INCH 2.54

double cm2inch(double cm) (1)
,
return cm CM_PER_INCH;
,

1)
%re ||re double cm2inch(double cm) dec|ares lre lurcl|or as relurr|rg a douo|e-prec|s|or
l|oal|rg po|rl va|ue ard la||rg a douo|e parareler, ca||ed cr, as ar argurerl.
%oy exarp|e: %r|s exarp|e |s a o|l 'over lre lop. %yp|ca||y, sucr a s|rp|e
ca|cu|al|or Wou|d oe d|recl|y eroedded |r lre source code
(or del|red as a maoro).
1.7.1. 6ent|metres to |n.hes (vers|on 2}
we car roW re-Wr|le lre main() ol lre or|g|ra| prograr as sroWr oe|oW.
(%re source code l||e |erglrCorvers|orv2.c |s ava||ao|e.)
1 /
Summary: Prints a table of Centimetres vs. Inches
/
#include <stdlib.h
5 #include <stdio.h
double cm2inch(double ); (1)
#define BIG_LENGTH_CM 4.0
#define DIFF_LENGTH 0.5
int main()
10 ,
double cm;

cm = SMALL_LENGTH_CM;

15 printf("Centimetres Inches\n");
printf("____________________\n");
while(cm <= BIG_LENGTH_CM) ,
printf(" %4.1f %4.2f\n", cm, cm2inch(cm));
cm = cm + DIFF_LENGTH;
20 ,
exit(0);
,

1)
%re double cm2inch(double ); slalererl |s a lunor|on 5rorory5e |rlorr|rg lre corp||er lre
dala lype relurred ard lre lype(s) ol lre passed parareler(s).
1.8. 8|m5|e d,t, .onvers|on (||ters}
0re ol lre rosl corror |d|ors |r C progrars |s lo read |rpul ore craracler al a l|re, perlorr sore
process|rg or |l, ard oulpul |l ore craracler al a l|re.
1.8.1. 6o5y|ng |n5:t to o:t5:t
lr lre s|rp|esl l||ler prograr, We s|rp|y copy lre |rpul lo lre oulpul. (%re source code l||e copy|r.c |s
ava||ao|e.)
/
Copyin copies its input to the output one character
at a time.
/

#include <stdio.h
main()
,
int ch; (1)

ch = getchar(); / get next input character /
/ loop until "End Jf File" is reached /
while (ch != EJF) ,
putchar(ch); / Jutput the character /
ch = getchar(); / Read next character /
,
exit(0);
,
1)
O Nole lral ch (lre relurr va|ue ol getchar()) |s dec|ared as ar int, not a char.
O wry?
O %re getchar() relurrs ar |rleger rol a craracler. lr lr|s Way, a spec|a| |rleger va|ue
lral does rol correspord lo ary aclua| craracler car oe used lo s|gra| erd-ol-l||e.
%re spec|a| va|ue |s del|red |r stdio.h as lre syroo||c corslarl EJF. (Nole lral EJF |s
a|rosl a|Ways del|red as oe|rg -1. loWever, you srou|d rol re|y or lr|s.)
%re while cord|l|or '(ch != EJF) rears lral lre oody srou|d oe execuled |l lre erd-
ol-l||e ras rol oeer reacred.
%re lurcl|or putchar(ch) oulpuls lre craracler g|ver as ar argurerl.
ll |s good pracl|ce lo ra|e lre |asl slalererl |r a prograr lre exit(value) slalererl:
a va|ue ol zero srou|d oe used lor a prograr lral lerr|raled rorra||y; ary olrer va|ue
|rd|cales aororra| lerr|ral|or.
1.8.2. %r,ns|,t|ng |ower .,se to :55er .,se
A s||grl|y rore corp|ex exarp|e |rvo|ves corverl|rg lre |rpul craraclers lror |oWer lo upper case.
(%re source code l||e loupper.c |s ava||ao|e.)
#include <stdio.h
main()
,
int ch;
ch = getchar();
while ( ch != EJF) ,
if ( ch = 'a' && ch <= 'z' ) / if lower case / (1)
ch = ch + 'A' - 'a'; / convert it to upper / (2)
putchar(ch);
ch = getchar();
,
,

1)
%r|s if slalererl |s lrue |l ch ||es |r lre rarge ol craraclers oelWeer 'a' ard 'z'.
2)
Corceplua||y, lre craracler |s corverled lo upper case oy suolracl|rg lre code lor ar 'a' (y|e|d|rg
ar |rleger oelWeer 0 ard 25) ard lrer add|rg lre code lor ar 'A'. Nole lral lre express|or 'A' -
'a' |s a corslarl (W|lr lre va|ue 32 lor A3Cll craracler ercod|rg) Wr|cr W||| oe eva|ualed al
corp||e l|re, rol al rur l|re. Nole a|so lral Wr|l|rg lre code lr|s Way ra|es |l |rdeperderl ol lre
parl|cu|ar craracler ercod|rg used (eg. A3Cll vs. Cl0lC).
Nole: Nole lral lre aoove prograr cou|d oe Wr|ller rore
c|ear|y as:
#include <stdio.h
main()
,
int ch;
while((ch = getchar()) != EJF) ,
if ( ch = 'a' && ch <= 'z' )
ch = ch +'A' - 'a';
putchar(ch);
,
,


F|ra||y, ar exper|erced C prograrrer Wou|d prooao|y
Wr|le: (%re source code l||e loupper3.c |s ava||ao|e.)
#include <ctype.h
#include <stdio.h
main()
,
int ch;
while ((ch = getchar()) != EJF) ,
putchar(islower(ch) . ch + 'A' -
'a' : ch);
/ JR simply:
putchar(toupper(ch)); /
,
,


wrer We |oo| al C |r rore dela|| |aler or, We W||| see
roW lrese rore ell|c|erl vers|ors Wor|.
1.9. 6,sts
O 0rce a var|ao|e ras oeer dec|ared, |l |s poss|o|e lo lorce |l lo arolrer lype W|lr a oasr.
O %re coerc|or lo arolrer lype |s dore oy preced|rg lre express|or W|lr lre rare ol dala lype We
Warl |r parerlres|s.
O For exarp|e, lo pr|rl oul lre |rleger i as a l|oal|rg po|rl ruroer, use:
printf("%f\n", (float) i);
O w|lroul lre casl, lre oulpul Wou|d oe garoage.
O Casls are espec|a||y uselu| Wrer 5o|nrers are used as We sra|| see Wrer We |oo| al po|rler
var|ao|es.
1.10. ||0 red|re.t|on ,nd 5|5|ng
wrer We la|| aooul '|rpul ard 'oulpul, We srou|d rea||y say sro|n (lor sranoaro |n5ur) ard sroour (lor
sranoaro our5ur). %re C ||orary lurcl|ors |||e printf(), putchar() ard getchar() aclua||y
rar|pu|ale lre 'l||es sro|n or sroour ard |l |s lre 0peral|rg 3ysler lral del|res Wral lrese 'l||es are.
urder oolr uNlX ard V|crosoll operal|rg syslers, sro|n |s oy delau|l lre |eyooard |rpul ard sroour |s lre
screer. loWever, oolr 0peral|rg 3yslers a||oW sro|n ard/or sroour lo oe redel|red al lre l|re lre
corrard |s |rvo|ed. 0r lre corrard ||re, < file_name_in |s used lo redel|re sro|n ard
file_name_out redel|res sroour.
%rus, assur|rg lre corrard .o5y|n cop|es sro|n lo sroour, We car Wr|le:
copyin < copyin.c copyin.bak

lo copy lre l||e copyin.c lo copyin.bak.
3|r||ar|y:
up1 < copyin.c copyin.up

creales a copy ol copyin.c W|lr a|| lre |oWer case |ellers corverled lo upper case |r lre l||e copyin.up
w|lr lr|s uselu| lr|c|, We car avo|d |earr|rg aooul roW lo use l||es url|| |aler or.
1.10.1. P|5|ng
olr uNlX ard w|rdoWs a|so a||oW lWo corrards lo oe jo|red logelrer so lral sroour ol ore oecores
sro|n ol lre secord. %r|s |s ca||ed a 5|5e||ne ard lre `j' craracler (verl|ca| oar) |s used lo spec|ly a
p|pe||re.
For exarp|e:
lengthConversion | toupper3

d|recls lre oulpul ol lre |ength6onvers|on corrard |rlo lre |rpul ol lre to:55er3 corrard. %re resu|l
|s lral a|| lre |oWer case |ellers |r lre rorra| oulpul ol |ength6onvers|on are corverled lo upper case.
we car coro|re lrese |deas W|lr:
lengthConversion | toupper3 lengthConversion.out

6h,5ter 2. ,s|. 6 8ynt,x
2.1. :nd,ment,| 0,t, %y5es
|ntegers (int}:
O up lo 3 s|zes ol |rlegers: 8h4rt, 4ng ard delau|l int;
O 0r rosl syslers: long ard int are 32 o|ls; short |s 1 o|ls.
O lrlegers car oe s|gred or urs|gred. For r-o|l (s|gred) |rlegers,
-2
r-1
> |rl > 2
r-1
-1
For r-o|l urs|gred |rlegers,
0 > urs|gred > 2
r
-1
Ex,m5|e 2.1. A|| one's -|t 5,ttern
%re o|l pallerr 1111...11 represerls -1 |l |rlerpreled as a s|gred ruroer or 2
r
-1 |l
|rlerpreled as urs|gred. (we assure lral s|gred ruroers use lre ruo's oom5|emenr
corverl|or Wr|cr |s a|rosl ur|versa||y adopled.)
%rus lre slalererl:
printf("-1 (signed): %d; -1 (unsigned) %u, -1 (hex) 0x%x\n", -1, -1, -1);

produces lre oulpul (or a racr|re Wrere ints are 32 o|ls):
-1 (signed): -1; -1 (unsigned) 4294967295, -1 (hex) 0xffffffff

(%re source code l||e pr|rllV|rus0re.c |s ava||ao|e.)
6h,r,.ter (.har}:
8 o|ls. usua||y |rlerpreled as s|gred. (AN3l C a||oWs spec|l|cal|or ol s|gred or urs|gred
craraclers.)
#e,|s
Rea| ruroers are (polerl|a||y) |rexacl. C prov|des lWo gerer|c lypes: float ard double.
Vosl corp||ers use lre l slardard lo represerl rea| ruroers. F|oals are usua||y 32 o|ls,
douo|es 1 o|ls.
No ooo|ear
lype:
%rere |s ro ooo|ear lype. lrlegers are used |rslead. Fa|se |s represerled as 0; lrue as
ary olrer va|ue.
%re lao|e oe|oW surrar|zes lre pr|r|l|ve dala lypes.
%,-|e 2.1. :nd,ment,| %y5e 8:mm,ry
[1j

Name Size (bits) Range
int
32 -2
31
...2
31
-1
long
32 -2
31
...2
31
-1
short
1 -2
15
...2
15
-1
unsigned
32 0...2
32
-1
unsigned long
32 0...2
32
-1
unsigned short
1 0...2
1
-1
unsigned char
8 0...2
8
-1
char
8 -2
Z
...2
Z
-1
float
32 -1.210
-38
...3.110
38

double
1 -2.210
-308
...1.810
308

2.2. 0e.|,r,t|ons
Ex,m5|e 2.2. 0e.|,r,t|ons
int i, j, k; (1)
short ii, jj; (1)
unsigned short lll_5; (1)
char ch, input_char; (1)
double big_or_small; (1)
int aVeryLong_NameMoreThanThirtyTwoCharacters; (1) (2)
unsigned _foo; (1) (3)
char CH; (1) (4)

1)
Nole lral craraclers |r rares car oe ary |eller, ar urderscore (_), or a d|g|l oul carrol oeg|r W|lr
a d|g|l.
2)
Nares are sorel|res ||r|led lo 1 or 32 craraclers.
)
Nares may oeg|r W|lr ar urderscore; roWever, oy corverl|or or|y slardard ||orary or 0peral|rg
3ysler lurcl|ors do lr|s. 0o not oeg|r a rare W|lr ar urderscore ur|ess you are sure you |roW
Wral you are do|rg.
4)
3|r||ar|y, you may use or|y upper case |ellers |r a rare; aga|r, oy oonvenr|on, upper-case or|y
rares are usua||y used or|y lor syroo||c corslarls.
2.2.1. En:mer,ted (0num} ty5es
O %re erureraled lype spec|l|es a suosel ol |rlegers W|lr eacr reroer rav|rg a syroo||c rare.
O For exarp|e, We car Wr|le:
enum Colours ,RED, GREEN, BLUE,;

O lo del|re lre enumerareo ry5e Colours Wr|cr ras lrree syroo||c va|ues: RED, GREEN ard
BLUE.
O we car roW dec|are argurerls ol lype Colours:
Colours colour1, colour2, colour3;

O %re var|ao|es colour1, colour2, ard colour3 car la|e or lre syroo||c va|ues assoc|aled
W|lr lre Colour (erur) lype. A|so, s|rce lrese are u|l|rale|y |rlegers, rorra| |rleger
ar|lrrel|c car oe perlorred or lrer. %rus slalererls |||e:
colour2 = RED;
colour3 = colour2++;

O are |ega|.
O Nole, roWever, lral C does ro rur l|re crec||rg lo ver|ly lral lre resu|l ol lre ar|lrrel|c |s a
va||d |rleger lor lre enum lype. (|.e. |l |s rol as sale as lre 5asoa| equ|va|erl.)
O y delau|l, lre l|rsl syroo||c corslarl W||| oe g|ver lre |rleger va|ue ol zero; eacr add|l|ora|
corslarl |s corverled lo lre rexl |rleger.
O %re erureraled lype |s a uselu| a|lerral|ve lo #define preprocessor d|recl|ves. For exarp|e:
enum ERRJR_CJDES ,
ERRJR_NJ_MEMJRY,
ERRJR_BAD_INPUT_FILE,
ERRJR_BAD_JUTPUT_FILE,
NUM_ERRJR_CJDES
,;

O Nole lral |r lre aoove enum, lre |rleger va|ue ol NUM_ERRJR_CJDES Wou|d oe 3|.e. lre
aclua| ruroer ol error codes erureraled.
2.3. 6onst,nts
O lrleger corslarls car oe Wr|ller |r lre delau|l dec|ra| rolal|or (eg. 123), as ocla| ruroers oy
us|rg a |ead|rg 0 (eg. 0123 (ocla|) |s lre sare ruroer as 83 (dec|ra|), or as rex ruroers oy
us|rg a |ead|rg 0x (e.g. 0x123 = 291 (dec|ra|) = 0113 (ocla|)).
O Lorg |rleger corslarls are spec|l|ed oy apperd|rg ar l or L lo lre |rleger. (e.g. 123| or 123L).
(Nole lral L |s prelerred: us|rg l |s eas||y corlused W|lr lre d|g|l 1).
O Craracler corslarls are |rd|caled oy pull|rg lre craracler |r s|rg|e quoles (e.g. 'a' lor lre
craracler code lor lre |eller a).
2.3.1. Ex,m5|es
long longNumber; char singleCharacter;
longNumber = 123L; singleCharacter = 'a';

2.4. 05er,tors ,nd Ex5ress|ons
2.4.1. Ar|thmet|. o5er,tors
%re lo||oW|rg ar|lrrel|c operalors are ava||ao|e:
%,-|e 2.2. Ar|thmet|. o5er,tors
Operator Description
,//ition
- subtr,ction
* multiplic,tion
/ /ivision
mo/ulus ints only)
;,7 preincrement
;,7 postincrement
--;,7 pre/erement
;,7-- post/erement
Operator Description
Nole: Nole lral lrere |s ro exporerl|al|or
operalor.
2.4.1.1. 0|fferen.es -etween 5re- ,nd 5ost- o5er,tors
O %rere |s ro d|llererce oelWeer lre slalererls ++x; ard x++;. %rey oolr s|rp|y |rcrererl lre
va|ue ol x oy 1.
O loWever, cors|der lre lo||oW|rg sequerces:
x = 1;
y = x++; / or y = ++x; /
printf("y: %d, x: %d\n", y, x);

O wrer We use y = x++;, y |s ass|gred lre va|ue x rad oelore oe|rg |rcrererled: x |s
|rcrererled aller |ls va|ue |s used |r lre express|or. %rus lre va|ues pr|rled lor y ard x Wou|d
oe 1 ard 2.
O ll lre correrled-oul slalererl y = ++x; Were used |rslead, x |s |rcrererled oelore oe|rg
used |r lre express|or. lerce oolr x ard y Wou|d rave lre va|ue ol 2 Wrer pr|rled.
2.4.2. Log|.,| 05er,tors
%re lo||oW|rg lao|e ||sls lre |og|ca| operalors lral car oe used.
%,-|e 2.3. Log|.,| o5er,tors
Operator Description
==
equ,ls
!=
not equ,l
<
less th,n
<=
less th,n or equ,l

gre,ter th,n
=
gre,ter th,n or equ,l
||
logic,l 47
&&
logic,l ,3/
!
logic,l 349
Nole lral s|rce lrere |s ro oo|ear lype, lre resu|l ol a |og|ca| operal|or |s ar |rleger: 1 |l lre cord|l|or |s
lrue; 0 |l la|se. (wr||e |l |s lrue lral, |r gerera|, any ror-zero |rleger represerls tr:e, lre spec|l|c va|ue ol
1 |s used lo represerl a lrue resu|l ol lrese |og|ca| operalors.)
lerce, lre lo||oW|rg |s |ega|:
int n;

n = (i 5) + (j 10);

lr lre aoove case, n W||| oe zero or|y |l oolr cord|l|ors la||; |l exacl|y ore |s lrue, n W||| oe 1 (oul We dor'l
|roW Wr|cr ore |s lrue); |l lrey are oolr lrue, n W||| oe 2.
Nole lral Wrer |og|ca| express|ors are jo|red oy lre |og|ca| ano (&&), lrey are eva|ualed |ell lo r|grl url||
ar express|or oecores la|se. lerce lre lo||oW|rg (Wr|cr Wou|d |ead lo d|sasler |r a |arguage |||e 5asoa|)
|s |ega| ard sale:
if (i != 0 && j/i 10)

(|.e. ll | |s zero, lre l|rsl lesl W||| la|| ard lre secord lesl, |rvo|v|rg d|v|s|or oy |, W||| rol oe dore, rerce
avo|d|rg a 'd|v|de-oy-zero error.)
3|r||ar|y, express|ors jo|red W|lr lre |og|ca| or (||) are eva|ualed |ell lo r|grl url|| ore eva|uales as lrue.
2.4.3. %he ,ss|gnment o5er,tor
O %re ass|nmenr o5eraror sels |ls |ell s|de lo lre va|ue ol lre r|grl s|de express|or. %r|s va|ue |s
a|so lre va|ue ol lre ass|nmenr ex5ress|on
lerce, lre lo||oW|rg are va||d slalererls:
i = j = 5;
i = (j = 3) + (k = 2);

O %re | = (j = 3) (| = 2); slalererl |s eq|va|erl lo:
j = 3;
k = 2;
i = j + k;

2.4.4. %he 8iz04f o5er,tor
%re s|zeof (lype rare or var|ao|e) g|ves lre ruroer ol oyles lor lre lype.
2.4.4.1. Ex,m5|e
int i;
char c;
long l;
.
.
printf("Jn this machine, ints are %d bytes"
"chars are %d bytes, and"
"longs are %d bytes\n",
sizeof(int),
sizeof char,
sizeof(l));

Nole: O we exp|o|l lre C preprocessor's ao|||ly lo corcalerale slr|rgs separaled oy Wr|lespace
|rlo a s|rg|e slr|rg |r lre aoove exarp|e.
O %re a|lerral|ve (|r K&C) Wou|d oe:
printf("Jn this machine, ints are %d bytes\
chars are %d bytes, and\
longs are %d bytes\n"
O lere, We use lre oac|s|asr ('\') lo Wr|le a |org slr|rg across severa| ||res lor |rcreased
readao|||ly.
O 0esp|le appeararces, sizeof |s ar o5eraror, rol a lurcl|or. %ral |s Wry sizeof char
|s |ega|. %re parerlres|s arourd lre operard are rorra||y added lor readao|||ly.
2.5. 8|m5|e & -|o. st,tements
1. A sraremenr car oe e|lrer a s|m5|e slalererl or a oom5ouno slalererl.
2. %re rosl e|ererlary lorr ol a s|rp|e slalererl |s ary express|or lo||oWed oy a ser|-co|or.
%rus:
x = i; / A simple statement /
3. %re olrer lorrs ol s|rp|e slalererls |rc|ude lr|rgs |||e lre |l sraremenr lo oe d|scussed oe|oW.
1. A corpourd slalererl |s ary ruroer ol ol slalererls orac|eled oy oraces ({...). %rus:
, / Compound statement enclosed with braces ,, /
x = j++;
i++;
,

2.. |ow 6ontro|
we roW exar|re lre prec|se syrlax ol lre l|oW corlro| slalererls |rc|ud|rg:
O |f slalererl;
O |f ... e|se slalererl;
O wh||e slalererl;
O do slalererl;
O for slalererl;
O sw|t.h slalererl;
2..1. if st,tement
|ver:
if (expression)
statement

%re sraremenr (s|rp|e or corpourd) |s execuled or|y |l ex5ress|on |s lrue (|.e. eva|uales lo ror-zero).
2..2. if...080 st,tement
|ver:
if (expression)
then_statement
else
else_statement

%re rnen_sraremenr (s|rp|e or corpourd) |s execuled |l ex5ress|on |s lrue (|.e. eva|uales lo ror-zero);
olrerW|se, lre e|se_sraremenr |s execuled.
2..3. wh||e |oo5
%re lorr:
while (expression)
statement

|s equ|va|erl lo:
label: if (expression)
,
statement
goto label;
,

|.e. lre oody ol lre |oop W||| oe execuled 0 or rore l|res url|| lre express|or oecores la|se.
2..4. Ex5ress|ons |n .ond|t|on,|s
1. Nole lral lre cord|l|ora| express|or car oe anyrn|n. ll lre va|ue ol lre express|or |s zero, lre
cord|l|or |s la|se; olrerW|se |l |s lrue.
2. lerce lre lo||oW|rg:
while (c = getchar())
putchar(c);

3. W||| copy sro|n lo sroour url|| a ru|| craracler (asc|| 0) |s read.
1. Ar ever rore corror |d|or |s:
while ((c = getchar()) != EJF)
putchar(c);

5. %re aoove prograr |s jusl |||e lre oo5y|n prograr We saW ear||er. Nole lral lre parerlres|s are
recessary lo lorce lre ass|grrerl lo occur oelore lre |requa||ly lesl. ll We Wrole:
if (c = getchar() != EJF)

. |l Wou|d oe |rlerpreled as:
if (c = (getchar() != EJF))

Z. %r|s Wou|d resu|l |r o oe|rg ass|gred lre va|ue rrue (1) or la|se (0), rol lre va|ue ol o read |rl
2..5. 0o ... wh||e |oo5
do
statement
while (expression);

|s equ|va|erl lo:
label: statement
if (expression) goto label

|.e. lre oody ol lre |oop W||| oe execuled 1 or rore l|res url|| lre express|oroecores la|se.
Nole lral un||e |oops are saler lrar oo |oops s|rce lre lorrer execule 0 or rore l|res oul lre |aller
execules al |easl orce. (%re oo |oops ray oe rore ell|c|erl, roWever.) Neg|ecl|rg lo accourl lor lre
poss|o|||ly lral a |oop srou|d rol oe execuled al a|| car |ead lo calaslropr|c prograr la||ure ard We
slrorg|y ercourage lre use ol un||e |rslead ol oo.
%o urderslard lre d|llererces, cors|der lre lo||oW|rg:
/ DJ version /
do
,
/ launch nuclear missiles /
, while ( / enemy is attacking us / )

/ WHILE version /
while ( / enemy is attacking us / )
,
/ launch nuclear missiles /
,

%re oo vers|or, ol course, Wou|d cause lre |rred|ale, |rev|lao|e oeg|rr|rg ol a ruc|ear Warl
2... or |oo5
for (expr1; expr2; expr3)
statement

|s equ|va|erl lo:
expr1; / i.e. expr1 is done before entering loop /
while (expr2)
,
/ loop if expr2 is non-zero /
statement / loop body proper /
expr3; / re-initialization /
,

Nole: A|| corporerls (ex5r', ex5r2, ard ex5rJ) are opl|ora|.
2...1. Ex,m5|es
/ Infinite loop /
for ( ; ;)
statement

/ Counting loops /
/ Do loop for i = 2, 3, 4, 5, 6, 7 /
for(i = 2; i & 8; i++)
s = s + i;

/ Do loop for i = 2, 4, 6 /
for(i = 2; i & 8; i = i + 2)
s = s + i;

/ Do loop for i = 4, 3, 2, 1, 0 /
for( i = 5 ; i--; )
s = s + i;
/
note: here there is no re-initialization.
The test also does the re-initialization.
This idiom is common because it results
in faster loops. (Counting down towards
zero eliminates a comparison in the loop.)
/

2...2. re, ,nd 6ont|n:e st,tements
1. %re -re, slalererl causes ar |rred|ale ex|l lror a |oop (or su|ron slalererl-see oe|oW). (lr
lre case ol resled |oops, or|y lre |rrerrosl |oop |s ex|led.)
2. %re .ont|n:e slalererl causes ar |rred|ale lrarsler lo lre lesl corporerl ol a |oop.
2...2.1. Ex,m5|es
3uppose We rorra||y Warl lo do a |oop 10 l|res, oul sorel|res Warl lo ex|l or reslarl lre |oop |r lre
r|dd|e:
for(i = 1; i &= 10; i++)
,
.
.
if ( / some condition indicating loop exit / )
break; / Exit loop immediately /
.
.
if ( / some condition indicating loop re-start / )
continue; / Go to loop test immediately /
.
.
,

2...3. 8w|t.h st,tement
|ver:
switch (expression) ,
case constant1:
statement_list1
case constant2:
statement_list2
.
.
default:
statement_list_default
,

%re sw|t.h slalererl perlorrs a ru|l|-Way orarcr. %re express|or |s eva|ualed ard lrer corpared lo
eacr ol lre corslarls |r lre case slalererls. wrer a ralcr |s lourd, lre correspord|rg sraremenr_||sr
ard ,|| other fo||ow|ng sraremenr_||srs are execuled. 0r|y Wrer a oreak slalererl |s lourd, does corlro|
ex|l lre sW|lcr slalererl.
2...3.1. Ex,m5|e
%re lurcl|or oe|oW delerr|res lre W|desl d|sp|ayed ||re (la||rg |rlo accourl laos). (%re source code l||e
pW|dlr.c |s ava||ao|e.)
/
print_width finds widest line to be printed
when array of characters is displayed
/
#define TABSTJP (8)
print_width(s)
char s,; / s an array of characters /
,
int width, column, i;

width = column = 0;
for( i = 0; si, != '\0'; i++) ,
if ( column width) width = column;
switch( si, ) ,
case '\n': / newline /
case '\r': / carriage return /
case '\f': / form feed /
/ Reset column count to zero for new line /
column = 0;
break;
case '\b': / backspace /
/ Decrement column count for backspace, but
don't make column count negative! /
if (column 0 ) column--;
break;
case '\t': / tab /
/ Increment column count to next tab position /
column = column + TABSTJP - column%TABSTJP;
break;
default:
/ For regular characters, just increment column count /
column++;
,
,
return (width);
,

2.7. |t 05er,tors
1. es|des ar|lrrel|c ard po|rler operalors, C prov|des operalors or o|l pallerrs.
%,-|e 2.4. |tw|se o5er,tors
Operator Meaning
bitwise ,n/
, bitwise or
` bitwise exclusive or
shiIt leIt
~~ shiIt right
~ invert e,ch bit
, bitwise or
2.7.1. Ex,m5|es
/ Determine number of bits in an integer /
int i;
j = 0;
for(i = 1; i != 0; i = i<<1)
j++;
printf("ints take %d bits\n", j);

/ Make n = lower 3 bits of i /
n = 7&i;

/ Invert all bits except least significant 4 bits /
n = (~0xf)^n;

1. Nole lral |r lre |asl exarp|e We use ~0xf lo |rd|cale a o|l pallerr ol 1's excepl |r lre |asl lour
pos|l|ors |rslead ol 0xfffffff0. %re reasor |s rol lo save lyp|rg; ralrer, lre ~0xf relrod |s
|rdeperderl ol lre ruroer ol o|ls |r ar |rleger. w|lr lre olrer relrod, We Wou|d rave lo use
0xfff0 lor 1-o|l racr|res.
2.8. Ex5,nded Ass|gnment 8t,tements
%o save lyp|rg ard poss|o|y |rcrease ell|c|ercy, lre exlerded ass|grrerl operalors car oe used:
%,-|e 2.5. Ass|gnment o5er,tors
Operator
+=
-=
=
/=
%=
<<=
=
&=
|=
^=
For lrese operalors,
x op= y
rears exacl|y lre sare lr|rg as:
x = x 45 y
2.9. 6ond|t|on,| (?} o5er,tor
1. Ar express|or us|rg lre lerrary cord|l|ora| operalor ras lre lo||oW|rg syrlax:
expression1 . expression2 : expression3

2. %re erl|re express|or la|es or lre va|ue ol ex5ress|on2 |l ex5ress|on' |s lrue or ol ex5ress|onJ
olrerW|se.
3. For exarp|e:
x = (i j) . i: j;
1. |s equ|va|erl lo:
if ( i j)
x = i;
else
x = j;

5. ar||er, We saW arolrer use ol lre ? operalor |r lre prograr up3.c:
putchar(islower(ch) . ch + 'A' - 'a' : ch);

2.10. %he 6omm, (,} o5er,tor
1. %re corra operalor separales express|ors |rlo a |arger express|or; lre va|ue ol lre |arger
express|or |s lre va|ue ol lre |asl corra-separaled express|or.
2. %re corra operalor |s oller used |r lor slalererls lo gel lre ellecl ol lWo |oop var|ao|es.
3. For exarp|e:
for (i = 0, j = 0; i < 10 ; i++, j += 2)
/ loop statements /

1. ellecl|ve|y del|res lWo |oop var|ao|es, | ard Wrere | la|es lre va|ues 0, 1, 2 ... 9 ard lre
va|ues 0, 2, 1 ... 18.


1|
%r|s lao|e represerls lyp|ca| s|zes lor 32-o|l racr|res. Nole, roWever, lral sra||er racr|res oller use
1-o|l |rlegers; 1-o|l racr|res usua||y rvae 1-o|l longs.
6h,5ter 3. Proje.t m,n,gement ,nd m,e
3.1. Us|ng se5,r,te so:r.e .ode f||es
wrer a prograr cors|sls ol rore lrar ore lurcl|or, |l |s oller uselu| lo sp||l lre prograr arorgsl severa|
souroe oooe l||es. acr l||e corla|rs lre code lor ore or rore lurcl|ors ard We ca|| eacr l||e a moou|e.
%re advarlages lo lr|s approacr |rc|ude:
1. lrd|v|dua| rodu|es are sra||er, eas|er lo ra|rla|r, ard lasler lo corp||e lrar corp|ele
progrars corla|red |r a s|rg|e l||e.
2. ll rodu|es are Wr|ller so lral lrey corla|r a uselu|, gerer|c sel ol lurcl|ors, lre rodu|es car oe
srared oy d|llererl progrars.
3. lr parl|cu|ar, lre corp||al|or process |s aclua||y d|v|ded |rlo 2 (or rore) separale prases: 1)
oom5||ar|on ol source code lo oojecl code, ard 2) ||nk|n ol oojecl code l||es |rlo ar execulao|e
l||e.
1. For exarp|e, suppose a prograr |s rade up ol lrree source code rodu|es a.o, o.o, ard o.o. lr
lre l|rsl prase, eacr source rodu|e |s corp||ed |rd|v|dua||y |rlo |ls correspord|rg oojecl
rodu|e. lr lr|s case, We Wou|d oola|r lre oojecl code l||es: a.o, b.o, ard c.o. Nexl, lre ||r|er
jo|rs lre oojecl rodu|es logelrer lo produce lre execulao|e ex_name (Wrere lre 'ex_rare ol
lre execulao|e |s del|red oy lre prograrrer).
5. 3uppose lral lre prograr |s lrer rod|l|ed ard lral lre crarges or|y occur |r source rodu|e
b.c. %rere |s ro reed lo re-gererale lre oojecl rodu|es a.o ard c.o; or|y b.o reed oe re-
gereraled.
. y us|rg lre make prograr ra|rlerarce pac|age, lre erl|re prograr car oe re-gereraled
auloral|ca||y aller |rd|v|dua| rodu|es rave oeer rod|l|ed W|lr lre r|r|rur poss|o|e arourl ol
corpuler l|re. we W||| exar|re lre dela||s ol lre ra|e ul|||ly |aler. Nole lral {\er ra|e |s
ava||ao|e lor a|rosl a|| operal|rg syslers.
Z. we W||| ercourage lr|s sly|e ol prograrr|rg |r lre ser|rar; role, roWever, lral lre suoslarl|a|
advarlages ol lr|s relrod or|y oecore lru|y ev|derl W|lr |arge projecls (severa| lrousard ||res
ol code).
3.2. 8.o5e of v,r|,-|e n,mes
elore |oo||rg al roW a prograr |s orgar|zed |rlo rodu|es, |l |s |rporlarl lo c|ar|ly lre soo5e ol rares |r
C ard roW sore ol lre lealures car oe used lo |rp|ererl, al sore |eve|, lre advarlages ol pure o|oc|
slruclured |arguages
Lo.,|s:
O var|ao|es dec|ared W|lr|r lre oody ol a lurcl|or (or ary corpourd slalererl) are |oca|
lo lre lurcl|or;
O Loca|s ray rol oe used oy olrer lurcl|ors;
O Loca|s do rol rela|r lre|r va|ues lror ore ca|| lo arolrer.
O Loca|s are a||ocaled or lre slac| Wrer lre lurcl|or |s erlered ard de-a||ocaled upor
ex|l.
O %rey rave urdel|red |r|l|a| va|ues.
|o-,|s:
O |ooa|s are dec|ared ouls|de ol a|| lurcl|ors;
O |ooa|s ray oe accessed oy ary lurcl|or;
O |ooa|s are a||ocaled al aoso|ule rerory |ocal|ors;
O |ooa|s are dec|ared ouls|de ol a|| lurcl|ors;
O Vary corp||ers/||r|ers |r|l|a||ze g|ooa|s as zero |l rol exp||c|l|y del|red |r lre
dec|aral|or; roWever, you srou|d rol re|y or lr|s oerav|or.
8t,t|. Lo.,|s:
O L||e auloral|c |oca|s lor scope ru|es, oul rela|r lre|r va|ue lror ore ca|| lo arolrer;
O A||ocaled |r aoso|ule rerory (|||e g|ooa|s).
8t,t|. |o-,|s:
O L||e rorra| g|ooa|s oul car or|y oe used W|lr|r lre sare source code l||e.
O uselu| lor a rodu|e Wrose lurcl|ors srare a a moou|e g|ooa| Wr|cr |s pr|vale lo lre
rodu|e (|.e. |raccess|o|e oy users).
3.2.1. Notes
3ore uselu| ru|es ol lruro:
O use slal|c |oca|s spar|rg|y.
O wrer a g|ooa| seers recessary, preler slal|c g|ooa|s W|lr|r a rodu|e (lor oolr lurcl|or rares
ard var|ao|es) over g|ooa|s. %r|s |s reduce lre name s5aoe 5o||ur|on ol g|ooa| var|ao|es.
O Carelu||y cors|der lre pros ard cors ol rav|rg g|ooa| var|ao|es vs. parareler pass|rg oelWeer
lurcl|ors. (lr a rulsre||, g|ooa|s are oller a rore ell|c|erl ard 'easy so|ul|or lor srar|rg dala
oelWeer re|aled lurcl|ors; roWever, pass|rg pararelers ray oe salerl (Furcl|ors lral
rar|pu|ale pure or slal|c g|ooa|s pr ever slal|c |oca|s are a|so nor re-erlrarl. %r|s ray |ead lo
ser|ous proo|ers |r lre server porl|or ol c||erl-server app||cal|ors.)
3.3. H,e
1. %re make ul|||ly |s a uselu| prograr ra|rlerarce loo| lor projecls sp||l |rlo severa| rodu|es (|.e.
source code l||es.)
2. %re ra|e ul|||ly aulorales lre las| ol regereral|rg rarer l||es lror l||es lral lrey oe5eno on.
3. Va|e uses a dala-oase (ca||ed lre makel||e: usua||y corla|red |r a l||e ca||ed Makefile or
makefile.
1. ake uses lre rod|l|cal|or l|re slarps or l||es lo delerr|re |l a largel srou|d oe regereraled.
ll lrer |rvo|es lre ru|es lourd |r lre makel||e lo do so
5. %re rosl corror use ol make |s lo recorp||e a prograr aller ed|l|rg source code l||es. ake
W||| carry oul lre r|r|rur ruroer ol sleps requ|red lo |eep lre var|ous largels up-lo-dale.
3.3.1. A 8|m5|e Ex,m5|e
1. A largel ca||ed oa| deperds or lWo l||es: a ard o as |||uslraled grapr|ca||y |r lre l|gure oe|oW:
|g:re 3.1. A s|m5|e de5enden.y tree

2. %re aoove deperdercy lree |s descr|oed lo make W|lr lre lo||oW|rg Makefile:
# Simple "Makefile" example
# Anything after a '#' is ignored
# i.e. treated as a comment
goal: a b # Target "goal" depends on "a" and "b"
touch goal # rule to generate "goal" if "a" or "b"
# is more recent
# "touch" is a command to set the modification
# time of a file to the current time
b: # Depends on nothing
touch b
a:
touch a
# NJTE: The white space before a rule
# must be TAB.
3.3.2. 6om5||,t|on ex,m5|e
1. A rore rea||sl|c exarp|e ol us|rg ra|e |rvo|ves corp|||rg. %re l|gure oe|oW sroWs lre
deperderc|es ol a l|ra| prograr, ca||ed 5ro, or lrree oojecl l||es: p1.o, p2.o ard p3.o. ll
5ro does rol ex|sl or |s o|der lrar ary ol lre lrree oojecl l||es |l deperds or, |l W||| oe
regereraled.
|g:re 3.2. 0e5enden.y tree of s|m5|e m,ef||e

2. 3|r||ar|y, eacr ol lre oojecl l||es deperds or a correspord|rg C source code l||e. ll ary ol lre
source code l||es |s reWer lrar |ls oojecl l||e, lre oojecl l||e W||| oe regereraled. 3|rce lr|s W|||
ra|e al |easl ore oojecl l||e reWer lrar lre execulao|e, make W||| auloral|ca||y re-||r| lre
oojecl l||es as We||.
3. F|ra||y, role lral lWo source l||esp2.c ard p3.c|rc|ude lre cuslor reader ex2.h.
Corsequerl|y, lre oojecl l||es p2.o ard p3.o oolr deperd |rp||c|l|y or ex2.h. 3|rce make
delecls |l a largel l||e |s o|der lrar arylr|rg |l deperds ore, lre oojecl l||es p2.o ard p3.o W|||
oe regereraled |l ex2.h |s rore recerl.
1. %re Makefile oe|oW sroWs roW a|| ol lr|s |s descr|oed.
# Simple "Makefile" example using compilation
prog: p1.o p2.o p3.o
gcc -o prog p1.o p2.o p3.o
p1.o: p1.c
gcc -c p1.c

p2.o: p2.c
gcc -c p2.c

p3.o: p3.c
gcc -c p3.c

# The following lines give additional
# files that object code depends on;
# in this case, these are header files
# included in the source code.
# If any of these are newer than the
# corresponding object file, the
# rules defined above will be invoked
# to re-create the object code.
p2.o: ex2.h
p3.o: ex2.h

3.3.3. Add|t|on,| rem,rs
1. Va|e a||oWs slr|rg var|ao|es lo lo ass|gred ard relererced as lo||oWs:
VAR_NAME = blah blah
.
$(VAR_NAME)

2. y delau|l, lre l|rsl largel |s rade Wrer ra|e |s |rvo|ed. loWever, olrer largels ray a|so oe
spec|l|ed. (%re rexl exarp|e sroWs lre corror largels clean ard depend.)
3. Norra||y, |l a corrard |r a ru|e ras a ror-zero ex|l slalus, ra|e slops. loWever, preced|rg
lre corrard W|lr a dasr (-) causes ra|e lo |grore lre ex|l slalus.
1. %r|s lealure |s used |r lre clean largel. %re ru|e spec|l|es lral a|| gereraled l||es srou|d oe
de|eled. 0ov|ous|y, |l ary ol lrese l||es do rol ex|sl, We sl||| Warl lre ra|e prograr lo proceed.
5. Pull|rg lrese |deas logelrer, We oola|r a rore e|egarl Makefile lor lre prev|ous exarp|e:
# Simple "Makefile" example using compilation
SRCS = p1.c p2.c p3.c
JBJS = p1.o p2.o p3.o

prog: $JBJS)
gcc -o prog $(JBJS)
p1.o: p1.c
gcc -c p1.c
p2.o: p2.c
gcc -c p2.c

p3.o: p3.c
gcc -c p3.c

depend: $(SRCS)
makedepend $(SRCS)
clean:
-rm -f $(JBJS) a.out core prog
# DJ NJT DELETE THIS LINE - - make depend depends on it.
p2.o: ex2.h /usr/include/stdio.h
p3.o: ex2.h /usr/include/stdio.h

3.3.4. Us|ng gener|. r:|es
1. You car spec|ly, |r gerera|, roW lo oola|r a largel lror a deperderl Wrer lrey or|y d|ller |r
lre|r sul|xes. For exarp|e, lre C corp||er |s used lo oola|r ar oojecl (.o) l||e lror a
correspord|rg source (.c) l||e.
2. %re lo||oW|rg gerer|c ru|e slales lr|s:
.c.o:
$(CC) -c $.c
3. Wrere $(CC) |s lre rare ol lre sysler C corp||er ard $ |s lre var|ao|e represerl|rg lre oase
rare ol lre largel.
1. 0lrer ou||l|r ra|e var|ao|es |rc|ude: S_lre rare ol lre currerl largel; S<lre rare ol lre
deperdercy l||e; S?lre ||sl ol deperderc|es reWer lrar lre largel.
5. Pull|rg lrese ru|es logelrer, We oola|r lre lo||oW|rg Makefile:
# Simple "Makefile" example using compilation
SRCS = p1.c p2.c p3.c
JBJS = p1.o p2.o p3.o
PRJG = prog
HJME = /home/eccles1/kclowes
INSTALL_PATH=$(HJME)/bin
CFLAGS = -c
CC = gcc
.c.o:
$(CC) $(CFLAGS) $.c
$(PRJG): $(JBJS)
gcc -o $(PRJG) $(JBJS)
depend: $(SRCS)
makedepend $(SRCS)

clean:
-rm -f $(JBJS) a.out core $(PRJG)
install: $(PRJG)
cp $(PRJG) $(INSTALL_PATH)/$(PRJG)
# DJ NJT DELETE THIS LINE - - make depend depends on it.
p2.o: ex2.h /usr/include/stdio.h
p3.o: ex2.h /usr/include/stdio.h
3.3.5. P,rt|ng rem,rs
O %re -n opl|or causes make lo reporl lre corrards |l Wou|d |rvo|e W|lroul aclua||y do|rg
lrer.
O %re -f file opl|or a||oWs you lo spec|ly a l||e olrer lrar Makefile or makefile.
O Nole lral a sre|| |s |rvo|ed lor eacr ||re |r a ra|el||e's ru|e. For exarp|e, lre lWo ||res:
cd sub
ls

O Wou|d |rvo|e a separale suosre|| lor eacr corrard; corsequerl|y, lre |s corrard Wou|d
execule or lre currerl d|reclory, rol lre ore crarged lo |r lre prev|ous suo-sre||.
O %r|s car oe avo|ded oy pull|rg oolr corrards or a s|rg|e ||re:
cd sub; ls
O lr lr|s case lre erl|re ||re ras |ls oWr suo-sre||.
6h,5ter 4. ,s|. Arr,ys ,nd Po|nters
4.1. Arr,ys
1. 3|rg|e d|rers|or arrays ol ary dala lype are dec|ared as:
char buffer120,, line80,;
int freq30,;
double coeffN,;

2. Ar array d|rers|ored n ras e|ererls |rdexed lror 0 lo n-'.
3. Nole lral var|ao|y-d|rers|ored arrays are rol a||oWed |r C. lerce, |r lre aoove exarp|e
dec|aral|or double coeffN,, rusl oe a syroo||c corslarl prev|ous|y del|red W|lr a
#define preprocessor d|recl|ve.
1. Vu|l|-d|rers|ora| arrays are dec|ared as 'arrays ol arrays:
unsigned short table20,30,;
float pressure100,100,100,;
double velocity100,100,100,3,;

5. we sra|| see |aler lral lre use ol po|rlers |s oller rore ell|c|erl lrar lre use ol ru|l|p|y-
d|rers|ored arrays. (lr parl|cu|ar, lrere are advarlages lo us|rg ar array ol po|rlers lo s|rg|y-
d|rers|ored arrays |rslead ol douo|y-d|rers|ored arrays.)
. Nole lral ru|l|-d|rers|ored arrays car requ|re a |ol ol rerory. For exarp|e, lre ve|oo|ry veclor
del|red al eacr po|rl |r a 3-d|rers|ora| space W|lr a gr|d s|ze ol 100 |r eacr d|recl|or requ|res
3100100100sizeof(double) = 21 Vegaoyles ol sloragel
4.2. Po|nters
1. A 5o|nrer var|ao|e corla|rs lre address ol a dala oojecl. %rey are dec|ared as lo||oWs:
char cp;
int integerp, ipp;

2. lr lre aoove dec|aral|ors, o5 |s a po|rler; o5 relers lo lre oojecl lral o5 |s po|rl|rg lo|.e. a
craracler.
3. %re var|ao|e |55 |s a 5o|nrer ro a 5o|nrer ro an |nreer. %re d|agrars oe|oW |||uslrale lre
re|al|orsr|p ol a po|rler var|ao|e (|lse|l slored soreWrere |r rerory) ard lre dala |l po|rls lo.
F|rsl, suppose o5 po|rls lo lre craracler `A' slored soreWrere |r rerory ard |55 po|rls lo a
po|rler po|rl|rg lo lre |rleger 123 slored soreWrere |r rerory:
|g:re 4.1. Po|nter v|s:,||z,t|on

4.2.1. %he & 05er,tor
%re & operalor |s used lo oola|r lre address ol ar oojecl. %rus po|rlers car oe |r|l|a||zed as lo||oWs:
int i, j, ip;
.
.
ip = &i; / Make ip point to i /
j = j + ip; / same as j = j + i /


4.2.2. Po|nter Ar|thmet|.
1. lrlegers ray oe added or suolracled lror po|rlers.
2. ll n |s added lo a po|rler 5 po|rl|rg lo ar oojecl oo, 5 |s |rcrererled lo po|rl n ooeors lurlrer.
(|.e. lre rurer|ca| va|ue ol 5 oecores 5 ns|zeol{ooeorj.
3. ll |s poss|o|e lo perlorr ord|rary ar|lrrel|c or po|rlers (|.e. ar|lrrel|c sucr lral add|rg 1 lo lre
po|rler resu|ls |r |rcrererl|rg lre rurer|ca| va|ue ol lre po|rler oy 1) oy oasr|n lre po|rler lo
ar |rleger. (Vore prec|se|y, |l srou|d oe casl lo a {vo|o j or {s|ze_rj. %rese corverl|ors are
assoc|aled W|lr lre sro||oWe W||| exar|re lre|r prec|se rear|rg |aler.)
1. Vore prec|se|y, |l |s rorra||y casl lo ar urs|gred |rleger, or, a vo|d po|rler (Wr|cr po|rls lo dala
ol s|ze 1).
5. For exarp|e, suppose |5 |s 0x1000 (|.e. |l po|rls lo dala al address 0x1000). ll lre dala |l po|rls
lo |s ar |rleger ard |rlegers occupy 1 oyles, lrer ip++ W||| resu|l |r |rcreas|rg lre rurer|ca|
va|ue ol |5 lo 0x1001 (lre address ol lre rexl |rleger).
. loWever, |l We use:
(unsigned) ip++;
/ or /
(void ) ip++;

Z. lre rurer|ca| va|ue ol |5 W||| |rcrease lror 0x1000 lo 0x1001, jusl |||e ar ord|rary ruroer.
4.2.2.1. 8tr|ngs ,re .h,r,.ter 5o|nters
1. A 3lr|rg corslarl (erc|osed |r douo|e quoles) are sel up as a NuLL lerr|raled array ol
craraclers |r rerory.
2. %re |erglr ol lre array |s lre ruroer ol craraclers |r lre slr|rg p|us 1 (lor lre ru||).
3. %re va|ue ol lre slr|rg corslarl |s a po|rler lo lre l|rsl craracler |r lre array.
1. For exarp|e, g|ver lre code:
char cp;
cp = "Hello";

5. lre corp||er slores lre craraclers lor lre |ellers `l', `e', `|', `|', ard `o' lo||oWed oy a ru||
lerr|ralor (a ||lera| zero) |r rerory ard ass|grs lre var|ao|e o5 lre address Wrere lre |eller `l'
|s slored.
. %re l|gure oe|oW |||uslrales lr|s:
Z. |g:re 4.2. Po|nter v|s:,||z,t|on .har *.p = "H04";}
8.
4.2.2.1.1. Ex,m5|e
|ver:
char cp1, cp2;
cp1 = "Hello"
/ Make cp2 point to dynamically allocated memory /
cp2 = malloc(strlen(cp1) + 1);
/ copy string1 to string 2 /
while (cp1 != '\0') ,
cp2 = cp1;
cp1++ ; cp2++;
,
cp2 = '\0';

O lr lre aoove prograr lragrerl We ra|e use ol lWo ||orary roul|res: malloc() ard strlen().
O strlen() relurrs lre ruroer ol craraclers |r a slr|rg (rol |rc|ud|rg lre ru|| lerr|ralor); |l |s
passed lre slarl|rg address ol lre slr|rg
O lerce strlen(cp1) + 1 |s lre lola| ruroer ol oyles requ|red lo slore lre slr|rg po|rled lo oy
cp1 (|rc|ud|rg lre ru|| lerr|ralor).
O malloc(n) dyrar|ca||y a||ocales n oyles ol rerory ard relurrs ar address lo lre l|rsl oyle
a||ocaled.
O lerce, cp2 = malloc(strlen(cp1) + 1) ra|es cp2 po|rl lo lre l|rsl oyle ol a
dyrar|ca||y a||ocaled reg|or o|g erougr lo ro|d lre slr|rg lral cp1 po|rls lo.
loW ar exper|erced C
prograrrer Wou|d do lr|s:
%re prograr cou|d rave oeer Wr|ller rore ell|c|erl|y as:
while ( cp1 != '\0')
cp2++ = cp1++;
cp2 = '\0';

F|ra||y, lre prograr cou|d rave oeer Wr|ller ever rore ell|c|erl|y
as:
while (cp2++ = cp1++)
;

Nole lral lrere |s ro |oop oodyl verylr|rg |s dore |r lre while lesl
|rc|ud|rg lre copy ol lre ru|| lerr|ralor.
4.3. Arr,ys ,nd Po|nters
1. %rere |s a slrorg re|al|orsr|p oelWeer arrays ard po|rlers. lr parl|cu|ar, lre rare ol ar array |s
del|red |r C as oe|rg lre slarl|rg address ol lre array. %r|s address car lrer oe ass|gred lo a
po|rler var|ao|e, ard We car slep lrrougr lre array oy crarg|rg lre po|rler |rslead ol us|rg
|rd|ces. lrdeed, lr|s |s roW arrays are aclua||y |rp|ererled |rlerra||y.
2. Cors|der lre lo||oW|rg:
char c1, c100,, cp;
int i;

/ The symbol "c" is a pointer to the start of array /
/ Hence, the following is legal /
cp = c;
/ It is equivalent to: /
cp = &c0,;
/ The following are all equivalent: /
c1 = ci,;
c1 = (cp + i);
/ Curiously, the following are also legal /
c1 = ic,;
c1 = "abcdef"i,;

3. %re |asl |d|or |s qu|le uselu|; lor exarp|e, cors|der:
vowel = "aeiou"vowel_number,;
/ or /
hex_ascii_code = "0123456789ABCDEF"i & 0xF,;
/ The above gives the ascii code for the
hex digit formed by the lower 4 bits of i /

4.4. :n.t|ons
1. Furcl|ors car relurr e|ererlary dala lypes or po|rlers lo lrer.
2. ur|ess olrerW|se dec|ared, lurcl|ors are assured lo relurr |rlegers.
3. Furcl|ors relurr|rg a dala lype olrer lrar |rleger rusl oe dec|ared oelore use.
1. Vosl corp||ers a||oW lurcl|ors lo oe dec|ared as lype void |l lrey relurr rolr|rg.
5. Furcl|ors argurerls are cop|ed orlo lre slac|. %re cop|es are d|scarded Wrer lre lurcl|or
relurrs. lerce, a|| argurerls are 5ass oy va|ue.
. %re sare ellecl as pass oy relererce car oe acr|eved oy pass|rg a po|rler lo lre dala.
Z. Furcl|ors srou|d oe dec|ared oelore lrey are used; |r AN3l C, We car dec|are a lurcl|or W|lr a
5rorory5e lral descr|oes lre lype ol |ls argurerls. %re corp||er car use lre prololype lo |ssue
Warr|rgs aooul |rcorrecl usage ard lo gererale rore ell|c|erl code.
4.4.1. Ex,m5|es
/ Prototype for function swap /
void swap(int , int );
/ Prototype for function pow /
double pow( double, int);

/ Actual function declaration begins here /
void swap(int ip1, int ip2) / function returns nothing /
,
int temp;
temp = ip1; / temp = what ip1 is pointing at /
ip1 = ip2;
ip2 = temp;
,
double pow(double x, int i) / function returns double /
,
double temp;
temp = 1;
if ( i 0)
while(i - - )
temp = tempx;
else
i = -i;
while(i - - )
temp = temp/x;
return temp;
,


4.4.2. 0|fferen.es -etween AN8| ,nd K&# 6
1. %re rosl v|s|o|e crarges oelWeer AN3l ard K&R C are |r lre Way lral lurcl|ors are dec|ared.
2. lr AN3l C, We use:
double pow(double x, int i)
,
/ body of function /
,


3. lr K&R C, We use:
double pow(x, i)
double x;
int i;
,
/ body of function /
,

1. ver |l you or|y use AN3l C, you reed lo oe lar|||ar W|lr lre o|d-lasr|ored relrod s|rce so
rucr code Was Wr|ller W|lr |l. (AN3l corp||ers do urderslard lre o|der relrod.)
4.5. Ex,m5|es of 5o|nters
%re lo||oW|rg progrars |||uslrale lre e|ererlary use ol po|rlers |r very lyp|ca| app||cal|ors. lr parl|cu|ar,
We exar|re:
O loW corrard ||re argurerls are passed lo execulao|e progrars.
O loW lo Wr|le a lurcl|or W|lr a var|ao|e ruroer ol argurerls
4.5.1. 6om,mnd ||ne ,rg:ments
1. wrer a prograr |s corp||ed ard lurred |rlo ar execulao|e l||e, ore ray W|sr lo a|ler lre
oerav|or ol lre execulao|e al lre l|re |l |s |rvo|ed oy pass|rg |l argurerls or lre corrard ||re
lo |rvo|e |l.
2. %re s|rp|esl sucr slardard corrard |s e.ho (|r oolr w|rdoWs ard uNlX) Wr|cr s|rp|y
ecroes |ls corrard ||re argurerls lo sroour Wrer |l |s |rvo|ed.
3. For exarp|e:
JS_prompt echo Display this
1. resu|ls |r lre oulpul:
Display this
5. %re corrard ||re argurerls are passed lo lre main() lurcl|or ol ary prograr |r a slardard
Way. lr parl|cu|ar:
O %re l|rsl argurerl passed lo main() |s lre lola| ruroer ol corrard ||re argurerls
(|rc|ud|rg lre corrard rare). y corverl|or (rol a ru|e lral rusl oe ooeyed), lr|s
argurerl |s ca||ed argc ('argurerl courl).
O %re secord argurerl passed |s lre slar|rg address ol ar array. y corverl|or |s |s
ca||ed argv ('argurerl va|ues) ard |s dec|ared as: char argv,. %rere are argc
e|ererls |r lre array ard eacr e|ererl |r lre array |s a po|rler lo a ru|| lerr|raled
slr|rg correspord|rg lo a corrard ||re argurerl. Array e|ererl zero (|.e. argv0,
|s lre corrard rare Wr||e array e|ererls 1 lo argc-1 are lre corrard ||re
argurerls lo||oW|rg lre corrard rare.
Nole: lr uNlX, |l |s poss|o|e lo rave d|llererl rares lor lre sare l||e. lerce,
argv0,|.e. lre parl|cu|ar rare lral Was used lo |rvo|e lre execulao|e l||e
car oe used lo delerr|re Wral acl|or lo la|e.
For exarp|e, lre corror uNlX corrards mv (rove or rerare), .5 (copy),
ard |n (||r|) a|| reler lo lre |derl|ca| execulao|e l||e. y |oo||rg al argv0,, lre
prograr delerr|res Wral |l srou|d do.
. %re lo||oW|rg exarp|e sroWs lre code lor a rod|l|ed e.ho corrard:
/
myecho echos its command name and
arguments to stdout.
/
main(int argc, char argv,)
,
int i;

printf("My argument count is: %d\n", argc);
printf("I was invoked under the name of %s\n",
argv0,);
printf("My arguments were:\n");
for (i = 1; i < argc; i++)
printf("Arg #%d: %s\n",
i, argvi,);
exit(0);
,

Z. A rore |rleresl|rg exarp|e |s sroWr oe|oW:
#include <stdio.h
char progname128,;
main(int argc, char argv,)
,
float princ, interest;
int i, n_years;

strcpy(progname, argv0,);
if (argc != 4) ,
printf("Usage: %s principal interest num_years\n",
progname);
exit(1);
,
princ = atof(argv1,);
printf("argv1,: %s, princ: %f\n", argv1,, princ);
interest = atof(argv2,);
printf("argv2,: %s, interest: %f\n", argv2,, interest);
n_years = atoi(argv3,);
printf("argv3,: %s, n_years: %d\n", argv3,, n_years);
interest = 1. + interest/100.;
for(i = 1; i <= n_years; i++) ,
princ = princinterest;
printf("After %d years, new principal is: %8.2f\n",
i, princ);
,
exit(0);
,


O %re corrard ||re argurerls are a|Ways passed as slr|rgs; |l lrese slr|rgs represerl
ruroers, lrey rusl oe corverled lo lre proper lorral oy lre prograrrer.
O %re lurcl|ors atof() ard atoi() (lror slardard ||orary) perlorr lre corvers|ors.
O Nole a|so roW argv0, |s cop|ed |rlo lre g|ooa| var|ao|e progname 3|rce argv0,
|s lre rare urder Wr|cr lre prograr Was |rvo|ed, lr|s a||oWs gerer|c error rard|ers
lo pr|rl oul lre prograr rare s|rce a|| lurcl|ors W||| rave access lo lre g|ooa| var|ao|e
progname Nole lral urder w|rdoWs, roWever, argv0, a|so |rc|udes lre lu|| palr.)
4.5.2. V,r|,-|e N:m-er of Arg:ments
1. Furcl|ors |||e printf() are passed a var|ao|e ruroer ol argurerls.
2. %re ruroer ol argurerls rusl, roWever, oe |rp||c|l |r lre argurerls lrerse|ves.
3. lr lre case ol printf(), lor exarp|e, lre ruroer ol argurerls |s equa| lo 1 p|us lre ruroer
ol (ror-escaped) craraclers |r lre lorrall|rg slr|rg Wr|cr rusl oe lre l|rsl argurerl.
1. %re .,t exarp|e oe|oW corcalerales ary ruroer ol slr|rgs. %re ruroer ol slr|rgs lo oe
corcaleraled |s exp||c|l|y g|ver as lre l|rsl argurerl. (Arolrer corror Way lo pass a var|ao|e
ruroer ol argurerls |s lo ra|e lre |asl argurerl a ru|| po|rler.)
5. we W||| l|rsl Wr|le lr|s lurcl|or |r a non-sranoaro Way, |||uslral|rg lre relrod rosl C corp||ers
use lo pass pararelers lo lurcl|ors. %r|s car oe uselu| |rlorral|or Wrer ||r||rg W|lr olrer
|arguages lral use a d|llererl corverl|or. ll |s a|so a good exerc|se |r lre use ol po|rlers.
warr|rg: loWever, |l W||| rol Wor| or a|| racr|res, espec|a||y Rl3C racr|res Wr|cr pass lre
l|rsl leW argurerls |r reg|slers, rol or lre slac|. For porlao|||ly, stdarg.h rusl oe
used. (we sra|| see roW lo use |l srorl|y.)
. lr lr|s exarp|e, We assure lral argurerls are passed lo lurcl|ors oy pusr|rg lrer orlo lre
slac|, lral lre slac| groWs loWards |oWer rerory, ard lral lre l|rsl argurerl |s lre |asl ore
pusred or.
Z. %re code lo||oWs:
/
Cat concatenates a variable number of strings, allocates
memory for the resulting string and returns a pointer to it.

arguments:
n - number of strings to concatenate
args - "n" pointers to NULL terminated character strings

returns:
a pointer to the string of the concatenated
arguments


/

char cat(int n, char args)
,
register int i, len = 0;
char malloc();
register char s, x, start;
s = &args; / s points to first argument on stack /

/ Add up the lengths of all the strings /
for(i = n;ien-- ;)
len += strlen(s++);

/ Allocate enough memory for all strings (plus NULL) /
x = malloc(len + 1);
start = x;

s = &args; / Point back to first argument on stack /

/ Concatenate all the input strings together into x /
while (n-- ) ,
while (x++ = (s)++); / Cat next string to x /
s++; / Point down stack to next argument /
x-- ; / Backspace over NULL /
,

return start;
,

4.5.2.1. 8tdarg() r|ght w,y to h,nd|e v,r|,-|e n:m-er of ,rg:ments
1. %re approacr aoove lo a var|ao|e ruroer ol argurerls |s uselu| |r sroW|rg roW parareler
pass|rg or lre slac| |s usua||y dore ard roW C car oe exp|o|led lo la|e advarlage ol |l.
2. loWever, Wr||e pararelers are usua||y passed or lre slac| as |rd|caled lrere, |l |s rol a|Ways
dore lr|s Way. (e.g. Rl3C racr|res sorel|res use reg|slers ard lre lP 3000 ras a slac| lral
groWs loWards r|grer rerory.);
3. %re porlao|e so|ul|or |s lo use stdarg.h (varargs.h |r K&R C corp||ers).
1. Cal car oe re-Wr|ller rore porlao|y as sroWr oe|oW:
/
PJRTABLE VERSIJN using stdarg.h

/

#ifdef __STDC__
#include <stdarg.h
#else
#include <varargs.h
#endif

char cat_va(int n, ...)
,
register int i, len = 0;
char malloc();
va_list ap; / points to each arg in turn /
register char x, start;

va_start(ap, n); / Make ap point to first anonymous arg. /

/ Add up the lengths of all the strings /
for(i = n;i-- ;)
len += strlen(va_arg(ap, char ));

/ Allocate enough memory for all strings (plus NULL) /
x = malloc(len + 1);
start = x;
va_end(ap);

va_start(ap, n); / Make ap point to first anonymous arg. /

/ Concatenate all the input strings together into x /
while (n - - ) ,
/ Cat next string to x /
while (x++ = ((char )ap)++);
va_arg(ap, char );
x-- ; / Backspace over NULL /
,

va_end(ap);
return start;
,

6h,5ter 5. Po|nters to f:n.t|ons
1. Arolrer ||rd ol po|rler used |r C |s a 5o|nrer ro a lunor|on. %r|s |s a very poWerlu| lecrr|que lral
We W||| exar|re |r grealer dela|| |aler or. For lre rorerl, We W||| corcerlrale or roW sucr
po|rlers are dec|ared ard used; spec|l|ca||y, We W||| |oo| al lre|r use |r lre slardard ||orary
sorl|rg lurcl|or qsort().
2. Po|rlers lo lurcl|ors corla|r lre address ol a lurcl|or. Al lre racr|re |eve|, lr|s rears lral lre
va|ue ol a lurcl|or po|rler |s lre address ol lre l|rsl execulao|e |rslrucl|or ol lre lurcl|or.
3. Furcl|or po|rlers car oe passed lo olrer lurcl|ors Wr|cr car lrer use lre passed lurcl|or.
1. very corror use: slardard ||orary sorl lurcl|or. %re sorl lurcl|or rusl oe passed a lurcl|or
po|rler ol a roul|re lral car corpare lWo e|ererls ol lre lype lo oe sorled. (lerce lre sorl
ul|||ly car oe used lo sorl ary ||rd ol dala.)
5. %re AN3l slardard ||orary descr|oes a lurcl|or qsort() (qu|c|er sorl) lral W||| sorl ar array ol
oojecls '|r p|ace.
. 3orl|rg '|r p|ace rears lral lre qsorl roul|re gels lre array as a passed parareler ard, Wrer
|l relurrs, lre array |s rod|l|ed so lral |ls e|ererls are sorled. Furlrerrore, ro aux|||ary arrays
are crealed.
Z. %re a|gor|lrr |s rol lr|v|a|; roWever, |l |l Were |rp|ererled d|recl|y, |l Wou|d requ|re d|llererl
|rp|ererlal|ors lor sorl|rg arrays ol crars, |rls, douo|es, elc.
8. xar|ral|or ol lre roul|re, roWever, |rd|cales lral lre or|y d|llererces oelWeer sorl|rg arrays
ol ore dala lype or arolrer are re|aled lo lre Ways |r Wr|cr lre e|ererls are corpared.
9. %re so|ul|or lo lre proo|er ol d|llererl vers|ors ol lre sorl lurcl|or lor arrays ol d|llererl dala
lypes car oe reso|ved oy a||oW|rg lre prograrrer lo pass, as a parareler, a po|rler lo a
lurcl|or lral W||| corpare e|ererls ol lre array.
10.%r|s |s lre so|ul|or used |r lre slardard ||orary qsort() lurcl|or.
11.%re lurcl|or prololype lor lre qsort lurcl|or |s:
void qsort((char ) base,
size_t num,
size_t width,
int ( compare) (const void elmt1, const void elmt2));

12.%re rear|rgs ol lre argurerls are:
13.-,se:
11.%re slarl|rg address ol lre array lo oe sorled.
15.n:m:
1.%re ruroer ol e|ererls |r lre array.
17.w|dth:
18.%re s|ze (|r oyles) ol eacr e|ererl ol lre array.
19..om5,re:
20.A po|rler lo a lurcl|or lral corpares lWo dala |lers ard relurrs a regal|ve ruroer |l lre l|rsl |s
|ess lrar lre secord, 0 |l lrey are equa| ard a pos|l|ve ruroer |l lre l|rsl |s grealer lrar lre
secord.
21.
Nole: O Nole lre |eyWord const |r lre prololype lor lre compare() lurcl|or.
O %r|s rears lral lre va|ue ol lre oojecl po|rled lo W||| rol oe rod|l|ed oy lre
lurcl|or qsorl. ll does rol rear lral lre correspord|rg va|ue |r lre ca|||rg
roul|re |s a corslarl.
22.%o |rvo|e qsort() lo sorl ar array ol 100 |rlegers, use:
#include <stdlib.h

,
int i_array100,;
.
qsort(i_array, 100, sizeof(i_array), icomp);
.
.
,

int icomp(const int a, const int b)
,
if ( a b)
return 1;
else if (a b)
return -1;
return 0;
,
/ NJTE: the following version of icmp() would be better in this case
(although the above illustrates the more generally
applicable pattern.)

int icomp(const int a, const int b;
,
return (a - b);
,
/

5.1. 6om5|ex de.|,r,t|ons
1. we rave roW seer a|| lre e|ererlary dala lypes C car rard|e.
2. 0ec|aral|ors lor corp|ex var|ao|es lral, lor exarp|e, are lurcl|ors po|rlers lral relurr lre oase
address ol ar array ol |rlegers car oe d|ll|cu|l lo dec|are.
3. Cors|der lre lo||oW|rg exarp|es:
/ funcp is a pointer to a function (that
has a single parameter of type double)
that returns the address of an array of N
integers
/
int (funcp(double))N,;

/
aupp is a matrix of pointers to pointers
to structures
/
struct ,
int i;
int j;
, auppM,N,;


6h,5ter . P,rs|ng
.1. 6om5||ers: An 0verv|ew
1. lr ar aoslracl serse, a corpuler prograr |s s|rp|y a sequerce ol oyles (or o|ls).
2. Fror a corpuler's po|rl ol v|eW, rore corcrele|y, lr|s |s exacl|y Wral lre source code lor a r|gr
|eve| |arguage (lLL) |s.
3. %re source code |s slored |r sore l||e or a d|s| ard lre joo ol lre corp||er |s lo read lr|s l||e
ard lrer soreroW lrarslorr |l |rlo arolrer l||e corla|r|rg racr|re |arguage lral W||| perlorr
lre prec|se las|s del|red oy lre serarl|cs (|.e. Wral a rurar Wou|d urderslard |l lo rear) ol
lre lLL source code l||e.
1. wrer lre corp||er, Wr|cr |s rere|y arolrer prograr, 'reads'lre source code l||e |l s|rp|y
or|rgs lr|s l||e, ore oyle al a l|re, |rlo |ls rerory.
5. %r|s read|rg ol lre source code |s erl|re|y d|llererl lror our oWr |dea ol Wral read|rg |s a||
aooul; lrus |l lWo oyles0x9 ard 0x are read |r sequerce lrere are ro rardWare oe||s lo
s|gra| lral lrese correspord lre lre A3Cll represerlal|or lor lre |ellers `|' ard `l' ard lral lre|r
sequerl|a| occurrerce |rlroduces ar if slalererl.
. wrer a rurar reads, lrere |s ||ll|e corsc|ous ellorl requ|red |r lrars|al|rg We|rd o|ac| srapes
|rlo '|ellers, group|rg lre |ellers |rlo 'Words ard ara|yz|rg lre group|rgs ol Words oy lre|r
corlexl |rlo 'rear|rgs.
Z. ver W|lr a|| lrese advarlages, roWever, rurars car l|rd lre process ol lrars|al|or d|ll|cu|l.
%re lrars|al|or process|.e. go|rg oac| lror aoslracl 'rear|rgs lo `'groups ol Words (|r
arolrer |arguagel) lo Words lo |ellers ard l|ra||y lo 'lurry o|ac| srapes (Wr|cr ray oe qu|le
d|llererl lror lre or|g|ra| |l lre We are go|rg lorr rg||sr lo Arao|c)requ|res corsc|ous ellorl
lror lre rurar.
8. ul Wrer We Warl a corpuler lo corp||e a prograr, We are as||rg lre corpuler lo perlorr ar
exacl lrars|al|or oelWeer lWo |arguages (lre C |arguage lo racr|re |arguage lor exarp|e)
ard, al lre sare l|re, depr|v|rg lre corpuler ol a|| lre |rlu|l|ve |roW|edge ol 'read|rg,
'rear|rg, 'corlexl, elc. lral We a|| rave.
9. %o Wr|le a corp||er, rol or|y do We rave lo descr|oe |r lre ulrosl dela|| lre lrars|al|or ol
'rear|rg (or serarl|cs) |rlo a d|llererl |arguage; We rusl a|so descr|oe (|.e. Wr|le a prograr)
roW lo |rlerprel sequerces ol oyles |rlo Words ard roW lo group Words |rlo serarl|c ur|ls.
10.%r|s |oo|s |||e a o|g jool
11.ll ore s|rp|y allac|s lr|s o|g joo as yel arolrer prograrr|rg ass|grrerl, |l does |rdeed la|e a
|ol ol ellorl. %re l|rsl Forlrar corp||er oac| |r lre 1950's, lor exarp|e, Was Wr|ller lror lr|s
perspecl|ve ard |l ras oeer roled lral lral:

%re l|rsl Forlrar corp||er, lor exarp|e, loo| 18 slall-years lo |rp|ererl.
2|


--ho
12.%oday, roWever, lre corp||al|or process |s rucr oeller urderslood. we roW rave a lreory ol
corp||al|or ard |l |s rol urreasorao|e lo expecl ar urdergraduale sluderl lo Wr|le a corp|ele
corp||er as a course projecl.
13.w|lr lr|s lreory, We d|v|de lre corp||al|or process |rlo lrree rajor sleps:
a. |ex|ca| ara|ys|s
o. pars|rg
c. code gereral|or.
acr ol lrese slages are descr|oed or|el|y |r lre lo||oW|rg secl|ors.
.1.1. Lex|.,| ,n,|ys|s
1. Lex|ca| ara|ys|s |s used lo lrars|ale lre |rcor|rg sequerce ol oyles read lror lre source code
l||e |rlo rore rear|rglu| rokens.
2. %re |ex|ca| ara|yzer car recogr|ze sequerces ol craraclers as Words.
3. For exarp|e, |rpul lral We read as:
thing := stuff10;
1. Wou|d oe read oy lre |ex|ca| ara|yzer as lre lo||oW|rg sequerce ol 18 oyles:
74 68 69 6e 67 20 3a 3d 20
73 74 75 66 66 2a 31 30 3b

5. %re |ex|ca| ara|yzer lrars|ales lrese 18 oyles |rlo a sequerce ol lo|ers as lo||oWs:
<identifier (with value of ``thing'')
<assignment operator
<identifier (with value of ``stuff'')
<multiply operator
<constant (with value of 5)
<statement terminator

. %r|s |s rol loo corp||caled lo do. %re |arguage del|r|l|or requ|res lral |eyWords oe separaled
oy Wr|le space (o|ar|s, laos or reW||res) or oy spec|a| craraclers (|||e = ; elc. rol a||oWed
lo oe parl ol |eyWords or |derl|l|ers (|.e. syroo|s).
Z. lerce lre |ex|ca| ara|yzer reads ore oyle al a l|re ard co||ecls lrer url|| |l r|ls Wr|le space or
a spec|a| craracler.
8. ll ras lrer co||ecled a 'Word ard corpares |l aga|rsl |ls ||sl ol |eyWords.
9. ll |l l|rds a ralcr |l oulpuls a roken represerl|rg lral |eyWord; |l ro ralcr |s lourd ar '|derl|l|er
lo|er |s oulpul a|org W|lr sore ||r| lo lre lo|er's 'va|ue. %re |ex|ca| ara|yzer a|so recogr|zes
lral a Word oeg|rr|rg W|lr a d|g|l srou|d oe oulpul as a 'corslarl lo|er W|lr a ||r| lo lre aclua|
d|g|l slr|rg.
10.F|ra||y, spec|a| craraclers (|||e ; + ) or groups ol spec|a| craraclers (|||e := =) are a|so
recogr|zed ard rave lre|r oWr |rd|v|dua| lo|ers.
11.%re ruroer ol lypes ol lo|ers |s qu|le ||r|led. %r|s |s a rar|ed corlrasl lror ralura| |arguages
|||e rg||sr W|lr vocaou|ar|es lral are o|gger oy rary orders ol ragr|lude.
12.%r|s ||r|led vocaou|ary ol prograrr|rg |arguages (a|so ca||ed lorma| |anuaes |r corlrasl lo
narura| |anuaes) ra|es lre |ex|ca| ara|yzer's joo rucr eas|er.
13.Nole lral lre |ex|ca| ara|yzer ra|es ro judgererls aooul lre s|gr|l|carce or sers|o|eress ol
lre slrear ol lo|ers |ls gererales.
11.(loWever, lre |ex|ca| ara|yzer ray oe ao|e lo delecl a ror-sers|ca| lo|er sucr as a slr|rg |||e
123ax5 Wr|cr, oecause |l slarls W|lr a d|g|l srou|d gererale a corslarl lo|er Wr||e lre slr|rg
as a Wro|e |s rol a ruroer.)
.1.2. P,rs|ng
1. 0rce lre |ex|ca| ara|yzer ras corverled lre source code |rlo a lo|er slrear, lre 5arser} (or
serarl|c ara|yzer) la|es over.
2. lls joo |s lo l|rd rear|rglu| pallerrs |r lre lo|er sequerce ard lo pass lrese 'rear|rgs lo lre
l|ra| slage ol corp||al|orlre code gereralor Wr|cr produces lre l|ra| racr|re |arguage
lrars|al|or ol lre or|g|ra| source code.
3. F|rd|rg rear|rglu| pallerrs |s greal|y s|rp||l|ed oy lre lorra| del|r|l|or ol lre source code
|arguage grarrar.
1. %re syrlax (or grarrar) ol a lorra| |arguage |||e C car oe corp|ele|y descr|oed us|rg lre
ac|us-Naul Forr (NF) rolal|or. %r|s rolal|or descr|oes roW lo|ers car oe coro|red lo lorr
serarl|c ur|ls.
5. 3ore ol lrese serarl|c ur|ls are very s|rp|e. %re 'addop serarl|c ur|l, lor exarp|e, |s e|lrer
ar add|l|or ('') or suolracl|or ('-') operalor ard NF uses lre lo||oW|rg rolal|or lo descr|oe lr|s:
<addop ::=
<+ operator | <- operator

. %re 'j' (verl|ca| oar) syroo| |s used lo descr|oe a|lerral|ves. Nole lral lre '' ard '-' craraclers
are s|rp|e lo|ers recogr|zed oy lre |ex|ca| ara|yzer.
Z. %re serarl|c ara|yzer or parser uses lre aoove ru|e or pallerr lo recogr|ze lrese s|rp|e
lo|ers as a rore aoslracl serarl|c ur|l.
8. %re NF descr|pl|or a|so descr|oes roW lre addop ur|l car oe coro|red W|lr olrer serarl|c
ur|ls lo lorr yel rore corp|ex aoslracl erl|l|es.
9. For exarp|e, We |roW lral We car add or suolracl lWo or rore 'lerrs ard lral a prograrrer
spec|l|es lr|s oy p|ac|rg '' or '-' craraclers oelWeer lre lerrs.
10.Lel's ca|| sorelr|rg |||e 'a o - c ar express|or. %re gerera| NF descr|pl|or lor ar
express|or |s:
<expression ::=
<term ,<addop <term,

11.%re '{' ard '' (cur|y oraces) |rd|cale lral lre syroo|s W|lr|r lrer ray oe repealed zero or rore
l|res.
12.Assur|rg lor lre rorerl lral a lerr |s a s|rp|e var|ao|e, a|| lre lo||oW|rg are va||d express|ors
accord|rg lo lre aoove NF del|r|l|or:
<term and 0 repetitions of <addop <term:
a
<term and 1 repetition of <addop <term:
c - d
<term and 2 repetitions of <addop <term:
a + b - c


13.%o use lre NF ru|e |r l|rd|rg lrese express|ors, lre parser Wou|d l|rsl recogr|ze lre |r|l|a|
lerr.
11.ll Wou|d lrer delerr|re |l lre rexl serarl|c erl|ly Was ar <addop: |l |l Was rol, lre parser
Wou|d relurr lre s|rp|e express|or; olrerW|se |l Wou|d |oo| lor lre <term lral rusl lo||oW lre
<addop ard lrer repeal lre sequerce |oo||rg lor arolrer <addop or lre erd ol lre
express|or.
15.%re u|l|rale goa| ol lre parser |s lo coro|re a|| lre lo|ers ard a|| lre serarl|c ur|ls |rlo lre
r|gresl-|eve| ur|l ol a||: lre <program. As lre r|grer-|eve| ur|ls are lorred, |rlorral|or aooul
lre|r slruclure |s passed lo lre code gereralor Wr|cr lrer ras sull|c|erl |rlorral|or lo perlorr
'acl|ors oased or lre serarl|c slruclure.
1.%rese acl|ors gererale lre racr|re code equ|va|erl lo lre serarl|c slruclures ol lre source
code.
1Z.we W||| cors|der lre lre exarp|e ol ar ass|nmenr sraremenr lo |||uslrale lr|s po|rl.
Cors|der lre NF:
<assignment statement ::=
<variable := <expression

<expression ::=
<term ,<addop <term,

<addop ::= + | -

<term ::=
<factor , <factor ,

<factor ::=
<variable | ( <expression )


18.ll We |oo| al roW express|ors are del|red rere, We see lral ary ar|lrrel|c express|or |rvo|v|rg
lre '', '-' ard '' opereralors ard lre '(' ard ')' group|rg craraclers |s del|red.
19.%re del|r|l|ors are recurs|ve as ar express|or |s del|red as a group|rg ol <terms; lerrs |r
lurr are del|red us|rg <factors; l|ra||y laclors are del|red us|rg <variables ard aga|r
W|lr <expressions.
20.%r|s relrod ol del|r|rg sorelr|rg |r lerrs ol |lse|l |oo|s slrarge al l|rsl g|arce oul |l |s a
poWerlu| relrod lor s|rp|e, e|egarl del|r|l|ors ol grarrars.
21.Cors|der roW lre parser Wou|d lreal lre lo||oW|rg express|or:
(a + b) c
22.wrer lre express|or delecl|rg roul|re |s ca||ed, |l l|rsl |rvo|es arolrer roul|re lo |oo| lor lre
l|rsl lr|rg |r ar express|or|r lr|s case a lerr. As soor as lre lerr roul|re |s ca||ed, |l
|rred|ale|y |oo|s lor |ls l|rsl |lera laclor.
23.A laclor, |r lurr, ras lWo a|lerral|ve del|r|l|ors: e|lrer |l |s a s|rp|e var|ao|e or |l |s ar express|or
erc|osed W|lr|r parerlres|s.
21.%re laclor roul|re exar|res lre l|rsl craracler lo see |l |l |s a s|rp|e var|ao|e or a '('.
25.lr lr|s case, |l l|rds lre '(' spec|a| craracler; |l lrer roves lo lre rexl |rpul lo|er Wr|cr |l
expecls lo oe lre slarl ol ar express|or ard ca||s lre express|or recogr|l|or roul|re orce aga|r.
2.wrer lre express|or roul|re slarls a secord l|re, |l aga|r ca||s lerr ard lrer laclor.
2Z.%r|s l|re, roWever, laclor l|rds a s|rp|e var|ao|e ard relurrs |rred|ale|y. %re lerr roul|re
lrer |oo|s lor a '' lo see |l |l srou|d ca|| laclor aga|r; |l doesr'l l|rd ore, so |l relurrs
|rred|ale|y. NoW lre secord |rvocal|or ol express|or |oo|s lor a '' s|gr lo see |l |l srou|d
aga|r ca|| lerr aga|r lo l|rd oul Wral srou|d oe added lo lre l|rsl lerr |l lourd.
28.xpress|or l|rds a s|rp|e var|ao|e, 'c', or lre olrer s|gr ol lre s|gr. ll lrer |oo|s lor arolrer ''
or '-' lo see |l |l srou|d corl|rue. 3|rce lre rexl craracler |s a ')', lr|s secord |rvocal|or ol
express|or lerr|rales ard relurrs lo lre laclor roul|re lral ca||ed |l.
29.Faclor lrer expecls lo l|rd a ')' lo oa|arce lre l|rsl ore |l delecled ard |l relurrs lo lerr aller
l|rd|rg lre rexl lo|er lo||oW|rg lre ')'. %err exar|res lr|s lo|er lo see |l |l |s a ''. 3|rce |l |s,
lerr ca||s laclor aga|r lo l|rd lre olrer laclor ol lre ru|l|p||cal|or. %err lrer l|rds ro rore ''s
ard relurrs lo lre l|rsl |rvocal|or ol express|or.
30.we are roW a|rosl dore. xpress|or |oo|s lor arolrer '' or '-', l|rds rore, ard lerr|rales. %re
erl|re express|or ras roW oeer corp|ele|y parsed. we roW |roW Wral ras lo added,
suolracled ard ru|l|p||ed ard are |r a pos|l|or lo gererale racr|re code lo perlorr lrese
operal|ors ard eva|uale lre express|or.
31.we car, ol course, Wr|le a prograr lo parse express|ors oased or lre aoove syrlax. 3ucr a
prograr, Wr|ller |r C, |s sroWr oe|oW. %r|s prograr does rore, roWever, lrar rere|y
recogr|ze express|ors. ll a|so does sore lrars|al|or; |r parl|cu|ar, |l lrars|ales a|geora|c
rolal|or lor express|ors del|red |r lre NF lor express|ors |rlo Reverse Po||sn orar|on (RPN).
32.w|lr Reverse Po||sr Nolal|or (used lor exarp|e lo erler express|ors |r leW|ell-Pac|ard
ca|cu|alors), lre express|or |s read ard eacr var|ao|e or corslarl |s pusred orlo a slac|. wrer
ar operalor |s ercourlered, lre lop lWo e|ererls are popped oll lre slac|, lre operal|or
perlorred or lrer, ard lre resu|l pusred oac| or lre slac|.
33.Cors|der lre lo||oW|rg express|or ard |ls RPN equ|va|erl:
(a+b)(c + d +e) //algebraic
ab+cd+e+ //RPN equivalent

31.ll lre RPN express|or |s exar|red ore lo|er al a l|re, lrer, jusl oelore ercourler|rg lre l|rsl
'' operalor, lre slac| Wou|d |oo| |||e lre l|gure oe|oW:
|g:re .1. #PN st,. -efore 5ro.ess|ng f|rst '+' |n ,-+.d+e+*

35.Aller process|rg lre l|rsl lWo craraclers (|.e. 'ao) |r lre RPN express|or, lre slac| Wou|d |oo|
|||e lre l|gure oe|oW:
|g:re .2. #PN st,. ,fter 5ro.ess|ng ",-" |n ,-+.d+e+*

3.ll Wou|d lrer urdergo lre lo||oW|rg lrarslorral|ors:
|g:re .3. #PN st,. when |nter5ret|ng ,-+.d+e+*

3Z.%o ra|e lre parser prograr corverl lre a|geora|c express|or lo reverse po||sr rolal|or al lre
sare l|re lral |l |s pars|rg |l We s|rp|y add lre lo||oW|rg: pr|rl |derl|l|ers as lrey are
ercourlered oul deler pr|rl|rg a '', '-' or '' url|| oolr ol |ls lerrs (or laclors) rave oeer lourd.
38.%re C prograr (ava||ao|e al parseRPN.c) |s:
#include <stdio.h
/
The program works on expressions conforming to the following BNF syntax
rules:
<expression ::= <term <addop <term ,
<term ::= <factor <factor ,
<factor ::= ( <expression ) | <id
<addop ::= + | -
<id ::= any single character except ()+-

How to run the program: The program reads algebraic expressions for
stdin and
writes their Reverse Polish Notation (rpn) equivalent to stdout. In
order
to avoid seeing all of this on the screen, redirect stdin or stdout. For
example, postfix1 < exprs will read expressions from the file "exprs"
(which you have to create previously).
/

char ch;

main()
,
find();
do
,
expression();
putchar('\n');
, while (ch != '.');
,

find() / Read input until non-white space or
end-of-line reached /
,
while (((ch = getchar()) == ' ') || (ch == '\n'))
;
,

expression()
/
Look for an expression and print
the + or - operand if and when a "term"
is found after such an operand
/

,
char op;
term();
while ((ch == '+') || (ch == '-'))
,
op = ch;
find();
term();
putchar(op);
,
,


term()
/
Look for a term and print the operand if and when a "factor" is
found
after such an operand
/
,
factor(); / Find the initial factor and print rpn for
it /
/
Move around the "factorfactor" loop as long as the next character
is the '' operand'
/
while (ch == '')
,
find(); / Move to next non-blank character /
factor(); / Find the factor after the '' and,
if it is a simple identfier, print it /
putchar(''); / Complete the rpn for the factor by
printing the '' operand /
,
,


factor()
/ Look for a factor; if the factor is a simple identifier, print it /
,
if (ch == '(')
,
find(); / Move to the next non-white character /
expression(); / Find the expression & print rpn for it /
/ After returning "ch" should be a ')' if syntax is correct /
, else
,
/
If not an expression enclosed in "(...)", it has to be a
simple identifier so print it
/
putchar(ch);
,
find(); / Now move to next non-blank character /
,


.1.2.1. P,rs|ng 6 de.|,r,t|ons
1. %re syrlax ol C dec|aral|ors (espc|a||y po|rlers lo lurcl|orsl) car oe corlus|rg. we roW |oo| al
lre lorra| NF spec|l|cal|or ol dec|aral|ors ard roW We car Wr|le a prograr lo |rlerprel lrese
dec|aral|ors.
2. %rese roles are oased or lre progrars or pages 122-12 ol Tne 0 Proramm|n lanuae
oy Kerr|grar ard R|lcr|e (2rd ed|l|or).
3. F|rsl, lre s|rp||l|ed NF syrlax ol a dec|aral|or |s:
<dcl ::= ,, <direct_dcl

<direct_dcl ::= <name
| '(' <dcl ')'
| <direct_dcl '(' ')'
| <direct_dcl''<size','


1. A C dec|aral|or car oe |rlerpreled oy a re|al|ve|y s|rp|e recurs|ve-descerl parser ol lre lype We
rave |oo|ed al.
5. %re source code (ava||ao|e al parse_dc|.c) |s:
/
NAME
parse_dcl
PURPJSE
This program parses C declaratations (reading from stdin)
and outputs an English language description of each declaration's
meaning to stdout.
NJTES
This program is a lsightly different version of the program
given in Section 5.12 (pages 122--126) of the K & R book,
second edition.

A simplified form of C declaration is used, as described
in the following BNF:

<typed_declaration ::= <type <declaration
<declaration ::= , '' , <direct_declaration
<direct_declaration ::= <name
| '(' <declaration ')'
| <declaration '(' ')'
| <declaration '' <dimension ','
<name ::= a sequence of characters
<dimension ::= , <digit ,

EXAMPLES
Assuming the program is called parse_c_decs, then
parse_c_decs << XXXX
char abc;
char simple();
char (foo)();
char ((bar()),)();
int ((foobar2,3,)())();
float ((f)())5,();
XXXX

produces:
abc is a pointer to pointer to pointer to char

simple is a function returning pointer to char

foo is a pointer to function returning char

bar is a function returning pointer to array, of pointer to
function
returning char

foobar is a array2, of array3, of pointer to function returning
pointer to function returning int

f is a pointer to function returning pointer to array5, of
function
returning float




BUGS
This is demonstration program only. It does not
understand the full C syntax of declarations.
For examples, structs are not supported, type qualifiers
like "const" or "volatile" are not supported, function argument
types are not supported, etc.

HISTJRY

kclowes (Ken Clowes) - Sept 25, 1993: Created.
/
#include <stdlib.h
#include <strings.h
#include <stdio.h
#include <ctype.h

#define MAX_TJKEN_LENGTH 100
#define MAX_DESCRIPTIJN_LENGTH 1000

enum
,
NAME,
BJTH_PARENS,
BRACKETS,
LEFT_PARENS,
RIGHT_PARENS,
DECLARATIJN_END
,;


typedef struct
,
int type;
char valueMAX_DESCRIPTIJN_LENGTH,;
, token_t;

static token_t token; / next token from input stream /
static char descriptionMAX_DESCRIPTIJN_LENGTH,;
static char nameMAX_TJKEN_LENGTH,;
static int line;
static int n_errors;

void declaration(void);
int gettoken(void);
void direct_declaration(void);


int main(int argc, char argv,)
,
char data_typeMAX_TJKEN_LENGTH,;

for (line = 1, n_errors = 0; gettoken() != EJF; line++)
,
/ 1st token is data declaration type /
strcpy(data_type, token.value);
description0, = '\0';
declaration();
if (token.type != DECLARATIJN_END)
,
fprintf(stderr, "Syntax error on line %d\n", line);
n_errors++;
,
printf("%s is a %s %s\n", name, description, data_type);
,
exit(n_errors);
,

/
NAME:
int gettoken()
PURPJSE:
Reads the next token from stdin and set the global variable
token to it.
ARGS:
None
RETURNS:
< The token type: i.e. NAME, BJTH_PARENS, BRACKETS, LEFT_PAREN,
RIGHT_PARENS, or the last return value form getchar
NJTES:
The "last return value" from getchar may, or course, be EJF.
/

int gettoken()
,
int ch;
char p = token.value;

while((ch = getchar()) == ' ' || ch == '\t' || ch == '\n')
;
if (ch == '(')
,
if ((ch = getchar()) == ')')
,
strcpy(token.value, "()");
return token.type = BJTH_PARENS;
,
else
,
ungetc(ch, stdin);
return token.type = LEFT_PARENS;
,
,
else if (ch == '')
,
for(p++ = ch; (p++ = getchar()) != ',';)
;
p = '\0';
return token.type = BRACKETS;
,
else if (isalpha(ch))
,
for (p++ = ch; isalnum(ch = getchar()); )
p++ = ch;
p = '\0';
ungetc(ch, stdin);
return token.type = NAME;
,
else if (ch == ';')
return token.type = DECLARATIJN_END;
else if (ch == ')')
return token.type = RIGHT_PARENS;
else
return token.type = ch;
,

/
NAME:
declaration
PURPJSE:
Parses the following BNF.
<declaration ::= , '' , <direct_declaration

ARGS:
None.
RETURNS:
< Nothing.
NJTES:

/

void declaration(void)
,
int num_stars;

for(num_stars = 0; gettoken() == ''; num_stars++)
;
direct_declaration();
while(num_stars-- 0)
strcat(description, " pointer to");
,

/
NAME:
direct_declaration
PURPJSE:
Implements the parsing of:
<direct_declaration ::= <name
| '(' <declaration ')'
| <declaration '(' ')'
| <declaration '' <dimension ','
ARGS:
None
RETURNS:
< Nothing
NJTES:
Called from declaration, so leading <declaration, if any, already
parsed.
/

void direct_declaration(void)
,
if (token.type == NAME)
strcpy(name, token.value);
else
if (token.type == LEFT_PARENS)
,
declaration();
if (token.type != RIGHT_PARENS)
,
fprintf(stderr, "missing ) on line %d\n", line);
n_errors++;
,
,
else
,
fprintf(stderr, "expected name or (dcl) on line %d\n", line);
n_errors++;
,
for(gettoken();
token.type == BJTH_PARENS || token.type == BRACKETS;
gettoken())
if (token.type == BJTH_PARENS)
strcat(description, " function returning");
else
,
strcat(description, " array");
strcat(description, token.value);
strcat(description, " of");
,
,



2|
A|lred v. Aro, Rav| 3elr|, Jellrey 0. u||rar 0om5||ers. Pr|no|5|es, Teonn|ques, ano Too|s, Add|sor-
wes|ey, 198, page 2.
6h,5ter 7. 0,t, 8tr:.t:res
7.1. 8tr:.t:res ,nd Un|ons
1. A srruor (|||e a 'record |r Pasca|) groups dala |lers |rlo a s|rg|e |og|ca| ur|l. For exarp|e:
O
/
The following declares a structure data type
called "complx".
No storage is reserved; only the name and data
type of the component fields of the structure
are defined.
/
struct complx ,
double real;
double im;
,;

O
/
The following declares two arrays of 100 items each.
Each array item is a structure of the type
defined above
/
struct complx z100,, y100,;

2. Porl|ors ol a slruclure are accessed as lo||oWs:
z2,.real = y1,.real y1,.real - y1,.im y1,.im;

7.2. 8tr:.t:re Ex,m5|es
1.
struct person ,
char first_name;
char last_name;
char sex;
int age;
, persons10,;

/
In the above declaration, both the definition
of the structure fields and the allocation of
of an array of 10 such structures is combined
into a single declaration.
/

persons0,.last_name = "Jones";
persons0,.first_name = "Robert";
persons0,.sex = 'M';
persons0,.age = 23;

2. Nole lral slruclures car oe ass|gred. %rus:
persons4, = persons8,;
3. W||| copy slruclure #8 lo slruclure #1.
Nole: eg|rrers are sorel|res surpr|sed lral slruclures car oe ass|gred oul rol arrays. %rey
oecore ever rore arazed Wrer lo|d lral |l lrey ra|e lre array lre or|y reroer ol a
slruclure, |l car oe ass|gred
Car you see Wry C Wor|s lr|s Way?
7.3. Us|ng typ0d0f
1. ll |s oller corver|erl lo use a 'lypedel lo g|ve a user del|red rare lo a dec|aral|or. (%r|s |s
rucr |||e lre 'lype |eyWord |r Pasca|.)
2. For exarp|e, lo del|re a reW dala lype ca||ed 'Corp|x lral correspords lo lre corp|ex
ruroer dala slruclure We saW ear||er, We Wr|le:
typedef struct complx ,
double real;
double im;
, Complx;

3. %re Word Complx W||| roW oe |rlerpreled oy lre corp||er as lre rare lor a dala lype. %rus:
Complx z100,, y100,;

1. Nole: lypedels are uselu| lor lr|rgs olrer lrar slruclures. For exarp|e, cors|der:
typedef unsigned char byte;

byte var1, var2;

5. %r|s creales a reW dala lype ca||ed byte Wr|cr |s ar a||as lor ar urs|gred crar. var|ao|es var1
ard var2are lrer dec|ared as lype oyle.
7.4. Po|nters to str:.t:res
1. Po|rlers lo slruclures are exlrere|y uselu| lor corror dala slruclures sucr as ||r|ed ||sls or
lrees.
2. A ||r|ed ||sl |s a group ol slruclures Wrere eacr slruclure corla|rs a po|rler lo lre rexl slruclure
|r lre ||sl. %re dec|aral|or ol sucr a slruclure |s ar exarp|e ol se|l-relererl|a| dala slruclures.
3. For exarp|e:
struct node ,
int data;
struct node next;
,;

1. Nole lral |l a lypedel |s used, lre lypedel rare carrol (urlorlurale|y) oe used |r lre slruclure
dec|aral|or. %rus We rusl Wr|le:
typedef struct node ,
int data;
struct node next;
, node, nodePtr;
node all_nodesNN,;
nodePtr node_ptr = &all_nodes3,;

5. loWever, lr|s o|er|sr car oe avo|ded oy separal|rg lre lypedel lror lre slrucl dec|aral|or as
lo||oWs:
typedef struct node node, nodePtr;
struct node ,
int data;
nodePtr next;
,;
node all_nodesNN,;
nodePtr node_ptr = &all_nodes3,;

7.5. 8|ng|e L|ned L|st Ex,m5|e
%re lo||oW|rg code lragrerls |||uslrale lre relrods used |r a||ocal|rg slorage lor reW slruclures,
access|rg a spec|l|c slruclure or a ||r|ed ||sl ard slepp|rg lrrougr a ||r|ed ||sl.
typedef struct elem elem, elemPtr;
struct elem ,
char name30,;
elemPtr next;
,;
elemPtr first, temp;
/ i.e. first is a pointer to a structure called elem;
The structure contains two fields:
a 30 character array and a pointer called next
to an other structure of the same type /

first = (elemPtr) malloc(sizeof elem);
strcpy(first-name, "Smith");
temp = first-next
= (elemPtr) malloc(sizeof elem);
temp-next = (elemPtr) malloc(sizeof elem);
.
/ Print out 3rd name /
printf("%s\n", first-next-next-name);
.
/ Step through list /
for(temp = first; temp != NULL ; temp = temp-next)
printf("%s\n", temp-name);


7.. |n|t|,||z|ng L|ned ||sts |n de.|,r,t|ons
1. %re lo||oW|rg code lragrerl sroWs roW a ||r|ed ||sl car oe sel up al corp||e l|re.
2. %re exarp|e oe|oW sels up a c|rcu|ar ||r|ed ||sl ol lrree rodes.
3. Nole lral slruclures or lre ||sl relerred lo lral rave rol yel oeer dec|ared requ|re ar extern
dec|aral|or oelore lrey are relerred lo.
1. %re sarp|e code |s:
typedef struct node node, nodePtr;
struct node ,
int data;
nodePtr next;
,;
extern node node2;
extern node node3;

node node1 = ,
1,
&node2
,;

node node2 = ,
22,
&node3
,;

node node3 = ,
333,
&node1
,;

7.7. Un|ons
1. A un|on |s a dala |ler lral car ro|d d|llererl lypes ol dala (al d|llererl l|res).
2. For exarp|e, We ray W|sr lo rar|pu|ale a ruroer lral ray oe slored as e|lrer ar |rleger or as
a l|oal|rg po|rl ruroer. %re lo||oW|rg ur|or a||oWs lr|s:
union number ,
int integer;
float floating_point;
, n1, n2;

3. %re corp||er W||| lorce lre s|ze ol ruroer lo oe o|g erougr lo ro|d lre |argesl var|arl. ll |s lre
prograrrer's respors|o|||ly lo |eep lrac| ol roW lre dala |s represerled W|lr|r lre ur|or.
1. %re ur|or reroer |s relererced rucr |||e slruclure e|ererls. For exarp|e, lo pr|rl r1 (slored
as ar |rleger) ard r2 (slored as a l|oal|rg po|rl ruroer), We use:
printf("n1: $d; n2: %f\n", n1.integer, n2.floating_point);

5. ur|ors are oller coro|red W|lr slruclures, W|lr ore l|e|d |r lre slruclure |rd|cal|rg lre lorral ol
lre ur|or.
. For exarp|e, suppose We sorel|res W|sr lo slore corp|ex po|rl ruroers |r reclargu|ar
rolal|or ard sorel|res |r po|ar coord|rales. we cou|d use lre lo||oW|rg:
struct cartesian ,
float real;
float imag;
,;

struct polar ,
float mag;
float angle;
,;

typedef struct ,
enum , CARTESIAN, PJLAR , complex_type;
union ,
struct cartesian cart;
struct polar polar;
, value;
, Complex;

7.8. Ex,m5|e: 0o:-|y L|ned L|st
1. A 'douo|y-||r|ed ||sl ras oolr lorWard ard oac|Wards po|rlers; lr|s ||rd ol ||sl requ|res rore
slorage (lWo po|rlers per slruclure) ard rore l|re lo |rserl or de|ele ar |ler. Vary proo|ers
are rore eas||y so|ved W|lr lre added l|ex|o|||ly, roWever. %re lo||oW|rg exarp|es sroW roW
douo|y ||r|ed ||sls car oe rar|pu|aled.
2. %rese exarp|es a|so |||uslrale:
O 3p||ll|rg a proo|er |rlo sra||er parls;
O us|rg lurcl|or po|rlers as argurerls.
O us|rg lre corra operalor lo oola|r 2 |oop var|ao|es |r a lor |oop. (%r|s |s a corror
|d|or Wrer rar|pu|al|rg ||r|ed ||sls.)
3. %re lo||oW|rg secl|ors g|ve dela||s.
7.8.1. he,der f||e d4ub0ink0di8t.h
%re reader l||e del|res lre oas|c dala slruclures ard racros. %re source code (ava||ao|e al
douo|eL|r|edL|sl.r) |s:
/ Header file describing structures
for a doubly-linked list /
#include <stdlib.h
typedef struct rec ,
char word80,;
struct rec next;
struct rec prev;
, REC, RECP;

#define NILREC ( (RECP) NULL)
#define allocrec (RECP) malloc(sizeof(REC))

7.8.2. H,|n ro:t|ne
/ Copyright K. Clowes (kclowes@ee.ryerson.ca) 1996
May be copied, modified, etc. by anyone.
The Copyright notice does NJT have to be retained.
/

/
This routine reads words from stdin
and inserts them in sorted order into
a doubly linked list.

It then prints out the list in forward
and reverse order.
/

#include <stdio.h
#include "double.h"
RecPtr headPtr, tailPtr;
RecPtr Forward();
RecPtr Backward();

main()
,
/ Initialize the list as empty /
headPtr = tailPtr = NILREC;

/ Create the doubly linked list /
BuildList();

/ Jutput the list in forward and reverse order /
PrintList(headPtr, Forward);
printf("\n");
PrintList(tailPtr, Backward);
,
\end,verbatim,
\subsection,Build list,

%\verbatimlisting,c_progs/doubleLinkedLists/dbuild.c,
\begin,verbatim,
/ Copyright K. Clowes (kclowes@ee.ryerson.ca) 1996
May be copied, modified, etc. by anyone.
The Copyright notice does NJT have to be retained.
/

/
BuildList reads stdin a line at a time
and builds a sorted doubly-linked list
from the input.
/
#include <stdio.h
#include "double.h"
extern RecPtr headPtr, tailPtr;
BuildList()
,
RecPtr newPtr, prevPtr, currentPtr;

while((newPtr = allocrec)
&& (scanf("%s", newPtr-word) != EJF)) ,
for(currentPtr = headPtr, prevPtr = NILREC;
currentPtr != NILREC && strcmp(currentPtr-word, newPtr-word) < 0;
prevPtr = currentPtr, currentPtr = currentPtr-next);

newPtr-next = currentPtr;
newPtr-prev = prevPtr;
if ( currentPtr == NILREC)
tailPtr = newPtr;
else
currentPtr-prev = newPtr;
if ( prevPtr == NILREC)
headPtr = newPtr;
else
prevPtr-next = newPtr;
,

if ( newPtr == NILREC) ,
fprintf(stderr, "!!!!!! JUT JF MEMJRY !!!!!!");
exit(1);
,
,


7.8.3. Pr|nt ||st
/ Copyright K. Clowes (kclowes@ee.ryerson.ca) 1996
May be copied, modified, etc. by anyone.
The Copyright notice does NJT have to be retained.
/

/
PrintList prints the contents of a linked list
using a supplied function to determine the
next element on the list.

Arguments:
RecPtr start: ptr to the first item on the list

getnext: pointer to a function to return the next
item from the current item.
/

#include <stdio.h
#include "double.h"

PrintList(RecPtr startPtr, RecPtr (getNextProc)(RecPtr))
,
RecPtr tempPtr;

for(tempPtr = startPtr;
tempPtr != NILREC;
tempPtr = (getNextProc)(tempPtr))
printf("%s\n", tempPtr-word);
,

RecPtr Forward(RecPtr recPtr)
,
return(recPtr-next);
,

RecPtr Backward(RecPtr recPtr)
,
return(recPtr-prev);
,

7.8.4. Notes
ll lre ||r|ed ||sl Were |rp|ererled as a c|rcu|ar ||sl, |rserl|or ard de|el|or Wou|d oe s|rp|er. %re c|rcu|ar
||sl Wou|d oe |r|l|a||zed W|lr a slruclure corla|r|rg a Word |ex|ca||y oeyord ary poss|o|e rea| Words (e.g
'zzzzzz).
6h,5ter 8. %he Pre5ro.essor
1. %re C preprocessor |s |s lre l|rsl slage ol lre corp||al|or process. ll lrarslorrs lre or|g|ra|
source code |rlo a 'lrarslorred source code lral |s led lo lre aclua| corp||er.
2. Nole lral lre preprocessor |s, |r ellecl, a lexl rar|pu|alor (or a oalcr ed|lor). olr |ls |rpul ard
oulpul are lexl l||es. ll |s qu|le poss|o|e lo use lre C preprocessor lor |arguages olrer lrar C.
3. %o use lre C preprocessor lor olrer |arguages requ|res e|lrer a spec|a| opl|or lo lre C corp||er
or |s a slard-a|org prograr.
1. %re corcepl ol auloral|c lrars|al|or ol ore lorr ol source code lo arolrer ras oeer exlerded
|r projecls sucr as 0. Krulr's ueo projecl. lere, a s|rg|e 'source code l||e |s lrarslorred |rlo
separale docurerlal|or ard |rp|ererlal|or l||es. Krulr's or|g|ra| Wor| Was largeled lo Pasca|,
oul r|s |deas rave oeer porled lo olrer |arguages (sucr as lre oueo pac|age lor C).
8.1. Us|ng the Pre5ro.essor
1. Preprocessor corrards oeg|r W|lr a # ard We rave a|ready used lWo sucr corrards:
#include ard #define.
2. Proper use ol lre pre-processor re|ps |r ra||rg progrars eas|er lo read (ard Wr|lel), eas|er lo
ra|rla|r, rore porlao|e, ard rore ell|c|erl. we roW exar|re lre lealures ol lre preprocessor
|r rore dela||.
3. we W||| l|rsl |oo| al lrose preprocessor lealures corror lo oolr AN3l ard K&R C. Laler, We
W||| |oo| al lre errarced capao|||l|es or|y ava||ao|e |r AN3l C.
8.1.1. #|n.|:de
1. %re #include d|recl|ve s|rp|y |rserls lre rared l||e |rlo lre source code. %re l||e |s ca||ed a
'reader l||e ard, oy corverl|or, |ls rare erds W|lr .h.
2. %re rosl corror lype ol |rc|ude slalererl |oo|s |||e:
#include <header_name.h
3. %r|s |s usua||y used lo |rc|ude a reader l||e assoc|aled W|lr lurcl|ors (or racros) supp||ed W|lr
lre corp||er. For exarp|e, #include <stdio.h.
1. %re corp||er |roWs Wrere lo l|rd lre l||e.
O lr uNlX, |l usua||y |oo|s lor lre reader l||e |r /usr/include ard
/usr/local/include.
O urder w|rdoWs us|rg lre g.. corp||er ard lre .ygw|n pac|age, |l |oo|s |r
C:\cygwin\usr\include.
5. loWever, lre corp||er car oe |rslrucled lo |oo| lor lre |rc|ude l||e |r olrer d|reclor|es oy g|v|rg
lre|r rares lo lre -I opl|or |r lre corp||er. %rus, |l lre corp||er srou|d |oo| lor reader l||es |r
d|reclory /usr/me/my_includes, use lre corrard ||re:
UNIX_PRJMPT% cc -I/usr/me/includes source_file.c

. %re olrer Way lo spec|ly ar |rc|ude l||e |s W|lr:
#include "path_file"

Z. lr lr|s case, lre exacl palr (re|al|ve or aoso|ule) lor lre l||e |s g|ver.
8. For exarp|e, |l lre reader l||e head.h |s |r lre sare d|reclory as lre source code, s|rp|y use:
#include "head.h"

9. ll |s a|so very corror lor a |arge projecl lo oe d|v|ded |rlo severa| suo-d|reclor|es: src lor
source code, doc lor docurerlal|or, include lor reader l||es, elc.
10.%rus a source code l||es |r suo-d|reclory src car access reader l||es oy rov|rg up lo lre
parerl d|reclory (..) ard doWr lo lre include d|reclory as lo||oWs:
#include "../include/head.h"

8.1.2. #def|ne
1. we rave used #define lo del|re lre va|ues ol syroo||c corslarls. ll car oe used lo del|re
arylr|rg.
2. 3yroo||c corslarls car oe re-used |r olrer #define slalererls as sroWr oe|oW:
/Clock freq (kHz) divided by prescaler/
#define CLJCK 4000/32
#define INT_TIME 200 / in units of milliseconds /
#define CJUNT (INT_TIMECLJCK)
/ Split 24 bit CJUNT into 8 bit parts (hi, mid, lo) /
#define CJUNTHI (CJUNT/(256256))
#define CJUNTMID (CJUNT/256 - CJUNTHI256)
#define CJUNTLJ (CJUNT%256)

3. #define d|recl|ves car a|so oe 5aramerer|zeo lo del|re maoros. For exarp|e:
#define max(A, B) (((A) (B) . (A) : (B))

1. ll, |aler |r lre source code, We see:
j = max(i+2, k);
5. lre preprocessor rep|aces lr|s W|lr:
j = (((i+2) (k) . (i+2) : (k))
. A racro appears lo oerave |||e a lurcl|or. loWever, |l |s rore ell|c|erl s|rce |l |s exparded |r-
||re. (%rere |s ro suoroul|re ca|| or relurr.)
Z. For exarp|e, We rave oeer us|rg getchar() as |l |l Were a lurcl|or. lr lacl |l |s (usua||y) a
racro del|red |r stdio.h.
8. %rere are dargers, roWever, |r lre lacl lral racros ard lurcl|ors |oo| lre sare. lr parl|cu|ar:
O You carrol la|e lre address ol a racro (ard pass |l as lurcl|or po|rler).
O You rusl oe carelu| aooul ary poss|o|e s|de ellecls assoc|aled W|lr a racro. For
exarp|e, cors|der:
m = max(++i, ++j);
O Wrere max() |s lre parareler|zed racro prev|ous|y del|red.
O ll W||| oe exparded lo:
m = (((++i) (++j) . (++i) : (++j))

O As a resu|l, e|lrer i or j W||| oe |rcrererled lW|cel
8.1.3. ifd0f ,nd ifnd0f
1. %re #ifdef (|l oel|neo) preprocessor d|recl|ve |s used lo cord|l|ora||y corp||e cerla|r secl|ors
ol code. %r|s oller |eads lo rore porlao|e code ard code lral car eas||y oe recorp||ed lo
oerave |r a d|llererl, corl|gurao|e Way.
2. %re lorr:
#ifdef Symbol
...
...
#endif

3. resu|ls |r lre slalererls oelWeer lre #ifdef ard lre ralcr|rg #endif oe|rg corp||ed or|y |l
lre slr|rg Symbol ras oeer del|red oy a prev|ous #define slalererl (or corrard ||re opl|or
Wrer lre corp||er Was |rvo|ed).
1. For exarp|e, cors|der:
#ifdef MJT68K
typedef unsigned int big_numbers;
#endif
#ifdef INTEL8088
typedef unsigned long big_numbers;
#endif

5. lere, lre proper typedef W||| oe corp||ed so lral lre lype big_numbers, W||| oe ar urs|gred
32-o|l |rleger or oolr PCs (Wr|cr use lrle| 8088 cr|ps) ard uNlX 80x0 racr|res.
. A very corror use lor #ifdef |s lo surrourd deougg|rg slalererls W|lr #ifdef DEBUG as
sroWr oe|oW:
#ifdef DEBUG
printf("i: %d now\n", i);
#endif

Z. wrer deve|op|rg lre code, DEBUG |s del|red; rerce lre deoug slalererls are corp||ed ard
execuled al rur l|re. 0rce lre prograr Wor|s, |l |s re-corp||ed W|lroul del|r|rg DEBUG ard |l
W||| roW rur W|lroul lre deougg|rg slalererls.
8. Nole lral lr|s |s prelerao|e lo de|el|rg lre deougg|rg slalererls. Aller a||, a r|dder oug ray oe
reporled |aler or. lr lr|s case, lre prograr ras lo oe deougged aga|r oul lrere |s ro reed lo re-
Wr|le lre deougg|rg slalererls; s|rp|y re-corp||e W|lr DEBUG del|red.
9. Nole lral a syroo| car oe del|red or lre corrard ||re lral |rvo|es lre corp||er |rslead ol |r
lre prograr |lse|l. %rus, lo corp||e W|lr deougg|rg slalererls, We Wr|le:
SHELL_PRJMPT% gcc -DDEBUG source_file.c

10.%re d|recl|ve #ifndef Wor|s jusl |||e #ifdef excepl lral lre slalererls lo||oW|rg |l up lo lre
#endif are or|y corp||ed |l lre syroo| |s rol del|red.
8.1.4. und0f
1. %re ellecl ol a #define slalererl car oe urdore W|lr lre #undef d|recl|ve.
2. %r|s |s oller uselu| |l you Warl lo use a lurcl|or lor sorelr|rg lral |s rorra||y a racro. For
exarp|e, |l you Warl lo use your oWr lurcl|or getchar() (Wr|cr |s a racro expars|or oy
delau|l), use:
#undef getchar
.
.
int getchar() ,
/ Your function body /
,

3. Arolrer Way ol lorc|rg getchar() lo oe a lurcl|or ralrer lrar a racro |s lo use:
(getchar)().
8.1.5. AN8| 6 5re5ro.essor
1. lr add|l|or lo lre lar|||ar #include, #define, #ifdef, elc., lre lo||oW|rg lealures rave oeer
added lo lre preprocessor |r AN3l C.
2. %re #if oonsranr |nreer ex5ress|on ras oeer added lor cord|l|ora| corp||al|or. %re 'corslarl
|rleger express|or |s cors|dered lrue |l |l eva|uales ror-zero ard la|se |l |l |s zero. %re
express|or car use C sly|e syrlax as We|| as lre defined(name) Wr|cr eva|uales as lrue |l
'rare ras oeer del|red.
3. %re reW d|recl|ves #else ard #elif (e|se |l) rave a|so oeer |rc|uded. For exarp|e:
#if SYSTEM == UNIXV.3\
|| SYSTEM == SUNJS\
|| SYSTEM == XENIX
#define UNIX
#endif
#if !defined(UNIX) && SYSTEM != MSDJS
#error Do not know operating system
#endif
#if defined(DEBUG)
#if defined(UNIX)
#define INCLUDE unixdebug.h
#elif defined(MSDJS)
#define INCLUDE msdosdebug.h
#endif
#else
#if defined(UNIX)
#define INCLUDE unix.h
#elif defined(MSDJS)
#define INCLUDE msdos.h
#endif
#endif
#include < HEADER

1. %re reW operalors # ard ## car oe used lo gererale slr|rgs oy corcaleral|or oy lre
preprocessor.
5. wrer a parareler rare |r a racro |s preceded oy a #, lre parareler W||| oe quoled ard
corcaleraled W|lr ary surrourd|rg slr|rgs.
. %re ## operalor |s used lo quole ard corcalerale adjacerl racro argurerls.
Z. %re predel|red |derl|l|ers __LINE__, __FILE__, __DATE__, __TIME__, ard __STDC__ rave
oeer added lo lre preprocessor. %rey corla|r, respecl|ve|y, lre dec|ra| ruroer ol lre currerl
||re, lre rare ol lre currerl source code l||e, lre dale ard lre l|re. __STDC__ |s del|red as 1 |l
lre corp||er corlorrs lo lre AN3l slardard. For exarp|e:
#define err( m ) fprintf(stderr,\
"Error on line %d:" #m "\n", __LINE__)
...
err(print this message after colon);

8. %re use ol ## |s sroWr oe|oW:
#define instance( prefix, root, postfix)\
prefix ## root ## postfix
...
i = j + instance(pre, _body_, 5);
/ Above is creates i = j + pre_body_5; /

6h,5ter 9. %he 8t,nd,rd ||-r,ry
1. Ar accorp||sred C prograrrer does rol re-|rverl lre Wree|. %re slardard ||orary ol lurcl|ors
del|red oy AN3l C |rc|udes a good ruroer ol uselu| roul|res lral srou|d rol oe re-Wr|ller.
2. For exarp|e, sore ol lrese roul|res (espec|a||y lre slr|rg ard rerory searcr ard copy ores)
ray oe rard-cralled |r assero|er lo exp|o|l lre urder|y|rg racr|re arcr|leclure lo lre
rax|rur. %r|s |eve| ol dela|| |s sorelr|rg lral rosl ol us W|sr lo avo|d.
0l course, ore ras lo |roW Wral lrey are. we roW exar|re lre rosl |rporlarl ores.
9.1. 8tr|ngs
use:
#include <string.h
lo use ary ol lrese lurcl|ors.
8tr0n(.har * .p)
relurrs lre ruroer ol craraclers |r |ls slr|rg argurerl;
8tr.mp(.har * 84ur.0 .har * targ0t)
corpares (craracler oy craracler) |ls lWo slr|rg argurerls ard relurrs -1, 0, or 1 |l lre l|rsl |s
a|praoel|ca||y oelore, |derl|ca| or aller lre secord;
8tr.at(.har * t4 .har * thi8)
corcalerales |ls secord slr|rg argurerl lo |ls l|rsl;
8tr.py(.har * .4py_t4 .har * .4py_fr4m)
cop|es |ls secord slr|rg argurerl lo |ls l|rsl;
1. Vary ol lrese rave n-var|arls lral ||r|l lre ruroer ol craraclers lo oe corpared, cop|ed, elc.
For exarp|e,
strncpy(char to, char from, int n)
2. cop|es al rosl n craraclers lror 'lror lo 'lo.
3. %rese vers|ors are oller prelerao|e; lor exarp|e, lo preverl ouller overl|oWs.
9.2. .ty5e.h
%r|s |rc|ude l||e corla|rs severa| very ell|c|erl racros lor delerr|r|rg craracler lype. use ol lrese
racros requ|res lre slalrerl:
#include <ctype.h
int i8digit(int .h)
va|uales lrue |l lre craracler |s a d|g|l;
int i88pa.0(int .h)
va|uales lrue |l lre craracler |s a Wr|le space craracler (e.g. lao, space, reW||re, elc.);
int i8apha(int .h)
va|uales lrue |l lre craracler |s a |eller ol lre a|praoel;
int i8anum(int .h)
va|uales lrue |l lre craracler |s a |eller ol lre a|praoel or a d|g|l;
int i8pun.t(int .h)
va|uales lrue |l lre craracler |s a purclual|or craracler;
int i840r(int .h)
va|uales lrue |l lre craracler |s a |oWer case a|praoel|c;
int i8upp0r(int .h)
va|uales lrue |l lre craracler |s a upper case a|praoel|c;
0lrer racros corverl lre craracler argurerl |rlo arolrer craracler:
int t4upp0r(int .h)
Corverls lre craracler lo upper case (does rolr|rg |l |l |s a|ready upper case);
int t440r(int .h)
Corverls lre craracler lo |oWer case (does rolr|rg |l |l |s a|ready |oWer case);
9.2.1. |m5|ement,t|on of .typ0.h
1. %re ctype.h reader l||e |s a good exarp|e ol roW lre poWer ol lre preprocessor car oe
exp|o|led lo y|e|d very ell|c|erl code.
2. lere |s a lyp|ca| (aor|dged) exarp|e:
#define _U 01
#define _L 02
#define _N 04
#define _S 010
#define _P 020
#define _C 040
#define _B 0100
#define _X 0200
extern char _ctype,;
#define isalpha(c) ((_ctype+1)c,&(_U|_L))
#define isupper(c) ((_ctype+1)c,&_U)
#define islower(c) ((_ctype+1)c,&_L)
#define isdigit(c) ((_ctype+1)c,&_N)
#define isxdigit(c) ((_ctype+1)c,&_X)
#define isspace(c) ((_ctype+1)c,&_S)
#define ispunct(c) ((_ctype+1)c,&(_P))
#define isalnum(c) ((_ctype+1)c,&(_U|_L|_N))
#define isprint(c) ((_ctype+1)c,&(_P|_U|_L|_N|_B))
#define isgraph(c) ((_ctype+1)c,&(_P|_U|_L|_N))
#define iscntrl(c) ((_ctype+1)c,&_C)
#define isascii(c) ((unsigned)(c)<=0177)
#define _toupper(c) ((c)-'a'+'A')
#define toupper(c) (islower(c) . _toupper(c) : (c))


3. Nole roW lre racro |||e |sd|g|l Wor|s. |ver:
#define _S 010
#define isspace(c) ((_ctype+1)c,&_S)

1. %re array _ctype |s 25Z craraclers |org ard eacr erlry corla|rs a o|l pallerr |rd|cal|rg |l lre
correspord|rg asc|| code |s a |oWer case |eller, a d|g|l, elc. (eacr ol lre 8 o|l pos|l|ors
correspords lo ore ol lre pr|r|l|ve lypes).
5. %re o|lW|se 'ard (&) |so|ales ar appropr|ale o|l ol lre _ctype array e|ererl ard lre
express|or eva|uales lo e|lrer 0 or 010 (|.e. 8 dec|ra|) Wr|cr are |rlerpreled respecl|ve|y as
la|se ard lrue. (Nole lral lre racro exp|o|ls lre lacl lral C cors|ders ary ror-zero va|ue lo oe
lrue. ll |s or|y lre resu|ls ol |og|ca| operal|ors (&&, >=, elc.) lral guararlee lral 'lrue W||| oe 1
(ore).)
9.3. 8tdi4.h
1. lrc|ude
#include <stdio
2. oelore |rvo||rg lre very corror|y used lurcl|ors/racros ol lr|s pac|age.
3. we rave a|ready used sore ol lrese sucr as:
O printf()
O getchar()
O putchar()
as We|| as corslarls sucr as EJF ('rd 0l F||e).
1. Arolrer corror|y used lurcl|or |s scanf() Wr|cr perlorrs lorralled |rpul Wrere lre lorral
|s spec|l|ed |r a slr|rg (|||e printf(). %re argurerls lo scanf() rusl oe passed oy
relererce (|.e. po|rlers lo lre aclua| argurerls).
warr|rg: Nole lral scanf() car cause secur|ly v|o|al|ors (lrrougr ouller overl|oWs). ll srou|d
oe avo|ded |r ary sers|l|ve progrars (sucr as 3ul0 code)
9.3.1. ||e ||0
we a|so reed stdio.h lo perlorr l||e l/0 (or olrer lrar sro|n ard sroour).
9.3.1.1. 05en|ng , f||e
1. elore oe|rg used, l||es rusl oe opered W|lr lre fopen() lurcl|or:
#include <stdio.h

FILE filep;

if ((filep = fopen("myfile", "r")) == NULL) ,
/ handle error /
,

2. %re l||e ca||ed 'ryl||e |s opered lor read|rg W|lr lre fopen() ca||.
3. fopen() relurrs a po|rler lo a FlL slruclure (del|red |r stdio.h, |ls dela||s do rol corcerr
us rere). ll |l carrol oper lre l||e, NULL (a|so del|red |r stdio.h) |s relurred.
1. %re relurred l||e po|rler rusl oe used lo access lre l||e |aler or.
5. lr gerera|, lre l|rsl argurerl lo fopen() |s lre rare ol lre l||e ard lre secord argurerl |s lre
mooe. Lega| rodes are:
O r lor read|rg a l||e;
O w lor Wr|l|rg lo a l||e lror lre oeg|rr|rg (ard creal|rg |l |l |l does rol ex|sl). ll |l does
a|ready ex|sl, lre prev|ous corlerls W||| oe overWr|ller.
O , lor apperd|rg (Wr|l|rg) lo a l||e lror lre erd ol ar ex|sl|rg l||e. ll lre l||e does rol
a|ready ex|sl, |l |s crealed.
O r+ lor read|rg ard Wr|l|rg lo ar ex|sl|rg l||e;
O w+ lor read|rg ard Wr|l|rg lo a l||e (|l lre l||e does rol a|ready ex|sl, |l |s crealed)
O ,+ lor read|rg ard apperd|rg (Wr|l|rg) lo a l||e lror lre erd ol ar ex|sl|rg l||e. ll lre l||e
does rol a|ready ex|sl, |l |s crealed.
9.3.1.2. wr|t|ng to , f||e
1. %re eas|esl Way lo Wr|le lo a l||e |s lo use fprintf().
2. ll Wor|s jusl |||e printf(), excepl |l ras ar add|l|ora| |r|l|a| argurerl lor lre l||e po|rler.
3. For exarp|e, lo Wr|le lo l||e W|lr lre rard|e file1p (assured lo oe a|ready opered), use:
fprintf(file1p, "Hello, world: 1 + 1 = %d\n", 1+1);

1. Nole lral lre operal|rg sysler auloral|ca||y opers 3 l||es lor you: sro|n, sroour ard sroerr. we
rave, ol course, used lre l|rsl lWo exlers|ve|y. %re lr|rd srou|d oe used lor a|| error ressages.
y delau|l, sroerr |s correcled lo lre screer jusl |||e sroour. loWever, |l sroour |s re-d|recled or
p|ped, sroerr |s rol. lerce, ever W|lr a red|recled corrard, lre error ressages W||| sl||| appear
or lre screer.
5. %re lo||oW|rg are |ega|:
fprintf(stdout, "Hello, world\n");
/ In fact, printf is really a macro that expands:
printf("Hello, world\n");
to the above fprintf statement /
fprintf(stderr, "Hello, world\n");

9.3.1.3. #e,d|ng , f||e
1. %re s|rp|esl Way lo read a l||e |s ore craracler al a l|re |s getc(FILE stream).
2. Nole lral lre getchar() lurcl|or (prev|ous|y used) |s jusl a s|rp|e Way lo |rvo|e
getc(stdin).
9.3.1.4. 6|os|ng , f||e
0rce you rave l|r|sred W|lr a l||e, c|ose |l W|lr:
close(file_ptr);
9.4. a880rt.h
1. A sar|ly crec| |r a prograr car use lre assert racro. For exarp|e:
#include <assert.h
assert(i j);

2. 3rou|d lre cord|l|or oe la|se, ar error ressage W||| oe pr|rled lo sroerr |rd|cal|rg lre la||ed
cord|l|or, lre ||re ruroer ard lre l||e rare. %re prograr lrer aoorls.
3. ll NDEBUG |s del|red, lre asserl racro expards lo a ru|| express|or.
1. xar|r|rg ar |rp|ererlal|or ol lre asserl racro car oe |rslrucl|ve. lere's a lyp|ca| vers|or:
/ Typical assert.h header /
#undef assert
#ifdef NDEBUG
#define assert(test) ((void) 0)
#else
void _Assert(char );
#define _STR(x) _VAL(x)
#define _VAL(x) #x
#define assert(test) ((test) . (void) 0 \
: _Assert(__FILE__ ":" __STR__(__LINE__) " " #test))
#endif

9.5. Hemory
3lardard roul|res ex|sl lor a||ocal|rg ard re|eas|rg rerory dyrar|ca||y ard or copy|rg, corpar|rg, ard
searcr|rg rerory. (3ore ol lrese lurcl|ors are dec|ared |r slr|rg.r, olrers |r sld||o.r)
we l|rsl cors|der lre rerory a||ocal|or ard re|ease roul|res. %re pr|rary rerory a||ocale roul|res are:
;4id * ma4.(8iz0_t 8iz0):
a||ocales s|ze oyles ard relurrs a po|rler lo lre area or NuLL |l ro rerory |s ava||ao|e.
;4id * .a4.(8iz0_t n_00m8iz0_t 8iz0):
a||ocales ard c|ears n_e|em |lers eacr ol s|ze oyles; relurrs a po|rler lo lre area or NuLL |l ro
rerory ava||ao|e.
;4id * r0a4.(;4id * buf 8iz0_t 8iz0):
rea||ocales lre area po|rled lo oy oul so lral |l |s s|ze oyles |org.
%re rerory o|oc| roul|res are:
;4id * m0mm4;0(;4id * t4 ;4id * fr4m 8iz0_t .4unt):
cop|es oounr oyles lror lrom lo ro ,nd ersures lral |l lre areas over|ap, lre or|g|ra| lrom oyles |r
lre over|app|rg reg|or are cop|ed oelore oe|rg overWr|ller; |l relurrs a po|rler lo lrom.
;4id * m0m.py(;4id * t4 ;4id * fr4m 8iz0_t .4unt):
|||e memmove() oul car rard|e over|app|rg reg|ors |r ary Way.
int m0m.mp(;4id * buf1 ;4id * buf2 8iz0_t .4unt):
corpares al rosl oounr oyles ard relurrs a regal|ve ruroer, zero, or a pos|l|ve ruroer
deperd|rg or Wrelrer oul'|s |ess lrar, equa| lo or grealer lrar oul2.
9.. 8tdarg.h
1. A porl|or ol a lyp|ca| stdarg.h reader l||e |s sroWr oe|oW:
typedef char va_list;
#define va_start(ap,v) ap = (va_list)&v + sizeof(v)
#define va_arg(ap,t) ((t )(ap += sizeof(t)))-1,
#define va_end(ap) ap = NULL

2. Nole lral lre va_arg(ap, t) racro does esserl|a||y Wral Was dore oy rard |r lre l|rsl oar
prograr We exar|red prev|ous|y.
3. %re reader a|so |||uslrales lre use ol lype casls:
O %re ((t ) casls lre erl|re express|or |rlo a po|rler ol lre proper lype.
O %re ap ('argurerl po|rler) var|ao|e |s |rcrererled oy lre s|ze ol lr|s lype (rerce
po|rl|rg lo lre rexl argurerl lo oe relr|eved) ard lre -1 |rdex relr|eves lre
appropr|ale address ol Wral ap Was po|rl|rg lo oelore oe|rg |rcrererled.
9.7. h,nd||ng errors
1. Vary ol lre sysler ca||s (lre roul|res docurerled |r 3ecl|or 2 ol lre uNlX rarua| ard |rl1
ca||s or 003 racr|res) relurr 0 |l successlu|, -1 |l ar error |s delecled (ard poss|o|y sore
olrer va|ues). wrer ar error occurs, lre g|ooa| var|ao|e errno |s sel lo a ruroer |rd|cal|rg lre
ralure ol lre ra|lurcl|or.
2. %re |rc|ude l||e errno.h del|res syroo||c corslarls lor a|| lre |erre| error ruroers. A srorl
excerpl lror lr|s l||e (lor uNlX) |s sroWr oe|oW:
#define EPERM 1 / Not super-user /
#define ENJENT 2 / No such file or directory /
#define ESRCH 3 / No such process /
#define EINTR 4 / interrupted system call /
#define EIJ 5 / I/J error /

3. 3|rce ro ore |||es rurer|ca| error codes as ressages, lre lurcl|or perror(char
my_msg) car oe used lo oulpul lre user ressage my_msg lo sroerr lo||oWed oy ar rg||sr
descr|pl|or ol lre proo|er |rd|caled oy lre g|ooa| errno var|ao|e.
1. A uselu| ur|versa| error rard|er us|rg lrese lealures |s sroWr oe|oW:
#define err_msg(msg) my_perror(msg,
" at line: %d in %s: ", __LINE__, __FILE__)

my_perror(char a1, char a2, int l, char f)
,
perror(a1);
fprintf(stderr, a2, l, f);
fprintf(stderr, "\n");
,

6h,5ter 10. 0,t,-dr|ven Progr,mm|ng
1. 3o|ul|ors lo proo|ers car oe descr|oed W|lr a|gor|lrrs (progrars) or dala orgar|zal|or
(slruclures).
2. Vary proo|ers are oesl so|ved W|lr s|rp|e a|gor|lrrs ard rore corp|ex dala slruclures lrar
lre olrer Way arourd.
3. Progrars or|ven oy oara are rucr eas|er lo adapl lo d|llererl s|lual|ors (or|y lre dala reed oe
crarged).
1. 0ller lre dala |lse|l car oe gereraled W|lr racr|re a|d g|v|rg yel ar ever rore l|ex|o|e so|ul|or
lo lre or|g|ra| proo|er.
5. 3orel|res lre a|gor|lrr requ|red lo rar|pu|ale lre rore corp|ex dala slruclure |s |lse|l so
s|rp|e lral |l |s a|rosl '|||e dala ard lre prograr |lse|l car oe gereraled auloral|ca||yl
. %h|NK aooul dala-dr|ver so|ul|ors oelore o||rd|y Wr|l|rg a prograr.
10.1. Ex,m5|e-|n|te 8t,te H,.h|ne
1. Cors|der lre slale racr|re del|red oy lre d|agrar oe|oW:
|g:re 10.1. A s|m5|e st,te m,.h|ne

2. we roW exar|re d|llererl Ways lo |rp|ererl a C prograr lo s|ru|ale lr|s slale racr|re.
10.1.1. %he A0 w,y
1. %re lo||oW|rg |s lre rosl alroc|ous C prograr l rope you W||| ever see. lopelu||y, a oad
exarp|e W||| ercourage lrougrllu| so|ul|ors.
/
This program illustrates the WRJNG WAY of
writing programs. The program is an attempt to
simulate a state machine having three states;
the algorithm chosen seems straight forward,
but solves the problem through brute force
instead of examining the fundamentals.

The program "goodstate3" shows the correct method.
/

#include <stdio.h
#include <ctype.h
#define RED (0)
#define GREEN (1)
#define BLUE (2)

main()
,
int switch_code, c, new_state, state;

state = RED;
printf("Initial state is RED\n");
printf("Enter switch_code value: ");

while ((c = getchar()) != EJF ) ,
switch_code = c - '0';
if (state == RED) ,
if (switch_code == 0) ,
new_state = GREEN;
, else
new_state = BLUE;
, else if (state == GREEN) ,
if (switch_code == 0)
new_state = RED;
else ,
new_state = BLUE;
,
, else if (switch_code == 0)
new_state = BLUE;
else
new_state = RED;
printf("New state is ");
state = new_state;
if (state == RED)
printf("RED\n");
else if (state == GREEN)
printf("GREEN\n");
else
printf("BLUE\n");
printf("\nEnter switch_code value: ");
while (!isdigit(c = getchar()))
;
ungetc(c, stdin);
,
,

10.1.2. A E%%E# w,y
1. Recogr|z|rg lral lre erl|re p|clor|a| represerlal|or ol a slale racr|re ray oe lrars|aled |rlo
dala slruclures, lre lar super|or so|ul|or lo lre lre slale racr|re proo|er |s sroWr oe|oW:
/

This program illustrates the BETTER WAY of writing programs.
We again attempt to simulate a state machine
having three states.

The algorithm used here is simplicity itself (the heart of
the program is one line long and can be used for any state
machine of arbitrary complexity!).

All the information about the state machine is maintained
as data (in data structures) not in the program code itself.
/

#include <stdio.h

typedef struct State State, StatePtr;
/ Note that a state has 3 associated properties:
- the state's name;
- an indicator of the next state if the input is 0
- an indicator of the next state if the input is 1

This initial description of the state's fields
can be improved.

In particular, the last 2 properties (next state if input is 0,
next state if input is 1) share a common property: each indicates
a "next state".
Furthermore, the one to follow is chosen using the input (either
0 or 1).

This suggests putting both of these "next state indicators" into
an array. The program can use the input to index into the
array (i.e. either next0, or next1,).

With this approach, the program does not have to use
If/Else logic to select which arrow to follow; if the
input is "input_value", the next state can be directly
accessed as nextinput_value,.

Finally, this approach is much more general and flexible.
Suppose, for example, that we had to simulate a state machine
that had 8 possible inputs.
All that need be done would be to dimension the "next" array
to have 8 elements and define the data stuctures properly.

/

struct State ,
char name;
StatePtr next2,;
,;

State red, green, blue;
/ Define the fields of each state /
State red = ,"Red", ,&green, &blue,,;
State green = ,"Green", ,&red, &green,,;
State blue = ,"Blue", ,&red, &green,,;

int main()
,
int sw;
int ch;
StatePtr currentStatePtr = &red;

printf("%s\n", currentStatePtr-name);
while((ch = getchar()) != EJF) ,
if((ch != '0') && (ch != '1')) / Ignore all chars except 0 & 1 /
continue;
sw = ch - '0';

/ Heart of program! /
currentStatePtr = currentStatePtr-nextsw,;

/ Display new state /
printf("%s\n", currentStatePtr-name);
,
,

10.1.3. 0o|ng |t A|| A:tom,t|.,||y
1. %re or|y slale racr|re deperderc|es |r lre prev|ous code |s lre dec|aral|ors ard del|r|l|ors.
2. Lel's Wr|le a C prograr lral la|es a descr|pl|or ol a slale racr|re W|lr ary ruroer ol slales
ard ary ruroer ol |rpuls. %re prograr |s:
/
genStateMachine takes the description of a state machine (from stdin)
and produces (on stdout) the C source code to simulate
the state machine.

The format of the input describing the state machine must be:

number of states
number of switches
name of 1st state
name of 2nd state
.
.
name of nth state
next state when in 1st state and switch input = 0
next state when in 1st state and switch input = 1
. . .
. . .
next state when in 1st state and switch input = (2n_switches) -1
next state when in 2nd state and switch input = 0
. . .
. . .
next state when in 2nd state and switch input = (2n_switches) -1
. . .
. . .
. . .
. . .
next state when in nth state and switch input = (2n_switches) -1


Normally the program would be run with redirection of stdin & stdout.

For example, to generate a C program called test.c from
a state machine description in file "test.state", use:

genStateMachine < rgbMachine.state rgbMachine.c

Jf course, "cc -o rgbMachine rgbMachine.c" is then used to compile the
mechanically
generated program; "rgbMachine" is subsequently used to run the
simulator.

Note that the format of the input description of the state machine
is very strict.
The solution, naturally, is to write yet another program that
allows a user to enter the description of a state machine
in a much more convenient (i.e. "user-friendly") way and which
in turn mechanically generates the more formal description
required here.
/

int n_switches, n_states, n_arrows, i, j;
char next_state16,, state_name16,100,;

#include <stdio.h
main()
,
scanf("%d%d", &n_states, &n_switches);
n_arrows = power(2, n_switches);

printf("/ This program was generated mechanically by genStateMachine
/\n");
printf("#include <stdio.h\n");
printf("#include <ctype.h\n");
printf("typedef struct State State, StatePtr;\n");
printf("struct State ,\n");
printf(" char name;\n");
printf(" StatePtr next%d,;\n,;\n", n_arrows);
printf("State ");

for(i = 0; i < n_states; i++) ,
scanf("%s", state_namei,);
printf("%s", state_namei,);
printf("%s", i < n_states-1 . ", " : ";\n");
,

for(i = 0; i < n_states; i++) ,
printf("State %s = ,\"%s\", ,", state_namei,, state_namei,);
for(j = 0; j < n_arrows; j++) ,
scanf("%s", next_state);
printf("&%s%s", next_state, j < n_arrows-1 . ", " : ",,;\n");
,
,

printf("int main()\n,\n int sw;\n int ch;\n StatePtr currentStatePtr =
&");
printf("%s;\n", state_name0,);
printf(" printf(\"%%s\\n\", currentStatePtr-name);\n");
printf(" while((ch = getchar()) != EJF) ,\n");
printf(" if (!isdigit(ch)) continue;\n");
printf(" sw = ch - '0';\n");
printf(" currentStatePtr = currentStatePtr-nextsw,;\n");
printf(" printf(\"%%s\\n\", currentStatePtr-name);\n");
printf(" ,\n exit(0);\n,\n");
,

power(n, i)
int n, i;
,
int temp;

temp = 1;
while (i 0) ,
i = i -1;
temp = tempn;
,
return temp;
,

10.1.3.1. Ex,m5|e
1. %o use lre gen8t,teH,.h|ne lo gererale (lor exarp|e) lre source code lor lre 3-slale 'Red-
reer-|ue racr|re, We l|rsl prepare a l||e (ca||ed rgbMachine.state) lral descr|oes lre
slale racr|re |r lre spec|l|ed lorral as lo||oWs:
3
1
red
green
blue
green
blue
red
green
red
green

2. Nexl, gererale lre C source code (|r lre l||e rgbMachine.c) lror lre descr|pl|or W|lr lre
corrard:
genStateMachine < rgbMachine.state rgbMachine.c

3. xar|re lre gereraled l||e rgbMachine.c. ll srou|d oe:
/ This program was generated mechanically by genStateMachine /
#include <stdio.h
#include <ctype.h
typedef struct State State, StatePtr;
struct State ,
char name;
StatePtr next2,;
,;
State red, green, blue;
State red = ,"red", ,&green, &blue,,;
State green = ,"green", ,&red, &green,,;
State blue = ,"blue", ,&red, &green,,;
int main()
,
int sw;
int ch;
StatePtr currentStatePtr = &red;
printf("%s\n", currentStatePtr-name);
while((ch = getchar()) != EJF) ,
if (!isdigit(ch)) continue;
sw = ch - '0';
currentStatePtr = currentStatePtr-nextsw,;
printf("%s\n", currentStatePtr-name);
,
exit(0);
,

1.
10.1.3.2. Notes
1. ll Wou|d prooao|y oe oeller lo use a 'scr|pl|rg |arguage (sucr as Per|, pylror, elc.) lor al |easl
parl ol lre prograr gereralor.
2. lr add|l|or, lre urvary|rg parl ol lre prograr srou|d oe |r l||es |rslead ol eroedded |r
printf() slalererls.
3. 0re cou|d cors|der us|rg a lorra| |arguage as a lrorl erd lo lre prograr gereralor. %re lorra|
|arguage Wou|d descr|oe lre slale racr|re; lre |arguage cou|d oe |rlerpreled oy a parser ol
lre lype We saW prev|ous|y.
1. For exarp|e, We r|grl Warl lo descr|oe lre racr|re W|lr slalererls |||e:
STATE_NAMES = RED, GREEN, BLUE, YELLJW
SWITCH_NAME = BUSY, READY
RED to GREEN if 1x
RED to RED if 0x
....

10.2. Ex,m5|e-8H ,nd f:n.t|on 5o|nters
1. %re slale racr|re car oe rade rore gerera| oy rav|rg a po|rler lo a lurcl|or del|red lor eacr
poss|o|e lrars|l|or. Cors|der, lor exarp|e, lre lo||oW|rg dec|aral|ors ol a rore corp|ex slale
racr|re:
/ States for sets /
enum SET_STATE ,
SET_JFF,
SET_READY,
SET_BUSY_1,
SET_HJLD_1,
SET_BUSY_2,
SET_HJLD_2,
N_SET_STATES
,;
/ A structure as follows defines
the behavior for a single state /
typedef struct ,
/ Next state to go to /
int next_state;
/ Function to implement transition /
int (transition_func)();
/ Secondary function passed to first /
int (second_func)();
, TRANSITIJN_STRUCTURE;

#ifndef GLJBAL_DECLARE
EXTERN TRANSITIJN_STRUCTURE
set_state_machine N_SET_STATES, N_EVENTS,;
#else
EXTERN TRANSITIJN_STRUCTURE
set_state_machine N_SET_STATES, N_EVENTS, = ,
/ Transitions if in SET_JFF /
,
/ EVENT_LJGJN / , SET_READY, set_logon, NULL ,,
/ EVENT_LJGJFF / , SET_JFF, ignore_event, NULL ,,
/ EVENT_FJRCEJFF / , SET_JFF, ignore_event, NULL ,,
/ EVENT_RING_START / , SET_JFF, ignore_event, NULL ,,
... etc.
/ Do set state machine /
old_set_state = set_stateevent.set_num,;
new_set_state =
set_state_machineold_set_state,event_code,.next_state;
secondary_func =
set_state_machineold_set_state,event_code,.second_func;
if ( (set_state_machineold_set_state,event_code,.transition_func)
(event, event_code, new_set_state, secondary_func)
== 0) ,
set_stateevent.set_num, = new_set_state;
,

10.3. Hen: 0r|ven 6ode
1. Veru dr|ver app||cal|ors are oller prelerred oy occas|ora| users.
2. 0ala-dr|ver lecrr|ques lre oesl Way lo |rp|ererl user reru |rlerlace.
3. %yp|ca||y, a reru app||cal|or d|sp|ays a ||sl ol se|ecl|ors or lre screer.
1. %re user se|ecls ar |ler oy lyp|rg |r lre reru ruroer (... or rov|rg lre rouse, ... or
r|gr||grl|rg |lers W|lr cursor |eys, elc.);
5. %re reru-rard|er prograr lrer |rvo|es a spec|l|c roul|re lo rard|e lre user's requesl or
s|gra|s lral lre requesl |s |rva||d.
. 3el up lre lo||oW|rg array ol slruclures W|lr eacr slruclure correspord|rg lo a reru se|ecl|or
PLu3 ore add|l|ora| slruclure lor |rva||d se|ecl|ors (lr|s W||| oe lre |asl ore).
acr slruclure corla|rs lre lo||oW|rg:
O A po|rler lo lre lurcl|or lo rard|e lre reru |ler
O A slr|rg |rd|cal|rg lre rare (or lre screer) ol lre reru se|ecl|or.
O %re co|urr ard roW Wrere lre reru |ler srou|d oe d|sp|ayed.
O A pallerr (say a s|rg|e |eller) lral lre user rusl erler lo se|ecl lr|s |ler
Z. A slep-oy-slep a|gor|lrr lo rard|e reru se|ecl|or |s:
1. Read lre user's resporse.
2. 3lore lre user's resporse |r lre pallerr parl ol lre slruclure correspord|rg lo
erroreous |rpul (lr|s slruclure rusl oe lre |asl ore |r lre array).
3. Varcr lrrougr lre array ol reru |ler slruclures ore oy ore url|| lre user erlered
pallerr ralcres lre pallerr requ|red lo se|ecl lr|s erlry;
1. Nole lral a ralcr |s g:,r,nteedro reed lo |eep lrac| ol roW rary |lers lrere are
5. lrvo|e lre lurcl|or lral W||| acl upor lre user's W|sres.
. wrer lre lurcl|or relurrs, redraW lre reru screer (|r case lre lurcl|or ras rod|l|ed
lre screer) ard slarl over aga|r.
Z. Nole lral |l lre user requesled lo qu|l lre reru erl|re|y, lre lurcl|or ol lre 'qu|l
se|ecl|or Wou|d ca|| exit() ard rerce rever relurrso ever lr|s everl does rol
rave lo oe cors|dered spec|a||y oy lre reru rard|er.
|-||ogr,5hy
KardRZ8| r|ar Kerr|grar ard 0err|s R|lcr|e. Tne 0 Proramm|n lanuae. F|rsl d|l|or.

You might also like