1
A Quick Start
1.1 Introduction
Itȱisȱalwaysȱdifficultȱtoȱstartȱdescribingȱaȱprogrammingȱlanguageȱbecauseȱlittleȱ detailsȱ doȱ notȱ makeȱ muchȱ senseȱ untilȱ oneȱ knowsȱ enoughȱ toȱ understandȱ theȱ Ȉbigȱ picture.ȈȱInȱthisȱchapter,ȱIȱtryȱtoȱgiveȱyouȱaȱglimpseȱofȱtheȱbigȱpictureȱbyȱlookingȱatȱaȱ sampleȱ programȱ andȱ explainingȱ itsȱ workingsȱ lineȱ byȱ line.ȱ Thisȱ sampleȱ programȱ alsoȱ showsȱyouȱhowȱfamiliarȱproceduresȱareȱaccomplishedȱinȱC.ȱThisȱinformationȱplusȱtheȱ otherȱtopicsȱdiscussedȱinȱtheȱchapterȱintroduceȱyouȱtoȱtheȱbasicsȱofȱtheȱCȱlanguageȱsoȱ thatȱyouȱcanȱbeginȱwritingȱusefulȱprograms.ȱ
ȱ
Theȱ programȱ weȱ dissectȱ readsȱ textȱ fromȱ theȱ standardȱ input,ȱ modifiesȱ it,ȱ andȱ writesȱitȱtoȱtheȱstandardȱoutput.ȱProgramȱl.lȱfirstȱreadsȱaȱlistȱofȱcolumnȱnumbers.ȱTheseȱ numbersȱ areȱ pairsȱ andȱ indicateȱ rangesȱ ofȱ columnsȱ inȱ theȱ inputȱ line.ȱ Theȱ listȱ isȱ terminatedȱwithȱaȱnegativeȱnumber.ȱTheȱremainingȱinputȱlinesȱareȱreadȱandȱprinted,ȱ thenȱtheȱselectedȱcolumnsȱfromȱtheȱinputȱlinesȱareȱextractedȱandȱprimed.ȱNoteȱthatȱtheȱ firstȱcolumnȱinȱaȱlineȱisȱnumberȱzero.ȱForȱexample,ȱifȱtheȱinputȱisȱ ȱ 4 9 12 20 -1 abcdefghijklmnopqrstuvwxyz Hello there, how are you? I am fine, thanks. See you! Bye ȱ thenȱtheȱprogramȱwouldȱproduce:ȱ ȱ
Original input : abcdefghijklmnopqxstuvwxyz Rearranged line: efghijmnopqrstu
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ȱ basicȱ techniquesȱyouȱneedȱtoȱknowȱtoȱbeginȱwritingȱCȱprograms.ȱ ȱ ȱ ȱ ȱ ȱ ȱ ȱ ȱ /*
** 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 <stdio.h> #inc1ude <stdlib.h> #include <string.h>
#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 */
ȱ
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 ȱ
** 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; /*
ȱ
1.1 Introduction 5 ** Copy the relevant data.
*/
strncpy( output + output_col, input + columns[col],
nchars );
output_col += nchars;
}
output[output_col] = '\0'; }
Programȱ1.1ȱ Rearrangeȱcharactersȱ ȱ ȱ ȱ ȱ ȱ ȱ rearrang.cȱ ȱ
ȱ ȱ ȱ
1.1.1 Spacing and Comments
ȱ
Now,ȱlet’sȱtakeȱaȱcloserȱlookȱatȱthisȱprogram.ȱTheȱfirstȱpointȱtoȱnoticeȱisȱtheȱspacingȱofȱ theȱprogram:ȱtheȱblankȱlinesȱthatȱseparateȱdifferentȱpartsȱfromȱoneȱanother,ȱtheȱuseȱofȱ tabsȱ toȱ indentȱ statementsȱ toȱ displayȱ theȱ programȱ structure,ȱ andȱ soȱ forth.ȱ Cȱ isȱ aȱ freeȬ formȱlanguage,ȱsoȱthereȱareȱnoȱrulesȱasȱtoȱhowȱyouȱmustȱwriteȱstatements.ȱHowever,ȱaȱ littleȱ disciplineȱ whenȱ writingȱ theȱ programȱ paysȱ offȱ laterȱ byȱ makingȱ itȱ easierȱ toȱ readȱ andȱmodify.ȱMoreȱonȱthisȱissueȱinȱaȱbit.ȱ
Whileȱitȱisȱimportantȱtoȱdisplayȱtheȱstructureȱofȱtheȱprogramȱclearly,ȱitȱisȱevenȱ moreȱ importantȱ toȱ tellȱ theȱ readerȱ whatȱ theȱ programȱ doesȱ andȱ howȱ itȱ works.ȱ Commentsȱfulfillȱthisȱroleȱ
ȱ
ȱ
/*
** 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
*/
ȱ ȱ
Thisȱ blockȱ ofȱ textȱ isȱ aȱ comment.ȱ Commentsȱ beginȱ withȱ theȱ/*ȱ charactersȱ andȱ endȱwithȱtheȱ*/ȱcharacters.ȱTheyȱmayȱappearȱanywhereȱinȱaȱCȱprogramȱinȱwhichȱwhiteȱ spaceȱ mayȱ appear.ȱ However,ȱ commentsȱ cannotȱ containȱ otherȱ comments,ȱ thatȱ is,ȱ theȱ Firstȱ*/ȱterminatesȱtheȱcommentȱnoȱmatterȱhowȱmanyȱ/*ȇsȱhaveȱappearedȱearlier.ȱ
CommentsȱareȱsometimesȱusedȱinȱotherȱlanguagesȱtoȱȈcommentȱoutȈȱcode,ȱthusȱ removingȱ theȱ codeȱ fromȱ theȱ programȱ withoutȱ physicallyȱ deletingȱ itȱ fromȱ theȱ sourceȱ file.ȱThisȱpracticeȱisȱaȱbadȱideaȱinȱC,ȱbecauseȱitȱwon’tȱworkȱifȱtheȱcodeȱyou‘reȱtryingȱtoȱ getȱridȱofȱhasȱanyȱcommentsȱinȱit.ȱAȱbetterȱwayȱtoȱlogicallyȱdeleteȱcodeȱinȱaȱCȱprogramȱ isȱtheȱ#ifȱdirective.ȱWhenȱusedȱlikeȱthis:ȱ
ȱ #if 0
ȱ statementsȱ
#endif
theȱprogramȱstatementsȱbetweenȱtheȱ#ifȱandȱtheȱ#endifȱareȱeffectivelyȱremovedȱfromȱ theȱprogram.ȱCommentsȱcontainedȱinȱtheȱstatementsȱhaveȱnoȱeffectȱonȱthisȱconstruct,ȱ thusȱitȱisȱaȱmuchȱsaferȱwayȱtoȱaccomplishȱtheȱobjective.ȱThereȱisȱmuchȱmoreȱthatȱyouȱ canȱdoȱwithȱthisȱdirective,ȱwhichȱIȱexplainȱfullyȱinȱChapterȱ14.ȱ ȱ ȱ ȱ
1.1.2 Preprocessor Directives
#include <stdio.h> #include <stdlib.h> #include <string.h>#define MAX_COLS 20 /* max # of columns to process */
#define MAX_INPUT 1000 /* max len of input & output lines */
Theseȱfiveȱlinesȱareȱcalledȱpreprocessorȱdirectives,ȱorȱjustȱdirectives,ȱbecauseȱtheyȱ areȱinterpretedȱbyȱtheȱpreprocessorȱTheȱpreprocessorȱreadsȱtheȱsourceȱcode,ȱmodifiesȱ itȱ asȱ indicatedȱ byȱ anyȱ preprocessorȱ directives,ȱ andȱ thenȱ passesȱ theȱ modifiedȱ codeȱ toȱ theȱcompiler.ȱ
Inȱourȱsampleȱprogram,ȱtheȱpreprocessorȱreplacesȱtheȱfirstȱ#includeȱstatementȱ withȱtheȱcontentsȱofȱtheȱlibraryȱheaderȱnamedȱstdio.h;ȱtheȱresultȱisȱtheȱsameȱasȱifȱtheȱ contentsȱ ofȱstdio.hȱ hadȱ beenȱ writtenȱ verbatimȱ atȱ thisȱ pointȱ inȱ theȱ sourceȱ file.ȱ Theȱ secondȱandȱthirdȱdirectivesȱdoȱtheȱsameȱwith stdlib.hȱandȱstring.h.ȱ
Theȱstdio.hȱheaderȱgivesȱusȱaccessȱtoȱfunctionsȱfromȱtheȱStandardȱI/OȱLibrary,ȱaȱ
collectionȱ ofȱ functionsȱ thatȱ performȱ inputȱ andȱ output,ȱ stdlib.hȱ definesȱ theȱ
EXIT_SUCCESSȱ andȱ EXIT_FAILUREȱ symbols.ȱ Weȱ needȱ string.hȱ toȱ useȱ theȱ stringȱ
manipulationȱfunctions.ȱ ȱ TIP Thisȱtechniqueȱisȱalsoȱaȱhandyȱwayȱtoȱmanageȱyourȱdeclarationsȱifȱtheyȱareȱneededȱinȱ severalȱdifferentȱsourceȱfiles—youȱwriteȱtheȱdeclarationsȱinȱaȱseparateȱfileȱandȱthenȱuseȱ #includeȱtoȱreadȱthemȱintoȱeachȱrelevantȱsourceȱtile.ȱThusȱthereȱisȱonlyȱoneȱcopyȱofȱtheȱ declarations;ȱtheyȱareȱnotȱduplicatedȱinȱmanyȱdifferentȱplaces,ȱwhichȱwouldȱbeȱmoreȱ errorȱproneȱtoȱmaintain.ȱ
1.1 Introduction 7 TIP Theȱ otherȱ directiveȱ isȱ#define,ȱ whichȱ definesȱ theȱ nameȱMAX_COLSȱ toȱ beȱ theȱ valueȱ 20,ȱ
andȱMAX_INPUTȱtoȱbeȱtheȱvalueȱ1000.ȱWhereverȱeitherȱnameȱappearsȱlaterȱinȱtheȱsourceȱ
tile,ȱ itȱ isȱ replacedȱ byȱ theȱ appropriateȱ value.ȱ Becauseȱ theyȱ areȱ definedȱ asȱ literalȱ constants,ȱtheseȱnamesȱcannotȱbeȱusedȱinȱsomeȱplacesȱwhereȱordinaryȱvariablesȱcanȱbeȱ usedȱ(forȱexample,ȱonȱtheȱleftȱsideȱofȱanȱassignment).ȱMakingȱtheirȱnamesȱuppercaseȱ servesȱasȱaȱreminderȱthatȱtheyȱareȱnotȱordinaryȱvariables.ȱ#defineȱdirectivesȱareȱusedȱ forȱtheȱsameȱkindsȱofȱthingsȱasȱsymbolicȱconstantsȱinȱotherȱlanguagesȱandȱforȱtheȱsameȱ reasons.ȱIfȱweȱlaterȱdecideȱthatȱ20ȱcolumnsȱareȱnotȱenough,ȱweȱcanȱsimplyȱchangeȱtheȱ definitionȱofȱMAX_COLS.ȱThereȱisȱnoȱneedȱtoȱhuntȱthroughȱtheȱprogramȱlookingȱforȱ20’sȱ toȱchangeȱandȱpossiblyȱmissingȱoneȱorȱchangingȱaȱ20ȱthatȱhadȱnothingȱtoȱdoȱwithȱtheȱ maximumȱnumberȱofȱcolumns.ȱȱ
ȱ ȱ
int read_column_numbers( int columns[], int max );
void rearrange( char *output, char const *input, int n_columns, int const columns[] );
Theseȱ declarationsȱ areȱ calledȱ functionȱ prototypes.ȱ Theyȱ tellȱ theȱ compilerȱ aboutȱ theȱ characteristicsȱ ofȱ functionsȱ thatȱ areȱ definedȱ laterȱ inȱ theȱ sourceȱ tile.ȱ Theȱ compilerȱ canȱthenȱcheckȱcallsȱtoȱtheseȱfunctionsȱforȱaccuracy.ȱEachȱprototypeȱbeginsȱwithȱaȱtypeȱ nameȱthatȱdescribesȱtheȱvalueȱthatȱisȱreturned.ȱTheȱtypeȱnameȱisȱfollowedȱbyȱtheȱnameȱ ofȱ theȱ function.ȱ Theȱ argumentsȱ expectedȱ byȱ theȱ functionȱ areȱ next,ȱ soȱ
read_column_numbers returnsȱ anȱ integerȱ andȱ takesȱ twoȱ arguments,ȱ anȱ arrayȱ ofȱ
integersȱandȱanȱintegerȱscalar.ȱTheȱargumentȱnamesȱareȱnotȱrequired;ȱIȱgiveȱthemȱhereȱ toȱserveȱasȱaȱreminderȱofȱwhatȱeachȱargumentȱisȱsupposedȱtoȱbe.ȱ
Theȱrearrangeȱfunctionȱtakesȱfourȱarguments.ȱTheȱfirstȱandȱsecondȱareȱpointers.ȱ
Aȱ pointerȱ specifiesȱ whereȱ aȱ valueȱ residesȱ inȱ theȱ computer’sȱ memory,ȱ muchȱ likeȱ aȱ houseȱnumberȱspecifiesȱwhereȱaȱparticularȱfamilyȱresidesȱonȱaȱstreet.ȱPointersȱareȱwhatȱ giveȱ theȱ Cȱ languageȱ itsȱ powerȱ andȱ areȱ coveredȱ inȱ greatȱ detailȱ startingȱ inȱ Chapterȱ 6.ȱ Theȱsecondȱandȱfourthȱargumentsȱareȱdeclaredȱconst,ȱwhichȱmeansȱthatȱtheȱfunctionȱ promisesȱ notȱ toȱ modifyȱ theȱ callerȇsȱ arguments.ȱ Theȱ keywordȱvoidȱ indicatesȱ thatȱ theȱ functionȱdoesȱnotȱreturnȱanyȱvalueȱatȱall;ȱsuchȱaȱfunctionȱwouldȱbeȱcalledȱaȱprocedureȱinȱ otherȱlanguages.ȱ
ȱ
TIP Ifȱ theȱ sourceȱ codeȱ forȱ thisȱ programȱ wasȱ containedȱ inȱ severalȱ sourceȱ tiles,ȱ functionȱ prototypesȱ wouldȱ haveȱ toȱ beȱ writtenȱ inȱ eachȱ tileȱ usingȱ theȱ function.ȱ Puttingȱ theȱ prototypesȱ inȱ headerȱ filesȱ andȱ usingȱ a #includeȱ toȱ accessȱ themȱ avoidsȱ theȱ maintenanceȱproblemȱcausedȱbyȱhavingȱmultipleȱcopiesȱofȱtheȱsameȱdeclarations.ȱ
1.1.3 The Main Function
int
main( void ) {
ȱ
Theseȱ linesȱ beginȱ theȱ definitionȱ ofȱ aȱ functionȱ calledȱmain.ȱ Everyȱ Cȱ programȱ mustȱhaveȱaȱmainȱfunction,ȱbecauseȱthisȱisȱwhereȱexecutionȱbegins.ȱTheȱkeywordȱintȱ indicatesȱthatȱtheȱfunctionȱreturnsȱanȱintegerȱvalue;ȱtheȱkeywordȱvoidȱindicatesȱthatȱitȱ expectsȱ noȱ arguments.ȱ Theȱ bodyȱ ofȱ theȱ functionȱ includesȱ everythingȱ betweenȱ thisȱ openingȱbraceȱandȱitsȱmatchingȱclosingȱbrace.ȱ
Observeȱhowȱtheȱindentationȱclearlyȱshowsȱwhatȱisȱincludedȱinȱtheȱfunction.ȱ
ȱ ȱ
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ȱ linesȱ declareȱ fourȱ variables:ȱ anȱ integerȱ scalar,ȱ anȱ arrayȱ ofȱ integers,ȱ andȱ twoȱarraysȱofȱcharacters.ȱAllȱfourȱofȱtheseȱvariablesȱareȱlocalȱtoȱtheȱmainȱfunction,ȱsoȱ theyȱ cannotȱ beȱ accessedȱ byȱ nameȱ fromȱ anyȱ otherȱ functions.ȱ Theyȱ can,ȱ ofȱ course,ȱ beȱ passedȱasȱargumentsȱtoȱotherȱfunctions.ȱ
ȱ /*
** 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ȱ theȱ constantȱ representedȱ by MAX_COLS (20)ȱ areȱ passedȱ asȱ arguments.ȱ Inȱ C,ȱ arrayȱ argumentsȱ behaveȱ asȱ thoughȱ theyȱ areȱ passedȱ byȱ reference,ȱ andȱ scalarȱ variablesȱ andȱ constantsȱareȱpassedȱbyȱvalueȱ(likeȱvarȱparametersȱandȱvalueȱparameters,ȱrespectively,ȱ inȱPascalȱorȱModula).ȱThus,ȱanyȱchangesȱmadeȱbyȱaȱfunctionȱtoȱaȱscalarȱargumentȱareȱ lostȱ whenȱ theȱ functionȱ returns;ȱ theȱ functionȱ cannotȱ changeȱ theȱ valueȱ ofȱ theȱ callingȱ programȇsȱargumentȱinȱthisȱmanner.ȱWhenȱaȱfunctionȱchangesȱtheȱvalueȱofȱanȱelementȱ ofȱanȱarrayȱargument,ȱhowever,ȱtheȱarrayȱinȱtheȱcallingȱprogramȱisȱactuallyȱmodified.ȱ ȱ TheȱruleȱaboutȱhowȱparametersȱareȱpassedȱtoȱCȱfunctionsȱactuallyȱstates:ȱ ȱ Allȱargumentsȱtoȱfunctionsȱareȱpassedȱbyȱvalue.ȱ ȱ Nevertheless,ȱanȱarrayȱnameȱasȱanȱargumentȱproducesȱtheȱcallȬbyȬreferenceȱbehavior
1.1 Introduction 9 describedȱabove.ȱTheȱreasonȱforȱthisȱapparentȱcontradictionȱbetweenȱtheȱruleȱandȱtheȱ actualȱbehaviorȱisȱexplainedȱinȱChapterȱ8.ȱ
ȱ
/*
** 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; } ȱ ȱ Theȱcommentȱdescribingȱthisȱpieceȱofȱcodeȱmightȱseemȱunnecessary.ȱHowever,ȱ theȱ majorȱ expenseȱ ofȱ softwareȱ todayȱ isȱ notȱ writingȱ itȱ butȱ maintainingȱ it.ȱ Theȱ firstȱ problemȱinȱmodifyingȱaȱpieceȱofȱcodeȱisȱfiguringȱoutȱwhatȱitȱdoes,ȱsoȱanythingȱyouȱcanȱ putȱinȱourȱcodeȱthatȱmakesȱitȱeasierȱforȱsomeoneȱ(ȱperhapsȱyou!)ȱtoȱunderstandȱitȱlaterȱ isȱ worthȱ doing.ȱ Beȱ sureȱ toȱ writeȱ accurateȱ commentȱ whenȱ youȱ changeȱ theȱ code.ȱ Inaccurateȱcommentsȱareȱworseȱthanȱnoneȱatȱall!ȱ
Thisȱpieceȱofȱcodeȱconsistsȱofȱaȱwhileȱloop.ȱInȱC,ȱwhileȱloopsȱoperateȱtheȱsameȱasȱ theyȱdoȱinȱotherȱlanguages.ȱTheȱexpressionȱisȱtested.ȱIfȱitȱisȱfalse,ȱtheȱbodyȱofȱtheȱloopȱ isȱ skipped.ȱ Ifȱ theȱ expressionȱ isȱ true,ȱ theȱ bodyȱ ofȱ theȱ loopȱ isȱ executedȱ andȱ theȱ wholeȱ processȱbeginsȱagain.ȱȱ Thisȱloopȱrepresentsȱtheȱmainȱlogicȱofȱtheȱprogram.ȱInȱbrief,ȱitȱmeans:ȱ ȱ whileȱweȱwereȱableȱtoȱreadȱanotherȱlineȱofȱinputȱ printȱtheȱinputȱ rearrangeȱtheȱinput,ȱstoringȱitȱinȱoutputȱ printȱtheȱoutputȱ ȱ
Theȱgetsȱ functionȱ readsȱ oneȱ lineȱ ofȱ textȱ fromȱ theȱ standardȱ inputȱ andȱ storesȱ itȱ inȱ theȱ arrayȱ passedȱ asȱ anȱ argument.ȱ Aȱ lineȱ isȱ aȱ sequenceȱ ofȱ charactersȱ terminatedȱ byȱ aȱ newlineȱ character;ȱgetsȱ discardsȱ theȱ newlineȱ andȱ storesȱ aȱNULȱ byteȱ atȱ theȱ endȱ ofȱ theȱ line1.ȱ(AȱNULȱbyteȱisȱoneȱwhoseȱbitsȱareȱallȱ0,ȱwrittenȱasȱaȱcharacterȱconstantȱlikeȱthis:ȱ '\0'.)ȱ getsȱ thenȱ returnsȱ aȱ valueȱ thatȱ isȱ not NULLȱ toȱ indicateȱ thatȱ aȱ lineȱ was
1ȱNULȱisȱtheȱnameȱgivenȱinȱtheȱASCIIȱcharacterȱsetȱtoȱtheȱcharacterȱ'\0',ȱwhoseȱbitsȱareȱallȱzero.ȱNULLȱrefersȱtoȱaȱpointerȱ
whoseȱvalueȱisȱzero.ȱBothȱareȱintegersȱandȱhaveȱtheȱsameȱvalue,ȱsoȱtheyȱcouldȱbeȱusedȱinterchangeably.ȱHowever,ȱitȱisȱworthȱ usingȱtheȱappropriateȱconstantȱbecauseȱthisȱtellsȱaȱpersonȱreadingȱtheȱprogramȱnotȱonlyȱthatȱyouȱareȱusingȱtheȱvalueȱzero,ȱ butȱwhatȱyouȱareȱusingȱitȱfor.ȱ
ȱ
successfullyȱread2.ȱWhenȱgetsȱisȱcalledȱbutȱthereȱisȱnoȱmoreȱinput,ȱitȱreturnsȱNULLȱtoȱ indicateȱthatȱitȱhasȱreachedȱtheȱendȱofȱtheȱinputȱ(endȱofȱtile).ȱ
DealingȱwithȱcharacterȱstringsȱisȱaȱcommonȱtaskȱinȱCȱprograms.ȱAlthoughȱthereȱ isȱ noȱ ȈstringȈȱ dataȱ type,ȱ thereȱ isȱ aȱ conventionȱ forȱ characterȱ stringsȱ thatȱ isȱ observedȱ throughoutȱtheȱlanguage:ȱaȱstringȱisȱaȱsequenceȱofȱcharactersȱterminatedȱbyȱa NULȱbyte.ȱ TheȱNULȱisȱconsideredȱaȱterminatorȱandȱisȱnotȱcountedȱasȱaȱpartȱofȱtheȱstring.ȱAȱstringȱ
literalȱisȱaȱsequenceȱofȱcharactersȱenclosedȱinȱquotationȱmarksȱinȱtheȱsourceȱprogram3.ȱ Forȱexample,ȱtheȱstringȱliteralȱ
ȱ
"Hello" ȱ
occupiesȱsixȱbytesȱinȱmemory,ȱwhichȱcontainȱ(inȱorder)ȱH,e,l,l,o,ȱandȱNUL.ȱ ȱ
Theȱprintfȱfunctionȱperformsȱformattedȱoutput.ȱModulaȱandȱPascalȱusersȱwillȱ beȱ delightedȱ withȱ theȱ simplicityȱ ofȱ formattedȱ outputȱ inȱ C.ȱprintfȱ takesȱ multipleȱ arguments;ȱ theȱ firstȱ isȱ aȱ characterȱ stringȱ thatȱ describesȱ theȱ formatȱ ofȱ theȱ output,ȱ andȱ theȱrestȱareȱtheȱvaluesȱtoȱbeȱprinted.ȱTheȱformatȱisȱoftenȱgivenȱasȱaȱstringȱliteral.ȱ
Theȱ formatȱ stringȱ containsȱ formatȱ designatorsȱ interspersedȱ withȱ ordinaryȱ characters.ȱ Theȱ ordinaryȱ charactersȱ areȱ printedȱ verbatim,ȱ butȱeachȱ formatȱ designatorȱ causesȱtheȱnextȱargumentȱvalueȱtoȱbeȱprintedȱusingȱtheȱindicatedȱformat.ȱAȱfewȱofȱtheȱ moreȱusefulȱformatȱdesignatorsȱareȱgivenȱinȱTableȱl.l.ȱIfȱ ȱ ȱ ȱ Format Meaning %d Printȱanȱintegerȱvalueȱinȱdecimal.ȱ %o Printȱanȱintegerȱvalueȱinȱoctal.ȱ %x Printȱanȱintegerȱvalueȱinȱhexadecimal.ȱ %g PrintȱaȱfloatingȬpointȱvalue.ȱ %c Printȱaȱcharacter.ȱ %s Printȱaȱcharacterȱstring.ȱ \n Printȱaȱnewline.ȱ ȱ ȱ
ȱ Tableȱ1.1ȱCommonȱprintfȱformatȱcodesȱ
2ȱTheȱsymbolȱNULLȱisȱdefinedȱinȱtheȱheader stdio.h.ȱOnȱtheȱotherȱhand,ȱthereȱisȱnoȱpredefinedȱsymbolȱNUL,ȱsoȱifȱyouȱwishȱ
toȱuseȱitȱinsteadȱofȱtheȱcharacterȱconstantȱ'\0'ȱyouȱmustȱdefineȱitȱyourselfȱ
3ȱ Thisȱ symbolȱisȱ aȱ quotationȱmark:ȱ ",ȱ andȱ thisȱ symbolȱ isȱ anȱ apostrophe:ȱ'.ȱ Theȱ penchantȱ ofȱ computerȱ peopleȱ toȱcallȱthemȱ
Ȉsingleȱ quoteȈȱ andȱ Ȉdoubleȱ quoteȈȱ whenȱ theirȱ existingȱ namesȱ areȱ perfectlyȱ goodȱ seemsȱ unnecessary,ȱ soȱ Iȱ willȱ useȱ theirȱ everydayȱnames.ȱ
1.1 Introduction 11 theȱarrayȱinputȱcontainsȱtheȱstringȱHi friends!,ȱthenȱtheȱstatementȱ
ȱ
printf( "Original input : %s\n", input ); ȱ
willȱproduceȱ ȱ
Original input : Hi friends! terminatedȱwithȱaȱnewline.ȱ
Theȱnextȱstatementȱinȱtheȱsampleȱprogramȱcallsȱtheȱrearrangeȱfunction.ȱTheȱlastȱ threeȱargumentsȱareȱvaluesȱthatȱareȱpassedȱtoȱtheȱfunction,ȱandȱtheȱfirstȱisȱtheȱanswerȱ thatȱtheȱfunctionȱwillȱconstructȱandȱpassȱbackȱtoȱtheȱmainȱfunction.ȱRememberȱthatȱitȱ isȱonlyȱpossibleȱtoȱpassȱtheȱanswerȱbackȱthroughȱthisȱargumentȱbecauseȱitȱisȱanȱarray.ȱ Theȱlastȱcallȱtoȱprintfȱdisplaysȱtheȱresultȱofȱrearrangingȱtheȱline.ȱ
Finally,ȱ whenȱ theȱ loopȱ hasȱ completed,ȱ theȱ mainȱ functionȱ returnsȱ theȱ valueȱ
EXIT_SUCCESS.ȱ Thisȱ valueȱ indicatesȱ toȱ theȱ operatingȱ systemȱ thatȱ theȱ programȱ wasȱ
successful.ȱTheȱclosingȱbraceȱmarksȱtheȱendȱofȱtheȱbodyȱofȱtheȱmainȱfunction.ȱ ȱ ȱ ȱ ȱ ȱ
1.1.4 The
read_column_numbersFunction
/*
** Read the list of column numbers, ignoring any beyond the specified ** maximum.
*/ int
read_column_numbers( int columns[], int max ) {
Theseȱlinesȱbeginȱtheȱdefinitionȱofȱtheȱread_column_numbersȱfunction.ȱNoteȱthatȱ thisȱdeclarationȱandȱtheȱfunctionȱprototypeȱthatȱappearedȱearlierȱinȱtheȱprogramȱmatchȱ inȱtheȱnumberȱandȱtypesȱofȱargumentsȱandȱinȱtheȱtypeȱreturnedȱbyȱtheȱfunction.ȱItȱisȱ anȱerrorȱifȱtheyȱdisagree.ȱ
Thereȱisȱnoȱindicationȱofȱtheȱarrayȱsizeȱinȱtheȱarrayȱparameterȱdeclarationȱtoȱtheȱ function.ȱThisȱformatȱisȱcorrect,ȱbecauseȱtheȱfunctionȱwillȱgetȱwhateverȱsizeȱarrayȱtheȱ callingȱ programȱ passedȱ asȱ anȱ argument.ȱ Thisȱ isȱ aȱ greatȱ feature,ȱ asȱ itȱ allowsȱ aȱ singleȱ functionȱ toȱ manipulateȱ one—dimensiona1ȱ arraysȱ ofȱ anyȱ size.ȱ Theȱ downȱ sideȱ ofȱ thisȱ featureȱisȱthatȱthereȱisȱnoȱwayȱforȱtheȱfunctionȱtoȱdetermineȱtheȱsizeȱofȱtheȱarray.ȱIfȱthisȱ informationȱisȱneeded,ȱtheȱvalueȱmustȱbeȱpassedȱasȱaȱseparateȱargument.ȱ
Whenȱ theȱread_column_numbersȱ functionȱ isȱ called,ȱ theȱ nameȱ ofȱ oneȱ ofȱ theȱ argumentsȱ thatȱ isȱ passedȱ happensȱ toȱ matchȱ theȱ nameȱ ofȱ theȱ formalȱ parameterȱ givenȱ above.ȱ However,ȱ theȱ nameȱ ofȱ theȱ otherȱ argumentȱ doesȱ notȱ matchȱ itsȱ correspondingȱ parameter.ȱ Asȱ inȱ mostȱ otherȱ languages,ȱ theȱ formalȱ parameterȱ nameȱ andȱ theȱ actualȱ argumentȱnameȱhaveȱnoȱrelationshipȱtoȱoneȱanother;ȱyouȱcanȱmakeȱthemȱtheȱsameȱifȱ youȱwish,ȱbutȱitȱisȱnotȱrequired.ȱ
ȱ
int num = 0;
int ch;
Twoȱ variablesȱ areȱ declared;ȱ theyȱ willȱ beȱ localȱ toȱ thisȱ function.ȱ Theȱ firstȱ oneȱ isȱ initializedȱ toȱ zeroȱ inȱ theȱ declaration,ȱ butȱ theȱ secondȱ oneȱ isȱ notȱ initialized.ȱ Moreȱ precisely,ȱ itsȱ initialȱ valueȱ willȱ beȱ someȱ unpredictableȱ value,ȱ whichȱ isȱ probablyȱ garbage.ȱTheȱlackȱofȱanȱinitialȱvalueȱisȱnotȱaȱproblemȱinȱthisȱfunctionȱbecauseȱtheȱfirstȱ thingȱdoneȱwithȱtheȱvariableȱisȱtoȱassignȱitȱaȱvalue.ȱ
ȱ ȱ
** 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ȱ charactersȱfromȱtheȱstandardȱinputȱandȱconvertsȱthemȱaccordingȱtoȱaȱformatȱstring— sortȱ ofȱ theȱ reverseȱ ofȱ whatȱprintfȱ does.ȱscanfȱ takesȱ severalȱ arguments,ȱ theȱ firstȱ ofȱ whichȱ isȱ aȱ formatȱ suingȱ thatȱ describesȱ theȱ typeȱ ofȱ inputȱ thatȱ isȱ expected.ȱ Theȱ remainingȱargumentsȱareȱvariablesȱintoȱwhichȱtheȱinputȱisȱstored.ȱTheȱvalueȱretunedȱ
byȱscanfȱisȱtheȱnumberȱofȱvaluesȱthatȱwereȱsuccessfullyȱconvertedȱandȱstoredȱintoȱtheȱ
arguments.ȱ ȱ ȱ
CAUTION! Youȱmustȱbeȱcarefulȱwithȱthisȱfunctionȱforȱtwoȱreasons.ȱFirst,ȱbecauseȱofȱtheȱwayȱscanfȱ isȱimplemented,ȱallȱofȱitsȱscalarȱargumentsȱmustȱhaveȱanȱampersandȱinȱfrontȱofȱthem.ȱ Forȱ reasonsȱ thatȱ Iȱ makeȱ clearȱ inȱ Chapterȱ 8,ȱ arrayȱ argumentsȱ doȱ notȱ requireȱ anȱ ampersand4.ȱHowever,ȱifȱaȱsubscriptȱisȱusedȱtoȱidentifyȱaȱspecificȱarrayȱelement,ȱthenȱ anȱ ampersandȱ isȱ required.ȱ Iȱ explainȱ theȱ needȱ forȱ theȱ ampersandsȱ onȱ theȱ scalar
1.1 Introduction 13 argumentsȱinȱChapterȱ15.ȱForȱnow,ȱjustȱbeȱsureȱtoȱputȱthemȱin.ȱbecauseȱtheȱprogramȱ willȱsurelyȱfailȱwithoutȱthem.ȱ
ȱ
CAUTION! Theȱsecondȱpitfallȱisȱtheȱformatȱcodes,ȱwhichȱareȱnotȱidenticalȱtoȱthoseȱin printfȱbutȱ similarȱ enoughȱ toȱ beȱ confusing.ȱ Tableȱ 1.2ȱ informallyȱ describesȱ aȱ fewȱ ofȱ theȱ formatȱ designatorsȱthatȱyouȱmayȱuseȱwithȱscanf.ȱNoteȱthatȱtheȱfirstȱfiveȱvalues,ȱsoȱtheȱvariableȱ givenȱasȱtheȱargumentȱmustȱbeȱprecededȱwithȱanȱampersand.ȱWithȱallȱofȱtheseȱformatȱ codesȱ(exceptȱ%c),ȱwhiteȱspaceȱ(spaces,ȱtabs,ȱnewlines,ȱetc.)ȱinȱtheȱinputȱisȱskippedȱtheȱ valueȱ isȱ encountered,ȱ andȱ subsequentȱ whiteȱ spaceȱ terminatesȱ theȱ value.ȱ Therefore,ȱ aȱ characterȱstringȱreadȱwithȱ%sȱcannotȱcontainȱwhiteȱspace.ȱThereȱareȱmanyȱotherȱformatȱ designators,ȱbutȱtheseȱwillȱbeȱenoughȱforȱourȱcurrentȱneeds.ȱ Weȱcanȱnowȱexplainȱtheȱexpressionȱ ȱ scanf( "%d", &columns[num] ) ȱ ȱ Theȱformatȱcodeȱ%dȱindicatesȱthatȱanȱintegerȱvalueȱisȱdesired.ȱCharactersȱareȱreadȱfromȱ theȱ standardȱ input,ȱ anyȱ leadingȱ whiteȱ spaceȱ foundȱ isȱ skipped.ȱ Thenȱ digitsȱ areȱ convertedȱ intoȱ anȱ integer,ȱ andȱ theȱ resultȱ isȱ storedȱ inȱ theȱ specifiedȱ arrayȱ element.ȱ Anȱ ampersandȱisȱrequiredȱinȱfrontȱofȱtheȱargumentȱbecauseȱtheȱsubscriptȱselectsȱaȱsingleȱ arrayȱelement,ȱwhichȱisȱaȱscalar.ȱ Theȱtestȱinȱtheȱwhileȱloopȱconsistsȱofȱthreeȱparts.ȱ ȱ num < max ȱ
makesȱ sureȱ thatȱ weȱ doȱ notȱ getȱ tooȱ manyȱ numbersȱ andȱ overflowȱ theȱ array.ȱscanf retumsȱtheȱvalueȱoneȱifȱitȱconvertedȱanȱinteger.ȱFinally,ȱ
ȱ
columns[num] >= 0
checksȱ thatȱ theȱ valueȱ enteredȱ wasȱ positive.ȱ lfȱ anyȱ ofȱ theseȱ testsȱ areȱ false.ȱ Theȱ loopȱ stops.ȱ
ȱ ȱ
Format Meaning Type of Variable
%d Readȱanȱintegerȱvalue.ȱ int
%ld Readȱaȱlongȱintegerȱvalue.ȱ long
%f Readȱaȱrealȱvalue.ȱ float
%lf Readȱaȱdoubleȱprecisionȱrealȱvalue.ȱ double
%c Readȱaȱcharacter.ȱ char
%s Readȱaȱcharacterȱstringȱfromȱtheȱinput.ȱ array of char
ȱ ȱ
TheȱStandardȱdoesȱnotȱrequireȱthatȱCȱcompilersȱcheckȱtheȱvalidityȱofȱarrayȱsubscripts,ȱ andȱtheȱvastȱmajorityȱofȱcompilersȱdon’t.ȱThus,ȱifȱyouȱneedȱsubscriptȱvalidityȱchecking,ȱ youȱ mustȱ writeȱ itȱ yourself.ȱ ifȱ theȱ testȱ forȱnum < maxȱ wereȱ notȱ hereȱ andȱ theȱ programȱ readȱ aȱ fileȱ containingȱ moreȱ thanȱ 20ȱ columnȱ numbers,ȱ theȱ excessȱ valuesȱ wouldȱ beȱ storedȱ inȱ theȱ memoryȱ locationsȱ thatȱ followȱ theȱ array,ȱ thusȱ destroyingȱ whateverȱ dataȱ wasȱ formerlyȱ inȱ thoseȱ locations,ȱ whichȱ mightȱ beȱ otherȱ variablesȱ orȱ theȱ functionȇsȱ returnȱaddress.ȱThereȱareȱotherȱpossibilitiesȱtoo,ȱbutȱtheȱresultȱisȱthatȱtheȱprogramȱwillȱ probablyȱnotȱperformȱasȱyouȱhadȱintended.ȱ
TIP
Theȱ &&ȱ isȱ theȱ Ȉlogicalȱ andȈȱ operator.ȱ Forȱ thisȱ expressionȱ toȱ beȱ true,ȱ theȱ expressionsȱonȱbothȱsidesȱofȱtheȱ&&ȱmustȱevaluateȱtoȱtrue.ȱHowever,ȱifȱtheȱleftȱsideȱisȱ false,ȱtheȱrightȱsideȱisȱnotȱevaluatedȱatȱall,ȱbecauseȱtheȱresultȱcanȱonlyȱbeȱfalse.ȱInȱthisȱ case,ȱ ifȱ weȱ findȱ thatȱ numȱ hasȱ reachedȱ theȱ maximumȱ value,ȱ theȱ loopȱ breaksȱ andȱ theȱ expressionȱ ȱ columns[num] ȱ isȱneverȱevaluated5.ȱ ȱ
CAUTION! Beȱcarefulȱnotȱtoȱuseȱtheȱ&ȱoperatorȱwhenȱyouȱreallyȱwantȱ&&;ȱtheȱformerȱdoesȱaȱbitwiseȱ AND,ȱ whichȱ sometimesȱ givesȱ theȱ sameȱ resultȱ thatȱ&&ȱ wouldȱ giveȱ butȱ inȱ otherȱ casesȱ doesȱnot.ȱIȱdescribeȱtheseȱoperatorsȱinȱChapterȱ5.ȱ
Eachȱ callȱ toȱscanfȱ roadsȱ aȱ decimalȱ integerȱ fromȱ theȱ standardȱ input.ȱ Ifȱ theȱ conversionȱ fails,ȱ eitherȱ becauseȱ endȱ ofȱ meȱ wasȱ reachedȱ orȱ becauseȱ theȱ nextȱ inputȱ charactersȱ wereȱ notȱ validȱ inputȱ forȱ anȱ integer,ȱ theȱ valueȱ0ȱ isȱ returned,ȱ whichȱ breaksȱ theȱ loop.ȱ Ifȱ theȱ charactersȱ areȱ legalȱ inputȱ forȱ anȱ integer,ȱ theȱ valueȱ isȱ convertedȱ toȱ binaryȱandȱstoredȱinȱtheȱarrayȱelementȱcolumns[num]. scanfȱthanȱreturnsȱtheȱvalueȱ1.ȱ
ȱ
CAUTION! Beware:ȱTheȱoperatorȱthatȱtestsȱtwoȱexpressionsȱforȱequalityȱisȱ==.ȱUsingȱtheȱ=ȱoperatorȱ insteadȱresultsȱinȱaȱlegalȱexpressionȱthatȱalmostȱcertainlyȱwillȱnotȱdoȱwhatȱyouȱwantȱitȱ toȱdo:ȱitȱdoesȱanȱassignmentȱratherȱthanȱaȱcomparison!ȱItȱisȱaȱlegalȱexpression,ȱthough,ȱ soȱtheȱcompilerȱwon’tȱcatchȱthisȱerrorȱforȱyou6.ȱBeȱextremelyȱcarefulȱtoȱuseȱtheȱdoubleȱ equalȱsignȱoperatorȱforȱcomparisons.ȱIfȱyourȱprogramȱisȱnotȱworking,ȱcheckȱallȱofȱyourȱ comparisonsȱforȱthisȱerror.ȱBelieveȱme,ȱyouȱwillȱmakeȱthisȱmistake,ȱprobablyȱmoreȱthanȱ once,ȱasȱIȱhave.ȱ 5ȱȱTheȱphraseȱȈtheȱloopȱbreaksȈȱmeansȱthatȱitȱterminates,ȱnotȱthatȱitȱisȱhasȱsuddenlyȱbecomeȱdefective.ȱThisȱphraseȱcomesȱ fromȱtheȱbreakȱstatement,ȱwhichȱisȱdiscussedȱinȱChapterȱ4.ȱ
6ȱȱSomeȱnewerȱcompilersȱwillȱprintȱaȱwarningȱaboutȱassignmentsȱin ifȱand whileȱstatementsȱonȱtheȱtheoryȱthatȱitȱisȱmuchȱ
1.1 Introduction 15 Theȱ nextȱ&&ȱ makesȱ sureȱ thatȱ theȱ numberȱ isȱ testedȱ forȱ aȱ negativeȱ valueȱ onlyȱ ifȱ
scanfȱwasȱsuccessfulȱinȱreadingȱit.ȱTheȱstatementȱ
ȱ
num += 1; ȱ
addsȱ1ȱtoȱtheȱvariableȱnum.ȱItȱisȱequivalentȱtoȱtheȱstatementȱ ȱ num = num + 1; ȱ IȱdiscussȱlaterȱwhyȱCȱprovidesȱtwoȱdifferentȱwaysȱtoȱincrementȱaȱvariable7.ȱ ȱ ȱ /*
** 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ȱ integersȱ wereȱ entered,ȱ whichȱ isȱ requiredȱ becauseȱtheȱnumbersȱareȱsupposedȱtoȱbeȱinȱpairs.ȱTheȱ% operatorȱperformsȱanȱintegerȱ division,ȱ butȱ itȱ givesȱ theȱ remainderȱ ratherȱ thanȱ theȱ quotient.ȱ Ifȱnumȱ isȱ notȱ anȱ evenȱ number,ȱtheȱremainderȱofȱdividingȱitȱbyȱtwoȱwillȱbeȱnonzero.ȱ
Theȱputsȱfunctionȱisȱtheȱoutputȱversionȱofȱgets;ȱitȱwritesȱtheȱspecifiedȱstringȱtoȱ theȱstandardȱoutputȱandȱappendsȱaȱnewlineȱcharacterȱtoȱit.ȱTheȱprogramȱthenȱcallsȱtheȱ exit;ȱfunction,ȱwhichȱterminatesȱitsȱexecution.ȱTheȱvalueȱEXIT_FAILUREȱisȱpassedȱbackȱ toȱtheȱoperatingȱsystemȱtoȱindicateȱthatȱsomethingȱwasȱwrong.ȱ
ȱ /*
** Discard the rest of the line that contained the final ** number.
*/
while( (ch = getchar()) != EOF && ch != '\n' ) ;
ȱ ȱ
scanfȱonlyȱreadsȱasȱfarȱasȱitȱhasȱtoȱwhenȱconvertingȱinputȱvalues.ȱTherefore,ȱtheȱ
remainderȱ ofȱ theȱ Lineȱ thatȱ containedȱ theȱ lastȱ valueȱ willȱ stillȱ beȱ outȱ there,ȱ waitingȱ to
beȱread.ȱItȱmayȱcontainȱjustȱtheȱterminatingȱnewline,ȱorȱitȱmayȱcontainȱotherȱcharactersȱ too.ȱRegardless,ȱthisȱwhileȱloopȱreadsȱandȱdiscardsȱtheȱremainingȱcharactersȱtoȱpreventȱ themȱfromȱbeingȱinterpretedȱasȱtheȱfirstȱlineȱofȱdata.ȱ
Theȱexpressionȱ ȱ
(ch = getchar()) != EOF && ch != '\n' ȱ
meritsȱ someȱ discussion.ȱ First,ȱ theȱ functionȱgetcharȱ readsȱ aȱ singleȱ characterȱ fromȱ theȱ standardȱinputȱandȱreturnsȱitsȱvalue.ȱIfȱthereȱareȱnoȱmoreȱcharactersȱinȱtheȱinput,ȱtheȱ constantȱEOFȱ(whichȱisȱdefinedȱinȱstdio.h)ȱisȱrammedȱinsteadȱtoȱsignalȱendȬofȬline.ȱ
Theȱ valueȱ returnedȱ byȱgetcharȱ isȱ assignedȱ toȱ theȱ variableȱch,ȱ whichȱ isȱ thenȱ comparedȱ toȱEOF.ȱ Theȱ parenthesesȱ enclosingȱ theȱ assignmentȱ ensureȱ thatȱ itȱ isȱ doneȱ beforeȱtheȱcomparison.ȱIfȱchȱisȱequalȱtoȱEOF,ȱtheȱexpressionȱisȱfalseȱandȱtheȱloopȱstops.ȱ Otherwise,ȱchȱisȱcomparedȱtoȱaȱnewline;ȱagain,ȱtheȱloopȱstopsȱifȱtheyȱareȱfoundȱtoȱbeȱ equal.ȱThus,ȱtheȱexpressionȱisȱtrueȱ{causingȱtheȱloopȱtoȱrunȱagain)ȱonlyȱifȱendȱofȱlineȱ wasȱnotȱreachedȱandȱtheȱcharacterȱreadȱwasȱnotȱaȱnewline.ȱThus,ȱtheȱloopȱdiscardsȱtheȱ remainingȱcharactersȱonȱtheȱcurrentȱinputȱline.ȱ Nowȱlet’sȱmoveȱonȱtoȱtheȱinterestingȱpart.ȱInȱmostȱotherȱlanguages,ȱweȱwouldȱ haveȱwrittenȱtheȱloopȱlikeȱthis:ȱ ȱ ch = getchar();
while( ch != EOF && ch != '\n' )
ch = getchar();
ȱ
Getȱaȱcharacter,ȱthereȱifȱweȇveȱnotȱyetȱreachedȱendȱ ofȱtileȱorȱgottenȱaȱ newline,ȱ getȱanotherȱcharacter.ȱNoteȱthatȱthereȱareȱtwoȱcopiesȱofȱtheȱstatement.ȱȱ
ȱ
ȱ ch = getchar();
ȱ
TheȱabilityȱtoȱembedȱtheȱassignmentȱinȱtheȱwhileȱstatementȱallowsȱtheȱCȱprogrammerȱ toȱeliminateȱthisȱredundantȱstatement.ȱ
ȱ
TIP Theȱloopȱinȱtheȱsampleȱprogramȱhasȱtheȱsameȱfunctionalityȱasȱtheȱoneȱshownȱabove,ȱ butȱ itȱ containsȱ oneȱ fewerȱ statement.ȱ Itȱ isȱ admittedlyȱ harderȱ toȱ road,ȱ andȱ oneȱ couldȱ makeȱaȱconvincingȱargumentȱthatȱthisȱcodingȱtechniqueȱshouldȱbeȱavoidedȱforȱjustȱthatȱ reason.ȱ However,ȱ most,ȱ ofȱ theȱ difficultyȱ inȱ readingȱ isȱ dueȱ coȱ inexperienceȱ withȱ theȱ languageȱ andȱ itsȱ idioms;ȱ experiencedȱ Cȱ programmersȱ haveȱ noȱ troubleȱ readingȱ (andȱ writing)ȱ statementsȱ suchȱ asȱ thisȱ one.ȱ Youȱ shouldȱ avoidȱ makingȱ codeȱ harderȱ toȱ readȱ whenȱthereȱisȱnoȱtangibleȱbenefitȱtoȱbeȱgainedȱfromȱit,ȱbutȱtheȱmaintenanceȱadvantageȱ inȱnotȱhavingȱmultipleȱcopiesȱofȱcodeȱmoreȱthanȱjustifiesȱthisȱcommonȱcodingȱidiom.ȱ
1.1 Introduction 17 Aȱ questionȱ frequentlyȱ askedȱ isȱ whyȱchȱ isȱ declaredȱ asȱ anȱ integerȱ whenȱ weȱ areȱ usingȱ itȱ toȱ readȱ characters?ȱ Theȱ answerȱ isȱ thatȱEOFȱ isȱ anȱ integerȱ valueȱ thatȱ requiresȱ moreȱbitsȱthanȱareȱavailableȱinȱaȱcharacterȱvariable;ȱthisȱfactȱpreventsȱaȱcharacterȱinȱtheȱ inputȱ fromȱ accidentallyȱ beingȱ interpretedȱ asȱEOF.ȱ Butȱ itȱ alsoȱ meansȱ thatȱch,ȱ whichȱ isȱ receivingȱ theȱ characters,ȱ mustȱ beȱ largeȱ enoughȱ toȱ holdȱ EOFȱ 100,ȱ whichȱ isȱ whyȱ anȱ integerȱisȱused.ȱAsȱdiscussedȱinȱChapterȱ3,ȱcharactersȱareȱjustȱtinyȱintegersȱanyway,ȱsoȱ usingȱanȱintegerȱvariableȱtoȱholdȱcharacterȱvaluesȱcausesȱnoȱproblems.ȱ
ȱ
TIP Oneȱ finalȱ commentȱ onȱ thisȱ fragmentȱ ofȱ theȱ program:ȱ thereȱ areȱ noȱ statementsȱ inȱ theȱ bodyȱ ofȱ theȱwhileȱ statement.ȱ Itȱ turnsȱ outȱ thatȱ theȱ workȱ doneȱ toȱ evaluateȱ theȱwhileȱ expressionȱisȱallȱthatȱisȱneeded,ȱsoȱthereȱisȱnothingȱleft forȱtheȱbodyȱofȱtheȱloopȱtoȱdo.ȱ Youȱ willȱ encounterȱ suchȱ loopsȱ occasionally,ȱ andȱ handlingȱ themȱ isȱ noȱ problem.ȱ Theȱ solitaryȱsemicolonȱafterȱtheȱwhileȱstatementȱisȱcalledȱtheȱemptyȱstatement,ȱandȱitȱisȱusedȱ inȱsituationsȱlikeȱthisȱoneȱwhereȱtheȱsyntaxȱrequiresȱaȱstatementȱbutȱthereȱisȱnoȱworkȱtoȱ beȱ done.ȱ Theȱ semicolonȱ isȱ onȱ aȱ lineȱ byȱ itselfȱ inȱ orderȱ toȱ preventȱ theȱ readerȱ fromȱ mistakenlyȱassumingȱthatȱtheȱnextȱstatementȱisȱmeȱbodyȱofȱtheȱloop.ȱ ȱ return num; } ȱ ȱ
Theȱreturnȱstatementȱisȱhowȱaȱfunctionȱreturnsȱaȱvalueȱtoȱtheȱexpressionȱfromȱ
whichȱitȱwasȱcalled.ȱInȱthisȱcase,ȱtheȱvalueȱofȱtheȱvariableȱnumȱisȱreturnedȱtoȱtheȱcallingȱ program,ȱwhereȱitȱisȱassignedȱtoȱtheȱmainȱprogramȇsȱvariableȱn_columns.ȱ
ȱ ȱ ȱ ȱ
1.1.5 The
rearrangeFunction
/*
** 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 */
Theseȱstatementsȱdefineȱtheȱrearrangeȱfunctionȱandȱdeclareȱsomeȱlocalȱvariablesȱ forȱit.ȱTheȱmostȱinterestingȱpointȱhereȱisȱthatȱtheȱfirstȱtwoȱparametersȱareȱdeclaredȱasȱ pointersȱbutȱarrayȱnamesȱareȱpassedȱasȱargumentsȱwhenȱtheȱfunctionȱisȱcalled.ȱWhenȱ anȱarrayȱnameȱisȱusedȱasȱanȱargument,ȱwhatȱisȱpassedȱtoȱtheȱfunctionȱisȱaȱpointerȱtoȱ theȱ beginningȱ ofȱ theȱ array,ȱ whichȱ isȱ actuallyȱ theȱ addressȱ whereȱ theȱ arrayȱ residesȱ inȱ memory.ȱTheȱfactȱthatȱaȱpointerȱisȱpassedȱratherȱthanȱatȱcopyȱofȱtheȱarrayȱisȱwhatȱgivesȱ arraysȱtheirȱcallȱbyȱreferenceȱsemantics.ȱTheȱfunctionȱcanȱmanipulateȱtheȱargumentȱasȱ aȱpointer,ȱorȱitȱcanȱuseȱaȱsubscriptȱwithȱtheȱargumentȱjustȱasȱwithȱanȱarrayȱname.ȱTheseȱ techniquesȱareȱdescribedȱinȱmoreȱdetailȱinȱChapterȱ8.ȱ
ȱ
Becauseȱ ofȱ theȱ callȱ byȱ referenceȱ semantics,ȱ though,ȱ ifȱ theȱ functionȱ modifiesȱ elementsȱofȱtheȱparameterȱarray,ȱitȱactuallyȱmodifiesȱtheȱcorrespondingȱelementsȱofȱtheȱ argumentȱ array.ȱ Thus,ȱ declaringȱcolumnsȱ toȱ beȱconstȱ isȱ usefulȱ inȱ twoȱ ways.ȱ First,ȱ itȱ statesȱ thatȱ theȱ intentionȱ ofȱ theȱ functionȇsȱ authorȱ isȱ thatȱ thisȱ parameterȱ isȱ notȱ toȱ beȱ modified.ȱ Second,ȱ itȱ causesȱ theȱ compilerȱ toȱ verifyȱ thatȱ thisȱ intentionȱ isȱ notȱ violated.ȱ Thus,ȱ callersȱ ofȱ thisȱ functionȱ needȱ notȱ worryȱ aboutȱ theȱ possibilityȱ ofȱ elementsȱ ofȱ meȱ arrayȱpassedȱasȱtheȱfourthȱargumentȱbeingȱchanged.ȱ
ȱ ȱ
len = strlen( input );
output_col = 0;
/*
** Process each pair of column numbers. */
for( col = 0; col < n_columns; col += 2 ){ ȱ
ȱ
Theȱrealȱworkȱofȱtheȱfunctionȱbeginsȱhere.ȱWeȱfirstȱgetȱtheȱlengthȱofȱtheȱinputȱ string,ȱsoȱweȱcanȱskipȱcolumnȱnumbersȱthatȱareȱbeyondȱtheȱendȱofȱtheȱinput.ȱTheȱforȱ statementȱinȱCȱisȱnotȱquiteȱlikeȱotherȱlanguages;ȱitȱisȱmoreȱofȱatȱshorthandȱnotationȱforȱ aȱ commonlyȱ usedȱ styleȱ ofȱ whileȱ statement.ȱ Theȱ forȱ statementȱ containsȱ threeȱ expressionsȱ (allȱ ofȱ whichȱ areȱ optional,ȱ byȱ theȱ way).ȱ Theȱ firstȱ expressionȱ isȱ theȱ
initializationȱandȱisȱevaluatedȱonceȱbeforeȱtheȱloopȱbegins.ȱTheȱsecondȱisȱtheȱtestȱandȱisȱ
evaluatedȱbeforeȱeachȱiterationȱofȱtheȱloop;ȱifȱtheȱresultȱisȱfalseȱtheȱloopȱterminates.ȱTheȱ thirdȱexpression,ȱisȱtheȱadjustmentȱwhichȱisȱevaluatedȱatȱtheȱendȱofȱeachȱiterationȱjustȱ beforeȱ theȱ testȱ isȱ evaluated.ȱ Toȱ illustrate,ȱ theȱforȱ loopȱ thatȱ beginsȱ aboveȱ couldȱ beȱ rewrittenȱasȱaȱwhileȱloop:ȱ
ȱ
1.1 Introduction 19
ȱ ȱ while( col < n_columns ){
bodyȱofȱtheȱloopȱ
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ȱ theȱ bodyȱ ofȱ theȱforȱ loop,ȱ whichȱ beginsȱ byȱ computingȱ theȱ numberȱ ofȱ charactersȱinȱthisȱrangeȱofȱcolumns.ȱThenȱitȱchecksȱwhetherȱtoȱcontinueȱwithȱtheȱloop.ȱ Ifȱtheȱinputȱlineȱisȱshorterȱthanȱthisȱstartingȱcolumn,ȱorȱifȱtheȱoutputȱlineȱisȱalreadyȱfull,ȱ thereȱisȱnoȱmoreȱworkȱtoȱbeȱdoneȱandȱtheȱbreakȱstatementȱexitsȱtheȱloopȱimmediately.ȱ
ȱTheȱ nextȱ testȱ checksȱ whetherȱ allȱ ofȱ theȱ charactersȱ fromȱ thisȱ rangeȱ ofȱ columnsȱ willȱfitȱinȱtheȱoutputȱline.ȱIfȱnot,ȱncharsȱisȱadjustedȱtoȱtheȱnumberȱthatȱwillȱfit.ȱ
ȱ
TIP ItȱisȱcommonȱinȱȈthrowawayȈȱprogramsȱthatȱareȱusedȱonlyȱonceȱtoȱnotȱbotherȱcheckingȱ thingsȱsuchȱasȱarrayȱboundsȱandȱtoȱsimplyȱmakeȱtheȱarrayȱȈbigȱenoughȈȱsoȱthatȱitȱwillȱ neverȱ overflow.ȱ Unfortunately,ȱ thisȱ practiceȱ isȱ sometimesȱ usedȱ inȱ productionȱ code,ȱ too.ȱ There,ȱ mostȱ ofȱ theȱ extraȱ spaceȱ isȱ wasted, butȱ itȱ isȱ stillȱ possibleȱ toȱ overflowȱ theȱ
array,ȱleadingȱtoȱaȱprogramȱfailure8.ȱ ȱ
Finally,ȱtheȱstrncpyȱfunctionȱcopiesȱtheȱselectedȱcharactersȱfromȱtheȱinputȱlineȱ toȱtheȱnextȱavailableȱpositionȱinȱtheȱoutputȱline.ȱTheȱfirstȱtwoȱargumentsȱtoȱstrncpyȱareȱ theȱdestinationȱandȱsource,ȱrespectively,ȱofȱaȱstringȱtoȱcopy.ȱTheȱdestinationȱinȱthisȱcallȱ isȱtheȱpositionȱoutput_colȱcolumnsȱpastȱtheȱbeginningȱofȱtheȱoutputȱarray.ȱTheȱsourceȱ isȱtheȱpositionȱcolumns[col]ȱpastȱtheȱbeginningȱofȱtheȱinputȱarray.ȱTheȱthirdȱargumentȱ specifiesȱ theȱ numberȱ ofȱ charactersȱ toȱ beȱ copied9.ȱ Theȱ outputȱ columnȱ counterȱ isȱ thenȱ advancedȱncharsȱpositions.ȱ
ȱ }
output[output_col] = '\0'; }
ȱ
Afterȱtheȱloopȱends,ȱtheȱoutputȱstringȱisȱterminatedȱwithȱaȱNULȱcharacter;ȱnoteȱ thatȱtheȱbodyȱofȱtheȱloopȱtakesȱcareȱtoȱensureȱthatȱthereȱisȱspaceȱinȱtheȱarrayȱtoȱholdȱit.ȱ Thenȱexecutionȱreachesȱtheȱbottomȱofȱtheȱfunction,ȱsoȱanȱimplicitȱreturnȱisȱexecuted.ȱ Withȱnoȱexplicitȱreturnȱstatement,ȱnoȱvalueȱcanȱbeȱpassedȱbackȱtoȱtheȱexpressionȱfromȱ whichȱtheȱfunctionȱwasȱcalled.ȱTheȱmissingȱreturnȱvalueȱisȱnotȱaȱproblemȱhereȱbecauseȱ theȱfunctionȱwasȱdeclaredȱvoidȱ(thatȱis,ȱreturningȱnoȱvalue)ȱandȱthereȱisȱnoȱassignmentȱ orȱtestingȱofȱtheȱfunction‘sȱreturnȱvalueȱwhereȱitȱisȱcalled.ȱ ȱ ȱ ȱ ȱ
1.2 Other Capabilities
Theȱ sampleȱ programȱ illustratedȱ manyȱ ofȱ theȱ Cȱ basics,ȱ butȱ thereȱ isȱ aȱ littleȱ moreȱ youȱ shouldȱ knowȱ beforeȱ youȱ beginȱ writingȱ yourȱ ownȱ programs.ȱ Firstȱ isȱ theȱputcharȱ function,ȱ whichȱ isȱ theȱ companionȱ toȱgetchar.ȱ Itȱ takesȱ aȱ singleȱ integerȱ argumentȱ andȱ printsȱthatȱcharacterȱonȱtheȱstandardȱoutput.ȱȱ Also,ȱthereȱareȱmanyȱmoreȱlibraryȱfunctionsȱforȱmanipulatingȱstrings.ȱI’llȱbrieflyȱ introduceȱaȱfewȱofȱtheȱmostȱusefulȱonesȱhere.ȱUnlessȱotherwiseȱnoted,ȱeachȱargumentȱ toȱtheseȱfunctionsȱmayȱbeȱaȱstringȱliteral,ȱtheȱnameȱofȱaȱcharacterȱarray,ȱorȱaȱpointerȱtoȱ aȱcharacter.ȱ 8ȱTheȱastuteȱreaderȱwillȱhaveȱnoticedȱthatȱthereȱisȱnothingȱtoȱpreventȱgetsȱfromȱoverflowingȱtheȱinputȱarrayȱifȱanȱextremelyȱ longȱinputȱlineȱisȱencountered.ȱThisȱloopholeȱisȱreallyȱaȱshortcomingȱofȱgets,ȱwhichȱisȱoneȱreasonȱwhyȱfgetsȱ(describedȱinȱ chapterȱ15)ȱshouldȱbeȱusedȱinstead.ȱ 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.
1.4 Summary 21 strcpyȱisȱsimilarȱtoȱstrncpyȱexceptȱthatȱthereȱisȱnoȱspecifiedȱlimitȱtoȱtheȱȱnumberȱ ofȱ charactersȱ thatȱ areȱ copied.ȱ Itȱ takesȱ twoȱ arguments:ȱ theȱ stringȱ inȱ theȱ secondȱ argumentȱisȱcopiedȱintoȱtheȱfirst,ȱoverwritingȱanyȱstringȱthatȱtheȱfirstȱargumentȱmightȱ alreadyȱcontain,ȱstrcatȱalsoȱtakesȱtwoȱarguments,ȱbutȱthisȱfunctionȱappendsȱtheȱstringȱ inȱtheȱsecondȱargumentȱtoȱtheȱendȱofȱtheȱstringȱalreadyȱcontainedȱinȱtheȱfirst.ȱAȱstringȱ literalȱmayȱnotȱbeȱusedȱasȱtheȱfirstȱargumentȱtoȱeitherȱofȱtheseȱlastȱtwoȱfunctions.ȱItȱisȱ theȱ programmersȱ responsibilityȱ withȱ bothȱ functionsȱ toȱ ensureȱ thatȱ theȱ destinationȱ arrayȱisȱlargeȱenoughȱtoȱholdȱtheȱresult.ȱ
Forȱsearchingȱinȱstrings,ȱthereȱisȱstrchr,ȱwhichȱtakesȱtwoȱargumentsȱȬȱtheȱfirstȱisȱ aȱstring,ȱandȱtheȱsecondȱisȱaȱcharacter.ȱItȱsearchesȱtheȱstringȱforȱtheȱfirstȱoccurrenceȱofȱ theȱ characterȱ andȱ returnsȱ aȱ pointerȱ toȱ theȱ positionȱ whereȱ itȱ wasȱ found.ȱ Ifȱ theȱ firstȱ argumentȱ doesȱ notȱ containȱ theȱ character,ȱ aȱNULLȱ pointerȱ isȱ returnedȱ instead.ȱ Theȱ strstrȱfunctionȱisȱsimilar.ȱItsȱsecondȱargumentȱisȱaȱstring,ȱandȱitȱsearchesȱforȱtheȱfirstȱ occurrenceȱofȱthisȱstringȱinȱtheȱfirstȱargument.ȱ ȱ ȱ ȱ ȱ
1.3 Compiling
ȱTheȱ wayȱ youȱ compileȱ andȱ runȱ Cȱ programsȱ dependsȱ onȱ theȱ kindȱ ofȱ systemȱ you’reȱ using.ȱToȱcompileȱaȱprogramȱstoredȱinȱtheȱfileȱtesting.cȱonȱaȱUNIXȱmachine,ȱtryȱtheseȱ commands:ȱ cc testing.c a.out ȱ OnȱPC’s,ȱyouȱneedȱtoȱknowȱwhichȱcompilerȱyouȱareȱusing.ȱForȱBorlandȱC++,ȱtryȱthisȱ commandȱinȱaȱMSȬDOSȱwindow:ȱ bcc testing.c testing ȱ ȱ ȱ ȱ
1.4 Summary
ȱ TheȱgoalȱofȱthisȱchapterȱwasȱtoȱdescribeȱenoughȱofȱCȱtoȱgiveȱyouȱanȱoverviewȱofȱtheȱ language.ȱ Withȱ thisȱ context,ȱ itȱ willȱ beȱ easierȱ toȱ understandȱ theȱ topicsȱ inȱ theȱ nextȱ chapters.ȱTheȱ sampleȱ programȱ illustratedȱ numerousȱ points.ȱ Commentsȱ beginȱ withȱ/ *ȱ andȱ endȱ withȱ */,ȱ andȱ areȱ usedȱ toȱ includeȱ descriptionsȱ inȱ theȱ program.ȱ Theȱ preprocessorȱ directiveȱ #includeȱ causesȱ theȱ contentsȱ ofȱ aȱ libraryȱ headerȱ toȱ beȱ
processedȱ byȱ theȱ compiler,ȱ andȱ theȱ#defineȱ directiveȱ allowsȱ youȱ toȱ giveȱ symbolicȱ namesȱtoȱliteralȱconstants.ȱ
Allȱ Cȱ programsȱ mustȱ haveȱ aȱ functionȱ calledȱmainȱ inȱ whichȱ executionȱ begins.ȱ Scalarȱargumentsȱtoȱfunctionsȱareȱpassedȱbyȱvalue,ȱandȱarrayȱargumentsȱhaveȱcallȱbyȱ referenceȱ semantics.ȱ Stringsȱ areȱ sequencesȱ ofȱ charactersȱ terminatedȱ withȱ aȱNULȱ byte,ȱ andȱthereȱisȱaȱlibraryȱofȱfunctionsȱtoȱmanipulateȱstringsȱinȱvariousȱways.ȱTheȱprintf functionȱ performsȱ formattedȱ output,ȱ andȱ theȱscanfȱ functionȱ isȱ usedȱ forȱ formattedȱ input;ȱ getcharȱ andȱ putcharȱ performȱ unformattedȱ characterȱ inputȱ andȱ output,ȱ respectively.ȱifȱ andȱwhileȱ statementsȱ workȱ muchȱ theȱ sameȱ inȱ Cȱ asȱ theyȱ doȱ inȱ otherȱ languages.ȱ
Havingȱseenȱhowȱtheȱsampleȱprogramȱworks,ȱyouȱmayȱnowȱwishȱtoȱtryȱwritingȱ someȱCȱprogramsȱofȱyourȱown.ȱIfȱitȱseemsȱlikeȱthereȱoughtȱtoȱbeȱmoreȱtoȱtheȱlanguage,ȱ youȱ areȱ right,ȱ thereȱ isȱ muchȱ more,ȱ butȱ thisȱ samplingȱ shouldȱ beȱ enoughȱ toȱ getȱ youȱ started.ȱ ȱ ȱ ȱ ȱ
1.5 Summary of Cautions
1. Notȱputtingȱampersandsȱinȱfrontȱofȱscalarȱargumentsȱtoȱscanfȱ(pageȱ12).ȱ 2. Usingȱprintfȱformatȱcodesȱin scanfȱ(pageȱ13).ȱ
3. Usingȱ&ȱforȱaȱlogicalȱANDȱinsteadȱofȱ&&ȱ(pageȱ14).ȱ
4. Using = toȱcompareȱforȱequalityȱinsteadȱof == (pageȱ14).ȱ ȱ
ȱ ȱ ȱ
1.6 Summary of Programming Tips
1. Usingȱ#includeȱfilesȱforȱdeclarationsȱ(pageȱ6).ȱ
2. Usingȱ#defineȱtoȱgiveȱnamesȱtoȱconstantȱvaluesȱ(pageȱ7).ȱ 3. Puttingȱfunctionȱprototypesȱinȱ#includeȱfilesȱ(pageȱ7).ȱ 4. Checkingȱsubscriptȱvaluesȱbeforeȱusingȱthemȱ(pageȱ14).ȱ 5. Nestingȱassignmentsȱinȱaȱwhileȱorȱifȱexpressionȱ(pageȱ16).ȱ 6. Howȱtoȱwriteȱaȱloopȱwithȱanȱemptyȱbodyȱ(pageȱ17).ȱ
1.8 Programming Exercises 23
1.7 Questions
1. Cȱ isȱ aȱ freeȬformȱ language,ȱ whichȱ meansȱ thatȱ thereȱ areȱ noȱ rulesȱ regardingȱ howȱ programsȱ mustȱ look10.ȱ Yetȱ theȱ sampleȱ programȱ followedȱ specificȱ spacingȱ rules.ȱ Whyȱdoȱyouȱthinkȱthisȱis?ȱ
2. Whatȱ isȱ theȱ advantageȱ ofȱ puttingȱ declarations,ȱ suchȱ asȱ functionȱ prototypes,ȱ inȱ headerȱfilesȱandȱthenȱusing #include toȱbringȱtheȱdeclarationsȱintoȱtheȱsourceȱfilesȱ whereȱtheyȱareȱneeded?ȱ
3. Whatȱisȱtheȱadvantageȱofȱusing #define toȱgiveȱnamesȱtoȱliteralȱconstants?ȱ
4. Whatȱformatȱstringȱwouldȱyouȱuseȱwithȱprintfȱinȱorderȱtoȱprintȱaȱdecimalȱinteger,ȱ aȱ string,ȱ andȱ aȱ floatingȬpointȱ value,ȱ inȱ thatȱ order?ȱ Separateȱ theȱ valuesȱ fromȱ oneȱ anotherȱwithȱaȱspace,ȱandȱendȱtheȱoutputȱwithȱaȱnewlineȱcharacter.ȱ
5. Writeȱtheȱscanfȱstatementȱneededȱtoȱreadȱtwoȱintegers,ȱcalledȱquantityȱandȱprice,ȱ followedȱbyȱaȱstring,ȱwhichȱshouldȱbeȱstoredȱinȱaȱcharacterȱarrayȱcalledȱdepartment.ȱ 6. ThereȱareȱnoȱchecksȱmadeȱonȱtheȱvalidityȱofȱanȱarrayȱsubscriptȱinȱC.ȱWhyȱdoȱyouȱ
thinkȱthisȱobviousȱsafetyȱmeasureȱwasȱomittedȱfromȱtheȱlanguage?ȱ 7. Theȱrearrangeȱprogramȱdescribedȱinȱtheȱchapterȱcontainsȱtheȱstatementȱ
ȱ
strncpy( output + output_col,
input + columns[col], nchars );
Theȱstrcpyȱ functionȱ takesȱ onlyȱ twoȱ arguments,ȱ soȱ theȱ numberȱ ofȱ charactersȱ itȱ
copiesȱisȱdeterminedȱbyȱtheȱstringȱspecifiedȱbyȱtheȱsecondȱargument.ȱWhatȱwouldȱ beȱ theȱ effectȱ ofȱ replacingȱ theȱstrncpyȱ functionȱ callȱ withȱ aȱ callȱ toȱstrcpyȱ inȱ thisȱ program?ȱ
8. Theȱrearrangeȱprogramȱcontainsȱtheȱstatementȱ while( gets( input ) != NULL ){
Whatȱmightȱgoȱwrongȱwithȱthisȱcode?ȱ ȱ ȱ ȱ ȱ ȱ ȱ
1.8 Programming Exercises
ȱ 1. TheȱȈHelloȱworld!ȈȱprogramȱisȱoftenȱtheȱfirstȱCȱprogramȱthatȱaȱstudentȱofȱCȱwrites.ȱ ItȱprintsȱHello world!ȱfollowedȱbyȱaȱnewlineȱonȱtheȱstandardȱoutput.ȱThisȱtrivialȱ programȱisȱaȱgoodȱoneȱtoȱuseȱwhenȱfiguringȱoutȱhowȱtoȱrun theȱCȱcompilerȱonȱyourȱ particularȱsystem.ȱ2. Writeȱaȱprogramȱthatȱreadsȱlinesȱfromȱtheȱstandardȱinput.ȱEachȱlineȱisȱprintedȱonȱ theȱstandardȱoutputȱprecededȱbyȱitsȱlineȱnumber.ȱTryȱtoȱwriteȱtheȱprogramȱsoȱthatȱ itȱhasȱnoȱbuiltȬinȱlimitȱonȱhowȱlongȱaȱlineȱitȱcanȱhandle.ȱ
3. Writeȱaȱprogramȱthatȱreadsȱcharactersȱfromȱtheȱstandardȱinputȱandȱwritesȱthemȱtoȱ theȱ standardȱ output.ȱ Itȱ shouldȱ alsoȱ computeȱ aȱ checksumȱ andȱ writeȱ itȱ outȱ afterȱ theȱ characters.ȱȱ
Theȱchecksumȱisȱcomputedȱinȱaȱsigned charȱvariableȱthatȱisȱinitializedȱtoȱ—1.ȱAsȱ eachȱ characterȱ isȱ readȱ fromȱ theȱ standardȱ input,ȱ itȱ isȱ addedȱ toȱ theȱ checksum.ȱ Anyȱ overflowȱ fromȱ theȱ checksumȱ variableȱ isȱ ignored.ȱ Whenȱ allȱ ofȱ theȱ charactersȱ haveȱ beenȱ written,ȱ theȱ checksumȱ isȱ thenȱ writtenȱ asȱ aȱ decimalȱ integer,ȱ whichȱ mayȱ beȱ negative.ȱBeȱsureȱtoȱfollowȱtheȱchecksumȱwithȱaȱnewȬline.ȱ
Onȱ computersȱ thatȱ useȱ ASCII,ȱ runningȱ yourȱ programȱ onȱ aȱ fileȱ containingȱ theȱ wordsȱȈHelloȱworld!Ȉȱfollowedȱbyȱaȱnewlineȱshouldȱproduceȱtheȱfollowingȱoutput:ȱ
Hello world! 102
4. Writeȱ aȱ programȱ thatȱ readsȱ inputȱ linesȱ oneȱ byȱ oneȱ untilȱ endȱ ofȱ fileȱ isȱ reached,ȱ determinesȱtheȱlengthȱofȱeachȱinputȱline,ȱandȱthenȱprintsȱoutȱonlyȱtheȱlongestȱlineȱ thatȱ wasȱ found.ȱ Toȱ simplifyȱ matters,ȱ youȱ mayȱ assumeȱ thatȱ noȱ inputȱ lineȱ willȱ beȱ longerȱthanȱ1000ȱcharacters.ȱ
5. Theȱstatementȱ
if( columns[col] >= len … ) break; inȱtheȱrearrangeȱprogramȱstopsȱcopyingȱrangesȱofȱcharactersȱasȱsoonȱasȱaȱrangeȱisȱ encounteredȱthatȱisȱpastȱtheȱendȱofȱtheȱinputȱline.ȱThisȱstatementȱisȱcorrectȱonlyȱifȱ theȱrangesȱareȱenteredȱinȱincreasingȱorder,ȱwhichȱmayȱnotȱbeȱtheȱcase.ȱModifyȱtheȱ rearrangeȱfunctionȱsoȱthatȱitȱwillȱworkȱcorrectlyȱevenȱifȱtheȱrangesȱareȱnotȱenteredȱ inȱorder.ȱ
6. Modifyȱ theȱ rearrangeȱ programȱ toȱ removeȱ theȱ restrictionȱ thatȱ anȱ evenȱ numberȱ ofȱ columnȱvaluesȱmustȱbeȱreadȱinitially.ȱIfȱanȱoddȱnumberȱofȱvaluesȱareȱread,ȱtheȱlastȱ valuedȱindicatesȱtheȱstartȱofȱtheȱfinalȱrangeȱofȱcharacters.ȱCharactersȱfromȱhereȱtoȱ theȱendȱofȱtheȱinputȱstringȱareȱcopiedȱtoȱtheȱoutputȱstring.ȱ ȱ ȱ ȱ
2
Basic Concepts
Thereȱisȱnoȱdoubtȱthatȱlearningȱtheȱfundamentalsȱofȱaȱprogrammingȱlanguageȱisȱnotȱasȱ muchȱ funȱ asȱ writingȱ programs.ȱ However,ȱ notȱ knowingȱ theȱ fundamentalsȱ makesȱ writingȱprogramsȱaȱlotȱlessȱfun.ȱ ȱ ȱ ȱ
2.1 Environments
ȱ Inȱanyȱ particularȱimplementationȱofȱANSIȱC,ȱthereȱareȱtwoȱdistinctȱenvironmentsȱthatȱ areȱ ofȱ interest:ȱ theȱ translationȱ environment,ȱ inȱ whichȱ sourceȱ codeȱ isȱ convertedȱ inȱ toȱ executableȱ machineȱ instructions;ȱ andȱ theȱ executionȱ environment,ȱ inȱ whichȱ theȱ codeȱ actuallyȱruns.ȱTheȱStandardȱmakesȱitȱclearȱthatȱtheseȱenvironmentsȱneedȱnotȱbeȱonȱtheȱ sameȱ machine.ȱ Forȱ example,ȱ crossȬcompilersȱ runȱ onȱ oneȱ machineȱ butȱ produceȱ executableȱ codeȱ thatȱ willȱ beȱ runȱ onȱ aȱ differentȱ typeȱ ofȱ machine.ȱ Norȱ isȱ anȱ operatingȱ systemȱ aȱ requirement:ȱ theȱ Standardȱ alsoȱ discussesȱ freestandingȱ environmentsȱ inȱ whichȱ thereȱ isȱ noȱ operatingȱ system.ȱ Youȱ mightȱ encounterȱ thisȱ typeȱ ofȱ environmentȱ inȱ anȱ embeddedȱsystemȱsuchȱasȱtheȱcontrollerȱforȱaȱmicrowaveȱoven.ȱȱ ȱ ȱ
2.1.1 Translation
Theȱ translationȱ phaseȱ consistsȱ ofȱ severalȱ steps.ȱ First,ȱ eachȱ ofȱ theȱ (potentiallyȱ many)ȱ sourceȱtilesȱthatȱmakeȱupȱaȱprogramȱareȱindividuallyȱconvertedȱtoȱobjectȱcodeȱviaȱtheȱ compilationȱ process.ȱ Then,ȱ theȱ variousȱ objectȱ filesȱ areȱ tiedȱ togetherȱ byȱ theȱ linkerȱ toȱ formȱ aȱ single,ȱ completeȱ executableȱ program.ȱ Theȱ linkerȱ alsoȱ bringsȱ inȱ anyȱ functionsȱ fromȱ theȱ standardȱ Cȱ librariesȱ thatȱ wereȱ usedȱ inȱ theȱ program,ȱ andȱ itȱ canȱ alsoȱ searchȱ personalȱprogramȱlibrariesȱasȱwell.ȱFigureȱ2.lȱillustratesȱthisȱprocess.ȱ
Source code
Source code
Libraries
Source code
Compiler
Compiler
Compiler
Linker
Object code
Object code
Object code
Executable
ȱ ȱ Figureȱ2.1ȱTheȱcompilationȱprocessȱ ȱ ȱ Theȱcompilationȱprocessȱitselfȱconsistsȱofȱseveralȱphases,ȱwithȱtheȱfirstȱbeingȱtheȱpreprocessor.ȱ Thisȱ phaseȱ performsȱ textualȱ manipulationsȱ onȱ theȱ sourceȱ code,ȱ forȱ
example,ȱsubstitutingȱtheȱtextȱofȱidentifiersȱthatȱhaveȱbeenȱ#define’dȱandȱreadingȱtheȱ textȱofȱtilesȱthatȱwereȱ#includeȇd.ȱ
Theȱsourceȱcodeȱisȱthenȱparsedȱtoȱdetermineȱtheȱmeaningsȱofȱitsȱstatements.ȱThisȱ secondȱstageȱisȱwhereȱmostȱerrorȱandȱwarningȱmessagesȱareȱproduced.ȱObjectȱcodeȱisȱ thenȱ generated.ȱ Objectȱ codeȱ isȱ aȱ preliminaryȱ formȱ ofȱ theȱ machineȱ instructionsȱ thatȱ implementȱ theȱ statementsȱ ofȱ theȱ programsȱ calledȱ forȱ byȱ aȱ commandȬlineȱ option,ȱ anȱ
optimizerȱprocessesȱtheȱobjectȱcodeȱinȱorderȱtoȱmakeȱitȱmoreȱefficient.ȱThisȱoptimizationȱ
takesȱextraȱtime,ȱsoȱitȱisȱusuallyȱnotȱdoneȱuntilȱtheȱprogramȱhasȱbeenȱdebuggedȱandȱisȱ readyȱtoȱgoȱintoȱproduction.ȱWhetherȱtheȱobjectȱcodeȱisȱproducedȱdirectlyȱorȱisȱinȱtheȱ formȱ ofȱ assemblyȱ languageȱ statementsȱ thatȱ mustȱ thenȱ beȱ assembledȱ inȱ aȱ separateȱ phaseȱtoȱformȱtheȱobjectȱfileȱisȱnotȱimportantȱtoȱus.ȱ ȱ ȱ ȱ
Filename Conventions
ȱAlthoughȱ theȱ Standardȱ doesȱ notȱ haveȱ anyȱ rulesȱ governingȱ theȱ namesȱ usedȱ forȱ tiles,ȱ mostȱenvironmentsȱhaveȱfilenameȱconventionsȱthatȱyouȱmustȱfollow.ȱCȱsourceȱcodeȱisȱ usuallyȱputȱinȱfilesȱwhoseȱnamesȱendȱwithȱtheȱ.cȱextension.ȱFilesȱthatȱareȱ#includeȇdȱ intoȱotherȱCȱsourceȱcodeȱareȱcalledȱheaderȱfilesȱandȱusuallyȱhaveȱnamesȱendingȱinȱ.h.ȱ
Differentȱ environmentsȱ mayȱ haveȱ differentȱ conventionsȱ regardingȱ objectȱ fileȱ names.ȱ Forȱ example,ȱ theyȱ endȱ withȱ.oȱ onȱ UNIXȱ systemsȱ butȱ withȱ.objȱ onȱ MSȬDOSȱ systems.ȱ
2.1 Environments 27
Compiling and Linking
ȱ
Theȱ specificȱ commandsȱ usedȱ toȱcompileȱ andȱ linkȱ Cȱ programsȱ varyȱ fromȱ system,ȱ butȱ manyȱ workȱ theȱ sameȱ asȱ theȱ twoȱ systemsȱ describedȱ here.ȱ Theȱ Cȱ compilerȱ onȱ mostȱ UNIXȱsystemsȱisȱcalledȱcc,ȱandȱitȱcanȱbeȱinvokedȱinȱaȱvarietyȱofȱways.ȱ ȱ ȱ ȱ 1. ToȱcompileȱandȱlinkȱaȱCȱprogramȱthatȱisȱcontainedȱentirelyȱinȱoneȱsourceȱfile:ȱ cc program.c
Thisȱcommandȱproducesȱanȱexecutableȱprogramȱcalled a.out.ȱAnȱobjectȱfileȱcalledȱ
program.oȱisȱproduced,ȱbutȱitȱisȱdeletedȱafterȱtheȱlinkingȱisȱcomplete.ȱ
ȱ
2. ToȱcompileȱandȱlinkȱseveralȱCȱsourceȱfiles:ȱ cc main.c sort.c lookup.c
Theȱ objectȱ filesȱ areȱ notȱ deletedȱ whenȱ moreȱ thanȱ oneȱ sourceȱ fileȱ isȱ compiled.ȱ Thisȱ factȱ allowsȱ youȱ toȱ recompileȱ onlyȱ theȱ file(s)ȱ thatȱ changedȱ afterȱ makingȱ modifications,ȱasȱshownȱinȱtheȱnextȱcommand.ȱ
ȱ
3. ToȱcompileȱoneȱCȱsourceȱfileȱandȱlinkȱitȱwhitȱexistingȱobjectȱfiles:ȱ cc main.o lookup.o sort.c
4. Toȱ compileȱ aȱ singleȱ Cȱ sourceȱ fileȱ andȱ produceȱ anȱ objectȱ fileȱ (inȱ thisȱ case,ȱ calledȱ program.o)ȱforȱlaterȱlinking:ȱ
cc –c program.c
5. ToȱcompileȱseveralȱCȱsourceȱfilesȱandȱproduceȱanȱobjectȱfileȱforȱeach:ȱ cc –c main.c sort.c lookup.c
6. Toȱlinkȱseveralȱobjectȱfiles:ȱ cc main.o sort.o lookup.o ȱ
ȱ ȱ
Theȱ –o name optionȱ mayȱ beȱ addedȱ toȱ anyȱ ofȱ theȱ commandsȱ aboveȱ thatȱ produceȱ anȱ executableȱprogram;ȱitȱcausesȱtheȱlinkerȱtoȱstoreȱtheȱexecutableȱprogramȱinȱaȱfileȱcalledȱ
name ratherȱthanȱa.out.ȱByȱdefault,ȱtheȱlinkerȱsearchesȱtheȱstandardȱCȱlibrary.ȱTheȱȱȱȱȬ
lnameȱ flagȱ tellsȱ theȱ linkerȱ toȱ alsoȱ searchȱ theȱ libraryȱ calledȱname;ȱ thisȱ optionȱ shouldȱ appearȱlastȱonȱtheȱcommandȱline.ȱThereȱareȱotherȱoptionsȱasȱwell;ȱconsultȱyourȱsystemȇȱ documentation.ȱ
Borlandȱ C/C++ȱ 5.0ȱ forȱ MSȬDOS/Windowsȱ hasȱ twoȱ interfacesȱ thatȱ youȱ canȱ use.ȱ Theȱ Windowsȱ Integratedȱ Developmentȱ Environmentȱ isȱ aȱ completeȱ selfȬcontainedȱ programmingȱ toolȱ thatȱ containsȱ aȱ sourceȬcodeȱ editor,ȱ debuggers,ȱ andȱ compilers.ȱ Itsȱ useȱ isȱ beyondȱ theȱ scopeȱ ofȱ thisȱ book.ȱ Theȱ MSȬDOSȱ commandȱ lineȱ interface,ȱ though,ȱ worksȱmuchȱtheȱsameȱasȱtheȱUNIXȱcompilers,ȱwithȱtheȱfollowingȱexceptions:ȱ ȱ 1. itsȱnameȱisȱbcc;ȱ ȱ 2. theȱobjectȱfilesȱareȱnamedȱfile.obj;ȱ ȱ
3. theȱ compilerȱ doesȱ notȱ deleteȱ theȱ objectȱ fileȱ whenȱ onlyȱ aȱ singleȱ sourceȱ fileȱ isȱ compiledȱandȱlinked;ȱandȱ
ȱ
4. byȱdefault,ȱtheȱexecutableȱfileȱnamedȱafterȱtheȱfirstȱsourceȱorȱobjectȱfileȱnamedȱonȱ theȱ commandȱ line,ȱ thoughȱ theȱ–enameȱ optionȱ mayȱ beȱ usedȱ toȱ putȱ theȱ executableȱ programȱinȱname.exe.ȱ ȱ ȱ ȱ ȱ
2.1.2 Execution
ȱ Theȱexecutionȱofȱaȱprogramȱalsoȱgoesȱthroughȱseveralȱphases.ȱFirst,ȱtheȱprogramȱmustȱ beȱloadedȱintoȱmemory.ȱInȱhostedȱenvironmentsȱ(thoseȱwithȱanȱoperatingȱsystem),ȱthisȱ taskȱisȱhandledȱbyȱtheȱoperatingȱsystem.ȱItȱisȱatȱthisȱpointȱthatȱpreȬinitializedȱvariablesȱ thatȱarcȱnotȱstoredȱonȱtheȱstackȱareȱgivenȱtheirȱinitialȱvalues.ȱProgramȱloadingȱmustȱbeȱ arrangedȱ manuallyȱ inȱ freestandingȱ environments,ȱ perhapsȱ byȱ placingȱ theȱ executableȱ codeȱinȱreadȬonlyȬmemoryȱ(ROM).ȱȱExecutionȱofȱtheȱprogramȱnowȱbegins.ȱInȱhostedȱenvironments,ȱaȱsmallȱstartupȱ routineȱisȱusuallyȱlinkedȱwithȱtheȱprogram.ȱItȱperformsȱvariousȱhousekeepingȱchores,ȱ suchȱasȱgatheringȱtheȱcommandȱlineȱargumentsȱsoȱthatȱtheȱprogramȱcanȱaccessȱthem.ȱ Theȱmainȱfunctionȱisȱthanȱcalled.ȱ
Yourȱ codeȱ isȱ nowȱ executed.ȱ Onȱ mostȱ machines,ȱ yourȱ programȱ willȱ useȱ aȱ runtimeȱ stack,ȱ whereȱ variablesȱ localȱ toȱ functionsȱ andȱ functionȱ returnȱ addressesȱ areȱ stored.ȱ Theȱ programȱ canȱ alsoȱ useȱ staticȱ memory;ȱ variablesȱ storedȱ inȱ staticȱ memoryȱ retainȱtheirȱvaluesȱthroughoutȱtheȱprogram’sȱexecution.ȱ
Theȱfinalȱphaseȱisȱtheȱterminationȱofȱtheȱprogram,ȱwhichȱcanȱresultȱfromȱseveralȱ differentȱ causes.ȱ ȈNormalȈȱ terminationȱ isȱ whenȱ theȱ mainȱ functionȱ returns.11ȱ Someȱ executionȱ environmentsȱ allowȱ theȱ programȱ toȱ returnȱ aȱ codeȱ thatȱ indicatesȱ whyȱ theȱ programȱ stoppedȱ executing.ȱ Inȱ hostedȱ environments,ȱ theȱ startupȱ routineȱ receivesȱ
2.2 Lexical Rules 29 ȱ controlȱagainȱandȱmayȱperformȱvariousȱhousekeepingȱtasks,ȱsuchȱasȱclosingȱanyȱfilesȱ thatȱtheȱprogramȱmayȱhaveȱusedȱbutȱdidȱnotȱexplicitlyȱclose.ȱTheȱprogramȱmightȱalsoȱ haveȱbeenȱinterrupted,ȱperhapsȱdueȱtoȱtheȱuserȱpressingȱtheȱbreakȱkeyȱorȱhangingȱupȱaȱ telephoneȱconnection,ȱorȱitȱmightȱhaveȱinterruptedȱitselfȱdueȱtoȱanȱerrorȱthatȱoccurredȱ duringȱexecution.ȱ ȱ ȱ ȱ
2.2 Lexical Rules
ȱTheȱ lexicalȱ rules,ȱ likeȱ spellingȱ rulesȱ inȱ English,ȱ governȱ howȱ youȱ formȱ theȱ individualȱ pieces,ȱcalledȱtokens,ȱofȱaȱsourceȱprogram.ȱ AnȱANSIȱCȱprogramȱconsistsȱofȱdeclarationsȱandȱfunctions.ȱTheȱfunctionsȱdefineȱ theȱworkȱtoȱbeȱperformed,ȱwhereasȱtheȱdeclarationsȱdescribeȱtheȱfunctionsȱand/orȱtheȱ kindȱofȱdataȱ(andȱsometimesȱtheȱdataȱvaluesȱthemselves)ȱonȱwhichȱtheȱfunctionsȱwillȱ operate.ȱCommentsȱmayȱbeȱinterspersedȱthroughoutȱtheȱsourceȱcode.ȱ ȱ ȱ ȱ
2.2.1 Characters
ȱTheȱ Standardȱ doesȱ notȱ requireȱ thatȱ anyȱ specificȱ characterȱ setȱ beȱ usedȱ inȱ aȱ Cȱ environment,ȱbutȱitȱdoesȱspecifyȱthatȱtheȱcharacterȱsetȱmustȱhaveȱtheȱEnglishȱalphabetȱ inȱ bothȱ upperȱ andȱ lowercase,ȱ theȱ digitsȱ 0ȱ throughȱ 9,ȱ andȱ theȱ followingȱ specialȱ characters.ȱ
ȱ
! " # % ' ( ) * + , - . / : ; < > = ? [ ] \ ^ _ { } | ~
Theȱ newlineȱ characterȱ isȱ whatȱ marksȱ theȱ endȱ ofȱ eachȱ lineȱ ofȱ sourceȱ codeȱ and,ȱ whenȱ characterȱ inputȱ isȱ readȱ byȱ theȱ executingȱ program,ȱ theȱ endȱ ofȱ eachȱ lineȱ ofȱ input.ȱ Ifȱ neededȱbyȱtheȱruntimeȱenvironment,ȱtheȱȈnewlineȈȱcanȱbeȱaȱsequenceȱofȱcharacters,ȱbutȱ theyȱareȱallȱtreatedȱasȱifȱtheyȱwereȱaȱsingleȱcharacter.ȱTheȱspace,ȱtab,ȱverticalȱtab,ȱandȱ formȱ feedȱ charactersȱ areȱ alsoȱ required.ȱ Theseȱ charactersȱ andȱ theȱ newlineȱ areȱ oftenȱ referredȱ toȱ collectivelyȱ asȱ whiteȱ spaceȱ character,ȱ becauseȱ theyȱ causeȱ spaceȱ toȱ appearȱ ratherȱthanȱmakingȱmarksȱonȱtheȱpageȱwhenȱtheyȱareȱprinted.ȱ
TheȱStandardȱdefinesȱseveralȱtrigraphsȱ–ȱaȱtrigraphȱisȱaȱsequenceȱofȱcharactersȱ thatȱrepresentsȱanotherȱcharacter.ȱTrigraphsȱareȱprovidedȱsoȱthatȱCȱenvironmentsȱcanȱ beȱimplementedȱwithȱcharacterȱsetsȱthatȱlackȱsomeȱofȱtheȱrequiredȱcharacters.ȱHereȱareȱ theȱtrigraphsȱandȱtheȱcharactersȱthatȱtheyȱrepresent.ȱ
??( [ ??< { ??= #
??) ] ??> } ??/ \
??! | ??' ^ ??- ~
ȱ
Thereȱ isȱ noȱ specialȱ significanceȱ toȱ aȱ pairȱ ofȱ questionȱ marksȱ followedȱ byȱ anyȱ otherȱ character.ȱ
ȱ ȱ
CAUTION! Althoughȱ trigraphsȱ areȱ vitalȱ inȱ aȱ fewȱ environments,ȱ theyȱ areȱ aȱ minorȱ nuisanceȱ forȱ nearlyȱ everyoneȱ else.ȱ Theȱ sequenceȱ??ȱ wasȱ chosenȱ toȱ beginȱ eachȱ trigrahpȱ becauseȱ itȱ doesȱ notȱ oftenȱ occurȱ naturally,ȱ butȱ thereinȱ liesȱ theȱ danger.ȱ Youȱ neverȱ thinkȱ aboutȱ trigraphsȱbecauseȱtheyȱareȱusuallyȱnotȱaȱproblem,ȱsoȱwhenȱoneȱisȱwrittenȱaccidentally,ȱ asȱinȱ
ȱ printf( "Delete file (are you really sure??): " );
theȱresultingȱ]ȱinȱtheȱoutputȱisȱsureȱtoȱsurpriseȱyou.ȱ
ThereȱareȱaȱfewȱcontextsȱinȱwritingȱCȱsourceȱcodeȱwhereȱyouȱwouldȱlikeȱtoȱuseȱaȱ particularȱ characterȱ butȱ cannotȱ becauseȱ thatȱ characterȱ hasȱ aȱ specialȱ meaningȱ inȱ thatȱ context.ȱForȱexample,ȱtheȱquotationȱmarkȱ"ȱisȱusedȱtoȱdelimitȱstringȱliterals.ȱHowȱdoesȱ oneȱ includeȱ aȱ quotationȱ markȱ withinȱ aȱ stringȱ literal?ȱ K&Rȱ Cȱ definedȱ severalȱ escapeȱ
sequencesȱorȱcharacterȱescapesȱtoȱovercomeȱthisȱdifficulty,ȱandȱANSIȱCȱhasȱaddedȱaȱfewȱ
newȱonesȱtoȱtheȱlist.ȱEscapeȱsequencesȱconsistȱofȱaȱbackslashȱfollowedȱbyȱoneȱorȱmoreȱ otherȱ characters.ȱ Eachȱ ofȱ theȱ escapeȱ sequencesȱ inȱ theȱ listȱ belowȱ representsȱ theȱ characterȱthatȱfollowsȱtheȱbackslashȱbutȱwithoutȱtheȱspecialȱmeaningȱusuallyȱattachedȱ toȱtheȱcharacter.ȱ ȱ ȱ \? Usedȱwhenȱwritingȱ multipleȱquestionȱmarksȱtoȱpreventȱthemȱfromȱbeingȱ interpretedȱasȱtrigraphs.ȱ \* Usedȱtoȱgetȱquotationȱmarksȱinsideȱofȱstringȱliterals.ȱ \' Usedȱtoȱwriteȱaȱcharacterȱliteralȱforȱtheȱcharacterȱ'.ȱ
\\ Usedȱ whenȱ aȱ backslashȱ isȱ neededȱ toȱ preventȱ itsȱ beingȱ interpretedȱ asȱ aȱ characterȱescape.ȱ
ȱ
Thereȱareȱmanyȱcharactersȱthatȱareȱnotȱusedȱtoȱexpressȱsourceȱcodeȱbutȱareȱveryȱ usefulȱ inȱ formattingȱ programȱ outputȱ orȱ manipulatingȱ aȱ terminalȱ displayȱ screen.ȱ Characterȱescapesȱareȱalsoȱprovidedȱtoȱsimplifyȱtheirȱinclusionȱinȱyourȱprogram.ȱTheseȱ characterȱescapesȱwereȱchosenȱforȱtheirȱmnemonicȱvalue.ȱ ȱ ȱ Theȱcharacterȱescapesȱmarkedȱwithȱ†ȱareȱnewȱtoȱANSIȱCȱandȱareȱnotȱimplementedȱinȱ K&RȱC.ȱ K&R C
2.2 Lexical Rules 31 ȱ
\a † Alertȱ character.ȱ Thisȱ ringsȱ theȱ terminalȱ bellȱ orȱ producesȱ someȱ otherȱ audibleȱorȱvisualȱsignal.ȱ \b Backspaceȱcharacter.ȱ \f Formfeedȱcharacter.ȱ \n Newlineȱcharacter.ȱ \r Carriageȱreturnȱcharacter.ȱ \t Horizontalȱtabȱcharacter.ȱ \v †Verticalȱtabȱcharacter.ȱ \ddd dddȱrepresentsȱfromȱoneȱtoȱthreeȱoctalȱdigits.ȱThisȱescapeȱrepresentsȱtheȱ characterȱwhoseȱrepresentationȱhasȱtheȱgivenȱoctalȱvalue.ȱ \xddd †Likeȱtheȱabove,ȱexceptȱthatȱtheȱvalueȱisȱspecifiedȱinȱhexadecimal.ȱ ȱ
Noteȱ thatȱ anyȱ numberȱ ofȱ hexadecimalȱ digitsȱ mayȱ beȱ includedȱ inȱ aȱ \xdddȱ sequence,ȱbutȱtheȱresultȱisȱundefinedȱifȱtheȱresultingȱvaluedȱisȱlargerȱthanȱwhatȱwillȱfitȱ inȱaȱcharacter.ȱ ȱ ȱ ȱ
2.2.2 Comments
ȱCȱcommentsȱbeginȱwithȱtheȱcharactersȱ/*,ȱendȱwithȱtheȱcharactersȱ*/,ȱandȱmayȱcontainȱ anythingȱ exceptȱ*/ȱ inȱ between.ȱ Whereasȱ commentsȱ mayȱ spanȱ multipleȱ linesȱ inȱ theȱ sourceȱ code,ȱ theyȱ mayȱ notȱ beȱ nestedȱ withinȱ oneȱ another.ȱ Noteȱ thatȱ theseȱ characterȱ sequencesȱdoȱnotȱbeginȱorȱendȱcommentsȱwhenȱtheyȱappearȱinȱstringȱliterals.ȱ
Eachȱ commentȱ isȱ strippedȱ fromȱ theȱ sourceȱ codeȱ byȱ theȱ preprocessorȱ andȱ replacedȱ byȱ aȱ singleȱ space.ȱ Commentsȱ mayȱ thereforeȱ appearȱ anywhereȱ thatȱ whiteȱ spaceȱcharactersȱmayȱappear.ȱ
ȱ
CAUTION! A.ȱcommentȱbeginsȱwhereȱitȱbeginsȱandȱendsȱwhereȱitȱends,ȱandȱitȱincludesȱeverythingȱ onȱ allȱ theȱ linesȱ inȱ between.ȱ Thisȱ statementȱ mayȱ seemȱ obvious,ȱ butȱ itȱ wasnȇtȱ toȱ theȱ studentȱwhoȱwroteȱthisȱinnocentȱlookingȱfragmentȱofȱcode.ȱ Canȱyouȱseeȱwhyȱonlyȱtheȱfirstȱvariableȱisȱinitialized?ȱ ȱ x1 = 0; /*********************** x2 = 0; ** Initialize the ** x3 = 0; ** counter variables. ** x4 = 0 ***********************/ ȱ
CAUTION! Takeȱcareȱtoȱterminateȱcommentsȱwithȱ*/ȱratherȱthanȱ*?.ȱTheȱlatterȱcanȱoccurȱifȱyouȱareȱ typingȱrapidlyȱorȱholdȱtheȱshiftȱkeyȱdownȱtooȱlong.ȱThisȱmistakeȱlooksȱobviousȱwhenȱ pointedȱout,ȱbutȱitȱisȱdeceptivelyȱhardȱtoȱfindȱinȱrealȱprograms.ȱ
2.2.3 Free Form Source Code
Cȱisȱaȱfreeȱformȱlanguage,ȱmeaningȱthatȱthereȱareȱnoȱrulesȱgoverningȱwhereȱstatementsȱ canȱbeȱwritten,ȱhowȱmanyȱstatementsȱmayȱappearȱonȱaȱline,ȱwhereȱspacesȱshouldȱbeȱ put,ȱ orȱ howȱ manyȱ spacesȱ canȱ occur.12ȱ Theȱ onlyȱ ruleȱ isȱ thatȱ oneȱ orȱ moreȱ whiteȱ spaceȱ charactersȱ(orȱaȱcomment)ȱmustȱappearȱbetweenȱtokensȱthatȱwouldȱbeȱinterpretedȱasȱaȱ singleȱlongȱtokenȱifȱtheyȱwereȱadjacent.ȱThus,ȱtheȱfollowingȱstatementsȱareȱequivalent:ȱ ȱ y=x+1; y = x + 1 ; y = x + 1; Ofȱtheȱnextȱgroupȱofȱstatements,ȱtheȱfirstȱthreeȱareȱequivalent,ȱbutȱtheȱlastȱisȱillegal.ȱ ȱ int x; int x; int/*comment*/x; intx; ȱ Thisȱfreedomȱisȱaȱmixedȱblessing;ȱyouȱwillȱhearȱsomeȱsoapboxȱphilosophyȱaboutȱthisȱ issueȱshortly.ȱ ȱ ȱ ȱ
2.2.4 Identifiers
ȱIdentifiersȱ areȱ theȱ namesȱ usedȱ forȱ variables,ȱ functions,ȱ types,ȱ andȱ soȱ forth.ȱ Theyȱ areȱ
composedȱ ofȱ upperȱ andȱ lowercaseȱ letters,ȱ digits,ȱ andȱ theȱ underscoreȱ character,ȱ butȱ theyȱmayȱnotȱbeginȱwithȱaȱdigit.ȱCȱisȱaȱcaseȱsensitiveȱlanguage,ȱsoȱabc,ȱAbc,ȱabC,ȱandȱABCȱ areȱfourȱdifferentȱidentifiers.ȱIdentifiersȱmaybeȱanyȱlength,ȱthoughȱtheȱStandardȱallowsȱ theȱcompilerȱtoȱignoreȱcharactersȱafterȱtheȱfirstȱ31.ȱItȱalsoȱallowsȱanȱimplementationȱtoȱ restrictȱidentifiersȱforȱexternalȱnamesȱ(thatȱis,ȱthoseȱthatȱtheȱlinkerȱmanipulates)ȱtoȱsixȱ monocaseȱcharacters.ȱ