609

Kenneth Reek - Pointers on C

Embed Size (px)

DESCRIPTION

good book on intro to C programming

Citation preview

  • orced version 1.0, by vivisimo, and posted in http://library.nu last modified: 2011.06.05

    1

    A Quick Start

    1.1 Introduction

    Itisalwaysdifficulttostartdescribingaprogramminglanguagebecauselittledetails do notmakemuch sense until one knows enough to understand the bigpicture.Inthischapter,Itrytogiveyouaglimpseofthebigpicturebylookingatasampleprogramandexplaining itsworkings lineby line.ThissampleprogramalsoshowsyouhowfamiliarproceduresareaccomplishedinC.ThisinformationplustheothertopicsdiscussedinthechapterintroduceyoutothebasicsoftheClanguagesothatyoucanbeginwritingusefulprograms.

    Theprogramwedissect reads text from the standard input,modifies it, and

    writesittothestandardoutput.Programl.lfirstreadsalistofcolumnnumbers.Thesenumbers are pairs and indicate ranges of columns in the input line. The list isterminatedwithanegativenumber.Theremaining input linesarereadandprinted,thentheselectedcolumnsfromtheinputlinesareextractedandprimed.Notethatthefirstcolumninalineisnumberzero.Forexample,iftheinputis

    4 9 12 20 -1 abcdefghijklmnopqrstuvwxyz Hello there, how are you? I am fine, thanks. See you! Bye

    thentheprogramwouldproduce:

    Original input : abcdefghijklmnopqxstuvwxyz Rearranged line: efghijmnopqrstu

  • Chapter 1 A Quick Start 2

    Original input : Hello there, how are you? Rearranged line: o ther how are Original input : I am fine, thanks. Rearranged line: fine, thanks. Original input : See you! Rearranged line: you! Original input : Bye Rearranged line:

    The important point about this program is that it illustrates most of the basictechniquesyouneedtoknowtobeginwritingCprograms.

    /* ** This program reads input lines from standard input and prints ** each input line, followed by just some portions of the line, to ** the standard output. ** ** The first input is a lint of column numbers, which ends with a ** negative number. The column numbers are paired and specify ** ranges of columns from the input line that are to be printed. ** For example, 0 3 10 12 -1 indicates that only columns 0 through 3 ** and columns 10 through 12 will be printed. */ #include #inc1ude #include #define MAX_COLS 20 /* max # of columns to process */ #define MAX_INPUT 1000 /* max len of input & output lines */ int read_column_numbers( int columns[], int max ); void rearrange( char *output, char const *input, int n_columns, int const columns[] ); int main( void ) { int n_columns; /* # of columns to process */ int columns[MAX_COLS]; /* the columns to process */ char input[MAX_INPUT]; /*array for input line */ char output[MAX_INPUT]; /*array for output line */ Program1.1 Rearrangecharacters continue

    Download at http://www.pin5i.com/

  • 1.1 Introduction 3

    /* ** Read the list of column numbers

    */ n_columns = read_column_numbers( columns, MAX_COLS ); /*

    ** Read, process and print the remaining lines of input */ while( gets(input ) != NULL ){ printf( "Original input : %s\n", input ); rearrange( output, input, n_columns, columns ); printf( "Rearranged line: %s\n", output ); }

    return EXIT_SUCCESS; } /* ** Read the list of column numbers, ignoring any beyond the specified ** maximum. */ int read_column_numbers( int columns[], int max ) { int num = 0; int ch; /* ** Get the numbers, stopping at eof or when a number is < 0. */ while( num < max && scanf( "%d", &columns[num] ) == 1 &&columns[num] >= 0 ) num +=1; /* ** Make sure we have an even number of inputs, as they are ** supposed to be paired. */ if( num % 2 != 0 ){ puts( "Last column number is not paired." ); exit( EXIT_FAILURE ); }

    /* ** Discard the rest of the line that contained the final Program1.1 Rearrangecharacters continue

    Download at http://www.pin5i.com/

  • Chapter 1 A Quick Start 4

    ** number.

    */ while( (ch = getchar()) != EOF && ch != '\n' ) ; return num; } /* ** Process a line of input by concatenating the characters from ** the indicated columns. The output line is the NUL terminated, */ void rearrange( char *output, char const *input, in n_columns, int const columns[] ) { int col; /* subscript for columns array */ int output_col; /* output column counter */ int len; /* length of input line */ len = strlen( input ); output_col = 0; /* ** Process each pair of column numbers. */ for( col = 0; col < n_columns; col += 2 ){ int nchars = columns[col + 1] columns[col] + 1; /* ** If the input line isn't this long or the output ** array is full, we're done */ if( columns[col] >= len || output_col == MAX_INPUT 1 ) break; /* ** If there isn't room in the output array, only copy ** what will fit. */ if( output_col + nchars > MAX_INPUT 1) nchars = MAX_INPUT output_col 1; /* Program1.1 Rearrangecharacters continue

    Download at http://www.pin5i.com/

  • 1.1 Introduction 5

    ** Copy the relevant data.

    */ strncpy( output + output_col, input + columns[col], nchars ); output_col += nchars; } output[output_col] = '\0'; } Program1.1 Rearrangecharacters rearrang.c1.1.1 Spacing and Comments

    Now,letstakeacloserlookatthisprogram.Thefirstpointtonoticeisthespacingoftheprogram:theblanklinesthatseparatedifferentpartsfromoneanother,theuseoftabs to indentstatements todisplay theprogramstructure,andso forth.C isa freeformlanguage,sotherearenorulesastohowyoumustwritestatements.However,alittledisciplinewhenwriting theprogrampaysoff laterbymaking iteasier to readandmodify.Moreonthisissueinabit.

    Whileitisimportanttodisplaythestructureoftheprogramclearly,itisevenmore important to tell the reader what the program does and how it works.Commentsfulfillthisrole

    /* ** This program reads input lines from the standard input and prints ** each input line, followed by just: some portions of the lines, to ** the standard output . ** ** The first input; is a list of column numbers, which ends with a ** negative number . The column numbers are paired and specify ** ranges of columns from the input line that are to be printed. ** For example, 0 3 l0 12 l indicates that only columns 0 through 3 ** and columns 10 through 12 will be printed */

    Thisblockof text isa comment.Commentsbeginwith the/* charactersand

    endwiththe*/characters.TheymayappearanywhereinaCprograminwhichwhitespacemayappear.However, comments cannot containother comments, that is, theFirst*/terminatesthecommentnomatterhowmany/*shaveappearedearlier.

    Download at http://www.pin5i.com/

  • Chapter 1 A Quick Start 6

    Commentsaresometimesusedinotherlanguagestocommentoutcode,thusremoving thecode from theprogramwithoutphysicallydeleting it from thesourcefile.ThispracticeisabadideainC,becauseitwontworkifthecodeyouretryingtogetridofhasanycommentsinit.AbetterwaytologicallydeletecodeinaCprogramisthe#ifdirective.Whenusedlikethis:

    #if 0 statements#endif

    theprogramstatementsbetweenthe#ifandthe#endifareeffectivelyremovedfromtheprogram.Commentscontainedinthestatementshavenoeffectonthisconstruct,thusitisamuchsaferwaytoaccomplishtheobjective.Thereismuchmorethatyoucandowiththisdirective,whichIexplainfullyinChapter14.

    1.1.2 Preprocessor Directives

    #include #include #include #define MAX_COLS 20 /* max # of columns to process */ #define MAX_INPUT 1000 /* max len of input & output lines */

    Thesefivelinesarecalledpreprocessordirectives,orjustdirectives,becausetheyareinterpretedbythepreprocessorThepreprocessorreadsthesourcecode,modifiesitas indicatedbyanypreprocessordirectives,and thenpasses themodifiedcode tothecompiler.

    Inoursampleprogram,thepreprocessorreplacesthefirst#includestatementwiththecontentsofthelibraryheadernamedstdio.h;theresultisthesameasifthecontents of stdio.h had beenwritten verbatim at thispoint in the source file.Thesecondandthirddirectivesdothesamewith stdlib.handstring.h.

    Thestdio.hheadergivesusaccesstofunctionsfromtheStandardI/OLibrary,acollection of functions that perform input and output, stdlib.h defines theEXIT_SUCCESS and EXIT_FAILURE symbols. We need string.h to use the stringmanipulationfunctions.

    TIP Thistechniqueisalsoahandywaytomanageyourdeclarationsiftheyareneededinseveraldifferentsourcefilesyouwritethedeclarationsinaseparatefileandthenuse#includetoreadthemintoeachrelevantsourcetile.Thusthereisonlyonecopyofthedeclarations;theyarenotduplicated inmanydifferentplaces,whichwouldbemoreerrorpronetomaintain.

    Download at http://www.pin5i.com/

  • 1.1 Introduction 7

    TIP Theotherdirective is#define,whichdefines thenameMAX_COLS tobe thevalue20,andMAX_INPUTtobethevalue1000.Wherevereithernameappearslaterinthesourcetile, it is replaced by the appropriate value. Because they are defined as literalconstants,thesenamescannotbeusedinsomeplaceswhereordinaryvariablescanbeused(forexample,onthe leftsideofanassignment).Makingtheirnamesuppercaseservesasareminderthattheyarenotordinaryvariables.#definedirectivesareusedforthesamekindsofthingsassymbolicconstantsinotherlanguagesandforthesamereasons.Ifwelaterdecidethat20columnsarenotenough,wecansimplychangethedefinitionofMAX_COLS.Thereisnoneedtohuntthroughtheprogramlookingfor20stochangeandpossiblymissingoneorchanginga20thathadnothingtodowiththemaximumnumberofcolumns.

    int read_column_numbers( int columns[], int max ); void rearrange( char *output, char const *input, int n_columns, int const columns[] );

    Thesedeclarations are called function prototypes.They tell the compiler aboutthecharacteristicsof functions thataredefined later in thesource tile.Thecompilercanthencheckcallstothesefunctionsforaccuracy.Eachprototypebeginswithatypenamethatdescribesthevaluethatisreturned.Thetypenameisfollowedbythenameof the function. The arguments expected by the function are next, soread_column_numbers returns an integer and takes two arguments, an array ofintegersandanintegerscalar.Theargumentnamesarenotrequired;Igivethemheretoserveasareminderofwhateachargumentissupposedtobe.

    Therearrangefunctiontakesfourarguments.Thefirstandsecondarepointers.A pointer specifieswhere a value resides in the computersmemory,much like ahousenumberspecifieswhereaparticularfamilyresidesonastreet.Pointersarewhatgive theC language itspowerandarecovered ingreatdetailstarting inChapter6.Thesecondandfourthargumentsaredeclaredconst,whichmeansthatthefunctionpromisesnot tomodify the callersarguments.Thekeywordvoid indicates that thefunctiondoesnotreturnanyvalueatall;suchafunctionwouldbecalledaprocedureinotherlanguages.

    TIP If the source code for this programwas contained in several source tiles, functionprototypes would have to be written in each tile using the function. Putting theprototypes in header files and using a #include to access them avoids themaintenanceproblemcausedbyhavingmultiplecopiesofthesamedeclarations.

    Download at http://www.pin5i.com/

  • Chapter 1 A Quick Start 8

    1.1.3 The Main Function int main( void ) {

    These lines begin the definition of a function called main. EveryC programmusthaveamainfunction,becausethisiswhereexecutionbegins.Thekeywordintindicatesthatthefunctionreturnsanintegervalue;thekeywordvoidindicatesthatitexpects no arguments. The body of the function includes everything between thisopeningbraceanditsmatchingclosingbrace.Observehowtheindentationclearlyshowswhatisincludedinthefunction.

    int n_columns; /* # of columns to process */ int columns[MAX_COLS]; /* the columns to process */ char input[MAX_INPUT]; /*array for input line */ char output[MAX_INPUT]; /*array for output line */

    These linesdeclare fourvariables:an integer scalar,anarrayof integers,andtwoarraysofcharacters.Allfourofthesevariablesarelocaltothemainfunction,sothey cannotbeaccessedbyname fromanyother functions.They can,of course,bepassedasargumentstootherfunctions.

    /* ** Read the list of column numbers

    */ n_columns = read_column_numbers( columns, MAX_COLS );

    This statement calls the function read_column_numbers. The array columns and theconstant represented by MAX_COLS (20) are passed as arguments. In C, arrayarguments behave as though they arepassed by reference, and scalar variables andconstantsarepassedbyvalue(likevarparametersandvalueparameters,respectively,inPascalorModula).Thus,anychangesmadebyafunctiontoascalarargumentarelostwhen the function returns; the function cannot change the value of the callingprogramsargumentinthismanner.Whenafunctionchangesthevalueofanelementofanarrayargument,however,thearrayinthecallingprogramisactuallymodified.

    TheruleabouthowparametersarepassedtoCfunctionsactuallystates:

    Allargumentstofunctionsarepassedbyvalue.Nevertheless,anarraynameasanargumentproducesthecallbyreferencebehavior

    Download at http://www.pin5i.com/

  • 1.1 Introduction 9

    describedabove.ThereasonforthisapparentcontradictionbetweentheruleandtheactualbehaviorisexplainedinChapter8.

    /* ** Read, process and print the remaining lines of input */ while( gets(input ) != NULL ){ printf( "Original input : %s\n", input ); rearrange( output, input, n_columns, columns ); printf( "Rearranged line: %s\n", output ); }

    return EXIT_SUCCESS; }

    Thecommentdescribingthispieceofcodemightseemunnecessary.However,themajor expense of software today is notwriting it butmaintaining it. The firstprobleminmodifyingapieceofcodeisfiguringoutwhatitdoes,soanythingyoucanputinourcodethatmakesiteasierforsomeone(perhapsyou!)tounderstanditlateris worth doing. Be sure to write accurate comment when you change the code.Inaccuratecommentsareworsethannoneatall!

    Thispieceofcodeconsistsofawhileloop.InC,whileloopsoperatethesameastheydoinotherlanguages.Theexpressionistested.Ifitisfalse,thebodyoftheloopisskipped. If theexpression is true, thebodyof the loop isexecutedand thewholeprocessbeginsagain.

    Thislooprepresentsthemainlogicoftheprogram.Inbrief,itmeans:whilewewereabletoreadanotherlineofinput

    printtheinputrearrangetheinput,storingitinoutputprinttheoutput

    Thegets function readsone lineof text from thestandard inputandstores it in thearray passed as an argument. A line is a sequence of characters terminated by anewlinecharacter;getsdiscards thenewlineandstoresaNULbyteat theendof theline1.(ANULbyteisonewhosebitsareall0,writtenasacharacterconstantlikethis:'\0'.) gets then returns a value that is not NULL to indicate that a line was

    1NUListhenamegivenintheASCIIcharactersettothecharacter'\0',whosebitsareallzero.NULLreferstoapointerwhosevalueiszero.Bothareintegersandhavethesamevalue,sotheycouldbeusedinterchangeably.However,itisworthusingtheappropriateconstantbecausethistellsapersonreadingtheprogramnotonlythatyouareusingthevaluezero,butwhatyouareusingitfor.

    Download at http://www.pin5i.com/

  • Chapter 1 A Quick Start 10

    successfullyread2.Whengets iscalledbut there isnomore input, itreturnsNULL toindicatethatithasreachedtheendoftheinput(endoftile).

    DealingwithcharacterstringsisacommontaskinCprograms.Althoughthereisno stringdata type, there is a convention for character strings that is observedthroughoutthelanguage:astringisasequenceofcharactersterminatedbya NULbyte.TheNULisconsideredaterminatorandisnotcountedasapartofthestring.Astringliteralisasequenceofcharactersenclosedinquotationmarksinthesourceprogram3.Forexample,thestringliteral

    "Hello"

    occupiessixbytesinmemory,whichcontain(inorder)H,e,l,l,o,andNUL.

    Theprintffunctionperformsformattedoutput.ModulaandPascaluserswillbe delighted with the simplicity of formatted output in C. printf takes multiplearguments; the first isacharacterstring thatdescribes the formatof theoutput,andtherestarethevaluestobeprinted.Theformatisoftengivenasastringliteral.

    The format string contains format designators interspersed with ordinarycharacters.Theordinarycharactersareprintedverbatim,buteach formatdesignatorcausesthenextargumentvaluetobeprintedusingtheindicatedformat.AfewofthemoreusefulformatdesignatorsaregiveninTablel.l.If

    Format Meaning %d Printanintegervalueindecimal.%o Printanintegervalueinoctal.%x Printanintegervalueinhexadecimal.%g Printafloatingpointvalue.%c Printacharacter.%s Printacharacterstring.\n Printanewline.

    Table1.1Commonprintfformatcodes

    2ThesymbolNULLisdefinedintheheader stdio.h.Ontheotherhand,thereisnopredefinedsymbolNUL,soifyouwishtouseitinsteadofthecharacterconstant'\0'youmustdefineityourself3Thissymbol isaquotationmark:",and thissymbol isanapostrophe:'.Thepenchantofcomputerpeople tocallthemsingle quote and double quotewhen their existing names are perfectly good seems unnecessary, so Iwill use theireverydaynames.

    Download at http://www.pin5i.com/

  • 1.1 Introduction 11

    thearrayinputcontainsthestringHi friends!,thenthestatement

    printf( "Original input : %s\n", input ); willproduce

    Original input : Hi friends!

    terminatedwithanewline.Thenextstatementinthesampleprogramcallstherearrangefunction.Thelast

    threeargumentsarevaluesthatarepassedtothefunction,andthefirstistheanswerthatthefunctionwillconstructandpassbacktothemainfunction.Rememberthatitisonlypossibletopasstheanswerbackthroughthisargumentbecauseitisanarray.Thelastcalltoprintfdisplaystheresultofrearrangingtheline.

    Finally,when the loop has completed, themain function returns the valueEXIT_SUCCESS. This value indicates to the operating system that the programwassuccessful.Theclosingbracemarkstheendofthebodyofthemainfunction.

    1.1.4 The read_column_numbers Function

    /* ** Read the list of column numbers, ignoring any beyond the specified ** maximum. */ int read_column_numbers( int columns[], int max ) {

    Theselinesbeginthedefinitionoftheread_column_numbersfunction.Notethat

    thisdeclarationandthefunctionprototypethatappearedearlierintheprogrammatchinthenumberandtypesofargumentsandinthetypereturnedbythefunction.Itisanerroriftheydisagree.

    Thereisnoindicationofthearraysizeinthearrayparameterdeclarationtothefunction.Thisformatiscorrect,becausethefunctionwillgetwhateversizearraythecallingprogrampassedasanargument.This isagreat feature,as itallowsasinglefunction tomanipulateonedimensiona1arraysofany size.Thedown sideof thisfeatureisthatthereisnowayforthefunctiontodeterminethesizeofthearray.Ifthisinformationisneeded,thevaluemustbepassedasaseparateargument.

    Download at http://www.pin5i.com/

  • Chapter 1 A Quick Start 12

    When the read_column_numbers function is called, the name of one of thearguments that ispassedhappens tomatch thenameof the formalparametergivenabove.However, thenameof theotherargumentdoesnotmatch its correspondingparameter.As inmost other languages, the formal parameter name and the actualargumentnamehavenorelationshiptooneanother;youcanmakethemthesameifyouwish,butitisnotrequired.

    int num = 0; int ch;

    Twovariablesaredeclared; theywillbe local to this function.The firstone is

    initialized to zero in the declaration, but the second one is not initialized.Moreprecisely, its initial value will be some unpredictable value, which is probablygarbage.Thelackofaninitialvalueisnotaprobleminthisfunctionbecausethefirstthingdonewiththevariableistoassignitavalue.

    ** Get the numbers, stopping at eof or when a number is < 0. */ while( num < max && scanf( "%d", &columns[num] ) == 1 &&columns[num] >= 0 ) num +=1;

    This second loop reads in the column numbers. The scanf function reads

    charactersfromthestandardinputandconvertsthemaccordingtoaformatstringsort of the reverse ofwhat printfdoes. scanf takes several arguments, the first ofwhich is a format suing that describes the type of input that is expected. Theremainingargumentsarevariables intowhichthe input isstored.Thevalueretunedbyscanfisthenumberofvaluesthatweresuccessfullyconvertedandstoredintothearguments.

    CAUTION! Youmustbecarefulwiththisfunctionfortworeasons.First,becauseofthewayscanfisimplemented,allofitsscalarargumentsmusthaveanampersandinfrontofthem.For reasons that I make clear in Chapter 8, array arguments do not require anampersand4.However,ifasubscriptisusedtoidentifyaspecificarrayelement,thenan ampersand is required. I explain the need for the ampersands on the scalar

    4Thereisnoharminputtinganampersandinfrontofanarraynamehere,however,soyoumayuseoneifyouwish.

    Download at http://www.pin5i.com/

  • 1.1 Introduction 13

    arguments inChapter15.Fornow, justbesuretoputthem in.becausetheprogramwillsurelyfailwithoutthem.

    CAUTION! Thesecondpitfallistheformatcodes,whicharenotidenticaltothosein printfbutsimilar enough to be confusing.Table 1.2 informally describes a few of the formatdesignatorsthatyoumayusewithscanf.Notethatthefirstfivevalues,sothevariablegivenastheargumentmustbeprecededwithanampersand.Withalloftheseformatcodes(except%c),whitespace(spaces,tabs,newlines,etc.)intheinputisskippedthevalue isencountered,andsubsequentwhitespace terminates thevalue.Therefore,acharacterstringreadwith%scannotcontainwhitespace.Therearemanyotherformatdesignators,butthesewillbeenoughforourcurrentneeds.

    Wecannowexplaintheexpressionscanf( "%d", &columns[num] )

    Theformatcode%dindicatesthatanintegervalueisdesired.Charactersarereadfromthe standard input, any leading white space found is skipped. Then digits areconverted intoan integer,and theresult isstored in thespecifiedarrayelement.Anampersandisrequiredinfrontoftheargumentbecausethesubscriptselectsasinglearrayelement,whichisascalar.

    Thetestinthewhileloopconsistsofthreeparts.num < max

    makes sure thatwe do not get toomany numbers and overflow the array. scanf retumsthevalueoneifitconvertedaninteger.Finally, columns[num] >= 0 checks that the value enteredwaspositive. lf any of these tests are false.The loopstops.Format Meaning Type of Variable %d Readanintegervalue. int %ld Readalongintegervalue. long %f Readarealvalue. float %lf Readadoubleprecisionrealvalue. double %c Readacharacter. char %s Readacharacterstringfromtheinput. array of char

    Table1.2Commonscanfformatcodes

    Download at http://www.pin5i.com/

  • Chapter 1 A Quick Start 14

    TheStandarddoesnotrequirethatCcompilerscheckthevalidityofarraysubscripts,andthevastmajorityofcompilersdont.Thus,ifyouneedsubscriptvaliditychecking,youmustwrite ityourself. if the test fornum < maxwerenothereand theprogramread a file containingmore than 20 column numbers, the excess valueswould bestored in thememory locations that follow thearray, thusdestroyingwhateverdatawas formerly in those locations,whichmight be other variables or the functionsreturnaddress.Thereareotherpossibilitiestoo,buttheresultisthattheprogramwillprobablynotperformasyouhadintended.

    TIP

    The && is the logical and operator. For this expression to be true, theexpressionsonbothsidesofthe&&mustevaluatetotrue.However,iftheleftsideisfalse,therightsideisnotevaluatedatall,becausetheresultcanonlybefalse.Inthiscase, ifwe find thatnumhas reached themaximumvalue, the loopbreaksand theexpression

    columns[num]

    isneverevaluated5.

    CAUTION! Becarefulnottousethe&operatorwhenyoureallywant&&;theformerdoesabitwiseAND,which sometimesgives the same result that&&wouldgivebut inothercasesdoesnot.IdescribetheseoperatorsinChapter5.

    Each call to scanf roads a decimal integer from the standard input. If theconversion fails, either because end ofmewas reached or because the next inputcharacterswerenotvalid input foran integer, thevalue0 isreturned,whichbreaksthe loop. If the characters are legal input for an integer, the value is converted tobinaryandstoredinthearrayelementcolumns[num]. scanfthanreturnsthevalue1.

    CAUTION! Beware:Theoperatorthatteststwoexpressionsforequalityis==.Usingthe=operatorinsteadresultsinalegalexpressionthatalmostcertainlywillnotdowhatyouwantittodo:itdoesanassignmentratherthanacomparison!Itisalegalexpression,though,sothecompilerwontcatchthiserrorforyou6.Beextremelycarefultousethedoubleequalsignoperatorforcomparisons.Ifyourprogramisnotworking,checkallofyourcomparisonsforthiserror.Believeme,youwillmakethismistake,probablymorethanonce,asIhave.

    5Thephrasetheloopbreaksmeansthatitterminates,notthatitishassuddenlybecomedefective.Thisphrasecomesfromthebreakstatement,whichisdiscussedinChapter4.6Somenewercompilerswillprintawarningaboutassignmentsin ifand whilestatementsonthetheorythatitismuchmorelikelythatyouwantedacomparisonthananassignmentinthiscontext.

    Download at http://www.pin5i.com/

  • 1.1 Introduction 15

    Thenext&&makessure that thenumber is tested foranegativevalueonly ifscanfwassuccessfulinreadingit.Thestatement

    num += 1;

    adds1tothevariablenum.Itisequivalenttothestatementnum = num + 1;

    IdiscusslaterwhyCprovidestwodifferentwaystoincrementavariable7.

    /* ** Make sure we have an even number of inputs, as they are ** supposed to be paired. */ if( num % 2 != 0 ){ puts( "Last column number is not paired." ); exit( EXIT_FAILURE ); }

    This test checks that an even number of integerswere entered,which is requiredbecausethenumbersaresupposedtobeinpairs.The% operatorperformsanintegerdivision, but it gives the remainder rather than the quotient. If num is not an evennumber,theremainderofdividingitbytwowillbenonzero.

    Theputsfunctionistheoutputversionofgets;itwritesthespecifiedstringtothestandardoutputandappendsanewlinecharactertoit.Theprogramthencallstheexit;function,whichterminatesitsexecution.ThevalueEXIT_FAILUREispassedbacktotheoperatingsystemtoindicatethatsomethingwaswrong.

    /* ** Discard the rest of the line that contained the final ** number. */ while( (ch = getchar()) != EOF && ch != '\n' ) ;

    scanfonlyreadsasfarasithastowhenconvertinginputvalues.Therefore,the

    remainderof theLine thatcontained the lastvaluewillstillbeout there,waiting to

    7Withtheprefixandpostfix++operators,thereareactuallyfourwaystoincrementavariable

    Download at http://www.pin5i.com/

  • Chapter 1 A Quick Start 16

    beread.Itmaycontainjusttheterminatingnewline,oritmaycontainothercharacterstoo.Regardless,thiswhileloopreadsanddiscardstheremainingcharacterstopreventthemfrombeinginterpretedasthefirstlineofdata.

    Theexpression(ch = getchar()) != EOF && ch != '\n'

    meritssomediscussion.First, the functiongetcharreadsasinglecharacter from thestandardinputandreturnsitsvalue.Iftherearenomorecharactersintheinput,theconstantEOF(whichisdefinedinstdio.h)isrammedinsteadtosignalendofline.

    The value returned by getchar is assigned to the variable ch,which is thencompared to EOF. The parentheses enclosing the assignment ensure that it is donebeforethecomparison.IfchisequaltoEOF,theexpressionisfalseandtheloopstops.Otherwise,chiscomparedtoanewline;again,theloopstopsiftheyarefoundtobeequal.Thus,theexpression istrue{causingthe looptorunagain)only ifendof linewasnotreachedandthecharacterreadwasnotanewline.Thus,theloopdiscardstheremainingcharactersonthecurrentinputline.

    Nowletsmoveontotheinterestingpart.Inmostotherlanguages,wewouldhavewrittenthelooplikethis:

    ch = getchar(); while( ch != EOF && ch != '\n' ) ch = getchar(); Getacharacter, there ifwevenotyetreachedendof tileorgottenanewline,

    getanothercharacter.Notethattherearetwocopiesofthestatement. ch = getchar(); TheabilitytoembedtheassignmentinthewhilestatementallowstheCprogrammertoeliminatethisredundantstatement.

    TIP The loop inthesampleprogramhasthesamefunctionalityastheoneshownabove,but it containsone fewer statement. It is admittedlyharder to road, andone couldmakeaconvincingargumentthatthiscodingtechniqueshouldbeavoidedforjustthatreason.However,most,of thedifficulty in reading isdue co inexperiencewith thelanguageand its idioms;experiencedCprogrammershaveno trouble reading (andwriting) statements suchas thisone.You shouldavoidmaking codeharder to readwhenthereisnotangiblebenefittobegainedfromit,butthemaintenanceadvantageinnothavingmultiplecopiesofcodemorethanjustifiesthiscommoncodingidiom.

    Download at http://www.pin5i.com/

  • 1.1 Introduction 17

    Aquestion frequentlyasked iswhych isdeclaredasan integerwhenweareusing it to read characters?Theanswer is thatEOF isan integervalue that requiresmorebitsthanareavailableinacharactervariable;thisfactpreventsacharacterintheinput fromaccidentallybeing interpretedasEOF.But italsomeans thatch,which isreceiving the characters,must be large enough to hold EOF 100,which iswhy anintegerisused.AsdiscussedinChapter3,charactersarejusttinyintegersanyway,sousinganintegervariabletoholdcharactervaluescausesnoproblems.

    TIP One final commenton this fragmentof theprogram: thereareno statements in thebodyof the while statement. It turnsout that theworkdone to evaluate the whileexpressionisallthatisneeded,sothereisnothingleft forthebodyofthelooptodo.Youwill encounter such loopsoccasionally, andhandling them isnoproblem.Thesolitarysemicolonafterthewhilestatementiscalledtheemptystatement,anditisusedinsituationslikethisonewherethesyntaxrequiresastatementbutthereisnoworktobe done. The semicolon is on a line by itself in order to prevent the reader frommistakenlyassumingthatthenextstatementismebodyoftheloop.return num;

    }

    Thereturnstatementishowafunctionreturnsavaluetotheexpressionfromwhichitwascalled.Inthiscase,thevalueofthevariablenumisreturnedtothecallingprogram,whereitisassignedtothemainprogramsvariablen_columns.

    1.1.5 The rearrange Function /* ** Process a line of input by concatenating the characters from ** the indicated columns. The output line is the NUL terminated, */ void rearrange( char *output, char const *input, in n_columns, int const columns[] ) { int col; /* subscript for columns array */ int output_col; /* output column counter */ int len; /* length of input line */

    Download at http://www.pin5i.com/

  • Chapter 1 A Quick Start 18

    Thesestatementsdefinetherearrangefunctionanddeclaresomelocalvariablesforit.Themostinterestingpointhereisthatthefirsttwoparametersaredeclaredaspointersbutarraynamesarepassedasargumentswhenthefunctioniscalled.Whenanarrayname isusedasanargument,what ispassedtothefunction isapointertothebeginningof thearray,which isactually theaddresswhere thearray resides inmemory.Thefactthatapointerispassedratherthanatcopyofthearrayiswhatgivesarraystheircallbyreferencesemantics.Thefunctioncanmanipulatetheargumentasapointer,oritcanuseasubscriptwiththeargumentjustaswithanarrayname.ThesetechniquesaredescribedinmoredetailinChapter8.

    Because of the call by reference semantics, though, if the functionmodifies

    elementsoftheparameterarray,itactuallymodifiesthecorrespondingelementsoftheargumentarray.Thus,declaringcolumns tobeconst isuseful in twoways.First, itstates that the intention of the functions author is that this parameter is not to bemodified.Second, it causes thecompiler toverify that this intention isnotviolated.Thus,callersof this functionneednotworryabout thepossibilityofelementsofmearraypassedasthefourthargumentbeingchanged.

    len = strlen( input ); output_col = 0; /* ** Process each pair of column numbers. */ for( col = 0; col < n_columns; col += 2 ){

    Therealworkofthe functionbeginshere.Wefirstgetthe lengthofthe input

    string,sowecanskipcolumnnumbersthatarebeyondtheendoftheinput.TheforstatementinCisnotquitelikeotherlanguages;itismoreofatshorthandnotationfora commonly used style of while statement. The for statement contains threeexpressions (all of which are optional, by the way). The first expression is theinitializationandisevaluatedoncebeforetheloopbegins.Thesecondisthetestandisevaluatedbeforeeachiterationoftheloop;iftheresultisfalsetheloopterminates.Thethirdexpression,istheadjustmentwhichisevaluatedattheendofeachiteration justbefore the test is evaluated. To illustrate, the for loop that begins above could berewrittenasawhileloop:

    col = 0;

    Download at http://www.pin5i.com/

  • 1.1 Introduction 19

    while( col < n_columns ){ bodyoftheloop col += 2; } int nchars = columns[col + 1] columns[col] + 1; /* ** If the input line isn't this long or the output ** array is full, we're done */ if( columns[col] >= len || output_col == MAX_INPUT 1 ) break; /* ** If there isn't room in the output array, only copy ** what will fit. */ if( output_col + nchars > MAX_INPUT 1) nchars = MAX_INPUT output_col 1; /* ** Copy the relevant data. */ strncpy( output + output_col, input + columns[col], nchars ); output_col += nchars;

    Here is thebodyof thefor loop,whichbeginsby computing thenumberof

    charactersinthisrangeofcolumns.Thenitcheckswhethertocontinuewiththeloop.Iftheinputlineisshorterthanthisstartingcolumn,oriftheoutputlineisalreadyfull,thereisnomoreworktobedoneandthebreakstatementexitstheloopimmediately.

    Thenext testcheckswhetherallof thecharacters from thisrangeofcolumnswillfitintheoutputline.Ifnot,ncharsisadjustedtothenumberthatwillfit.

    TIP Itiscommoninthrowawayprogramsthatareusedonlyoncetonotbotherchecking

    thingssuchasarrayboundsandtosimplymakethearraybigenoughsothatitwillnever overflow.Unfortunately, thispractice is sometimesused inproduction code,too.There,mostof the extra space iswasted, but it is stillpossible tooverflow the

    Download at http://www.pin5i.com/

  • Chapter 1 A Quick Start 20

    array,leadingtoaprogramfailure8.Finally,thestrncpyfunctioncopiestheselectedcharactersfromtheinputline

    tothenextavailablepositionintheoutputline.Thefirsttwoargumentstostrncpyarethedestinationandsource,respectively,ofastringtocopy.Thedestinationinthiscallisthepositionoutput_colcolumnspastthebeginningoftheoutputarray.Thesourceisthepositioncolumns[col]pastthebeginningoftheinputarray.Thethirdargumentspecifies thenumberofcharacters tobecopied9.Theoutputcolumncounter is thenadvancedncharspositions.

    } output[output_col] = '\0'; }

    After the loopends, theoutputstring is terminatedwithaNULcharacter;note

    thatthebodyofthelooptakescaretoensurethatthereisspaceinthearraytoholdit.Thenexecutionreachesthebottomofthefunction,soan implicitreturn isexecuted.Withnoexplicitreturnstatement,novaluecanbepassedbacktotheexpressionfromwhichthefunctionwascalled.Themissingreturnvalueisnotaproblemherebecausethefunctionwasdeclaredvoid(thatis,returningnovalue)andthereisnoassignmentortestingofthefunctionsreturnvaluewhereitiscalled.

    1.2 Other Capabilities

    The sampleprogram illustratedmanyof theCbasics,but there isa littlemoreyoushould know before you begin writing your own programs. First is the putcharfunction,which is thecompanion togetchar. It takesasingle integerargumentandprintsthatcharacteronthestandardoutput.

    Also,therearemanymorelibraryfunctionsformanipulatingstrings.Illbrieflyintroduceafewofthemostusefuloneshere.Unlessotherwisenoted,eachargumenttothesefunctionsmaybeastringliteral,thenameofacharacterarray,orapointertoacharacter.

    8Theastutereaderwillhavenoticedthatthereisnothingtopreventgetsfromoverflowingtheinputarrayifanextremelylonginputlineisencountered.Thisloopholeisreallyashortcomingofgets,whichisonereasonwhyfgets(describedinchapter15)shouldbeusedinstead.9 lf the source of the copy contains fewer characters than indicated by the third argument, the destination is padded to the proper length with NUL. bytes.

    Download at http://www.pin5i.com/

  • 1.4 Summary 21

    strcpyissimilartostrncpyexceptthatthereisnospecifiedlimittothenumberof characters that are copied. It takes two arguments: the string in the secondargumentiscopiedintothefirst,overwritinganystringthatthefirstargumentmightalreadycontain,strcatalsotakestwoarguments,butthisfunctionappendsthestringinthesecondargumenttotheendofthestringalreadycontainedinthefirst.Astringliteralmaynotbeusedasthefirstargumenttoeitheroftheselasttwofunctions.Itisthe programmers responsibilitywith both functions to ensure that the destinationarrayislargeenoughtoholdtheresult.

    Forsearchinginstrings,thereisstrchr,whichtakestwoargumentsthefirstisastring,andthesecondisacharacter.Itsearchesthestringforthefirstoccurrenceofthe character and returns a pointer to the positionwhere itwas found. If the firstargument does not contain the character, a NULL pointer is returned instead. Thestrstrfunctionissimilar.Itssecondargumentisastring,anditsearchesforthefirstoccurrenceofthisstringinthefirstargument.

    1.3 Compiling

    Theway you compile and runC programs depends on the kind of system youreusing.Tocompileaprogramstoredinthefiletesting.conaUNIXmachine,trythesecommands:

    cc testing.c a.out

    OnPCs,youneedtoknowwhichcompileryouareusing.ForBorlandC++,trythiscommandinaMSDOSwindow:

    bcc testing.c testing

    1.4 Summary

    ThegoalofthischapterwastodescribeenoughofCtogiveyouanoverviewofthelanguage.With this context, itwill be easier to understand the topics in the nextchapters.

    The sampleprogram illustratednumerouspoints.Commentsbeginwith/ *and end with */, and are used to include descriptions in the program. Thepreprocessor directive #include causes the contents of a library header to be

    Download at http://www.pin5i.com/

  • Chapter 1 A Quick Start 22

    processed by the compiler, and the #define directive allows you to give symbolicnamestoliteralconstants.

    AllCprogramsmusthave a function called main inwhich executionbegins.Scalarargumentstofunctionsarepassedbyvalue,andarrayargumentshavecallbyreference semantics.Stringsare sequencesof characters terminatedwithaNULbyte,and there isa libraryof functions tomanipulatestrings invariousways.Theprintf function performs formatted output, and the scanf function is used for formattedinput; getchar and putchar perform unformatted character input and output,respectively.ifandwhilestatementsworkmuch thesame inCas theydo inotherlanguages.

    Havingseenhowthesampleprogramworks,youmaynowwishtotrywritingsomeCprogramsofyourown.Ifitseemslikethereoughttobemoretothelanguage,you are right, there ismuchmore, but this sampling should be enough to get youstarted.

    1.5 Summary of Cautions

    1. Notputtingampersandsinfrontofscalarargumentstoscanf(page12).2. Usingprintfformatcodesin scanf(page13).3. Using&foralogicalANDinsteadof&&(page14).4. Using = tocompareforequalityinsteadof == (page14).

    1.6 Summary of Programming Tips

    1. Using#includefilesfordeclarations(page6).2. Using#definetogivenamestoconstantvalues(page7).3. Puttingfunctionprototypesin#includefiles(page7).4. Checkingsubscriptvaluesbeforeusingthem(page14).5. Nestingassignmentsinawhileorifexpression(page16).6. Howtowritealoopwithanemptybody(page17).7. Alwayschecktobesurethatyoudontgooutoftheboundsofanarray(page19).

    Download at http://www.pin5i.com/

  • 1.8 Programming Exercises 23

    1.7 Questions 1. C is a freeform language,whichmeans that there are no rules regarding how

    programsmust look10.Yet the sample program followed specific spacing rules.Whydoyouthinkthisis?

    2. What is the advantage of putting declarations, such as function prototypes, inheaderfilesandthenusing #include tobringthedeclarationsintothesourcefileswheretheyareneeded?

    3. Whatistheadvantageofusing #define togivenamestoliteralconstants?

    4. Whatformatstringwouldyouusewithprintfinordertoprintadecimalinteger,a string, and a floatingpointvalue, in thatorder?Separate thevalues fromoneanotherwithaspace,andendtheoutputwithanewlinecharacter.

    5. Writethescanfstatementneededtoreadtwointegers,calledquantityandprice,followedbyastring,whichshouldbestoredinacharacterarraycalleddepartment.

    6. TherearenochecksmadeonthevalidityofanarraysubscriptinC.Whydoyouthinkthisobvioussafetymeasurewasomittedfromthelanguage?

    7. Therearrangeprogramdescribedinthechaptercontainsthestatementstrncpy( output + output_col, input + columns[col], nchars );

    The strcpy function takes only two arguments, so the number of characters itcopiesisdeterminedbythestringspecifiedbythesecondargument.Whatwouldbe the effect of replacing the strncpy function callwith a call to strcpy in thisprogram?

    8. Therearrangeprogramcontainsthestatement while( gets( input ) != NULL ){

    Whatmightgowrongwiththiscode? 1.8 Programming Exercises

    1. TheHelloworld!programisoftenthefirstCprogramthatastudentofCwrites.ItprintsHello world!followedbyanewlineonthestandardoutput.Thistrivialprogramisagoodonetousewhenfiguringouthowtorun theCcompileronyourparticularsystem.

    10Otherthanforthepreprocessordirectives.

    Download at http://www.pin5i.com/

  • Chapter 1 A Quick Start 24

    2. Writeaprogramthatreads linesfromthestandard input.Each line isprintedonthestandardoutputprecededbyitslinenumber.Trytowritetheprogramsothatithasnobuiltinlimitonhowlongalineitcanhandle.

    3. Writeaprogramthatreadscharactersfromthestandardinputandwritesthemtothestandardoutput. Itshouldalsocomputeachecksumandwrite itoutafter thecharacters.

    Thechecksumiscomputedinasigned charvariablethatisinitializedto1.Aseachcharacter isread from thestandard input, it isadded to thechecksum.Anyoverflow from thechecksumvariable is ignored.Whenallof thecharactershavebeenwritten, the checksum is thenwritten as a decimal integer,whichmay benegative.Besuretofollowthechecksumwithanewline.

    Oncomputers thatuseASCII, runningyourprogramona filecontaining thewordsHelloworld!followedbyanewlineshouldproducethefollowingoutput:

    Hello world! 102

    4. Write a program that reads input lines one by one until end of file is reached,determinesthelengthofeachinputline,andthenprintsoutonlythelongestlinethatwas found.To simplifymatters,youmayassume thatno input linewillbelongerthan1000characters.

    5. Thestatement if( columns[col] >= len ) break;

    intherearrangeprogramstopscopyingrangesofcharactersassoonasarangeisencounteredthatispasttheendoftheinputline.Thisstatementiscorrectonlyiftherangesareenteredinincreasingorder,whichmaynotbethecase.Modifytherearrangefunctionsothatitwillworkcorrectlyeveniftherangesarenotenteredinorder.

    6. Modify the rearrangeprogram to remove the restriction thatanevennumberofcolumnvaluesmustbereadinitially.Ifanoddnumberofvaluesareread,thelastvalued indicatesthestartofthefinalrangeofcharacters.Charactersfromheretotheendoftheinputstringarecopiedtotheoutputstring.

    Download at http://www.pin5i.com/

  • 2

    Basic Concepts

    Thereisnodoubtthatlearningthefundamentalsofaprogramminglanguageisnotasmuch fun as writing programs. However, not knowing the fundamentals makeswritingprogramsalotlessfun.

    2.1 Environments

    Inanyparticular implementationofANSIC, thereare twodistinctenvironments thatare of interest: the translation environment, inwhich source code is converted in toexecutablemachine instructions; and the execution environment, in which the codeactuallyruns.TheStandardmakesitclearthattheseenvironmentsneednotbeonthesame machine. For example, crosscompilers run on one machine but produceexecutablecode thatwillberunonadifferent typeofmachine.Nor isanoperatingsystemarequirement: theStandardalsodiscusses freestandingenvironments inwhichthere is no operating system.Youmight encounter this type of environment in anembeddedsystemsuchasthecontrollerforamicrowaveoven.

    2.1.1 Translation

    The translationphase consistsof several steps.First, eachof the (potentiallymany)sourcetilesthatmakeupaprogramareindividuallyconvertedtoobjectcodeviathecompilationprocess.Then, the various object files are tied together by the linker toforma single,completeexecutableprogram.The linkeralsobrings inany functionsfrom the standardC libraries thatwereused in theprogram,and itcanalso searchpersonalprogramlibrariesaswell.Figure2.lillustratesthisprocess.

    Download at http://www.pin5i.com/

  • Chapter 2 Basic Concepts 26

    Source code

    Source code

    Libraries

    Source code

    Compiler

    Compiler

    Compiler

    Linker

    Object code

    Object code

    Object code

    Executable

    Figure2.1Thecompilationprocess

    Thecompilationprocessitselfconsistsofseveralphases,withthefirstbeingthepreprocessor. This phase performs textual manipulations on the source code, forexample,substitutingthetextofidentifiersthathavebeen#definedandreadingthetextoftilesthatwere#included.

    Thesourcecodeisthenparsedtodeterminethemeaningsofitsstatements.Thissecondstageiswheremosterrorandwarningmessagesareproduced.Objectcodeisthen generated.Object code is a preliminary form of themachine instructions thatimplement the statementsof theprograms called forbya commandlineoption,anoptimizerprocessestheobjectcodeinordertomakeitmoreefficient.Thisoptimizationtakesextratime,soitisusuallynotdoneuntiltheprogramhasbeendebuggedandisreadytogointoproduction.Whethertheobjectcodeisproduceddirectlyorisintheform of assembly language statements thatmust then be assembled in a separatephasetoformtheobjectfileisnotimportanttous.

    Filename Conventions Although theStandarddoesnothaveany rulesgoverning thenamesused for tiles,mostenvironmentshavefilenameconventionsthatyoumustfollow.Csourcecodeisusuallyputinfileswhosenamesendwiththe.cextension.Filesthatare#includedintootherCsourcecodearecalledheaderfilesandusuallyhavenamesendingin.h.

    Different environmentsmay have different conventions regarding object filenames.Forexample, theyendwith.oonUNIX systemsbutwith.objonMSDOSsystems.

    Download at http://www.pin5i.com/

  • 2.1 Environments 27

    Compiling and Linking Thespecificcommandsused tocompileand linkCprogramsvary fromsystem,butmanywork the same as the two systems described here. TheC compiler onmostUNIXsystemsiscalledcc,anditcanbeinvokedinavarietyofways.1. TocompileandlinkaCprogramthatiscontainedentirelyinonesourcefile:

    cc program.c

    Thiscommandproducesanexecutableprogramcalled a.out.Anobjectfilecalledprogram.oisproduced,butitisdeletedafterthelinkingiscomplete.

    2. TocompileandlinkseveralCsourcefiles:

    cc main.c sort.c lookup.c

    Theobject filesarenotdeletedwhenmore thanonesource file iscompiled.Thisfact allows you to recompile only the file(s) that changed after makingmodifications,asshowninthenextcommand.

    3. TocompileoneCsourcefileandlinkitwhitexistingobjectfiles:cc main.o lookup.o sort.c

    4. To compile a singleC source file andproduce anobject file (in this case, calledprogram.o)forlaterlinking:

    cc c program.c

    5. TocompileseveralCsourcefilesandproduceanobjectfileforeach:cc c main.c sort.c lookup.c

    6. Tolinkseveralobjectfiles:cc main.o sort.o lookup.o

    Theo name optionmaybeadded toanyof the commandsabove thatproduceanexecutableprogram;itcausesthelinkertostoretheexecutableprograminafilecalledname ratherthana.out.Bydefault,thelinkersearchesthestandardClibrary.Thelname flag tells the linker to also search the library called name; this option shouldappearlastonthecommandline.Thereareotheroptionsaswell;consultyoursystemdocumentation.

    Download at http://www.pin5i.com/

  • Chapter 2 Basic Concepts 28

    BorlandC/C++5.0 forMSDOS/Windowshas two interfaces thatyoucanuse.The Windows Integrated Development Environment is a complete selfcontainedprogramming tool that contains a sourcecode editor,debuggers, and compilers. Itsuse isbeyond thescopeof thisbook.TheMSDOScommand line interface, though,worksmuchthesameastheUNIXcompilers,withthefollowingexceptions:1. itsnameisbcc;2. theobjectfilesarenamedfile.obj;3. the compiler does not delete the object file when only a single source file is

    compiledandlinked;and4. bydefault,theexecutablefilenamedafterthefirstsourceorobjectfilenamedon

    the command line, though theenameoptionmaybeused toput the executableprograminname.exe.

    2.1.2 Execution

    Theexecutionofaprogramalsogoesthroughseveralphases.First,theprogrammustbeloadedintomemory.Inhostedenvironments(thosewithanoperatingsystem),thistaskishandledbytheoperatingsystem.Itisatthispointthatpreinitializedvariablesthatarcnotstoredonthestackaregiventheirinitialvalues.Programloadingmustbearrangedmanually in freestandingenvironments,perhapsbyplacing theexecutablecodeinreadonlymemory(ROM).

    Executionoftheprogramnowbegins.Inhostedenvironments,asmallstartuproutineisusuallylinkedwiththeprogram.Itperformsvarioushousekeepingchores,suchasgatheringthecommandlineargumentssothattheprogramcanaccessthem.Themainfunctionisthancalled.

    Your code is now executed. On most machines, your program will use aruntime stack,where variables local to functions and function return addresses arestored.Theprogram can alsouse staticmemory; variables stored in staticmemoryretaintheirvaluesthroughouttheprogramsexecution.

    Thefinalphaseistheterminationoftheprogram,whichcanresultfromseveraldifferent causes. Normal termination iswhen themain function returns.11 Someexecution environments allow theprogram to return a code that indicateswhy theprogram stopped executing. In hosted environments, the startup routine receives

    11Orwhensomefunctioncalls exit,describedinChapter16.

    Download at http://www.pin5i.com/

  • 2.2 Lexical Rules 29

    controlagainandmayperformvarioushousekeepingtasks,suchasclosinganyfilesthattheprogrammayhaveusedbutdidnotexplicitlyclose.Theprogrammightalsohavebeeninterrupted,perhapsduetotheuserpressingthebreakkeyorhangingupatelephoneconnection,oritmighthaveinterrupteditselfduetoanerrorthatoccurredduringexecution.

    2.2 Lexical Rules The lexical rules, like spelling rules inEnglish,governhowyou form the individualpieces,calledtokens,ofasourceprogram.

    AnANSICprogramconsistsofdeclarationsandfunctions.Thefunctionsdefinetheworktobeperformed,whereasthedeclarationsdescribethefunctionsand/orthekindofdata(andsometimesthedatavaluesthemselves)onwhichthefunctionswilloperate.Commentsmaybeinterspersedthroughoutthesourcecode.

    2.2.1 Characters

    The Standard does not require that any specific character set be used in a Cenvironment,butitdoesspecifythatthecharactersetmusthavetheEnglishalphabetin both upper and lowercase, the digits 0 through 9, and the following specialcharacters.

    ! " # % ' ( ) * + , - . / : ; < > = ? [ ] \ ^ _ { } | ~

    Thenewlinecharacter iswhatmarks theendofeach lineofsourcecodeand,whencharacter input is read by the executing program, the end of each line of input. Ifneededbytheruntimeenvironment,thenewlinecanbeasequenceofcharacters,buttheyarealltreatedasiftheywereasinglecharacter.Thespace,tab,verticaltab,andform feed characters are also required. These characters and the newline are oftenreferred to collectively aswhite space character, because they cause space to appearratherthanmakingmarksonthepagewhentheyareprinted.

    TheStandarddefinesseveraltrigraphsatrigraphisasequenceofcharactersthatrepresentsanothercharacter.TrigraphsareprovidedsothatCenvironmentscanbeimplementedwithcharactersetsthatlacksomeoftherequiredcharacters.Herearethetrigraphsandthecharactersthattheyrepresent.

    Download at http://www.pin5i.com/

  • Chapter 2 Basic Concepts 30

    ??( [ ??< { ??= # ??) ] ??> } ??/ \ ??! | ??' ^ ??- ~

    There is no special significance to a pair of questionmarks followed by any othercharacter.

    CAUTION! Although trigraphs are vital in a few environments, they are aminor nuisance fornearlyeveryoneelse.The sequence??waschosen tobegineach trigrahpbecause itdoes not often occur naturally, but therein lies the danger.You never think abouttrigraphsbecausetheyareusuallynotaproblem,sowhenoneiswrittenaccidentally,asin printf( "Delete file (are you really sure??): " ); theresulting]intheoutputissuretosurpriseyou.

    ThereareafewcontextsinwritingCsourcecodewhereyouwouldliketouseaparticular characterbut cannotbecause that characterhasa specialmeaning in thatcontext.Forexample,thequotationmark"isusedtodelimitstringliterals.Howdoesone include a quotationmarkwithin a string literal?K&RCdefined several escapesequencesorcharacterescapestoovercomethisdifficulty,andANSIChasaddedafewnewonestothelist.Escapesequencesconsistofabackslashfollowedbyoneormoreother characters. Each of the escape sequences in the list below represents thecharacterthatfollowsthebackslashbutwithoutthespecialmeaningusuallyattachedtothecharacter.

    \? Usedwhenwritingmultiplequestionmarks toprevent them frombeing

    interpretedastrigraphs.\* Usedtogetquotationmarksinsideofstringliterals.\' Usedtowriteacharacterliteralforthecharacter'.\\ Usedwhen a backslash is needed to prevent its being interpreted as a

    characterescape.

    Therearemanycharactersthatarenotusedtoexpresssourcecodebutareveryuseful in formatting program output or manipulating a terminal display screen.Characterescapesarealsoprovidedtosimplifytheirinclusioninyourprogram.Thesecharacterescapeswerechosenfortheirmnemonicvalue.

    ThecharacterescapesmarkedwitharenewtoANSICandarenotimplementedinK&RC.

    K&R C

    Download at http://www.pin5i.com/

  • 2.2 Lexical Rules 31

    \a Alertcharacter.This rings the terminalbellorproducessomeother

    audibleorvisualsignal.\b Backspacecharacter.\f Formfeedcharacter.\n Newlinecharacter.\r Carriagereturncharacter.\t Horizontaltabcharacter.\v Verticaltabcharacter.\ddd dddrepresentsfromonetothreeoctaldigits.Thisescaperepresentsthe

    characterwhoserepresentationhasthegivenoctalvalue.\xddd Liketheabove,exceptthatthevalueisspecifiedinhexadecimal.Note that any number of hexadecimal digits may be included in a \xddd

    sequence,buttheresultisundefinediftheresultingvaluedislargerthanwhatwillfitinacharacter.

    2.2.2 Comments

    Ccommentsbeginwiththecharacters/*,endwiththecharacters*/,andmaycontainanything except */ in between.Whereas commentsmay spanmultiple lines in thesource code, theymaynot benestedwithin one another.Note that these charactersequencesdonotbeginorendcommentswhentheyappearinstringliterals.

    Each comment is stripped from the source code by the preprocessor andreplaced by a single space. Commentsmay therefore appear anywhere thatwhitespacecharactersmayappear.

    CAUTION! A.commentbeginswhereitbeginsandendswhereitends,anditincludeseverythingon all the lines in between.This statementmay seem obvious, but itwasnt to thestudentwhowrotethisinnocentlookingfragmentofcode.Canyouseewhyonlythefirstvariableisinitialized?

    x1 = 0; /*********************** x2 = 0; ** Initialize the ** x3 = 0; ** counter variables. ** x4 = 0 ***********************/

    CAUTION!

    Takecaretoterminatecommentswith*/ratherthan*?.Thelattercanoccurifyouaretypingrapidlyorholdtheshiftkeydowntoolong.Thismistakelooksobviouswhenpointedout,butitisdeceptivelyhardtofindinrealprograms.

    Download at http://www.pin5i.com/

  • Chapter 2 Basic Concepts 32

    2.2.3 Free Form Source Code

    Cisafreeformlanguage,meaningthattherearenorulesgoverningwherestatementscanbewritten,howmanystatementsmayappearona line,wherespacesshouldbeput,orhowmanyspacescanoccur.12Theonlyrule is thatoneormorewhitespacecharacters(oracomment)mustappearbetweentokensthatwouldbeinterpretedasasinglelongtokeniftheywereadjacent.Thus,thefollowingstatementsareequivalent:

    y=x+1; y = x + 1 ; y = x + 1;

    Ofthenextgroupofstatements,thefirstthreeareequivalent,butthelastisillegal.int x; int x; int/*comment*/x; intx;

    Thisfreedomisamixedblessing;youwillhearsomesoapboxphilosophyaboutthisissueshortly.

    2.2.4 Identifiers

    Identifiers are thenamesused forvariables, functions, types, and so forth.They arecomposed ofupper and lowercase letters,digits, and theunderscore character, buttheymaynotbeginwithadigit.Cisacasesensitivelanguage,soabc,Abc,abC,andABCarefourdifferentidentifiers.Identifiersmaybeanylength,thoughtheStandardallowsthecompilertoignorecharactersafterthefirst31.Italsoallowsanimplementationtorestrictidentifiersforexternalnames(thatis,thosethatthelinkermanipulates)tosixmonocasecharacters.

    12Exceptforpreprocessordirectives,describedinChapter14,whicharelineoriented.

    Download at http://www.pin5i.com/

  • 2.3 Program Style 33

    ThefollowingCkeywordsarereserved,meaningthattheycannotalsobeusedasidentifiers.

    auto do goto signed unsigned break double if sizeof void case else int static volatile char enum long struct while const extern register switch continue float return typedef default for short union

    2.2.5 Form of a Program

    ACprogrammaybestoredinoneormoresourcetiles.Althoughonesourcefilemaycontainmore than one function, every functionmust be completely contained in asingle source file.13 There are no rules in the Standard governing this issue, but areasonableorganizationofaCprogram is foreachsource file tocontainagroupofrelated functions. This technique has the side benefit of making it possible toimplementabstractdatatypes.

    2.3 Program Style

    A few comments onprogram style are in order. Freeform language such asCwillacceptsloppyprograms,whicharequickandeasy towritebutdifficult toreadandunderstandlater.Wehumansrespondtovisualcluessoputtingtheminyoursourcecodewill aidwhoevermust read it later. (Thismight be you!) Program 2.1 is anexamplethat,althoughadmittedlyextreme,illustratestheproblem.Thisisaworkingprogram that performs amarginally useful function. The question is,what does itdo?14Worseyet,supposeyouhadtomakeamodificationtothisprogram!AlthoughexperiencedCprogrammerscouldfigureitoutgivenenoughtime,fewwouldbother.Itwould be quicker and easier to just toss it out andwrite a new program fromscratch.

    13Technically,afunctioncouldbegininonesourcefileandcontinueinanotherifthesecondwere#includedintothefirst.However,thisprocedureisnotagooduseofthe#includedirective.14Believeitornot,itprintsthelyricstothesongThetwelveDaysofChristmas.TheprogramisaminormodificationofonewrittenbyIanPhillippsofCambridgeConsultantsLtd.fortheInternationalObfuscatedCCodeContest(seehttp://reality.sgi.com/csp/ioccc).Reprintedbypermission.Copyright1988,LandonCurtNoll&LarryBassel.AllRightsReserved.Permissionforpersonal,educationalornonprofituseisgrantedprovidedthiscopyrightandnoticeisincludedinitsentiretyandremainsunaltered.AllotherusersmustreceivepriorpermissioninwritingformbothLandonCurtNollandLarryBassel.

    Download at http://www.pin5i.com/

  • Chapter 2 Basic Concepts 34

    #include main(t,_,a) char *a; {return!0

  • 2.4 Summary 35

    beabletovisuallylocatematchingpartsoftheprogramoverapageofcode.Twoorthreespacesarenotenough.

    Somepeopleavoidtabsbecausetheythinktabsindentstatementstoomuch.Incomplexfunctionswithdeeplynestedstatements,thelargetabindentmeansthatthereislittlespaceleftonthelinetowritethestatements.Howeverifthefunctionis that complex, it would probably benefit from being broken into smallerfunctions, one of which contains the statements that were formerly nested sodeeply.

    5. Mostcommentsarewritten inblocks,whichmakesthemstandoutvisuallyformthecode.Theyareeasierforthereadertofind,andeasiertoskip.

    6. Inthedefinitionofafunction,thereturntypeappearsonaseparatelinebeforethefunction name,which appears at the beginning of the next line. To locate thedefinitionofafunction,searchforthefunctionnameatthebeginningofaline.

    Therearemanyothercharacteristicthatyouwillseeasyoustudythecodeexamples.Otherprogrammershaveotherpersonal styles that theyprefer.Whetheryouadoptthis style or a different one is not nearly as important as consistently using somereasonablestyle.Ifyouareconsistent,anycompetentreaderwillbeabletofigureoutyourcodeeasilyenough.

    2.4 Summary ThesourcecodeofaCprogramisstoredinoneormorefiles,witheachfunctionbeingcompletelycontained inone file.Placingrelated functions in thesame file isagoodstrategy.Eachsourcefileisindividuallycompiledtoproduceanobjectfile.Theobjectfilesarethenlinkedtoformtheexecutableprogram.Thismayormaynotbedoneonthesamemachinethatwilleventuallyruntheprogram.

    Theprogrammustbeloadedintomemorybeforeitcanbeexecuted.Inhostedenvironments, this task is performed by the operating system; in freestandingenvironments,theprogramisoftenstoredpermanentlyinROM.Staticvariablesthathavebeeninitializedaregiventheirvaluesbeforeexecutionbegins.Executionofyourcode begins in the main function. Most environments use a stack to store localvariablesandotherdata.

    ThecharactersetusedbyaCimplementationmustincludecertaincharacters.Trigraphs allow you towrite characters that aremissing from some character sets.Escape sequences allow characterswith no printable representation, such aswhitespacecharacters,tobeincludedinaprogram.

    Download at http://www.pin5i.com/

  • Chapter 2 Basic Concepts 36

    Commentsbeginwith/*andendwith*/,andmaynotbenested.Commentsareremoved by the preprocessor. Identifiers are composed of letters, digits, and theunderscore character, and may not begin with a digit. Uppercase and lowercasecharactersaredistinctfromoneanotherinidentifiers.Keywordsarereservedandmaynotbeusedasidentifiers.Cisafreeformlanguage;however,writingprogramswithaclearstylemakesthemeasiertoreadandmaintain.

    2.5 Summary of Cautions

    1. Charactersinstringliteralsbeingmistakenlyinterpretedastrigraphs(page30).

    2. Badlywrittencommentscanunexpectedlyenclosestatements(page31).

    3. Improperterminationofcomments(page31).2.6 Summary of Programming Tips

    1. Good style and documentation result in programs that are easier to read andmaintain(page34).

    2.7 Questions

    1. Comments inCdonotnest.Whatwouldbe the resultof commentingout the

    codeintheexampleshownbelow?void squares( int limit ) { /* Comment out this entire function int i; /* loop counter */ /* ** Print table of squares */ for( i = 0; i < limit; i += 1 ) printf( "%d %d0, i, i * i ); End of commented-out code */ }

    Download at http://www.pin5i.com/

  • 2.7 Questions 37

    2. Whataretheadvantagesofputtingalargeprogramintoasinglesourcefile?Whatarethedisadvantages?

    3. Show the string literal that you would use with printf in order to print thefollowingtext,includingthequotationmarks:

    "Blunder??!??"

    4. Whatisthevalueof\40?Of\100?Of\x40?Of\x100?Of\0123?Of\x0123?

    5. Whatistheresultofthisstatement?int x/*blah blah*/y;

    6. What(ifanything)iswrongwiththefollowingdeclaration?int Case, If, While, Stop, stop;

    7. True or False: Because C (excluding the preprocessor directives) is a freeformlanguage, the only rules that govern how programs arewritten are the syntaxrules,soitdoesntmatterhowtheprogramactuallylooks.

    8. Istheloopinthefollowingprogramcorrect?

    #include < stdio.h> int main( void ) { int x, y; x = 0; while( x < 10 ){ y = x * x; printf( "%d\t%d\n", x, y ); x += 1; }

    Istheloopinthisprogramcorrect? #include

    int main( void ) { int x, y;

    Download at http://www.pin5i.com/

  • Chapter 2 Basic Concepts 38

    x = 0; while( x < 10 ){

    y = x * x; printf( "%d\t%d\n", x, y ); x += 1; }

    Whichprogramwaseasiertocheck?

    9. SupposeyouhaveaCprogramwhosemainfunctionisinthefilemain.candhasotherfunctionsinthefileslist.candreport.c.Whatcommand(s)wouldyouuseonyoursystemtocompileandlinkthisprogram?

    10. Howwouldyoumodifythecommandforthepreviousquestioninordertolinkalibrarycalledparsewiththeprogram?

    11. Suppose you have a C program composed of several separate files, and theyincludeoneanotherasshownbelow.

    File Includes Files main.c stdio.h, table.h list.c list.h symbol.c symbol.h table.c table.h table.h symbol.h, list.h

    Which fileswouldhave toberecompiledafteryoumakeachange tolist.c?Tolist.h?Totable.h?

    2.8 Programming Exercises 1. Writeaprogramwith three functions in threeseparatesource files.The function

    increment should take a single integer argument and return the value of thatargumentplusone.Thisfunctionshouldbeinthefile increment.cThesecond function iscallednegate. Italso takesasingle integerargumentandreturnthenegatedvalueofthatargument(forexample,iftheargumentis25,thefunctionshouldreturn25;iftheargumentis612,thefunctionshouldreturn612).The final function ismain, in the filemain.c,and it should calleachof theotherfunctionswiththevalues10,0,and10andprinttheresults.

    2. WriteaprogramthatwillreadCsourcecodefromthestandardinputandensurethat thebraces arepaired correctly.Note:youneednotworry aboutbraces thatappearwithincomments,stringliterals,orcharacterconstants.

    Download at http://www.pin5i.com/

  • 3

    Data

    Programs operate on data, and this chapter describes data: its various types, itscharacteristics, and how to declare it. Three properties of variables their scope,linkage,andstorageclassarealsodescribed.These threepropertiesdetermine thevisibilityofavariable(thatis,whereitcanbeused)anditslifetime(howlongitsvaluelasts).

    3.1 Basic Data Types Thereareonly fourbasicdata types inC integers, floatingpointvalues,pointers,and aggregate types such as arrays and structures.Allother types arederived fromsomecombinationofthesefour.Letsbeginbyintroducingtheintegersandfloatingpointtypes.

    3.1.1 The Integer Family Theintegerfamilycontainscharacters,shortintegers,integers,andlongintegers.Allhavebothsignedandunsignedversions.

    Itsoundsasthoughalongintegeroughttobeabletoholdlargervaluesthana short integer,but thisassumption isnotnecessarily true.The rule regarding therelativesizesofintegersissimple:

    Longintegersareasleastaslargeasintegers,whichthemselvesareatleastaslargeasshortintegers.

    Download at http://www.pin5i.com/

  • Chapter 3 Data 40

    Type Minimum Range char 0to127signed char 127to127unsigned char 0to255short int 32767to32767unsigned short int 0to65535int 32767to32767unsigned int 0to65535long int 2147483647to2147483647unsigned long int 0to4294967295Table3.1Minimumvariableranges

    K&R C Note that there isnorequirement thata long integeractuallybe longer thanashortinteger, itsimplycannotbeanyshorter.TheANSIStandardaddsaspecification fortheminimum allowable range of values that each different typemay represent, asshown in Table 3.1. This specification is a big improvement over K&R C whenportabilityamongenvironments is important,especiallywhen theenvironmentsareonmachineswithwildlydifferentarchitectures.

    Ashort intmustbeatleast16bits,andalong intatleast32bits. Itisuptotheimplementortodecidewhethertomakethedefaultint16or32bits,orsomethingelse.Usually thedefault is chosen tobewhatever ismostnatural (efficient) for themachine. Note that there is still no requirement that the three sizes actually bedifferent.Anenvironmentforamachinewith32bilwordsandnoinstructionstodealeffectivelywithshorterintegralvaluescouldimplementthemallas32bitintegers.

    The include file limits.h specifies the characteristics of the various integertypes. Itdefines thenamesshown inTable3.2. limits.h alsodefines the followingnames. CHAR_BIT is the number of bits in a character (at least eight). CHAR_MIN andCHAR_MAXdefinetherangeforthedefault

    Signed Unsigned Type Minimum Value Maximum Value Maximum Value

    Character SCHAR_MIN SCHAR_MAX UCHAR_MAX Shortinteger SHRT_MIN SHRT_MAX USHRT_MAX Integer INT_MIN INT_MAX UINT_MAX Longinteger LONG_MIN LONG_MAX ULONG_MAX

    Talbe3.2Limitsofvariableranges

    Download at http://www.pin5i.com/

  • 3.1 Basic Data Types 41

    charactertype;thesewillbethesameaseitherSCHAR_MINandSCHAR_MAXorzeroandUCHAR_MAX. Finally, MB_LEN_MAX specifies the maximum number of characters in amultibytecharacter.

    Although the intention behind char variables is for them to hold characters,charactersareactuallytiny integervalues.Thedefaultchar isalwayseitherasigned charoran unsigned char,butwhatyougetdependsonthecompiler.Thisfactmeansthatacharondifferentmachinesmightholddifferentrangesofvalues,soprogramsthatusecharvariablesareportableonlyiftheyrestrictthesevariablestovaluesintheintersection of the signed and unsigned ranges, for example, the characters in theASCIIcharactersetallfallwithinthisrange.

    The portability of programs that use characters as little integers can beimproved by explicitly declaring these variables as either signed or unsigned. Thispracticeensuresthattheirsignednessisconsistentfrommachinetomachine.Ontheotherhand,dealingwithsignedcharactersonamachinethatismorecomfortablewithunsigned characterswill be less efficient, so declaring all char variables as eithersignedorunsignedisprobablynotagoodidea.Also,manylibraryfunctionsdealingwith characters declare their arguments as char,whichmay cause a compatibilityproblemwithargumentsthatareexplicitlydeclaredsignedorunsigned.

    TIP Whenportabilityisanissue,thesignednessofcharactersposesadilemma.Thebestcompromise is to limit thevalues stored in charvariables to the intersectionof thesigned and unsigned ranges, which maximizes portability without sacrificingefficiency,andperformarithmeticonlyon charvariablesthatareexplicitlysignedorunsigned.Integer Literals The term literal isanabbreviation for literalconstantanentity thatspecifies itsownvalue, andwhose value cannot be changed. This distinction is important becauseANSICallowsthecreationofnamedconstants(variablesdeclaredtobeconst),whichareverymuchlikeordinaryvariablesexceptthat,onceinitialized,theirvaluescannotbechanged.

    When an integer literal iswritten in a program,which of the nine differenttypesof the integer familydoes ithave?The answerdependsonhow the literal iswritten,butthedefaultrulescanbeoverriddenforsomeliteralsbyappendingasuffixtotheendofthevalue.ThecharactersLand l(thatsanel,notthedigitone)causealiteraltobeinterpretedasalongintegervalue,andthecharactersUanduspecifyanunsignedvalue.Aliteralmaybedesignatedunsigned longbyappendingoneofeachtoit.

    Download at http://www.pin5i.com/

  • Chapter 3 Data 42

    There aremanydifferentways to specify integer literals in source code.Themostnaturalaredecimalintegervalues,suchasthese:

    123 65535 -275 15

    Decimal literals are either int, long, or unsigned long. The shortest type thatwillcontainthevalueiswhatisusedbydefault.

    Integerscanbegiveninoctalbystartingwiththedigitzero,orinhexadecimalbystartingwith0x,asin

    0173 0177777 000060 0x7b 0xFFFF 0xabcdef00

    Thedigits8and9areillegalinoctalliterals;thecharactersABCDEForabcdefmayallbeusedasdigitsinhexadecimalliterals.Octalandhexadecimalliteralsareint,unsigned int, long,orunsigned long;theshortestonethatisbigenoughtoholdthevaluediswhatisusedbydefault.

    And then therearecharacter literals.Thesealwayshave typeint;youcannotusetheunsignedorlongsuffixesonthem.Acharacterliteralisasinglecharacter(orcharacterescapeortrigraph)enclosedinapostrophies,asin

    'M' '\n' \'??(' '\3777' Multibye character literals such as abc are allowed by the Standard, but theirimplementation may vary from one environment to the next so their use isdiscouraged.

    Finally, wide character literals are written as an L followed by a multibytecharacterliteral,asin:

    L'X' L'e^'

    Theseareusedwhentheruntimeenvironmentsupportsalargecharacterset.

    TIP Whenyouneed an integer literal, the compilerdoesnt carewhich formyouwrite,although itmakesabigdifferencetoahumanreader.Whichformyouchoose,then,should be determined by the context inwhich the literal is used.Most literals arewritten indecimal form because it themost natural forpeople to read.Here are acoupleofexampleswhereothertypesofintegerliteralsaremoreappropriate.

    15Technically,-275 isnot a literal constantbut a constant expression.Theminus sign is interpreted as aunaryoperatorinsteadofbeingpartofthenumber.Thisambiguityhaslittlepracticalconsequence,though,astheexpressionisevaluatedbythecompilerandhasthedesireeffect

    Download at http://www.pin5i.com/

  • 3.1 Basic Data Types 43

    A literal that identifies certain bit positionswithin awordwould be betterwrittenasahexadecimaloroctalvalue,becausetheseformsdisplaymoreclearlythespecialnatureofthevalue.Forexample,thevalue983040hasa1bitinpositionsl6l9, but you would never guess it from looking at its decimal value. Written inhexadecimal,though,thevalueis0xF0000,whichclearlyshowsthosebitsaslandtheremainingbits0.Ifthisvalueisbeingusedinacontextinwhichthesespecificbitsareimportant, for exampleasamask to extract the correspondingbits fromavariable,thenwriting the literal in hexadecimalmakes themeaning of the operationmuchclearertoahumanreader.

    lfavalueisgoingtobeusedasacharacter,expressingthevalueasacharacterliteralmakes clearer themeaning that is intended for the value. For example, thestatements

    value = value 48; v alue = value \60;

    areentirelyequivalentinoperationtov alue = value '0' ;

    but it ismuch easier to see from the latter that the digit stored in value is beingconvertedfromacharactertoabinaryvalue.Moreimportantly,thecharacterconstantyields the correct value no matter which character set is used. so it improvesportability.Enumerated Type An enumerated type is onewhose values are symbolic constants rather than literal.Thesearedeclaredinthisfashion: enum Jar_Type { CUP, PINT, QUART, HALF_GALLON, GALLON }; whichdeclaresatypecalledJar_Type.Variablesofthistypearedeclaredlikethis: enum Jar_Type milk_jug, gas_can, medicine_bottle; If there is only one declaration of variables of a particular enumerated type, bothstatementsmaybecombinedlikethis: enum { CUP, PINT, QUART, HALF_GALLON, GALLON } milk_jug,gas_can,medicine_bottle;

    Download at http://www.pin5i.com/

  • Chapter 3 Data 44

    Thevariablesare in fact storedas integers,and thevaluesused internally torepresentthesymbolicnamesaretheintegervalues0forCUP,1forPINT,etc.Whereappropriate,specificintegervaluesmaybespecifiedforthesymbolicnameslikethis:

    enum Jar_Type { CUP=8, PINT=16, QUART=32, HALF_GALLON=64, GALLON=128 };

    It is legalforonlysomeofthesymbolstobegivenvaluesthisway.Anysymbolnotgivenanexplicitvaluegetsavalueonegreaterthanthesymbolbeforeit.

    TIP Thesymbolicnamesare treatedas integerconstants,andvariablesdeclaredwithanenumeratedtypeareactuallyintegers.Thisfactmeansthatyoucansassingtheliteral623 toavariableof typeJar_Type,andyoucanassign thevalueHALF_GALLON toanyinteger variable.Avoidusing enumerations in thismanner, however, because theirvalueisweakenedbymixingthemindiscriminatelywithintegers.

    3.1.2 Floating-Pint Types Numberssuchas3.14159and6.0231023cannotbestoredasintegers.Thefirstisnotawhole number, and the second is far too large. They can, however, be stored asfloatingpointvalues.Theseareusuallystoredasa fractionandanexponentofsomeassumedbase,suchas .3243F161 .1100100100011111122both of which represent the value 3.14159. There are many different methods ofrepresentingfloatingpointvalues;theStandarddoesnotdictateanyspecificformat.

    Thefloatingpointfamilyincludes float, double, and long double types.Thesetypes usually provide single precision, double precision, and on machines thatsupport it,extendedprecisionvaluesrespectively.TheANSIStandardrequiresonlythatlongdoublesbeatleastaslongasdoubles,whichthemselvesmustbeatleastasbig as floats. It also imposes aminimum range; all floatingpoint typesmust becapableofstoringvaluesintherange1037through1037.

    Anincludefilecalledfloat.hdefinesthenamesFLT_MAX,DBL_MAX,LDBL_MAXtothe maximum values that can be stored in a float, double, and long double,respectively;minimumvaluesaregivenbyFLT_MIN.

    Download at http://www.pin5i.com/

  • 3.1 Basic Data Types 45

    DBL_MIN, and LDBL_MIN.Additional names that specify certain characteristics of thefloatingpoint implementation, such as the radix being used and the number ofsignificantdigitsthedifferentlengthshave,arealsodefinedhere.

    Floatingpoint literalsarealwayswritten indecimalandmustcontaineitheradecimalpoint,anexponent,orboth.Herearesomeexamples:

    3.14159 1E10 25. .5 6.023e23

    Floatingpoint literalsaredoublevaluesunless theyare followedbya suffix:Lor1specifylong double,andForfspecify float.

    3.1.3 Pointers PointersareamajorreasonwhytheClanguageispopular.Pointersallowtheefficientimplementationofadvanceddatastructuressuchastreesand lists.Other languages,such as Pascal andModula2, implement pointers but do not allow arithmetic orcomparisonstobeperformedonthem.Nordotheyallowanywayofcreatingpointerstoexistingdataobjects.ThelackofsuchrestrictionsiswhatallowstheCprogrammerto produce programsmat aremore efficient and compact than programs in otherlanguages.Atthesametime,theunrestricteduseofpointersinCisthecauseofmuchweepingandgnashingofteethbybothbeginningandexperiencedCprogrammers.

    The values of variables are stored in the computers memory, each at aparticularlocation.Eachmemorylocationisidentifiedandreferencedwithanaddress,justas thehousesona streetcanbe locatedby theiraddress.Pointer is justanothernameforanaddress;atpointervariableisavariablewhosevalueistheaddressofsomeothermemorylocation.Thereareoperatorsthatallowyoutoobtaintheaddressofavariable and to follow apointer variable to the value ordata structure towhich itpoints,butwewilldiscussthoseinChapter5.

    The idea of accessing data by its address instead of by its name frequentlycausesconfusion.Itshouldnt,becauseyouhavebeendoingthisallyourlife.Locatinghousesonastreetbytheiraddressisexactlythesamething.Nooneeverconfusestheaddressofahousewithitscontents;nooneevermistakenlywritesalettertoMr.428ElmhurstSt.livingatRobertSmith.

    Apointerisexactlythesame.Imaginethecomputersmemoryashousesalongaverylongstreet,eachidentifiedbyitsownuniquenumber.Eachlocationcontainsavalue,whichisseparateanddistinctfromitsaddress,eventhoughbothaxenumbers.

    Download at http://www.pin5i.com/

  • Chapter 3 Data 46

    Pointer Constants Pointerconstantsarefundamentallydifferentfromnonpointerconstants.Becausethecompilertakescareofassigningvariablestolocationsinthecomputersmemory,theprogrammer usually has no way of knowing in advance where some particularvariable will reside. Therefore, you obtain the address of a variable by using anoperatorratherthanwritingitsaddressasaliteralconstant.Forexample,ifwewanttheaddressofthevariablexyz,wecannotwritea literalsuchas0xff2044ecbecausewehavenowayofknowingwhetherthatiswherethecompilerwillactuallyputthevariable.Indeed,anautomaticvariablemaybeallocatedatdifferentplaceseachtimeafunction is called.Thus, there is littleuse forpointer constants expressed as literalnumericvalues,sothereisnonotationbuiltintoCspecificallyforthem.16String Literals Manypeople find itstrange that there isnostring type inC,yet the languagehasastringliteral.Thereisinfactanotionofastring,asequenceofzeroormorecharactersterminatedbyNULbyte.Stringsareusuallystored incharacterarrays,which iswhythere isnoexplicitstring type.Because theNUL isused to terminatestrings, it isnotpossibleforastringtocontainNULs.Thisrestrictionisusuallynotaproblem,though;NULwaschosenasterminatorbecauseithasnoprintablegraphicassociatedwithit.

    String literals arewritten as a sequence of characters enclosed in quotationmarks,likethese:

    "Hello" "\aWarning!\a" "Line 1\nLine2" ""

    The last example illustrates that a string literal (unlike a character literal)may beempty;theterminatingNULbytewillalwaysbethere,though.String literalscause the specifiedcharactersanda terminatingNULbyte tobe storedsomewhereintheprogram.K&RCmadenomentionastowhetherthecharactersinastring literal could bemodified by the program, but it explicitly stated that stringliteralswithidenticalvalueswerestoredseparately.Manyimplementations,therefore,allowedliteralstobemodifiedbytheprogram.

    ANSICstates that theeffectofmodifyingastring literal isundefined. Italsoallowsthecompilertostoreastring literalonceeven if itappearsmanytimes inthesource code. This fact makes modifying string literals extremely risky, because achange made to one literal may change the value of other string literals in the

    K&R C

    16Thereisoneexception:theNULLpointer,whichcanbeexpressedasthevaluezero.SeeChapter6formoreinformation.

    Download at http://www.pin5i.com/

  • 3.2 Basic Declarations 47

    program.Therefore,manyANSI compilersdonot letyoumodify string literals, orprovidecompiletimeoptionstoletyouchoosewhetherornotyouwantmodificationofliteralstobeallowed.Avoidthispractice:ifyouneedtomodifyastring,storeitinenarrayinstead.

    Idiscussstring literalsalongwithpointersbecauseusingastring literal inatprogramgeneratesa constantpointer tocharacter.Whenastring literalappears inanexpression,thevalueusedintheexpressionistheaddresswhereitscharacterswerestored,notthecharactersthemselves.Thus,youcanassignastringliteraltoavariableoftypepointertocharacter,whichmakesthevariablepointtowherethecharactersarestored.Youcannotassignastringliteraltoacharacterarray,though,becausetheimmediatevalueoftheliteralisapointer,notthecharactersthemselves.

    lf not being able to assign or copy strings sounds inconvenient, you shouldknow that the standardC library includes a suiteof functionswhosepurpose is tomanipulate strings.The suite includes functions to copy, concatenate, compare,andcomputethelengthofstringsandtosearchstringsforspecificcharacters.

    3.2 Basic Declarations

    Knowingthebasicdatatypesisoflittleuseunlessyoucandeclarevariables.Thebasicformofadeclarationis specifier(s)declaration_expression_listForsimpletypes,thedeclaration_expression_listisjustalistoftheidentifiersbeingdeclared. For more involved types, each of the items in the list is actually anexpressionthatshowshowthenamebeingdeclaredmightbeused.lfthisideaseemsobscurenow,dontworry,weexploreitinmoredetailshortly.

    The specifier(s) includes keywords that describe the base type of theidentifiersbeingdeclared.Specifiersmayalsobegiventochangethedefaultstorageclassandscopeoftheidentifier.Wediscussthesetopicsshortly.

    YousawsomebasicdeclarationsinthesampleprograminChapter1.Hereareacouplemore.

    int i; char j, k, l;

    Thefirstdeclarationindicatesthatthevariableiisaninteger.Theseconddeclaresj,k,andltobecharactervariables.

    Download at http://www.pin5i.com/

  • Chapter 3 Data 48

    Thespecifiersmayincludekeywordstomodifythelengthand/orsignednessoftheidentifier.Theseinclude

    short long signed unsigned Also,thekeywordintmaybeomittedfromthedeclarationofanyintegraltype

    if at least one other specifier is given in the declaration. Thus, the following twodeclarationsareequivalent:

    unsigned short int a; unsigned short a;

    Table 3.3 shows all of the variations on thesedeclarations.Thedeclarationswithineachboxareequivalent.Thesignedkeywordisordinarilyusedonlyforcharsbecausetheotherintegertypesaresignedbydefault.Itisimplementationdependentwhetherchar is signed or unsigned, so char is equivalent to either signed char or unsigned char.Table3.3doesnotincludethisequivalence.

    The situation is simpler with the floatingpoint types, because none of thespecifiersareapplicableexceptfor long double.

    3.2.1 Initialization

    A declaration may specify an initial value for a scalar variable by following thevariablenamewithanequalsignandthedesiredvalue.Forexample, int j = 15; declares jtobeanintegervariableandassignsitthevalue15.Wereturntothetopicofinitializationagainlaterinthischapter.short signed short unsigned short short int signed short int unsigned short int int signed int unsigned int

    signed unsigned long signed long unsigned long long int singed long int unsigned long int Table3.3Equivalentintegerdeclarations

    Download at http://www.pin5i.com/

  • 3.2 Basic Declarations 49

    3.2.2 Declaring Simple Arrays Todeclare aonedimensional array, the arrayname is followedby a subscript thatspecifies the number of elements in the array. This is the first example of thedeclaration_expressionmentionedearlier.Forexample,considerthedeclaration: int values[20]; Theobvious interpretationof thisdeclaration is thatwearedeclaringanarrayof20integers.Thisinterpretationiscorrect,butthereisabetterwaytoreadthedeclaration.Thenamevalues,whenfollowedbyasubscript,yieldsanvalueoftypeint(andbytheway,thereare20ofthem).Thedeclarationexpressionshowstheidentifierusedinanexpressionthatresultsinavalueofthebasetype,integerinthiscase.

    Thesubscriptsofarraysalwaysbeginatzeroandextendthroughonelessthanthedeclared size of the array.There is noway to change thisproperty, but if youabsolutelymusthaveanarraywhosesubscriptsbeginatten,itisnotdifficultto justsubtracttenineachofyoursubscripts.

    AnotheraspectofarraysinCisthatthecompilerdoesnotcheckthesubscriptstoseewhethertheyare intheproperrange.17The lackofchecking isbothgoodandbad.Itisgoodbecausethereisnotimelostcheckingarraysubscriptsthatareknowntobecorrect,anditisbadbecauseinvalidsubscriptsarenotdetected.Agoodruleofthumbtouseis:

    Ifasubscriptwascomputedfromvaluesthatarealreadyknowntobecorrect,thenthereisnoneedtocheckitsvalue.Anyvaluethatisderivedinanywayfromdatathattheuserhasenteredmustbecheckedbeforebeingusedasasubscripttoensurethatitisintheproperrange.

    WecovertheinitializationofarraysinChapter8.

    3.2.3 Declaring Pointers Declaration expressions are also used to declare pointers. In Pascal andModula, adeclaration gives a list of identifiers followed by their type. InC, the base type isgiven,followedbyalistofidentifiersusedintheexpressionsneededtoproducethatbasetype.Forexample,

    17 It is technicallypossible for a compiler to accurately check subscriptvalues butdoing so involves a lot of additionaloverhead.Some later compilers, suchasBorlandC++5.0, implement subscript checkingasadebugging tool that canbeturnedonoroff.

    Download at http://www.pin5i.com/

  • Chapter 3 Data 50

    int *a; states that the expression *a results in the type int. Knowing that the * operatorperformsindirection,wecaninferthatamustbeapointertoaninteger.18The free formnatureofCmakes it tempting towrite theasterisknear the type, likethis: int* a; Thisdeclarationhasthesamemeaningasthepreviousone,anditnowseemstomoreclearlydeclarethataisoftype int *.Thistechniqueisnotgood,andhereiswhy. int* b, c, d; Peoplenaturallyread thisstatementasdeclaringall threevariables tobepointers tointegersbutitdoesnt.Wearefooledbyhowitlooks.Theasteriskisreallypartoftheexpression *b and applies only to that one identifier, b is a pointer, the other twovariablesareordinaryintegers.Hereisthecorrectdeclarationforthreepointers. int *b, *c, *d;

    Declarations of pointer variables may also specify initial values for thevariables.Hereisanexampleinwhichapointerisdeclaredandinitializedtoastringliteral.

    char *message = "Hello world!";

    This statement declaresmessage to be a pointer to a character and initializes thepointertotheaddressofthefirstcharacterinthestringliteral.

    Onedangerwiththistypeofinitializationisthatitiseasytomisinterpretitsmeaning.In the previous declaration, it appears that the initial value is assigned to theexpression *messagewhen in fact the value is assigned to message itself. In otherwords,thepreviousdeclarationisequivalentto:

    char *message; message = "Hello world!";

    CAUTION!

    CAUTION!

    18Indirection isonly legalonapointervalue.Thepointerpointstotheresult,andthe indirection followsthepointertoobtaintheresult.SeeChapter6formoredetails.

    Download at http://www.pin5i.com/

  • 3.3 Typedef 51

    3.2.4 Implicit Declarations There are a few declarations in which type names may be omitted altogether.Functions, for example, are assumed to return integers unless declared otherwise.Whendeclaringformalparameterstofunctionsintheoldstyle,anyparameterswhosedeclarationsareomittedareassumed tobe integers.Finally, if the compiler can seeenough to determine that a statement is in fact a declaration, an omitted type isassumedtobeinteger.

    Considerthisprogram:int a[10]; int c; b[10]; d; f( x ) { return x + 1; }

    The first and second lines are notunusual, however the third and fourth lines areillegal inANSIC.The third lineomits the type,but there isenough information leftthat some K&R compilers can still figure out that the statement is a declaration.Amazingly,afewK&Rcompilerscorrectlyprocessthefourthlineasadeclarationtoo.Thefunctionfisassumedtoreturnaninteger,anditsargumentisassumedtobeaninteger.Depending on implicit declarations is a bad idea. An implicit declaration alwaysleavesaquestioninthereadersmind:Wastheomissionofthetypeintended,ordidtheprogrammersimplyforgettheproperdeclaration?Explicitdeclarationsmakeyourintentclear.

    3.3 Typedef Csupportsamechanismcalledtypedef,whichallowsyou todefinenewnames forvarious data types. Typedefs arewritten exactly the same as ordinary declarationsexcept that the keyword typedef appears at the beginning. For example, thedeclaration char *ptr_to_char;

    declaresthevariableptr_to_chartobeapointertoacharacter.Butaddthekeywordtypedefandyouget.

    Download at http://www.pin5i.com/

  • Chapter 3 Data 52

    typedef char *ptr_to_char;

    whichdeclares the identifierptr_to_char tobeanewname for the typepointer tocharacter.Youcanuse thenewname insubsequentdeclarations just likeanyof thepredefinednames.Forexample, ptr_to_char a; declaresatobeapointertoacharacter.Usinga typedef todeclare types,particularly complexones, reduces the chancesofmessingupadeclaration.19Furthermore,ifyoushoulddecidelatertochangethetypeofsomekindofdatabeingusedinyourprogram,chan