Practical C Programming (Nutshell Handbook)

Practical C Programming (Nutshell Handbook)

ID:39973165

大小:2.72 MB

页数:549页

时间:2019-07-16

上传者:新起点
Practical C   Programming (Nutshell Handbook)_第页
预览图正在加载中,预计需要20秒,请耐心等待
资源描述:

《Practical C Programming (Nutshell Handbook)》由会员上传分享,免费在线阅读,更多相关内容在学术论文-天天文库

PracticalC++ProgrammingSteveOuallineO'Reilly&Associates,Inc.Beijing·Cambridge·Köln·Paris·Sebastopol·Taipei·TokyoPageivPracticalC++ProgrammingbySteveOuallineCopyright©1995O'Reilly&Associates,Inc.Allrightsreserved.PrintedintheUnitedStatesofAmerica.Editors:AdrianNyeandDaleDoughertyProductionEditor:NicoleGipsonPrintingHistory:August1995FirstEdition.January1997:Minorcorrections.NutshellHandbook,theNutshellHandbooklogo,andtheO'ReillylogoareregisteredtrademarksandTheJavaSeriesisatrademarkofO'Reilly&Associates,Inc.Manyofthedesignationsusedbymanufacturersandsellerstodistinguishtheirproductsareclaimedastrademarks.Wherethosedesignationsappearinthisbook,andO'Reilly&Associates,Inc.wasawareofatrademarkclaim,thedesignationshavebeenprintedincapsorinitialcaps.Whileeveryprecautionhasbeentakeninthepreparationofthisbook,thepublisherassumesnoresponsibilityforerrorsoromissions,orfordamagesresultingfromtheuseoftheinformationcontainedherein.Thisbookisprintedonacid-freepaperwith85%recycledcontent,15%post-consumerwaste.O'Reilly&Associatesiscommittedtousingpaperwiththehighestrecycledcontentavailableconsistentwithhighquality.ISBN.1-56592-139-9[12/98]Pagev TableofContentsPrefacexvI:TheBasics11:WhatIsC++?33ABriefHistoryofC++3C++Organization4HowtoLearnC++62:TheBasicsofProgramWriting9ProgramsfromConceptiontoExecution12CreatingaRealProgram13CreatingaProgramUsingaCommand-LineCompiler13CreatingaProgramUsinganIntegratedDevelopmentEnvironment16GettingHelpinUNIX32GettingHelpinanIntegratedDevelopmentEnvironment33ProgrammingExercises333:Style35Comments36C++Code441NamingStyle42CodingReligion43IndentationandCodeFormat43PageviClarity44 44Simplicity45ConsistencyandOrganization46FurtherReading46Summary464:BasicDeclarationsandExpressions49TheElementsofaProgram49BasicProgramStructure50SimpleExpressions51ThecoutOutputClass53VariablesandStorage53VariableDeclarations54Integers55AssignmentStatements56FloatingPointNumbers57FloatingPointVersusIntegerDivide58Characters59ProgrammingExercises60AnswersChapterQuestions615:Arrays,Qualifiers,andReadingNumbers63Arrays63Strings64ReadingData67InitializingVariables69MultidimensionalArrays70TypesofIntegers72TypesofFloats74 74ConstantandReferenceDeclarations74Qualifiers76HexadecimalandOctalConstants78OperatorsforPerformingShortcuts78SideEffects79ProgrammingExercises82AnswerstoChapterQuestions82Pagevii6:DecisionandControlStatements85ifStatement85elseStatement87HowNottoUsestrcmp88LoopingStatements88whileStatement88BreakStatement91continueStatement92TheAssignmentAnywhereSideEffect92ProgrammingExercises94AnswerstoChapterQuestions957.TheProgrammingProcess97SettingUp99TheSpecification100CodeDesign101ThePrototype102TheMakefile103 103Testing105Debugging106Maintenance108Revisions108ElectronicArchaeology109MarkUptheProgram109UsetheDebugger110UsetheTextEditorasaBrowser110AddComments110ProgrammingExercises113II:SimpleProgramming1158:MoreControlStatements117forStatement117switchStatement120switch,break,andcontinue125ProgrammingExercises127AnswerstoChapterQuestions128Pagevii9:VariableScopeandFunctions129ScopeandStorageClass129Functions133SummaryofParameterTypes146StructuredProgrammingBasics146Recursion148 148ProgrammingExercises149AnswerstoChapterQuestions14910.TheC++Preprocessor151#defineStatement151ConditionalCompilation157#includeFiles159ParameterizedMacros160AdvancedFeatures162Summary163ProgrammingExercises163AnswerstoChapterQuestions16411:BitOperations167BitOperators168TheANDOperator(&)168BitwiseOR(|)171TheBitwiseExclusiveOR(^)171TheOnesComplementOperator(NOT)(-)171TheLeftandRightShiftOperators(<<,>>)172Setting,Clearing,andTestingBits173BitmappedGraphics176ProgrammingExercises181AnswerstoChapterQuestions182III:AdvancedTypesandClasses18312:AdvancedTypes185Structures185 185Unions188typedef190PageixenumType191BitFieldsorPackedStructures193ArraysofStructures195ProgrammingExercises19613:SimpleClasses197Stacks197ImprovedStack201UsingaClass203IntroductiontoConstructorsandDestructors205AutomaticallyGeneratedMemberFunctions210Shortcuts211Style212ProgrammingExercises21414:MoreonClasses217Friends217ConstantFunctions219ConstantMembers220StaticMemberVariables222StaticMemberFunctions223TheMeaningofstatic224ProgrammingExercises225 22515:SimplePointers227ConstantPointers232PointersandPrinting233PointersandArrays233SplittingStrings237PointersandStructures240Command-LineArguments241ProgrammingExercises245AnswerstoChapterQuestions245PagexIV:AdvancedProgrammingConcepts24916:FileInput/Output251C++FileI/O252ConversionRoutines256BinaryandASCIIFiles260TheEnd-of-LinePuzzle261BinaryI/O262BufferingProblems263UnbufferedI/O264DesigningFileFormats268C-StyleI/ORoutines270C-StyleConversionRoutines273C-StyleBinaryI/O276ProgrammingExercises278 278AnswerstoChapterQuestions27817:DebuggingandOptimization281Debugging281SerialDebugging289DivideandConquer290Debug-OnlyCode290DebugCommand-LineSwitch290GoingThroughtheOutput292InteractiveDebuggers292DebuggingaBinarySearch296RuntimeErrors307TheConfessionalMethodofDebugging309Optimization309ThePowerofPowersof2311HowtoOptimize314CaseStudy:InlineFunctionsVersusNormalFunctions316CaseStudy:OptimizingaColor-RenderingAlgorithm316ProgrammingExercises317AnswerstoChapterQuestions317Pagexi18:OperatorOverloading319OperatorFunctions322OperatorMemberFunctions330FullDefinitionoftheComplexClass332 332ProgrammingExercises341AnswerstoChapterQuestions34219:FloatingPoint343Floating-PointFormat343FloatingAddition/Subtraction344Multiplication345Division346OverflowandUnderflow346RoundoffError347Accuracy347MinimizingRoundoffError348DeterminingAccuracy348PrecisionandSpeed350PowerSeries351ProgrammingExercises35220:AdvancedPointers355Pointers,Structures,andClasses355deleteOperator358LinkedList359OrderedLinkedLists362Double-linkedList365Trees368PrintingaTree373TheRestoftheProgram373DataStructuresforaChessProgram377ProgrammingExercises378 378AnswerstoChapterQuestions37921:AdvancedClasses381DerivedClasses381VirtualFunctions387PagexiiVirtualClasses393FunctionHidinginDerivedClasses395ConstructorsandDestructorsinDerivedClasses396Summary398ProgrammingExercises399AnswerstoChapterQuestions399V:OtherLanguageFeatures40122:Exceptions403StackExceptions405RuntimeLibraryExceptions410ProgrammingExercises41023:ModularProgramming413Modules413PublicandPrivate414TheexternModifier414Headers416TheBodyoftheModule418AProgramtoUseInfiniteArrays418TheMakefileforMultipleFiles420UsingtheInfiniteArray424 424DividingaTaskintoModules429ModuleDivisionExample:TextEditor430CompilerConstruction431Spreadsheet432ModuleDesignGuidelines433ProgrammingExercises43424:Templates435WhatIsaTemplate?435Templates:TheHardWay435FunctionSpecialization439ClassTemplates440ClassSpecialization442ImplementationDifficulties442PagexiiiSummary445ProgrammingExercises44525:PortabilityProblems447Modularity447WordSize448Byte-OrderProblem448AlignmentProblem449NULL-PointerProblem450FilenameProblems451FileTypes452 452Summary452AnswerstoChapterQuestions45326:PuttingItAllTogether455Requirements455CodeDesign457Coding459FunctionalDescription459Testing463Revisions464AFinalWarning464ProgramFiles464ProgrammingExercises48327:FromCtoC++485Overview485K&R-StyleFunctions485struct486mallocandfree486TurningStructuresintoClasses488ssetjmpandlongjmp489Summary491ProgrammingExercise491Pagexiv28.C++'sDustierCorners493do/while493 493goto493The?:Construct495TheCommaOperator495Overloadingthe()Operator495PointerstoMembers496VampireFeatures497AnswerstoChapterQuestions49829:ProgrammingAdages499General499Design500Declarations500switchStatement500Preprocessor500Style501Compiling501TheTenCommandmentsforC++Programmers501FinalNote502AnswerstoChapterQuestions503VI:Appendixes505A:ASCIITable507B:Ranges511C:OperatorPrecedenceRules513D:ComputingsineUsingaPowerSeries515Glossary521Index543 PagexvPrefaceThisbookisdevotedtopracticalC++programming.Itteachesyounotonlythemechanicsofthelanguage,butalsostyleanddebugging.Theentirelifecycleofaprogramisdiscussed,includingconception,design,writing,debugging,release,documentation,maintenance,andrevision.Styleisemphasized.Creatingagoodprograminvolvesmorethanjusttypingcode.Itisanartinwhichwritingandprogrammingskillsblendtoformamasterpiece.Awell-writtenprogramnotonlyfunctionscorrectly,butalsoissimpleandeasytounderstand.Commentsallowprogrammerstoincludedescriptivetextintheirprograms.Clearlywritten,well-commentedprogramsarehighlyprized.Aprogramshouldbeassimpleaspossible.Avoidtheuseofclevertricks.Clevernessandcomplexitycankillprograms.Thisbookstressessimple,practicalrules.Forexample,the15operator-precedencerulesinC++canbesimplifiedto2:1.Multiplyanddividebeforeyouaddandsubtract.2.Putparenthesesaroundeverythingelse.Considertwoprograms.Onewaswrittenbyacleverprogrammer,usingallthetricks.Theprogramcontainsnocomments,butitworks.Theotherisnicelycommentedandwellstructured,butdoesn'twork.Whichprogramismoreuseful?Inthelongrun,the''broken"oneismoreusefulbecauseitcanbefixedandmaintainedeasily.Althoughthecleveroneworksnow,soonerorlateritwillhavetobemodified.Thehardestworkyouwilleverhavetodoismodifyingacleverlywrittenprogram.PagexviScopeofThisHandbookThishandbookiswrittenforpeoplewithnopreviousprogrammingexperience,forprogrammerswhoknowCandwanttoupgradetheirskillstoC++,andforthosewhoalreadyknowC++andwanttoimprovetheirprogrammingstyleandreliability.Youshouldhaveaccesstoacomputerandknowhowtousethebasicfunctionssuchasthetexteditorandfilesystem.Computerlanguagesarebestlearnedbywritinganddebuggingprograms.Sweatingoverabrokenprogramattwoo'clockinthemorningonlytofindthatyoutyped=whereyoushouldhavetyped==isaveryeffectiveteachingtool.Manyprogrammingexamplesareusedthroughoutthisbook.Mostofthemcontaindeliberateerrors.Youareencouragedtoentertheexamplesintoyourcomputerandthenrunanddebugthem.Thisprocessintroducesyoutocommonerrorsusingshortprogramssoyouwillknowhowtospotandcorrectsucherrorsin yourownlargerprograms.(Instructionsforobtainingcopiesoftheprogramspresentedinthisbookarelocatedattheendofthischapter.)SeveraldialectsofC++arepresented:·A"generic"UNIXcompilerthatshouldworkonmostUNIXsystems·TheGNUC++compiler,namedg++(availableformostUNIXsystems*)·Borland'sTurboC++compilerforMS-DOS·BorlandC++forMS-DOS/Windows·Microsoft'sVisualC++forMS-DOS/WindowsAsfarasstandardC++isconcernedthereareonlyminordifferencesamongthevariouscompilers.Thisbookclearlyindicateswherecompilerdifferencescanaffecttheprogrammer.Specificinstructionsaregivenforproducingandrunningprogramsusingeachofthesecompilers.Thebookalsogivesexamplesofusingtheprogrammingutilitymakeforautomatedprogramproduction.HowThisBookIsOrganizedYoumustcrawlbeforeyouwalk.InPartI:TheBasicsyoulearnhowtocrawl.Thesechaptersteachyouenoughtowriteverysimpleprograms.Youstartwiththemechanicsofprogrammingandprogrammingstyle.Next,youlearnhowtousevariablesandverysimpledecisionandcontrolstatements.*TheGNUg++compilercanbeobtainedbyanonymousFTPfromprep.almitedu,oryoucancontacttheFreeSoftwareFoundation,Inc,at675MassachusettsAvenue,Cambridge,MA02139,(617)876-3296.PagexviiAtthispointyouwillhavelearnedenoughtocreateverysimpleprograms;therefore,inChapter7,TheProgrammingProcess,youembarkonacompletetouroftheprogrammingprocessthatshowsyouhowrealprogramsarecreated.Chapter1,WhatIsC++?,givesyouanovervieinsthebasicprogrammingprocessandgivesyouenoughinformationtowriteaverysimpleprogram.wofC++,describesitshistoryanduses,andexplainshowthelanguageisorganized.Chapter2,TheBasicsofProgramWriting,explaChapter3,Style,discussesprogrammingstyle.HoChapter4,BasicDeclarationsandExpressions,intwtocommentaprogramiscovered,aswellashowtowriteclearandsimplecode.roducessimpleC++statements.Basicvariablesandtheassignmentstatementarecoveredindetailalongwiththearithmeticoperators:+,-,*,/,and%.Chapter5,Arrays,Qualifiers,andReadingNumbers,coversarraysandmorecomplex variables.Theshorthandoperators++,--,*=,=,+=,-=,and%=aredescribed.Chapter6,DecisionandControlStatements,explainssimpledecisionstatementsincludingif,elseandfor.Theproblemof==versus=isdiscussed.Chapter7,TheProgrammingProcess,takesyouthroughthestepsrequiredforcreatingasimpleprogram,fromspecificationthroughrelease.Structuredprogramming,fastprototyping,anddebuggingarediscussed.PartII:SimpleProgramming,describesalltheothersimplestatementsandoperatorsthatareusedinprogramming.Youalsolearnhowtoorganizethesestatementsintosimplefunctions.Chapter8,MoreControlStatements,describesadditionalcontrolstatements.Includedarewhile,break,andcontinue.Theswitchstatementisdiscussedindetail.Chapter9,VariableScopeandFunctions,introduceslocalvariables,functions,andparameters.Chapter10,TheC++Preprocessor,describestheC++preprocessor,whichgivesyougreatflexibilityincreatingcode.Italsoprovidesatremendousnumberofwaysforyoutoscrewup.Simplerulesthathelpkeepthepreprocessorfrombecomingaproblemaredescribed.Chapter11,BitOperations,discussesthelogicalC++operatorsthatworkonbits.InPartIII:AdvancedTypesandClasses,youlearnhowbasicdeclarationsandstatementscanbeusedintheconstructionofadvancedtypessuchasstructures,unions,andclasses.Youalsolearnabouttheconceptofpointers.PagexviiiChapter12,AdvancedTypes,explainsstructuresandotheradvancedtypes.Thesizeofoperatorandtheenumtypeareincluded.Chapter13,SimpleClasses,introducestheconceptofaclass.ThisisoneofthemorepowerfulfeaturesofC++.Classesallowyoutogroupdataandtheoperationsthatcanbeperformedonthatdataintooneobject.Chapter14,MoreonClasses,describesadditionaloperationsthatcanbeperformedwithclasses.Chapter15,SimplePointers,introducesC++pointervariablesandshowssomeoftheiruses.AdvancedprogrammingtechniquesareexploredinPartIV:AdvancedProgrammingConcepts.Inthissection,youexploreanumberofC++featuresthatletyoucreatecomplex,yeteasy-to-useobjectsorclasses.Chapter16,FileInput/Output,describesbothbufferedandunbufferedinput/output(I/O).ASCIIandbinaryfilesarediscussedandyouareshownhowtoconstructasimplefile.OldC-styleI/Ooperationsarealsoincluded.Chapter17,DebuggingandOptimization,describeshowtodebugaprogram,aswellashowtouseaninteractivedebugger.Youareshownnotonlyhowtodebugaprogram,butalsohowtowriteaprogramsothatitiseasytodebug.Thischapteralsodescribesmany optimizationtechniquestomakeyourprogramsrunfasterandmoreefficiently.Chapter18,OperatorOverloading,explainsthatC++allowsyoutoextendthelanguagebydefiningadditionalmeaningsforthelanguage'soperators.Inthischapter,youcreateacomplextypeandtheoperatorsthatworkonit.Chapter19.FloatingPoint,usesasimpledecimalfloating-pointformattointroducetheproblemsinherentinusingfloatingpoints,suchasroundofferrors,precisionloss,overflow,andunderflow.Chapter20,AdvancedPointers,describesadvanceduseofpointerstoconstructdynamicstructuressuchaslinkedlistsandtrees.Chapter21,AdvancedClasses,showshowtobuildcomplex,derivedclassesoutofsimple,baseones.FinallyanumberofmiscellaneousfeaturesaredescribedinV:OtherLanguageFeatures.Chapter22,Exceptions,explainshowtohandleunexpectedconditionswithinaprogram.PagexixChapter23,ModularProgramming,showshowtosplitaprogramintoseveralfilesandusemodularprogrammingtechniques.Themakeutilityisexplainedinmoredetail.Chapter24,Templates,allowsyoutodefineagenericfunctionorclassthatgeneratesafamilyoffunctions.Chapter25,PortabilityProblems,describestheproblemsthatcanoccurwhenportingaprogram(movingaprogramfromonemachinetoanother).Chapter26,PuttingItAllTogether,detailsthestepsnecessarytotakeacomplexprogramfromconceptiontocompletion.Informationhidingandmodularprogrammingtechniques,aswellasobject-orientedprogramming,arestressed.Chapter27,FromCtoC++,describeshowtoturnCcodeintoC++code,andaddressesmanyofthetrapslurkinginCcodethatbitetheC++programmer.Chapter28,C++'sDustierCorners,describesthedo/whilestatement,thecommaoperator,andthe?:operators.Chapter29,ProgrammingAdages,listsprogrammingadagesthatwillhelpyouconstructgoodC++programs.AppendixA,ASCIITable,containsalistofcharactercodesandtheirvalues.AppendixB,Ranges,liststhenumericrangesofsomeC++variabletypes.AppendixC,OperatorPrecedenceRules,liststherulesthatdeterminetheorderinwhichoperatorsareevaluated.AppendixD,ComputingsineUsingaPowerSeries,containsaprogramthatshowshowthecomputercancomputethevalueofthesinefunction. HowtoReadThisBookIfYouAlreadyKnowCC++isbuiltontheClanguage.IfyouknowC,youwillfindmuchofthematerialpresentedinChapters2through12familiar.C++doesintroduceanumberofnewfeatures,including:·AnentirelynewI/Osystem.(ThebasicsaredescribedinChapter4,BasicDeclarationsandExpressions.ThenewfilesystemisdiscussedindetailinChapter16,FileInput/Output.)·Constantandreferencevariables.(DescribedinChapter5,Arrays,Qualifiers,andReadingNumbers.)Pagexx·Functionoverloading,inlinefunctions,referenceparameters,anddefaultparameters.(ReadChapter9,VariableScopeandFunctions.)StartingwithChapter13,SimpleClasses,youwillbegintolearnentirelynewconcepts.ClassesareuniquetoC++andareoneofthemorepowerfulfeaturesofthelanguage.FontConventionsThefollowingconventionsareusedinthisbook:Italicisusedfordirectoriesandtoemphasizenewtermsandconceptswhentheyareintroduced.Italicisalsousedtohighlightcommentsinexamples.BoldisusedforCkeywords.ConstantWidthisusedforprogramsandtheelementsofaprogramandinexamplestoshowthecontentsoffilesortheoutputfromcommands.Areferenceintexttoawordoritemusedinanexampleorcodefragmentisalsoshowninconstantwidthfont.ConstantBoldisusedinexamplestoshowcommandsorothertextthatshouldbetypedliterallybytheuser.(Forexample,rmfoomeanstotype"rmfoo"exactlyasitappearsinthetextortheexample.)ConstantItalicisusedinexamplestoshowvariablesforwhichacontext-specificsubstitutionshouldbemade.(Thevariablefilename,forexample,wouldbereplacedbysomeactualfilename.)Quotesareusedtoidentifysystemmessagesorcodefragmentsinexplanatorytext.% istheUNIXCshellprompt.$istheUNIXBourneshellorKornshellprompt.#istheUNIXsuperuserprompt(eitherBourneorCshell).Weusuallyusethisforexamplesthatshouldbeexecutedonlybyroot.Pagexxi[]surroundoptionalvaluesinadescriptionofprogramsyntax.(Thebracketsthemselvesshouldneverbytyped.)...standsfortext(usuallycomputeroutput)that'sbeenomittedforclarityortosavespace.ThenotationCTRL-Xor^Xindicatesuseofcontrolcharacters.Itmeansholddownthe"control"keywhiletypingthecharacter"x".Wedenoteotherkeyssimilarly(e.g.,RETURNindicatesacarriagereturn).AllexamplesofcommandlinesarefollowedbyaRETURNunlessotherwiseindicated.ObtainingSourceCodeYoucanobtainthesourcecodefortheprogramspresentedinthisbookfromO'Reilly&AssociatesthroughtheirInternetserver.Theexampleprogramsinthisbookareavailableelectronicallyinanumberofways:byFTP,Ftpmail,BITFTP,andUUCP.Thecheapest,fastest,andeasiestwaysarelistedfirst.Ifyoureadfromthetopdown,thefirstonethatworksforyouisprobablythebest.UseFTPifyouaredirectlyontheInternet.UseFtpmailifyouarenotontheInternet,butcansendandreceiveelectronicmailtoInternetsites(thisincludesCompuServeusers).UseBITFTPifyousendelectronicmailviaBITNET.UseUUCPifnoneoftheaboveworks.FTPTouseFTP,youneedamachinewithdirectaccesstotheInternet.Asamplesessionisshown,withwhatyoushouldtypeinboldface.%ftpftp.uu.netConnectedtoftp.uu.net.220FTPserver(Version6.21TueMar1022:09:55EST1992)ready.Name(ftp.uu.net:joe):anonymous331Guestloginok,senddomainstylee-mailaddressaspassword.Password:joe@ora.com(useyourusernameandhosthere)230Guestloginok,accessrestrictionsapply.ftp>cd/published/oreilly/nutshell/practcpp250CWDcommandsuccessful.ftp>binary(Veryimportant!Youmustspecifybinarytransferforcompressedfiles)200TypesettoI.ftp>getexamples.tar.gz 200PORTcommandsuccessful.150OpeningBINARYmodedataconnectionforexamples.tar.gz.226Transfercomplete.Pagexxiiftp>quit221Goodbye.%Thefileisacompressedtararchive;extractthefilesfromthearchivebytyping:%gzcatexamples.tar.gz|tarxvf-SystemVsystemsrequirethefollowingtarcommandinstead:%gzcatexamples.tar.gz|tarxof-Ifgzcatisnotavailableonyoursystem,useseparategunzipandtarorsharcommands.%gunzipexamples.tar.gz%tarxvfexamples.tarFtpmailFtpmailisamailserveravailabletoanyonewhocansendelectronicmailtoandreceiveitfromInternetsites.ThisincludesanycompanyorserviceproviderthatallowsemailconnectionstotheInternet.Here'showyoudoit.Yousendmailtoftpmail@online.ora.com.Inthemessagebody,givetheFTPcommandsyouwanttorun.TheserverwillrunanonymousFTPforyouandmailthefilesbacktoyou.Togetacompletehelpfile,sendamessagewithnosubjectandthesingleword"help"inthebody.Thefollowingisasamplemailsessionthatshouldgetyoutheexamples.Thiscommandsendsyoualistingofthefilesintheselecteddirectoryandtherequestedexamplefiles.Thelistingisusefulifthere'salaterversionoftheexamplesyou'reinterestedin.%mailftpmaileonline.ora.comSubject:reply-tojanetvgxyz.com(Whereyouwantfilesmailed)opencd/published/oreilly/nutshell/practcppmodebinaryuuencodegetexamples.tar.gzquit.Asignatureattheendofthemessageisacceptableaslongasitappearsafter"quit."BITFTPBITFTPisamailserverforBITNETusers.Yousenditelectronicmailmessagesrequestingfiles,anditsendsyoubackthefilesbyelectronicmail.BITFTPcurrentlyPagexxiii servesonlyuserswhosenditmailfromnodesthataredirectlyonBITNET,EARN,orNetNorth.BITFTPisapublicserviceofPrincetonUniversity.Here'showitworks.TouseBITFTP,sendmailcontainingyourftpcommandstoBITFTP@PUCC.Foracompletehelpfile,sendHELPasthemessagebody.ThefollowingisthemessagebodyyousendtoBITFTP:FTPftp.uu.netNETDATAUSERanonymousPASSmyname@podunk.eduPutyourInternetemailaddresshere(notyourBITNETaddress)CD/published/oreilly/nutshell/practcppDIRBINARYGETexamples.tar.gzQUITOnceyou'vegotthedesiredfile,followthedirectionsunderFTPtoextractthefilesfromthearchive.SinceyouareprobablynotonaUNIXsystem,youmayneedtogetversionsofuudecode,uncompress,atob,andtarforyoursystem.VMS,DOS,andMacversionsareavailable.UUCPUUCPisstandardonvirtuallyallUNIXsystemsandisavailableforIBM-compatiblePCsandAppleMacintoshes.TheexamplesareavailablebyUUCPviamodemfromUUNET;UUNET'Sconnect-timechargesapply.YoucangettheexamplesfromUUNETwhetheryouhaveanaccountthereornot.IfyouoryourcompanyhasanaccountwithUUNET,youhaveasystemsomewherewithadirectUUCPconnectiontoUUNET.Findthatsystem,andtype:uucpuunet!~/published/oreilly/nutshell/practcpp/examples.tar.gzyourhost!~/yourname/ThebackslashescanbeomittedifyouusetheBourneshell(sh)insteadofcsh.Thefileshouldappearsometimelater(uptoadayormore)inthedirectory/usr/spool/uucppublicyourname.Ifyoudon'thaveanaccount,butwouldlikeonesothatyoucangetelectronicmail,contactUUNETat703-204-8000.It'sagoodideatogetthefile/published/oreilly/ls-lR.Zasashorttestfilecontainingthefilenamesandsizesofallthefilesavailable.Onceyou'vegotthedesiredfile,followthedirectionsunderFTPtoextractthefilesfromthearchive.PagexxivCommentsandQuestionsPleaseaddresscommentsandquestionsconcerningthisbooktothepublisher:O'Reilly&Associates,Inc. 101MorrisStreetSebastopol,CA954721-800-998-9938(intheU.S.orCanada)1-707-829-0515(internationalorlocal)1-707-829-0104(FAX)AcknowledgmentsThankstoPegKovarforherproofreadingandeditinghelp.SpecialthankstoDaleDoughertyforrippingapartmyfirstbookandforcingmetoputittogethercorrectly.IgreatlyappreciatethehardworkputinbyPhilStraiteandGregorySatir.Iespeciallythankallthosepeoplewhoreviewedandeditedmybook.MythanksalsogototheproductiongroupatO'Reilly&Associates—NicoleGipson,projectmanagerandproductioneditor;JohnFiles,JulietteMuellner,andJaneEllln,productionassistants;andMikeSierra,bookdesignimplementor.Finally,specialthanksgotoallthehard-workingprogrammersouttherewhosecodehastaughtmesomuch.Page1ITheBasicsPage31WhatIsC++?InThisChapter:·ABriefHistotyofC++·C++Organization·HowtoLearnC++Profanityistheonelanguagethatallprogrammersunderstand.—AnonymousTheabilitytoorganizeandprocessinformationisthekeytosuccessinthemodernage.Computersaredesignedtohandleandprocesslargeamountsofinformationquicklyandefficiently.However,theycan'tdoanythinguntilsomeonetellsthemwhattodo.That'swhereC++comesin.C++isahigh-levelprogramminglanguagethatallowsasoftwareengineertoefficientlycommunicatewithacomputer. C++isahighlyflexibleandadaptablelanguage.Sinceitscreationin1980,ithasbeenusedforawidevarietyofprogramsincludingfirmwareformicro-controllers,operatingsystems,applications,andgraphicsprogramming.C++isquicklybecomingtheprogramminglanguageofchoice.Thereisatremendousdemandforpeoplewhocantellcomputerswhattodo,andC++letsyoudosoquicklyandefficiently.ABriefHistoryofC++In1970twoprogrammers,BrianKernighanandDennisRitchie,createdanewlanguagecalledC.(ThenamecameaboutbecauseCwasprecededbytheoldprogramminglanguagetheywereusingcalledB.)Cwasdesignedwithonegoalinmind:writingoperatingsystems.Thelanguagewasextremelysimpleandflexibleandsoonwasusedformanydifferenttypesofprograms.Itquicklybecameoneofthemostpopularprogramminglanguagesintheworld.Page4Chadonemajorproblem,however.Itwasaprocedure-orientedlanguage.ThismeantthatindesigningatypicalCprogram,theprogrammerwouldstartbydescribingthedataandthenwriteprocedurestomanipulatethatdata.Programmerseventuallydiscoveredthatitmadeaprogramclearerandeasiertounderstandiftheywereabletotakeabunchofdataandgroupittogetherwiththeoperationsthatworkedonthatdata.Suchagroupingiscalledanobjectorclass.Designingprogramsbydesigningclassesisknownasobject-orienteddesign(OOD).In1980BjarneStroustrupstartedworkingonanewlanguage,called''CwithClasses."ThislanguageimprovedonCbyaddinganumberofnewfeatures,themostimportantofwhichwasclasses.Thislanguagewasimproved,augmented,andfinallybecameC++.C++owesitssuccesstothefactthatitallowstheprogrammertoorganizeandprocessinformationmoreeffectivelythanmostotherlanguages.Also,itbuildsontheworkalreadydonewiththeClanguage.Infact,mostCprogramscanbetransformedintoC++programswithlittletrouble.Theseprogramsusuallydon'tuseallthenewfeaturesofC++,buttheydowork.Inthisway,C++allowsprogrammerstobuildonanexistingbaseofCcode.C++OrganizationC++isdesignedasabridgebetweentheprogrammerandtherawcomputer.Theideaistolettheprogrammerorganizeaprograminawaythatheorshecaneasilyunderstand.Thecompilerthentranslatesthelanguageintosomethingthemachinecanuse.Computerprogramsconsistoftwomainparts:dataandinstructions.Thecomputerimposeslittleornoorganizationonthesetwoparts.Afterall,computersaredesignedtobeasgeneralaspossible.Theideaisfortheprogrammertoimposehisorherownorganizationonthecomputerandnottheotherwayaround.Thedatainacomputerisstoredasaseriesofbytes.C++organizesthosebytesintousefuldata.Datadeclarationsareusedbytheprogrammertodescribetheinformationheorsheisworkingwith.Forexample:inttotal;//Totalnumberaccounts tellsC++thatyouwanttouseasectionofthecomputer'smemorytostoreanintegernamedtotal.Youcanletthecompilerdecidewhatparticularbytesofmemorytouse;that'saminorbookkeepingdetailyoudon'tneedtoworryabout.Page5Thevariabletotalisasimplevariable.Itcanholdonlyoneintegeranddescribeonlyonetotal.Aseriesofintegerscanbeorganizedintoanarray.Again,C++willhandlethedetails,imposingthatorganizationonthecomputer'smemory.intbalance[100];//Balance(incents)forall100accountsFinally,therearemorecomplexdatatypes.Forexample,arectanglemighthaveawidth,aheight,acolor,andafillpattern.C++letsyouorganizethesefourattributesintoonegroupcalledastructure.structrectangle{intwidth;//Widthofrectangleinpixelsintheight;//Heightofrectangleinpixelscolor_typecolor;//Coloroftherectanglefill_typefill;//Fillpattern};However,dataisonlyonepartofaprogram.Youalsoneedinstructions.Asfarasthecomputerisconcerneditknowsnothingaboutthelayoutoftheinstructions.Itknowsonlywhatit'sdoingforthecurrentinstructionandwheretogetthenextinstruction.C++isahigh-levellanguage.Itletsyouwriteahigh-levelstatementsuchas:area=(base*height)/2.0;//ComputeareaoftriangleThecompilertranslatesthisstatementintoaseriesofcrypticmachineinstructions.Thissortofstatementiscalledanassignmentstatement.Itisusedtocomputeandstorethevalueofanarithmeticexpression.Youcanalsousecontrolstatementstocontroltheorderofprocessing.Statementssuchastheifandswitchstatementsenablethecomputertomakesimpledecisions.Statementscanberepeatedbyusingloopingstatementssuchaswhileandfor.Groupsofstatementscanbewrappedtoformfunctions.Thusyouonlyneedtowriteageneral-purposefunctiontodrawarectangleonceandthenyoucanreusethatfunctionwheneveryouwanttodrawanewrectangle.C++providesarichsetofstandardfunctionsthatperformcommonfunctionssuchassearching,sorting,input,andoutput.Asetofrelatedfunctionscanbegroupedtogethertoformamodule,andmodulesarelinkedtoformprograms.OneofthemajorgoalsoftheC++languageistoorganizeinstructionsintoreusablecomponents.Afterall,youcanwriteprogramsmuchfasterifyou"borrow"mostofyourcodefromsomewhereelse.Groupsofreusablemodulescanbecombinedintoalibrary.Forexample,ifyouneedasortroutine,youcanusethestandardfunctionqsortfromthelibraryandlinkitintoyourprogram. Page6Acomputerdividestheworldintodataandinstructions.Foralongtime,highlevellanguagessuchasCkeptthatdividinglineinplace.InCyoucandefinedataorwriteinstructions,butyoucan'tcombinethetwo.OneofC++'smajorinnovationsistheideaofcombiningdataandinstructionstogetherinaconstructcalledaclassorobject.Object-orientedprogrammingallowsyoutogroupdatawiththeoperationsthatcanbeperformedonthatdata.ThisconceptistakenonestepfurtherinC++byallowingyoutoderivenewclassesfromexistingones.Thislastfeatureisextremelypowerful.Itallowsyoutobuildcomplexclassesontopofsmaller,simplerones.Italsoallowsyoutodefineabasic,abstractclassandthenderivespecificclassesfromit.Forexample,anabstractclassofshapemightbeusedtodefinetheshapesrectangle,triangle,andcircle.Organizationisthekeytowritinggoodprograms.Inthisbook,youknowthatthetableofcontentsisinthefrontandtheindexisintheback,becausethat'sthewaybooksareorganized.Organizationmakesthisbookeasiertouse.TheC++languageletsyouorganizeyourprogramsusingasimpleyetpowerfulsyntax.ThisbookgoesbeyondtheC++syntaxandteachesyoustylerulesthatenableyoutocreatehighlyreadableandreliableprograms.Bycombiningapowerfulsyntaxwithagoodprogrammingstyleyoucancreatepowerfulprogramsthatperformcomplexandwonderfuloperations.HowtoLearnC++Theonlywaytolearnhowtoprogramistowriteprograms.You'lllearnalotmorebywritinganddebuggingprogramsthanyoueverwillbyreadingthisbook.Thisbookcontainsmanyprogrammingexercises,andyoushouldtrytodoasmanyofthemaspossible.Whendoingtheexerciseskeepgoodprogrammingstyleinmind.Alwayscommentyourprograms,evenifyou'redoingtheexercisesonlyforyourself.Commentinghelpsyouorganizeyourthoughts,andcommentingyourownprogramsisgoodpracticeforwhenyougointothe"realworld."Don'tletyourselfbeseducedbytheideathat,"I'monlywritingtheseprogramsformyself,soIdon'tneedtocommentthem."Firstofall,codethatlooksobvioustoyouwhenyouwriteitcanoftenbeconfusingandcrypticwhenyourevisititaweeklater.Writingcommentsalsohelpsyouorganizeyourideas.(IfyoucanwriteoutanideainEnglish,youarehalfwaytowritingitinC++.)Finally,programstendtobearoundfarlongerthanexpected.IoncewroteaprogramthatwasdesignedtoworkonlyonthecomputeratCaltech.Theprogramwashighlysystemdependent.AsIwastheonlyonewhowouldeverPage7usetheprogram,theprogramwouldprintthefollowingmessageifIgotthecommandlinewrong:?LSTUITUserisatwit AfewyearslaterIwasastudentatSyracuseUniversity.ThesecretaryattheSchoolofComputerScienceneededaprogramthatwassimilartomyCaltechlistingprogram,soIadaptedmyprogramforheruse.Unfortunately,Ihadforgottenaboutmyfunnylittleerrormessage.ImaginehowhorrifiedIwaswhenIcameintotheComputerScienceofficeandwasaccostedbythechiefsecretary.Thisladyhadsomuchpowershecouldmakethedeancringe.Shelookedatmeandsaid,"Userisatwit,huh?"Luckilyshehadasenseofhumor,orImightnotbeheretoday.Sprinkledthroughoutthisbookare"broken"programs.Spendthetimetofigureoutwhytheydon'twork.Oftentheproblemisverysubtle,suchasamisplacedsemicolonorusing=insteadof==.Theseprogramsletyoulearnhowtospotmistakesinasmallprogram.Thatwaywhenyoumakesimilarmistakesinabigprogram,andyouwillmakemistakes,youwillbetrainedtospotthem.Page92TheBasicsofProgramWritingInThisChapter:·ProgramsfromConceptiontoExecution·CreatingaRealProgram·CreatingaProgramUsingaCommand-LineCompiler·CreatingaProgramUsinganIntegratedDevelopmentEnvironment·GettingHelp·ProgrammingExercisesThefirstandmostimportantthingofall,atleastforwriterstoday,istostriplanguageclean,tolayitbaredowntothebone—ErnestHemingwayComputersareverypowerfultoolsthatcanstore,organize,andprocessatremendousamountofinformation.However,theycan'tdoanythinguntilsomeonegivesthemdetailedinstructions.Communicatingwithcomputersisnoteasy.Theyrequireinstructionsthatareexactand detailed.Wouldn'tlifebeeasierifwecouldwriteprogramsinEnglish?Thenwecouldtellthecomputer,"Addupallmychecksanddeposits,andthentellmethetotal,"andthemachinewouldbalanceourcheckbooks.ButEnglishisalousylanguagewhenyoumustwriteexactinstructions.Thelanguageisfullofambiguityandimprecision.GraceHopper,thegrandoldladyofcomputing,oncecommentedontheinstructionsshefoundonabottleofshampoo:WashRinseRepeatShetriedtofollowthedirections,butsheranoutofshampoo.(Wash-rinse-repeat.Wash-rinse-repeat.Wash-rinse-repeat....)Ofcourse,wecantrytowriteinpreciseEnglish.We'dhavetobecarefulandmakesuretospelleverythingoutandbesuretoincludeinstructionsforeverycontingency.Ifweworkedreallyhard,wecouldwritepreciseEnglishinstructions,right?Page10Asitturnsout,thereisagroupofpeoplewhospendtheirtimetryingtowritepreciseEnglish.They'recalledthegovernment,andthedocumentstheywritearecalledgovernmentregulations.Unfortunately,intheirefforttomaketheregulationsprecise,thegovernmentalsohasmadethedocumentsalmostunreadable.Ifyou'veeverreadtheinstructionbookthatcomeswithyourtaxforms,youknowwhatpreciseEnglishcanbelike.Still,evenwithalltheextraverbiagethegovernmentputsin,problemscanoccur.AfewyearsagoCaliforniapassedalawrequiringallmotorcycleriderstowearahelmet.Shortlyafterthislawwentintoeffectacopstoppedaguyfornotwearingahelmet.Themansuggestedthepoliceofficertakeacloserlookatthelaw.Thelawhadtworequirements:1)thatmotorcycleridershaveanapprovedcrashhelmetand2)thatitbefirmlystrappedon.Thecopcouldn'tgivethemotorcyclistaticketbecausethemandidhaveahelmetfirmlystrappedon—tohisknee.SoEnglish,withallitsproblems,isoutasacomputerlanguage.Now,howdowecommunicatewithacomputer?Thefirstcomputerscostmillionsofdollars,whileatthesametimeagoodprogrammercostabout$15,000ayear.Programmerswereforcedtoprograminalanguagewherealltheinstructionswerereducedtoaseriesofnumbers,calledmachinelanguage.Thislanguagecouldbedirectlyinputintothecomputer.Atypicalmachine-languageprogramlookslike:101011110011011101110110..andsoonforseveralhundredinstructionsWhereasmachines"think"innumbers,peopledon't.Toprogramtheseancientmachines,softwareengineerswouldwriteouttheirprogramsusingasimplelanguagewhereeachwordwouldstandforasingleinstruction.Thiswascalledassemblylanguagebecausethe programmershadtomanuallytranslate,orassemble,eachlineintomachinecode.Atypicalprogrammightlooklike:ProgramTranslationMOVA,4710101111ADDA,B00110111HALT01110110..andsoonforseveralhundredinstructionsThisprocessisillustratedbyFigure2-1.Translationwasadifficult,tedious,exactingtask.Onesoftwareengineerdecidedthiswasaperfectjobforacomputer,sohewroteaprogram,calledanassembler,thatwoulddothejobautomatically.Page11Figure2-1.AssemblingaprogramHeshowedhisnewcreationtohisbossandwasimmediatelychewedout:"Howdareyoueventhinkofusingsuchanexpensivemachineforamere'clerical'task?"Giventhecostofanhourofcomputertimeversusthecostofanhourofprogrammer'stime,thiswasnotanunreasonableattitude.Fortunately,astimepassedthecostofprogrammerswentupandthecostofcomputerswentdown.Soitbecamemorecost-effectivetolettheprogrammerswriteprogramsinassemblylanguageandthenuseaprogramcalledanassemblertotranslatetheprogramsintomachinelanguage.Assemblylanguageorganizedprogramsinawaythatwaseasierfortheprogrammerstounderstand.However,theprogramwasmoredifficultforthemachinetouse.Theprogramhadtobetranslatedbeforethemachinecouldexecuteit.Thiswasthestartofatrend.Programminglanguagesbecamemoreandmoreconvenientforprogrammerstouseandstartedrequiringmoreandmorecomputertimetotranslatethemintosomethingusefulforcomputers.Overtheyearsaseriesofhigh-levellanguageshasbeendevised.Theselanguagesareattemptstoletprogrammerswriteinsomethingthatiseasyforthemtounderstandandthatisalsopreciseandsimpleenoughforcomputerstounderstand.Earlyhigh-levellanguagesweredesignedtohandlespecifictypesofapplications.FORTRANwasdesignedfornumbercrunching;COBOL,forwritingbusinessreports;andPASCAL,forstudentuse.(Manyoftheselanguageshavefaroutgrowntheirinitialuses.ItisrumoredthatNicklausWirthhassaid,"IfIhadknownthatPASCALwasgoingtobesosuccessful,Iwould havebeenmorecarefulinitsdesign.")Lateron,BrianKernighanandDennisRitchiedevelopedCandBjarneStroustrupturneditintoC++.Page12ProgramsfromConceptiontoExecutionC++programsarewritteninahigh-levellanguageusingletters,numbers,andtheothersymbolsyoufindonacomputerkeyboard.Computersactuallyexecuteaverylow-levellanguagecalledmachinecode(aseriesofnumbers).So,beforeaprogramcanbeused,itmustundergoseveraltransformations.Programsstartoutasanideainaprogrammer'shead.Hewritesdownhisthoughtsinafile,calledasourcefileorsourcecode,usingatexteditor.Thisfileistransformedbythecompilerintoanobjectfile.Nextaprogramcalledthelinkertakestheobjectfile,combinesitwithpredefinedroutinesfromastandardlibrary,andproducesanexecutableprogram(asetofmachine-languageinstructions).Inthefollowingsections,you'llseehowthesevariousformsoftheprogramworktogethertoproducethefinalprogram.Figure2-2showsthestepsthatmustbetakentotransformaprogramwritteninahigh-levellanguageintoanexecutableprogram.Figure2-2Transformationofahigh-levellanguageintoaprogramWrappersFortunatelyyoudon'thavetorunthecompiler,assembler,andlinkerindividually.MostC++compilersuse"wrapper"programs,whichdeterminewhichtoolsneedtoberunandthenrunthem. Page13Someprogrammingsystemsgoevenfartherandprovidethedeveloperwithanintegrateddevelopmentenvironment(IDE).TheIDEcontainsaneditor,compiler,linker,projectmanager,debugger,andmoreinoneconvenientpackage.BothBorlandandMicrosoftprovideIDESwiththeircompilers.CreatingaRealProgramBeforeyoucanactuallystartcreatingyourownprogramsyouneedtoknowhowtousethebasicprogrammingtools.Thissectionwilltakeyoustepbystepthroughtheprocessofentering,compiling,andrunningasimpleprogram.Thissectiondescribeshowtousetwodifferenttypesofcompilers.Thefirsttypeisthestandaloneorcommand-linecompiler.Thistypeofcompilerisoperatedinabatchmodefromthecommandline.Inotherwords,youtypeacommandandthecompilerturnsyoursourcecodeintoanexecutableprogram.TheothertypeofcompileriscontainedinanIDE.MostUNIXsystemsusecommand-linecompilers.AfewIDE-typecompilersareavailableforUNIX,buttheyarerare.OntheotherhandalmostallthecompilersusedwithMS-DOSandWindowscontainanintegrateddevelopmentenvironment.Forcommand-linedie-hards,thesecompilersdocontaincommand-linecompilersaswell.CreatingaProgramUsingaCommand-LineCompilerInthissectionyou'llgothroughthestep-by-stepprocessneededtocreateaprogramusingacommand-linecompiler.InstructionisgivenforusingagenericUNIXcompiler,theFreeSoftwareFoundation'sg++compiler,Turbo-C++,BorlandC++,andMicrosoftVisualC++.However,ifyouareusingaBorlandorMicrosoftcompiler,youmightwanttoskipaheadtothesectiononusingtheIDE.Step1:CreateaPlaceforYourProgramItiseasiertomanagethingsifyoucreateaseparatedirectoryforeachprogramyouareworkingon.Inthiscaseyou'llcreateadirectorycalledhellotoholdyourhelloprogram.InUNIX,type:%mkdirhello%cdhelloPage14InMS-DOS,type:C:MKDIRHELLOC:CDHELLOStep2:CreatetheProgramAprogramstartsoutasatextfile.Example2-1showsthehelloprograminsourceform.Example2-1Sourceforthehello.ccprogram #includeintmain(){cout<<"HelloWorld ";return(0);}Useyourfavoritetexteditortoentertheprogram.InUNIXyourfileshouldbenamedhello.ccandinMS-DOS/WindowsthefileshouldbenamedHELLO.CPP.WARNINGMS-DOS/Windowsusersshouldnotuseaword-processingprogramsuchasMicrosoftWordorWordPerfecttowritetheirprograms.Word-processingprogramsaddformattingcodestothefilethatconfusethecompiler.YoumustuseatexteditorsuchastheMS-DOSEDITprogramthatiscapableofeditingASCIIfiles.Step3:RuntheCompilerThecompilerchangesthesourcefileyoujustcreatedintoanexecutableprogram.Eachcompilerhasadifferentcommandline.Thecommandsforthemostpopularcompilersarelistedbelow.UNIXCCCompiler(GenericUNIX)MostUNIX-basedcompilersfollowthesamegenericstandard.TheC++compilerisnamedCC.Tocompileourhelloprogramweneedthefollowingcommand:%CC-g-ohellohello.ccThe-goptionenablesdebugging.(Thecompileraddsextrainformationtotheprogramtomakeiteasiertodebug.)Theswitch-ohellotellsthecompilerthattheprogramistobecalledhello,andthefinalhello.ccisthenameofthesourcefile.Seeyourcompilermanualfordetailsonallthepossibleoptions.ThereareseveraldifferentC++compilersforUNIX,soyourcommandlinemaybeslightlydifferent.Page15FreeSoftwareFoundation'sg++CompilerTheFreeSoftwareFoundation,theGNUpeople,publishesanumberofhigh-qualityprograms.(Seetheglossaryentry''FreeSoftwareFoundation"forinformationonhowtogettheirsoftware.)AmongtheirofferingsisaC++compilercalledg++.Tocompileaprogramusingtheg++compiler,usethefollowingcommandline:%g++-g-Wall-ohellohello.ccTheadditionalswitch-Wallturnsonallthewarnings.Borland'sTurboC++inMS-DOS BorlandInternationalmakesalow-costMS-DOSC++compilercalledTurbo-C++.Thiscompilerisidealforlearning.ThecommandlineforTurbo-C++is:C:>tcc-ml-v-N-P-w-ehellohello.cppThe-mltellsTurbo-C++tousethelargememorymodel.(ThisPChasalargenumberofdifferentmemorymodelsthatcanbeusedwhencreatingprograms.Thisbookdiscussesnoneofthem.Insteadwetaketheattitude,"Uselargeanddon'tworryaboutituntilyoubecomeanexpertprogrammer.")The-vswitchtellsTurbo-C++toputdebugginginformationintheprogram.Warningsareturnedonby-w;stackcheckingby-N.ThecompilerwillactuallycompilebothCandC++.WeforceaC++compileusingthe-Pswitch.Finally,-ehellotellsTurbo-C++tocreateaprogramnamedhello,andhello.cppisthenameofthesourcefile.SeetheTurbo-C++referencemanualforacompletelistofoptions.BorlandC++inMS-DOSandWindowsInadditiontoTurbo-C++,BorlandInternationalalsomakesafull-featured,professionalcompilerforMS-DOS/WindowscalledBorlandC++.Itscommandlineis:C:>bcc-ml-v-N-P-w-ehellohello.cppThecommand-lineoptionsarethesameforbothTurbo-C++andBorlandC++.MicrosoftVisualC++MicrosoftVisualC++isanotherC++compilerforMS-DOS/Windows.ItisnotasrobustorfullfeaturedasitsBorlandcounterpart,butitwillcompilemostoftheprogramsinthisbook.(Version1.5failstohandletemplatesandexceptions.)Tocompile,usethefollowingcommandline:C:>cl/AL/Zi/W1hello.cppPage16The/ALoptiontellstheprogramtousethelargememorymodel.Debuggingisturnedonwiththe/Zioptionandwarningswiththe/W1option.Step4:ExecutetheProgramNow,whenyouruntheprogrambytyping,forexample:helloattheUNIXorMS-DOSprompt,themessage:HelloWorldwillappearonthescreen.CreatingaProgramUsinganIntegratedDevelopmentEnvironmentIntegrateddevelopmentenvironmentsprovideaone-stopshopwhenitcomestoprogramming. Theytakeacompiler,editor,anddebuggerandwrapthemintooneneatpackagefortheprogrammer.Sincedevelopmentenvironmentstendtochange,theparticularversionyouusemayrequireslightlydifferentkeystrokes.Step1.CreateaPlaceforYourProgramItiseasiertomanagethingsifyoucreateaseparatedirectoryforeachprogramyouareworkingon.Inthiscaseyou'llcreateadirectorycalledHELLOtoholdyourhelloprogram.InMS-DOS,type:C:MKDIRHELLOC:CDHELLOStep2:Enter,Compile,andRunYourProgramEachIDEisalittledifferent,sowe'veincludedseparateinstructionsforeachone.Turbo-C++1.StarttheTurbo-C++IDEwiththecommand:C:TC2.UsetheOptions|Compiler|CodeGenerationcommandtopulluptheCodeGenerationdialogboxasseeninFigure2-3.Changethememorymodeltolarge.3.UsetheOptions|Compiler|Entry/Exitcommandtoturnstackcheckingon,asshowninFigure2-4.Page17Figure2-3.CodeGenerationdialogbox Figure2-4.Entry/ExitCodeGenerationdialogbox4.UsetheOptions|Compiler|Messages|DisplaycommandtobringuptheCompilerMessagesdialogboxasseeninFigure2-5.SelectAlltodisplayallthewarningmessages.5.UsetheOptionsISavecommandtosavealltheoptionsyou'veusedsofar.Page18Figure2-5.CompilerMessagesdialogbox6.UsetheOpenProjectFiledialogboxtoselectaprojectfile.InthiscaseyourprojectfileiscalledHELLO.PRJ.ThescreenshouldlooklikeFigure2-6whenyou'refinished. Figure2-6OpenProjectFiledialogbox7.PresstheInsertkeytoaddafiletotheproject.ThefileyouwanttoaddisHELLO.CPPasseeninFigure2-7.Page19Figure2-7.AddtoProjectListdialogbox8.PressESCtogetoutofthe"addfile"cycle.9.Presstheup-arrowkeytogouponeline.Thelinewithhello.cppshouldnow,behighlightedasseeninFigure2-8 .Figure2-8"Hello"project10.PressReturntoeditthisfile.Page2011.Enterthefollowingcode.#includeintmain(){cout<<"HelloWorld ";return(0);}TheresultsshouldlooklikeFigure2-9.Figure2-9.Finishedproject12.UsetheRunIRuncommandtoexecutetheprogram.13.Aftertheprogramruns,controlreturnstotheIDE.Thismeansthatyoucan'tseewhatyourprogramoutput.Toseetheresultsoftheprogramyoumustswitchtotheuserscreenusing thecommandWindowIUser.PressinganykeywillreturnyoutotheIDE.Figure2-10showstheoutputoftheprogram.14.WhenyouarefinishedyoucansaveyourprogramwiththeFileISavecommand.15.ToexittheIDEusetheFileIQuitcommand.Page21Figure2-10.UserscreenBorlandC++1.CreateadirectorycalledHELLOtoholdthefilesforourhelloprogram.YoucancreateadirectoryusingtheWindows'FileManagerProgramorbytypingthefollowingcommandattheMS-DOSprompt:mkdirHELLO2.FromWindows,double-clickontheBorlandC++icontostarttheIDETheprogrambeginsexecutionanddisplaysablankworkspaceasseeninFigure2-11.3.SelecttheProjectINewProjectitemtocreateaprojectforourprogram.Fillinthe"ProjectPathandName:"blankwithc:hellohello.ide.FortheTargetTypeselectEasyWin[.exe].TheTargetModelissettoLarge.TheresultsareshowninFigure2-12.4.ClickontheAdvancedbuttontobringuptheAdvancedOptionsdialog.Clearthe.rcand.defitemsasshowninFigure2-13.5.ClickonOKtoreturntotheNewTargetdialog.6.PressAlt-F10tobringupnodesub-menushowninFigure2-14.7.SelectEditNodeAttributestobringupthedialogshowninFigure2-15.IntheStyleSheetblank,selecttheitem"DebugInfoandDiagnostics."ClickonOKtoreturntothemainwindow.Page22 Figure2-11BorlandC++initialscreenFigure2-12.NewTargetdialogboxPage23 Figure2-13AdvancedOptionsdialogboxFigure2-14.TargetOptionssub-menuPage24 Figure2-15NodeAttributesdialogbox8.GototheProjectOptionsdialogbyselectingtheOptions|ProjectOptionsitem.GodowntotheCompileritemandclickonthe"+"toexpandtheoptions.TurnontheTeststackoverflowoptionshowninFigure2-16.ClickonOKtosavetheseoptions.9.ClickonOKtoreturntothemainwindow.Pressthedownarrowtoselectthehello[.cpp]itemintheproject(seeinFigure2-17).10.PressReturntostarteditingthefilehello.cpp.Typeinthefollowingcode:#includeintmain(){cout<<"HelloWorld ";return(0);}Whenyouhavefinished,yourscreenwilllooklikeFigure2-18.11.CompileandruntheprogrambyselectingtheDebug|Runmenuitem.Theprogramwillrunanddisplay"HelloWorld"inawindow,asshowninFigure2-19.Page25 Figure2-16ProjectOptionsdialogboxFigure2-17.HelloProjectPage26 Figure2-18''HelloWorld"programFigure2-19"HelloWorld"afterexecutionPage27MicrosoftVisualC++1.CreateadirectorycalledHELLOtoholdthefilesforourhelloprogram.YoucancreateadirectoryusingtheWindowsFileManagerProgramorbytypingthefollowingcommandattheMS-DOSprompt:mkdirHELLO2.FromWindows,double-clickontheVisualC++icontostarttheIDE.AblankworkspacewillbedisplayedasshowninFigure2-20. Figure2-20MicrosoftVisualC++initialscreen3.ClickonProject|NewtobringuptheNewProjectdialogshowninFigure2-21.FillintheProjectNameblankwithhellohello.mak.ChangetheProjectTypetoQuickWinapplication[.EXE].4.VisualC++goestotheEditdialogtoallowyoutonamethesourcefilesinthisproject(seeFigure2-22).Inthiscasewehaveonlyfilehello.cpp.ClickonAddtoenterthenameintheprojectandthenclickonClosetotellVisualC++thattherearenomorefilesintheprogram.5.SelectOptions|ProjectOptionstobringuptheProjectOptionsdialogshowninFigure2-23.ClickontheCompilerbuttontochangethecompileroptions.Page28 Figure2-21ProjectcreatescreenFigure2-22ProjecteditdialogboxPage29 Figure2-23ProjectOptionsdialogbox6.GodowntotheCustomOptionsitemintheCategoryandchangethewarninglevelto4asshowninFigure2-24.7.ChangetotheMemoryModelcategoryandchangethememorymodeltolarge(seeFigure2-25).8.ClosethedialogbyclickingontheOKbutton.ThisbringsyoubacktotheProjectOptionsdialog.ClickonOKtodismissthisdialogaswell.9.Select"File|New"tostartanewprogramfile.Typeinthefollowinglines:#includeintmain(){cout<<"HelloWorld ";return(0);}YourresultsshouldlooklikeFigure2-26.10.UsetheFileISaveAsmenuitemtosavethefileunderthenamehello.cpp.11.UsetheProject|Buildcommandtocompiletheprogram.Thecompilerwilloutputmessagesasitbuilds.WhenitisfinishedyourscreenshouldlooklikeFigure2-27.Page30 Figure2-24CompilerOptionsdialogboxFigure2-25MemoryModeloptionsPage31 Figure2-26VisualC++with"HelloWorld"enteredFigure2-27.VisualC++buildscreenPage3212.TheprogramcannowbestartedwiththeDebug|Gocommand.TheresultsappearinFigure2-28. Figure2-28"HelloWorld"resultsGettingHelpinUNIXMostUNIXsystemshaveanonlinedocumentationsystemcalledthe"manpages."Thesecanbeaccessedwiththemancommand.(UNIXusesmanasanabbreviationfor"manual.")Togetinformationaboutaparticularsubject,usethecommand:mansubjectForexample,tofindoutabouttheclassesdefinedintheiostreampackage,youwouldtype:maniostreamThecommandalsohasakeywordsearchmode:man-kkeywordTodeterminethenameofeverymanpagewiththeword"output"initstitle,usethecommand:man-koutputPage33GettingHelpinanIntegratedDevelopmentEnvironmentIntegrateddevelopmentenvironmentssuchasTurbo-C++,BorlandC++,andMicrosoftC++haveaHelpmenuitem.Thisitemactivatesahypertext-basedHelpsystem.ProgrammingExercisesExercise2-1:Onyourcomputer,typeinthehelloprogramandexecuteit.Exercise2-2:Takeseveralprogrammingexamplesfromanysource,enterthemintothecomputer,andrunthem. Page353StyleInThisChapter:·Comments·C++Code·NamingStyle·CodingReligion·IndentationandCodeFormat·Clarity·Simplicity·ConsistencyandOrganization·FurtherReading·SummaryThereisnoprogramminglanguage,nomatterhowstructured,thatwillpreventprogrammersfromwritingbadprograms—L.FlonItisthenobiliy,oftheirstylewhichwillmakeourwritersof1840unreadablefortyyearsfromnow—StendhalThischapterdiscusseshowtousegoodprogrammingstyletocreateasimple.easy-to-readprogram.Itmayseembackwardtodiscussstylebeforeyouknowhowtoprogram,butstyleisthemostimportantpartofprogramming.Styleiswhatseparatesthegemsfromthejunk.Itiswhatseparatestheprogrammingartistfromthebutcher.Youmustlearngoodprogrammingstylefirst,beforetypinginyourfirstlineofcode,soeverythingyouwritewillbeofthehighestquality.Contrarytopopularbelief,programmersdonotspendmostoftheirtimewritingprograms.Farmoretimeisspentmaintaining,upgrading,anddebuggingexistingcodethaniseverspentoncreatingnewwork.Theamountoftimespentonmaintenanceisskyrocketing.From1980to1990theaveragenumberoflinesinatypicalapplicationwentfrom23,000to1.2million.Theaveragesystemagehasgonefrom4.75to9.4years.Tomakemattersworse,74%ofthemanagerssurveyedatthe1990AnnualMeetingandConferenceoftheSoftwareMaintenanceAssociationreportedthatthey"havesystemsintheirdepartmentthathavetobemaintainedbyspecificindividualsbecausenooneelseunderstandsthem." Page36Mostsoftwareisbuiltonexistingsoftware.Irecentlycompletedcodingfor12newprograms.Onlyoneofthesewascreatedfromscratch;theother11areadaptationsofexistingprograms.Programmersbelievethatthepurposeofaprogramisonlytopresentthecomputerwithacompactsetofinstructions.Thisisnottrue.Programswrittenonlyforthemachinehavetwoproblems:·Theyaredifficulttocorrectbecausesometimeseventheauthordoesnotunderstandthem.·Modificationsandupgradesaredifficulttomakebecausethemaintenanceprogrammermustspendaconsiderableamountoftimefiguringoutwhattheprogramdoesfromitscode.CommentsIdeally,aprogramservestwopurposes:First,itpresentsthecomputerwithasetofinstructionsand,second,itprovidestheprogrammerwithaclear,easy-to-readdescriptionofwhattheprogramdoes.Example2-1containsaglaringerror.Itisanerrorthatmanyprogrammersstillmakeandonethatcausesmoretroublethananyotherproblem.Theprogramcontainsnocomments.Aworkingbutuncommentedprogramisatimebombwaitingtoexplode.Soonerorlatersomeonewillhavetomodifyorupgradetheprogram,andthelackofcommentswillmakethejobtentimesmoredifficult.Awell-commented,simpleprogramisaworkofart.Learninghowtocommentisasimportantaslearninghowtocodeproperly.C++hastwoflavorsofcomments.Thefirsttypestartswith/*andendswith*/.Thistypeofcommentcanspanmultiplelinesasshown:/*Thisisasingle-linecomment.*//**Thisisamultilinecomment.*/Theotherformofcommentbeginswith//andgoestotheendoftheline://Thisisanotherformofcomment.//The//mustbegineachlinethatistobeacomment.Page37Theadvantageofthe/**/commentstyleisthatyoucaneasilyspanmultiplelines,whereaswiththe//styleyouhavetokeepputtingthe//oneachline.Thedisadvantageof/**/isthatforgettinga*/canreallyscrewupyourcode.Whichflavorshouldyouuse?Whicheveronemakesyourprogramasclearandaseasytoreadaspossible.Mostly,it'samatteroftaste.Inthisbookweusethe/**/stylecommentsforbig,multilinecommentswhilethe//styleisreservedforcommentsthattakeuponlyasingleline.Whatevercommentstyleyoudecidetouse,youmustcommentyourprograms.Example3-1showshowthe''helloworld"programlooksaftercommentsareadded. Example3-1.hello2/hello2.cc/************************************************************hello--programtoprintout"HelloWorld".**Notanespeciallyearth-shatteringprogram.****Author:SteveOualline****Purpose:Demonstrationofasimpleprogram****Usage:**Runtheprogramandthemessageappears************************************************************/#includemain(){//Telltheworldhellocout<<"HelloWorld ";return(0);}Inthisprogram,thebeginningcommentsareinaboxofasterisks(*)calledacommentbox.Thisisdonetoemphasizethemoreimportantcomments,muchlikeboldcharactersareusedfortheheadingsinthisbook.Lessimportantcommentsarenotboxed.Forexample://Telltheworldhellocout<<"HelloWorld ";Towriteaprogram,youmusthaveaclearideaofwhatyouaregoingtodo.Oneofthebestwaystoorganizeyourthoughtsistowritethemdowninalanguagethatisclearandeasytounderstand.Oncetheprocesshasbeenclearlystated,itcanbetranslatedintoacomputerprogram.Understandingwhatyouaredoingisthemostimportantpartofprogramming.Ioncewrotetwopagesofcommentsdescribingacomplexgraphicsalgorithm.ThecommentswererevisedtwicebeforeIevenstartedcoding.TheactualinstructionsPage38 PoorPerson'sTypesettingIntypesettingyoucanusefontstyleandsize,bold,anditalictomakedifferentpartsofyourtextstandout.Inprogramming,youarelimitedtoasingle,monospacedfont.However,peoplehavecomeupwithingeniouswaystogetaroundthelimitationsofthetypeface.Someofthevariouscommentingtricksare:/************************************************************************************************************************WARNING:Thisisanexampleofa***************warningmessagethatgrabsthe***************attentionoftheprogrammer.***********************************************************************************************************************//------------>Another,lessimportantwarning<---------//>>>>>>>>>>>>Majorsectionheader<<<<<<<<<<<<<<<<<atthebeginningofablockwillcausethestring:/************************************************toappear(forbeginningacommentbox).Typing#ewillendabox.Thenumberofstarswascarefullyselectedsotheendoftheboxisalignedonatabstop.Page41C++CodeTheactualcodeforyourprogramconsistsoftwoparts:variablesandexecutableinstructions.Variablesareusedtoholdthedatausedbyyourprogram.Executableinstructionstellthecomputerwhattodowiththedata.C++classesareacombinationofdataandtheinstructionsthatworkonthedata.Theyprovideaconvenientwayofpackagingbothinstructionsanddata.Avariableisaplaceinthecomputer'smemoryforstoringavalue.C++identifiesthatplacebythevariablename.Namescanbeanylengthandshouldbechosensotheirmeaningisclear.(Actually,alimitdoesexist,butitissolargethatyouprobablywillneverencounterit.)EveryvariableinC++mustbedeclared.(VariabledeclarationsarediscussedinChapter9,VariableScopeandFunctions.)ThefollowingdeclarationtellsC++thatyouaregoingtousethreeinteger(int)variablesnamedp,q,andr:intp,q,r;Butwhatarethesevariablesfor?Thereaderhasnoidea.Theycouldrepresentthenumberofangelsontheheadofapin,orthelocationandaccelerationofaplasmaboltinagameofSpaceInvaders.Avoidabbreviations.Exs.abb.arediff.tord.andhd.toustnd.(Excess abbreviationsaredifficulttoreadandhardtounderstand.)Nowconsideranotherdeclaration:intaccount_number;intbalance_owed;Nowweknowthatwearedealingwithanaccountingprogram,butwecouldstillusesomemoreinformation.Forexample,isthebalance_owedindollarsorcents?Itwouldbemuchbetterifweaddedacommentaftereachdeclarationexplainingwhatwearedoing.intaccount_number;//Indexforaccounttableintbalance_owed;//Totalowedus(inpennies)Byputtingacommentaftereachdeclarationwe,ineffect,createamini-dictionarywherewedefinethemeaningofeachvariablename.Sincethedefinitionofeachvariableisinaknownplace,it'seasytolookupthemeaningofaname.(Programmingtools,suchaseditors,cross-referencers,andgrep,canalsohelpyouquicklyfindavariable'sdefinition.)Unitsareveryimportant.Iwasonceaskedtomodifyaprogramthatconvertedplotdatafilesfromoneformattoanother.ManydifferentunitsoflengthwereusedthroughouttheprogramandnoneofthevariabledeclarationswasPage42commented.Itriedveryhardtofigureoutwhatwasgoingon,butitwasimpossibletodeterminewhatunitswerebeingusedintheprogram.Finally,Igaveupandputthefollowingcommentintheprogram:/*********************************************************Note:Ihavenoideawhattheinputunitsare,nor**doIhaveanyideawhattheoutputunitsare,**butIhavediscoveredthatifIdivideby3**theplotslookabouttherightsize.*********************************************************/Oneproblemmanybeginningprogrammershaveisthattheydescribethecode,notthevariable.Forexample:inttop_limit;//Toplimitisaninteger[badcomment]It'sobviousfromthecodethattop_limitisaninteger.WhatIwanttoknowiswhatistop_limit.Tellme.inttop_limit;//NumberofitemswecanloadbeforelosingdataYoushouldtakeeveryopportunitytomakesureyourprogramisclearandeasytounderstand.Donotbeclever.Clevernessmakesforunreadableandunmaintainableprograms.Programs,bytheirnature,areextremelycomplex.Anythingyoucantodotocutdownonthiscomplexitywillmakeyourprogramsbetter.Considerthefollowingcode,writtenbyaverycleverprogrammer.while(' '!=*p++=*q++);Itisalmostimpossibleforthereadertotellataglancewhatthismessdoes.Properlywritten thiswouldbe:while(1){*destination_ptr=*source_ptr;++destination_ptr;++source_ptr;if(*(destination_ptr-1)==' ')break;//exittheloopifdone}Althoughthesecondversionislonger,itismuchclearerandeasiertounderstand.EvenanoviceprogrammerwhodoesnotknowC++wellcantellthatthisprogramhassomethingtodowithmovingdatafromasourcetoadestination.Thecomputerdoesn'tcarewhichversionisused.Agoodcompilerwillgeneratethesamemachinecodeforbothversions.Itistheprogrammerwhobenefitsfromtheverbosecode.NamingStyleNamescancontainbothuppercaseandlowercaseletters.Inthisbookweusealllowercasenamesforvariables(e.g.,source_ptr,current_index).AlluppercasePage43isreservedforconstants(e.g.,MAX_ITEMS,SCREEN_WIDTH).ThisconventionistheclassicconventionfollowedbymostCandC++programs.Manynewerprogramsusemixed-casenames(e.g.,RecordsInFile).Sometimestheyusethecapitalizationofthefirstlettertoindicateinformationaboutthevariable.Forexample,recordsInFilemightbeusedtodenotealocalvariablewhileRecordsInFilewoulddenoteaglobalvariable.(SeeChapter9,VariableScopeandFunctions,forinformationaboutlocalandglobalvariables.)Whichnamingconventionyouuseisuptoyou.Itismoreamatterofreligionthanofstyle.However,usingaconsistentnamingstyleisextremelyimportant.Inthisbookwehavechosenthefirststyle,lowercasevariablenamesanduppercaseconstants,andweuseitthroughoutthebook.CodingReligionComputerscientistshavedevisedmanyprogrammingstyles.Theseincludestructuredprogramming,top-downprogramming,andgoto-lessprogramming.Eachofthesestyleshasitsownfollowingorcult.Iusetheterm"religion"becausepeoplearetaughttofollowtherulesblindlywithoutknowingthereasonsbehindthem.Forexample,followersofthegoto-lesscultwillneveruseagotostatement,evenwhenitisnaturaltodoso.Therulespresentedinthisbookaretheresultofyearsofprogrammingexperience.Ihavediscoveredthatbyfollowingtheserules,Icancreatebetterprograms.Youdonothavetofollowthemblindly.Ifyoufindabettersystem,byallmeansuseit.(Ifitreallyworks,dropmealine.I'dliketouseit,too.)IndentationandCodeFormat Tomakeprogramseasiertounderstand,mostprogrammersindenttheirprograms.ThegeneralruleforaC++programistoindentonelevelforeachnewblockorconditional.InExample3-1therearethreelevelsoflogic,eachwithitsownindentationlevel.Thewhilestatementisoutermost.Thestatementsinsidethewhileareatthenextlevel.Thestatementinsidetheif(break)isattheinnermostlevel.Therearetwostylesofindentation,andavastreligiouswarisbeingwagedintheprogrammingcommunityastowhichisbetter.Thefirstistheshortform:while(!done){cout<<"Processing ";next_entry();}Page44if(total<=0){cout<<"Youowenothing ";total=0;}else{cout<<"Youowe"<Page51ThisstatementsignalsC++thatyouaregoingtouseasetofstandardclassescalledtheI/Ostreamclasses.Thisisatypeofdatadeclaration.*Lateryouusetheclasscoutfromthispackage.(WedefineaclassmorecompletelyinChapter13,SimpleClasses,butuntilweknowmorewe'lltreatcoutasa"blackbox"thatsendsdatatotheconsole.)Themainroutinecontainstheinstruction:cout<<"HelloWorld ";whichisanexecutablestatementinstructingC++toprintthemessage"HelloWorld"onthescreen.C++usesasemicolontoendastatementinmuchthesamewayweuseaperiodtoendasentence.Unlikewithline-orientedlanguagessuchasBASIC,theendofalinedoesnotendastatement.Thesentencesinthisbookcanspanseverallines—theendofalineistreatedasaspaceseparatingwords.C++worksthesameway.Asinglestatementcanspanseverallines.Similarly,youcanputseveralsentencesonthesameline,justasyoucanputseveralC++statementsonthesameline.However,mostofthetimeyourprogramismorereadableifeachstatementstartsonaseparateline.Weareusingthestandardclasscout(consoleout)tooutputthemessage.AstandardclassisagenerallyusefulC++objectthathasalreadybeendefinedandputinthestandardlibrary.Alibraryisacollectionofclasses,functions,anddatathathavebeengroupedtogetherforreuse.Thestandardlibrarycontainsclassesandfunctionsforinput,output,sorting,advancedmath,andfilemanipulation.SeeyourC++referencemanualforacompletelistoflibraryfunctionsandstandardclasses."HelloWorld"isoneofthesimplestC++programs.Itcontainsnocomputations,merelysendingasinglemessagetothescreen.Itisastartingpoint.Onceyouhavemasteredthissimpleprogram,youhavedoneagreatdealofthingsright.Theprogramisnotassimpleasitlooks.Butonceyougetitworking,youcanmoveontocreatemorecomplexcode.SimpleExpressionsComputerscandomorethanjustprintstrings.Theycanalsoperformcalculations.Expressionsareusedtospecifysimplecomputations.C++hasthefivesimpleoperatorslistedinTable4-1.*Technically,thestatementcausesasetofdatadeclarationstobetakenfromanincludefileChapter10,TheC++Preprocessor,discussesincludefiles. Page52Table4-1.SimpleOperatorsOperatorMeaning*Multiply/Divide+Add-Subtract%Modulus(remainderafterdivision)Multiply(*),divide(/),andmodulus(%)haveprecedenceoveraddition(+)andsubtraction(-).Parenthesesmaybeusedtogroupterms.Thus:(1+2)*4yields12.while:1+2*4yields9.TheprograminExample4-1computesthevalueoftheexpression(1+2)*4.Example4-1SimpleExpressionmain(){(1+2)*4;return(0);}Althoughwecalculatetheanswer,wedon'tdoanythingwithit.(Thisprogramwillgeneratea"nulleffect"warningtoindicatethatthereisacorrectlywritten,butuseless,statementintheprogram.)Ifwewereconstructingabuilding,thinkabouthowconfusedaworkerwouldbeifwesaid,"Takeyourwheelbarrowandgobackandforthbetweenthetruckandthebuildingsite.""Doyouwantmetocarrybricksinthewheelbarrow?""No.Justgobackandforth."Youneedtooutputtheresultsofyourcalculations.Page53ThecoutOutputClass Thestandardclassvariablecoutisusedtooutputdatatotheconsole.We'lllearnwhataclassislaterinChapter13,SimpleClasses.Butfornowallwehavetoknowisthattheoperator<<*tellsC++whattooutput.Sothestatement:cout<<"HelloWorld ";tellsC++totakethestring"HelloWorld "andwriteittotheconsole.Multiple<intterm;//termusedintwoexpressionsmain(){term=3*5;cout<<"Twice<floatanswer;//theresultofthedividemain(){answer=1/3;cout<<"Thevalueof1/3is"<charchar1;//firstcharactercharchar2;//secondcharactercharchar3;//thirdcharactermain(){charl='A';char2='B';char3='C';cout<floatdata[5];//datatoaverageandtotalfloattotal;//thetotalofthedataitemsfloataverage;//averageoftheitemsmain(){data[0]=34.0;data[1]=27.0;data[2]=46.5;data[3]=82.0;data[4]=22.0;total=data[0]+data[1]+data[2]+data[3]+data[4];average=total/5.0;cout<<"Total"<charname[4];main(){strcpy(name,"Sam");//Legalreturn(0);}NOTETheline#includeisneededtoinformC++thatyouareusingthestringfunctionlibrary.C++usesvariable-lengthstrings.Forexample,thedeclaration:#includecharstring[50];main(){strcpy(string,"Sam");createsanarray(string)thatcancontainupto50characters.Thesizeofthearrayis50,butthelengthofthestringis3.Anystringupto49characterslongcanbestoredinstring.(OnecharacterisreservedfortheNULLthatindicatestheendofthestring.)Thereareseveralstandardroutinesthatworkonstringvariables.ThesearelistedinTable5-1.Table5-1StringFunctionsFunctionDescriptionstrcpy(string1,string2)Copiesstring2intostring1strcat(string1,string2)Concatenatesstring2ontotheendofstring1(Table5-1continuedonnextpage) Page66Table5-1StringFunctions(Continuedfrompreviouspage)FunctionDescriptionlength=strlen(string)Getsthelengthofastringstrcmp(stringl,string2)0ifstring1equalsstring2;otherwise,nonzeroExample5-2illustrateshowstrcpyisused.Example5-2str/samcc#include#includecharname[30];//Firstnameofsomeonemain(){strcpy(name,"Sam");cout<<"Thenameis"<#includecharfirst[100];//firstnamecharlast[100];//lastnamecharfull_name[100];//fullversionoffirstandlastnamemain(){strcpy(first,"Steve");//Initializefirstnamestrcpy(last,"Oualline");//Initializelastnamestrcpy(full_name,first);//full="Steve"//Note:strcatnotstrcpystrcat(full_name,"");//full="Steve"strcat(full_name,last);//full="SteveOualline" Page67Example5-3.name2/man2.cc(Continued)cout<<"Thefullnameis"<>toreadthem.Forexample,thecode:cin>>price>>numbero_on_hand;readstwonumbers:priceandnumber_on_hand.Theinputtothisprogramshouldbetwonumbers,separatedbywhitespace.Forexample,ifyoutype:325thenpricegetsthevalue32andnumber_on_handgets5.NOTEThisdoesnotgiveyouveryprecisecontroloveryourinput.C++doesareasonablejobforsimpleinput.Ifyourprogramexpectsanumberandyoutypeinstead,theprogramwillskipthe(it'swhitespace)andwaitforyoutotypeanumber.Sometimesthismayleadyoutothinkyourprogram'sstuck.InExample5-4,weusecintogetanumberfromtheuserandthenwedoubleit:Example5-4double/double.cc#includecharline[100];//inputlinefromconsoleintvalue;//avaluetodoublemain(){cout<<"Enteravalue:";cin>>value;cout<<"Twice"<intheight;/*theheightofthetriangleintwidth;/*thewidthofthetriangle*/intarea;/*areaofthetriangle(computed)*/main(){cout<<"Enterwidthheight?";cin>>width>>height;area=(width*height)/2;cout<<"Theareais"<>variable;Thisworksforalltypesofsimplevariablessuchasint,float,andchar.Readingstringsisalittlemoredifficult.Toreadastring,usethestatement:cin.getline(string,sizeof(string));Forexample:charname[100];//Thenameofapersoncin.getline(name,sizeof(name));WediscussthegetlineandsizeoffunctionsinChapter16,FileInput/Output.Page69Whenreadingastring,thecinclassconsidersanythinguptotheend-of-linepartofthestring. Example5-6readsalinefromthekeyboardandreportstheline'slength.Example5-6len/lencc#include#includecharline[100];//Alineofdatamain(){cout<<"Enteraline:";cin.getline(line,sizeof(line));cout<<"Thelengthofthelineis:"<intarray[3][5]={//Twodimensionalarray{0,1,2,3,4},{10,11,12,13,14},{20,21,22,23,24}};main(){cout<<"Lastelementis"<oronehundredtwenty-one?Thetypeshortintuses2bytes,or16bits.Fifteenbitsareusednormallyforthenumberand1bitforthesign.Thisgivesitarangeof-32,768(-215)to32,767(215-1).Anunsignedshortintusesall16bitsforthenumber,givingittherangeof0to65,535(216-1).Allintdeclarationsdefaulttosigned,sothatthedeclaration:signedlongintanswer;//finalresultPage73isthesameas:longintanswer//finalresultFinallythereistheveryshortinteger,thetypechar.Charactervariablestakeup1byte.Theycanalsobeusedfornumbersintherangeof-128to127or0to255.Unlikeintegers,theydonotdefaulttosigned;thedefaultiscompilerdependent.*Question:Isthefollowingcharactervariablesignedorunsigned?charfoo;Answers: a.It'ssigned.b.It'sunsigned.c.It'scompilerdependent.d.Ifyoualwaysspecifysignedorunsignedyoudon'thavetoworryaboutproblemslikethis.Readingandwritingveryshortintegersisalittletricky.Ifyoutrytouseacharvariableinanoutputstatement,itwillbewritten,asacharacter.YouneedtotrickC++intobelievingthatthecharvariableisaninteger.Thiscanbeaccomplishedwiththeintoperator.Example5-8showshowtowriteoutaveryshortintegerasanumber.Example5-8two2/tuo2cc#includesignedcharch;//Veryshortinteger//Rangeis-128to127intmain(){ch=37;cout<<"Thenumberis"<staticshortunsignedfloatexterndoublecharautoSpecialThevolatilekeywordisusedforspecializedprogrammingsuchasI/Odriversandsharedmemoryapplications.Itisanadvancedmodifierwhoseuseisfarbeyondthescopeofthisbook. volatileIndicatesaspecialvariablewhosevaluemaychangeatanytimeNormalvariableClassTheclassofavariableisdiscussedindetailinChapter9,VariableScopeandFunctions.Abriefdescriptionofthevariousclassesfollows:registerThisindicatesafrequentlyusedvariablethatshouldbekeptinamachineregister.SeeChapter17,DebuggingandOptimization.staticThemeaningofthisworddependsonthecontext.ThiskeywordisdescribedinChapter9,VariableScopeandFunctions,andChapter23,ModularProgramming.Page77externThevariableisdefinedinanotherfile.SeeChapter23formoreinformation.autoAvariableallocatedfromthestack.Thiskeywordishardlyeverused.Indicatesthatthedefaultclass(auto)isselected.SizeThesizequalifierallowsyoutoselectthemostefficientsizeforthevariable.longIndicatesalargerthannormalinteger.(Somenonstandardcompilersuselongdoubletoindicateaverylargefloating-pointvariable.)shortAsmallerthannormalinteger.doubleAdouble-sizefloating-pointnumber.Indicatesanormalsizenumber.SignNumberscanbesignedorunsigned.Thisqualifierappliesonlytocharandinttypes.Floating-pointnumbersarealwayssigned.Thedefaultissignedforintandundefinedfor characters.TypeThisspecifiesthetypeofthevariable.Simpletypesinclude:intIntegerfloatFloating-pointnumbercharSinglecharacters,butcanalsobeusedforveryshortintegersPage78HexadecimalandOctalConstantsIntegernumbersarespecifiedasastringofdigits,suchas1234,88,-123,andsoon.Thesearedecimal(base10)numbers:174or17410.Computersdealwithbinary(base2)numbers:101011102.Theoctal(base8)systemeasilyconvertstoandfrombinary.Eachgroupofthreedigits(23=8)canbetransformedintoasingleoctaldigit.Thus101011102canbewrittenas101011102andchangedtotheoctal2568.Hexadecimal(base16)numbershaveasimilarconversion,but4bitsatatimeareused.Forexample,100101002is10000100,or8416.TheC++languagehasconventionsforrepresentingoctalandhexadecimalvalues.Leadingzerosareusedtosignalanoctalconstant.Forexample,0123is123(octal)or83(decimal).Startinganumberwith"Ox"indicatesahexadecimal(base16)constant.So0x15is21(decimal).Table5-3showsseveralnumbersinallthreebases.Table5-3IntegerExamplesBase10Base8Base166060x690110x9150170xFQuestion5-3:Whydoesthefollowingprogramfailtoprintthecorrectzipcode?Whatdoesitprintinstead?longintzip;//Zipcodemain(){zip=02137L;//UsethezipcodeforCambridgeMA cout<<"NewYork'szipcodeis:"<intheight;/*Theheightofthetriangleintwidth;/*Thewidthofthetriangle*/intarea;/*Areaofthetriangle(computed)*/main(){cout<<"Enterwidthandheight?";cin>>width>>height;area=(width*height)/2;cout<<"Theareais"<Greaterthan>=Greaterthanorequalto==Equal!=Notequal Multiplerelationalexpressionsmaybegroupedtogetherwithlogicaloperators.Forexample,thestatement:if((oper_char=='Q')||(oper_char=='q'))cout<<"Quit ";usesthelogicalORoperator(||)tocausetheifstatementtoprint"Quit"ifoper_chariseitheralowercase"q"oranuppercase"Q."Table6-2liststhelogicaloperators.Table6-2LogicalOperatorsOperatorUsageMeaningLogicalOR(||)(expr1)||(expr2)Trueifexpr1orexpr2istrueLogicalAND(&&)(expr1)&&(expr2)Trueifexprlandexpr2aretrueLogicalNOT(!)!(expr)ReturnsfalseifexpristrueorreturnstrueifexprisfalseMultiplestatementsaftertheifmaybegroupedbyputtingtheminsidecurlybraces({}).Forexample:if(total_owed<=0){++zero_count;cout<<"Youowenothing. ";}Forreadability,thestatementsenclosedincurlybracesareusuallyindented.Thisallowstheprogrammertoquicklytellwhichstatementsaretobeconditionallyexecuted.Asyouwillseelater,mistakesinindentationcanresultinprogramsthataremisleadingandhardtoread.Page87elseStatementAnalternativeformoftheifstatementis:if(condition)statement;elsestatement;Iftheconditionistrue,thefirststatementisexecuted.Ifitisfalse,thesecondstatementisexecuted.Inouraccountingexample,wewroteoutamessageonlyifnothingwasowed.Inreallifeweprobablywanttotellthecustomerhowmuchheowesifthereisabalancedue.if(total_owed<=0)cout<<"Youowenothing. ";elsecout<<"Youowe"<intold_number;//previousFibonaccinumberintcurrent_number;//currentFibonaccinumberintnext_number;//nextnumberintheseriesmain(){//startthingsoutold_number=1;current_number=1;cout<<"l ";//Printfirstnumberwhile(current_number<100){cout<inttotal;//Runningtotalofallnumberssofarintitem;//nextitemtoaddtothelistmain(){total=0;while(1)cout<<"Enter#toadd "; cout<<"or0tostop:";cin>>item;if(item==0)break;total+=item;cout<<"Total:"<inttotal;//Runningtotalofallnumberssofarintitem;//nextitemtoaddtothelistintminus_items;//numberofnegativeitemsmain(){total=0;minus_items=0;while(1){cout<<"Enter#toadd ";cout<<"or0tostop:";cin>>item;if(item==0)break;if(item<0){++minus_items;continue;}total+=item;cout<<"Total:"<=100)break;cout<<"Term"<intbalance_owed;//amountowedmain(){cout<<"Enternumberofdollarsowed:";cin>>balance_owed;if(balance_owed=0)cout<<"Youowenothing. ";elsecout<<"Youowe"<8-0+Forexample,81=B-,94=A,and68=D+.Note:AnFisonlyanF.ThereisnoF+orF-.NOTEProgrammersfrequentlyhavetomodifycodethatsomeoneelsewrote.Agoodexerciseistotakesomeoneelse'sExercise6-2andmodifyit. Exercise6-4:Givenanamount(lessthan$1.00),computethenumberofquarters,dimes,nickels,andpenniesneeded.Exercise6-5:Aleapyearisanyyeardivisibleby4unlessitisdivisibleby100,butnot400.Writeaprogramtotellwhetherayearisaleapyear.Page95Exercise6-6:Writeaprogramthat,giventhenumberofhoursanemployeeworkedandhishourlywage,computeshisweeklypay.Countanyhoursover40asovertimeattime-and-a-half.AnswerstoChapterQuestionsAnswer6-1:ThisprogramillustratesthemostcommonC++errorandoneofthemostfrustrating.TheproblemisthatC++allowsassignmentstatementsinsideofifconditionals.Thestatement:if(balance_owed=0)usesasingleequalsigninsteadofthedoubleequal.C++willassignbalance_owedthevalue0andthentesttheresult(whichiszero).Iftheresultwerenonzero(true),theifclausewouldbeexecuted.Sincetheresultiszero(false).theelseclauseisexecutedandtheprogramprintsthewronganswer.Thestatementif(balance_owed=0)isequivalenttobalance_owed=0;if(balanced_owed!=0)Thestatementshouldbewritten:if(balance_owed==0)Thisisthemostcommonerrorthatbeginningprogrammersmake.Itisalsooneofthemostdifficultandfrustratingtofind.IoncetaughtacourseinCprogramming.OnedayaboutamonthafterthecoursehadendedIsawoneofmyformerstudentsonthestreet.Hegreetedmeandsaid,"Steve,Ihavetotellyouthetruth.DuringtheclassIthoughtyouweregoingabitoverboardonthis=vs.==bug,untilnow.Yousee,IjustwrotethefirstCprogramformyjob,andguesswhatmistakeImade."Onetrickmanyprogrammersuseistoputtheconstantfirstinany==statement.Forexample:if(0==balanced_owed)Inthisway,iftheprogrammermakesamistakeandputsin=insteadof==,theresultis:if(0=balancedowed)whichcausesacompilererror.(Youcan'tassignbalance_owedto0.) Page977TheProgrammingProcessInThisChapter:·SettingUp·TheSpecification·CodeDesign·ThePrototype·TheMakefile·Testing·Debugging·Maintenance·Revisions·ElectronicArchaeology·MarkUptheProgram·ProgrammingExercisesIt'sjustasimplematterofprogramming.—AnyBossWhoHasNeverWrittenaProgramProgrammingismorethanjustwritingcode.Softwarehasalifecycle.Itisborn,growsup,becomesmature,andfinallydies,onlytobereplacedbyanewer,youngerproduct.Understandingthiscycleisimportantbecauseasaprogrammeryouwillspendonlyasmallamountoftimeactuallywritingnewcode.Mostprogrammingtimeisspentmodifyinganddebuggingexistingcode.Softwaredoesnotexistinavacuum;itmustbedocumented,maintained,enhanced,andsold.Inthissectionwetakealookatasmallprogrammingprojectusingoneprogrammer.LargerprojectsthatinvolvemanypeoplearediscussedinChapter23,ModularProgramming.Althoughthefinalcodeisfewerthanahundredlines,theprinciplesusedinitsconstructioncanbeappliedtoprogramswiththousandsoflinesofcode.Figure7-1illustratesthesoftwarelifecycle.Themajorstepsinmakingaprogramare:·Requirements.Programsstartwhensomeonegetsanideaandassignsyoutoimplementit.Therequirementdocumentdescribes,inverygeneralterms,whatiswanted.·Specification.Adescriptionofwhattheprogramdoes.Inthebeginning,aPreliminarySpecificationisusedtodescribewhattheprogramisgoingtodo.Later,astheprogrambecomesmorerefined,sodoesthespecification.Finally,whentheprogramisfinished,thespecificationservesasacompletedescriptionofwhattheprogramdoes. Page98Figure7-1.Softwarelifecycle·Codedesign.Theprogrammerdoesanoveralldesignoftheprogram.Thedesignshouldincludemajoralgorithms,classdefinitions,modulespecifications,fileformats,anddatastructures.·Onethingcannotbeover-stressed;''Thinkbeforeyouact."Studieshaveshownthatagooddesigncanresultinaprogramthatis1/10ofthesizeofapoorlydesignedone.ThisisespeciallytruewhenusingC++,wheredesign-Page99inggoodobjectsiscriticaltowritingagoodprogram.(YouwillfindoutwhatobjectsareinChapter13,SimpleClasses.)Note:"Thinkbeforeyouact"isgoodadvicenotonlyforcoding,butalsoforlifeingeneral. ·Coding.Thenextstepiswritingtheprogram.Thisinvolvesfirstwritingaprototypeandthenfillingitintocreatethefullprogram.·Testing.Theprogrammershoulddesignatestplananduseittotesttheprogram.Itisagoodidea,whenpossible,tohavesomeoneelsetesttheprogram.·Debugging.Unfortunately,veryfewprogramsworkthefirsttime.Theymustbecorrectedandtestedagain.·Release.Theprogramispackaged,documented,andsentoutintotheworldtobeused.·Maintenance.Programsareneverperfect.Bugswillbefoundandwillneedcorrection.·Revisingandupdating.Afteraprogramhasbeenworkingforawhile,theuserswillwantchanges,suchasmorefeaturesormoreintelligentalgorithms.Atthispointanewspecificationiscreatedandtheprocessstartsagain.SettingUpTheoperatingsystemallowsyoutogroupfilesindirectories.Justasfilefoldersserveasawayofkeepingpaperstogetherinafilingcabinet,directoriesserveasawayofkeepingfilestogether.Inthischapteryouwillbecreatingasimplecalculatorprogram.Allthefilesforthisprogramwillbestoredinadirectorynamedcalc.TocreateadirectoryinUNIX,executethefollowingcommands:%cd-%mkdircalcInMS-DOS,type:C:>cdC:>mkdircalcTotelltheoperatingsystemwhichdirectoryyouwanttouse,inUNIXtypethecommand:%cd~/calcInMS-DOS,type:C:>cdcalcC:CALC>Page100Moreinformationonhowtoorganizedirectoriescanbefoundinyouroperatingsystemdocumentation.TheSpecificationForthischapterwearegoingtoassumethatyouhavebeengiventheassignmentto"writeaprogramthatactslikeafour-functioncalculator."Typically,thespecificationyouaregivenisvagueandincomplete.Itisuptoyoutorefineitintosomethingthatexactlydefinestheprogramyouaregoingtoproduce. ThefirststepistowriteadocumentcalledThePreliminaryUsers'Specification,whichdescribeswhatyourprogramisgoingtodoandhowtouseit.Thisdocumentdoesnotdescribetheinternalstructureoftheprogramorthealgorithmyouplantouse.Asamplespecificationforthefour-functioncalculatoris:CalcAfour-functioncalculatorPreliminarySpecificationDec.10,1994SteveOuallineWarning:Thisisapreliminaryspecification.Anyresemblancetoanysoftwarelivingordeadispurelycoincidental.Calcisaprogramthatallowstheusertoturnhis$10,000computerintoa$1.98four-functioncalculator.Theprogramadds,subtracts,multiplies,anddividessimpleintegers.Whentheprogramisrun,itzerostheresultregisteranddisplaysitscontents.Theusercanthentypeinanoperatorandnumber.Theresultisupdatedanddisplayed.Thefollowingoperatorsarevalid:OperatorMeaning+Addition-Subtraction*Multiplication/DivisionExample(userinputisinboldface)calcResult:0Enteroperatorandnumber:+123Result:123Enteroperatorandnumber:-23Result:100Page101Enteroperatorandnumber:/25Result:4Enteroperatorandnumber:*4Result:16Thepreliminaryspecificationservestwopurposes.First,youshouldgiveittoyourboss(orcustomer)tomakesurethatwhathethoughthesaidandwhatyouthoughthesaidagree.Second,youcancirculateitamongyourcolleaguestoseewhethertheyhaveanysuggestionsorcorrections.Thispreliminaryspecificationwascirculatedandreceivedthecomments:1)"Howareyou goingtogetoutoftheprogram?"and2)"Whathappenswhenyoutrytodivideby0?"Soanewoperatorisadded:q-quitandweaddanotherparagraph:Dividingby0resultsinanerrormessageandtheresultregisterisleftunchanged.IV+III=VIIAcollegeinstructoroncegavehisstudentsanassignmentto"writeafour-functioncalculator."Oneofhisstudentsnoticedthatthiswasaprettyloosespecificationanddecidedtohavealittlefun.Theprofessordidn'tsaywhatsortofnumbershadtobeused,sothestudentcreatedaprogramthatworkedonlywithRomannumerals(IV+III=VII).Theprogramcamewithacompleteusermanual—writteninLatin.CodeDesignAfterthepreliminaryspecificationhasbeenapproved,youcanstartdesigningcode.Inthecode-designphase,youplanyourwork.Inlargeprogrammingprojectsinvolvingmanypeople,thecodewouldbebrokenupintomodulesforeachprogrammer.Atthisstage,fileformatsareplanned,datastructuresaredesigned,andmajoralgorithmsaredecidedupon.Thissimplecalculatorusesnofilesandrequiresnofancydatastructures.What'sleftforthisphaseistodesignthemajoralgorithm.Outlinedinpseudo-code,ashorthandhalfwaybetweenEnglishandrealcode,itis:LoopReadanoperatorandnumberDothecalculationPage102DisplaytheresultEnd-LoopThePrototypeOncethecodedesigniscompleted,youcanbeginwritingtheprogram.Butratherthantrytowritetheentireprogramatonceandthendebugit,youwilluseamethodcalledfastprototyping.Thisconsistsofwritingthesmallestportionofthespecificationyoucanimplementthatwillstilldosomething.Inourcase,youwillcutthefourfunctionsdowntoaone-functioncalculator.Onceyougetthissmallpartworking,youcanbuildtherestofthefunctionsontothisstablefoundation.Also,theprototypegivesthebosssomethingtolookatandplayaroundwithsohehasagoodideaofthedirectiontheprojectistaking.Goodcommunicationisthekeytogoodprogramming,andthemoreyoucanshowsomeone,thebetter.Thecodeforthefirstversionofthefour-functioncalculatorisfoundinExample7-1. Example7-1calc/calccc#includeintresult;//theresultofthecalculationscharoper_char;//theuser-specifiedoperatorintvalue;//valuespecifiedaftertheoperatorintmain(){result=0;//initializetheresult//Loopforever(ortillwehitthebreakstatement)while(1){cout<<"Result:"<>oper_char;cin>>value;if(oper_char='+')result+=value;}else{cout<<"Unknownoperator"<>oper_char>>value;askstheuserforanoperatorandnumber.Theseareparsedandstoredinthevariablesoper_charandvalue.(ThefullsetofI/Ooperationssuchas<>aredescribedinChapter16,FileInput/Output.)Finally,youstartcheckingtheoperators.Iftheoperatorisaplus(+),youperformanadditionusingtheline:if(oper_char='+'){result+=value;Sofaryouonlyrecognizetheplusoperator.Assoonasthisworks,youwilladdmoreoperatorsbyaddingmoreifstatements.Finally,ifanillegaloperatorisentered,theline:}else{cout<<"Unknownoperator"<>value;cin>>oper_char;cout<<"##aftercin"<intresult;//theresultofthecalculationscharoper_char;//theuser-specifiedoperatorintvalue;//valuespecifiedaftertheoperatormain(){result=0;//initializetheresult//loopforever(oruntilbreakreached)while(1){cout<<"Result:"<>oper_char;if((oper_char=='q')||(oper_char=='Q'))break;cin>>value;if(oper_char=='+')result+=value;}elseif(oper_char=='-'){result-=value;}elseif(oper_char=='*')result*=value;}elseif(oper_char=='/')if(value==0)cout<<"Error:Dividebyzero ";cout<<"operationignored ";}elseresult/=value;}else{cout<<"Unknownoperator"<#includeintnumber_to_guess;//Randomnumbertobeguessedintlow_limit;//Currentlowerlimitofplayer'srangeinthigh_limit;//Currentupperlimitofplayer'srangeintguess_count;//Numberoftimesplayerguessedintplayer_number;//Numbergottenfromtheplayercharline[80];//Inputbufferforasinglelinemain(){while(1)/**Notapurerandomnumber;seerestrictions*/number_to_guess=rand()%100+1;//Initializevariablesforlooplow_limit=0;high_limit=100;guess_count=0;while(1){//Telluserwhattheboundsareandgethisguesscout<<"Bounds"<>player_number;//Didheguessright?if(player_number==number_to_guess)break;//Adjustboundsfornextguessif(player_numberinttotal;//Totalofallthenumbersintcurrent;//Currentvaluefromtheuserintcounter;//Whileloopcountermain(){total=0;counter=0;while(counter<5)Page118Example8-1.tota16/total6w.cc(Continued)cout<<"Number?";cin>>current;total+=current;++counter;}cout<<"Thegrandtotalis"<inttotal;//Totalofallthenumbersintcurrent;//Currentvaluefromtheuserintcounter;//Forloopcountermain(){total=0;for(counter=0;counter<5;++counter){cout<<"Number?"; cin>>current;total+=current;}cout<<"Thegrandtotalis"</**ThisprogramproducesaCelsiustoFahrenheitconversion*chartforthenumbers0to100.**Restrictions:*Thisprogramdealswithintegersonly,sothe*calculationsmaynotbeexact. *///ThecurrentCelsiustemperatureweareworkingwithintcelsius;main(){for(celsius=0;celsius<=100;++celsius);cout<<"Celsius:"<intseven_count;//Numberofsevensinthedataintdata[5];//Thedatatocount3and7inintthree_count;//Numberofthreesinthedataintindex;//Indexintothedatamain(){seven_count=0;three_count=0;cout<<"Enter5numbers ";cin>>data[1]>>data[2]>>data[3]>>data[4]>>data[5];for(index=1;index<=5;++index)if(data[index]==3)++three_count;if(data[index]==7)++seven_count;}cout<<"Threes"<intresult;//Theresultofthecalculationscharoper_char;//Theuser-specifiedoperatorintvalue;//Valuespecifiedaftertheoperatormain(){result=0;//Initializetheresult//Loopforever(oruntilbreakreached)while(1){cout<<"Result:"<>oper_char>>value;if((oper_char=='q')||(oper_char=='Q'))break;switch(oper_char)case'+':result+=value;break;case'-':result-=value;break;case'*':result*=value;break;case'/':if(value==0)cout<<"Error:Dividebyzero ";cout<<"operationignored "; }elseresult/=value;break;default:cout<<"Unknownoperator"<-1orinthiscase0to4.data[5]isillegal.Whenweuseitstrangethingshappen;inthiscasethevariablethree_countischanged.Thesolutionistouseonlydata[0]todata[4].Page1299VariableScopeandFunctionsInThisChapter:·ScopeandStorageClass·Functions·SummaryofParameterTypes·StructuredProgrammingBasics·Recursion·ProgrammingExercises·AnswerstoChapterQuestionsButinthegrossandscopeofmyopinionThisbodessomestrangeeruptiontoourstate.—ShakesreareHamlet,ActI,SceneISofaryouhavebeenusingonlyglobalvariables.Thesearevariablesthatcanbesetorusedalmostanywhereintheprogram.Inthischapteryoulearnaboutotherkindsofvariablesandhowtousethem.Thischapteralsotellsyouhowtodivideyourcodeintofunctions.Manyaspectsoffunctionsaredetailed,includingfunctionoverloading,usingfunctionstobuildstructuredprograms,andtheuseofrecursivefunctioncalls.ScopeandStorageClassAllvariableshavetwoattributes,scopeandstorageclass.Thescopeofavariableistheareaoftheprogramwherethevariableisvalid.Aglobalvariableisvalidfromthepointitisdeclaredtotheendoftheprogram.Alocalvariable'sscopeislimitedtotheblockwhereitisdeclaredandcannotbeaccessed(setorread)outsidethatblock.Ablockisasectionofcodeenclosedincurlybraces({}).Figure9-1illustratesthedifferencebetweenlocalandglobalvariables. Itispossibletodeclarealocalvariablewiththesamenameasaglobalvariable.Normally,thescopeofthevariablecount(firstdeclarationinFigure9-2)wouldbethewholeprogram.Thedeclarationofasecond,localcounttakesprecedenceovertheglobaldeclarationinsidethesmallblockwherethelocalcountisdeclared.Inthisblock,theglobalcountishidden.Youcanalsonestlocaldeclarationsandhidelocalvariables.These"verylocal"variableshaveanevensmallerandmorelocalscopethanthe"normallocal"variables.(TheclarityPage130Figure9-1.Localandglobalvariablesoftheprevioussentencegivesyousomeideawhyusingnestingtohidelocalvariablesdoesnotmakeyourprogrameasytounderstand.)Figure9-2illustratesahiddenvariable.Figure9-2HiddenvariablesThevariablecountisdeclaredbothasalocalvariableandasaglobalvariable.Normallythescopeofcount(global)wouldbetheentireprogram,butwhenavariableisdeclaredinsideablock,thatinstanceofthevariablebecomesthe Page131activeoneforthelengthoftheblock.Theglobalcounthasbeenhiddenbythelocalcountforthescopeofthisblock.Theshadedareainthefigureshowswherethescopeofcount(global)ishidden.Itisnotgoodprogrammingpracticetohidevariables.Theproblemisthatwhenyouhavethestatement:count=1;itisdifficulttotellwhichcountyouarereferringto.Isittheglobalcount,theonedeclaredatthetopofmain,ortheoneinthemiddleofthewhileloop?Itisbettertogivethesevariablesdifferentnames,suchastotal_count,current_count,anditem_count.Thestorageclassofavariablemaybeeitherpermanentortemporary.Globalvariablesarealwayspermanent.Theyarecreatedandinitializedbeforetheprogramstartsandremainuntilitterminates.Temporaryvariablesareallocatedfromasectionofmemorycalledthestackatthebeginningoftheblock.Ifyoutrytoallocatetoomanytemporaryvariablesyouwillgetastackoverflowerror.Thespaceusedbythetemporaryvariablesisreturnedtothestackattheendoftheblock.Eachtimetheblockisentered,thetemporaryvariablesareinitialized.Thesizeofthestackdependsonthesystemandcompileryouareusing.OnmanyUNIXsystems,theprogramisautomaticallyallocatedthelargestpossiblestack.Onothersystems,adefaultstacksizeisallocatedthatcanbechangedbyacompilerswitch.InTurbo-C++thestackspacemustbefewerthan64,000bytes.Thismayseemlikealotofspace,butseverallargearrayscaneatitupquickly.Youshouldconsidermakingalllargearrayspermanent.Localvariablesaretemporaryunlesstheyaredeclaredstatic.NOTEstatichasanentirelydifferentmeaningwhenusedwithglobalvariables.(Itindicatesthatavariableislocaltothecurrentfile.)SeeChapter23,ModularProgramming.Foracompletediscussionofthemanymeaningsoftheword"static,"seeTable14-1.Example9-1illustratesthedifferencebetweenpermanentandtemporaryvariables.Wehavechosenobviousvariablenames;temporaryisatemporaryvariablewhilepermanentispermanent.C++initializestemporaryeachtimeitiscreated(atthebeginningoftheforstatementblock),whilepermanentgetsinitializedonlyonce,atprogramstart-uptime.Intheloopbothvariablesareincremented.However,atthetopofthelooptemporaryisinitializedto1.Page132Example9-1perm/perm.cc #includemain(){intcounter;//Loopcounterfor(counter=0;counter<3;++counter){inttemporary=1;staticintpermanent=1;cout<<"Temporary"<main(){//Functiontocomputeareaoftrianglefloattriangle(floatwidth,floatheight);cout<<"Triangle#1"<//Thisfunctionwon'tworkvoidinc_counter(intcounter){++counter;}main(){inta_count=0;//Randomcounterinc_counter(a_count);cout<//Worksvoidinc_counter(int&counter){++counter;}main(){inta_count=0;//Randomcounterinc_counter(a_count);cout<23constint&min(constint&il,constint&i2)4{5if(i1=0.Butwhathappensifwetrytocomputefact(-3)?Theprogramabortswithastackoverfloworsimilarmessage.fact(-3)callsfact(-4)callsfact(-5)andsoon.Thereisnoendingpoint.Thisiscalledaninfiniterecursionerror.Manythingswedoiterativelycanbedonerecursively,suchassummingtheelementsofanarray.Youcandefineafunctiontoaddelementsmthroughnofanarrayasfollows:Ifyouhaveonlyoneelement,thenthesumissimple.Otherwise,itisthesumofthefirstelementandthesumoftherest.InC++thisis:intsum(intfirst,intlast,intarray[]){if(first==last)return(array[first]);/*else*/return(array[first]+sum(first+1,last,array));}Page149Forexample: Sum(1832)=1+Sum(832)=8+Sum(32)=3+Sum(2)=23+2=53+2=58+5=131+13=14Answer=14ProgrammingExercisesExercise9-1:Writeaprocedurethatcountsthenumberofwordsinastring.(Yourdocumentationshoulddescribeexactlyhowyoudefineaword.)Writeaprogramtotestyournewprocedure.Exercise9-2:Writeafunction"begins(string1,string2)"thatreturnstrueifstring1beginsstring2.Writeaprogramtotestthefunction.Exercise9-3:Writeafunctioncount(number,array,length)thatwillcountthenumberoftimesnumberappearsinarray.Thearrayhaslengthelements.Thefunctionshouldberecursive.Writeatestprogramtogowiththefunction.Exercise9-4:Writeafunctionthatwilltakeacharacterstringandreturnaprimitivehashcodebyaddingupthevalueofeachcharacterinthestring.Exercise9-5:Writeafunctionthatreturnsthemaximumvalueofanarrayofnumbers.Exercise9-6:Writeafunctionthatscansastringforthecharacter''-"andreplacesitwith"_".AnswerstoChapterQuestionsAnswer9-1:Theprogrammerwenttoalotoftroubletoexplainthattheforloopdidnothing(exceptincrementtheindex).However,thereisnosemicolonattheendofthefor.C++keepsreadinguntilitseesastatement(inthiscasereturn(index))andputsthatintheforloop.Example9-11containsacorrectlywrittenversionoftheprogram.Example9-11.length/rlen.ccintlength(charstring[]){intindex;//indexintothestring/*Page150Example9-11length/rlencc(Continued)*Loopuntilwereachtheendofstringcharacter*/ for(index=0;string[index]!='';++index)/*donothing*/;return(index);}Page15110TheC++PreprocessorInThisChapter:·#defineStatement·ConditionalCompilation·#includeFiles·ParameterizedMacros·AdvancedFeatures·Summary·ProgrammingExercises·AnswerstoChapterQuestionsThespeechofmanislikeembroideredtapestries.sincelikethemthishastobeextendedinordertodisplayitspatterns,butwhenitisrolledupitconcealsanddistortsthem—ThemistoclesThefirstCcompilershadnoconstantsorinlinefunctions.WhenCwasstillbeingdeveloped,itsoonbecameapparentthatCneededafacilityforhandlingnamedconstants,macros,andincludefiles.ThesolutionwastocreateapreprocessorthatisrunontheprogramsbeforetheyarepassedtotheCcompiler.Thepreprocessorisnothingmorethanaspecializedtexteditor.ItssyntaxiscompletelydifferentfromC'sandithasnounderstandingofCconstructs.Itismerelyadumbtexteditor.ThepreprocessorwasveryusefulandsoonitwasmergedintothemainCcompiler.TheC++compilerkeptthispre-processor.Onsomesystems,likeUNIX,itisstillaseparateprogram,automaticallyexecutedbythecompilerwrappercc.Someofthenewercompilers,likeTurbo-C++,havethepre-processorbuiltin.#defineStatementThe#definestatementcanbeusedtodefineaconstant.Forexample,thefollowingtwolinesperformsimilarfunctions:#defineSIZE20//Thearraysizeis20 constintSIZE=20;//Thearraysizeis20Actuallytheline#defineSIZE20actsasacommandtothepreprocessortogloballychangeSIZEto20.Thistakesthedrudgeryandguessworkoutofmakingchanges.Page152Allpreprocessorcommandsbeginwithahashmark(#)incolumn1.C++isfreeformat.Languageelementscanbeplacedanywhereonaline,andtheend-of-lineistreatedjustlikeaspace.Thepreprocessorisnotfreeformat.Itdependsonthehashmark(#)beinginthefirstcolumn.Asyouwillsee,thepreprocessorknowsnothingaboutC++andcanbe(andis)usedtoeditthingsotherthanC++programs.WARNINGThepreprocessorisnotpartoftheC++compiler.Itusesanentirelydifferentsyntaxandrequiresanentirelydifferentmind-settouseitwell.MostproblemsyouwillseeoccurwhenthepreprocessoristreatedlikeC++.Preprocessordirectivesterminateattheendoftheline.InC++asemicolon(;)endsastatement.Thepreprocessordirectivesdonotendinasemicolon,andputtingoneincanleadtounexpectedresults.Apreprocessordirectivecanbecontinuedbyputtingabackslash()attheendoftheline.Thesimplestuseofthepreprocessoristodefineareplacementmacro.Forexample,thecommand:#defineFOObarcausesthepreprocessortoreplacetheword"FOO"withtheword"bar"everywhere"FOO"occurs.Itiscommonprogrammingpracticetousealluppercaselettersformacronames.Thismakesitveryeasytotellthedifferencebetweenavariable(alllowercase)andamacro(alluppercase).Thegeneralformofasimpledefinestatementis:#defineNameSubstitute-TextNamecanbeanyvalidC++identifier.Substitute-Textcanbeanythingaslongasitfitsonasingleline.TheSubstitute-Textcanincludespaces,operators,andothercharacters.Itispossibletousethefollowingdefinition:#defineFOR_ALLfor(i=0;i#defineFIRST_PART7#defineLAST_PART5#defineALL_PARTSFIRST_PART+LAST_PARTmain()cout<<"Thesquareofallthepartsis"<45#defineMAX1067main()8{9intcounter;1011for(counter=MAX;counter>0;12--counter)13cout<<"Hithere ";1415return(0);16}Hint:Takealookatthepreprocessoroutput.Question10-3:Example10-3computesthewrongvalueforsize.Why?Example10-5.size/sizecc#include#defineSIZE10;#defineFUDGESIZE-2;main(){intsize;//Sizetoreallyusesize=FUDGE;cout<<"Sizeis"<2#include/*ANSIStandardonly*/34#defineDIE5cerr<<"FatalError:Abort ";exit(8);67main(){8//Arandomvaluefortesting9intvalue;1011value=1; 12if(value<0)13DIE;1415cerr<<"Wedidnotdie ";16return(0);17}#defineversusconstTheconstkeywordisrelativelynew.Beforeconst,#definewastheonlywaytodefineconstants,somostoldercodeuses#definedirectives.However,theuseofconstispreferredover#defineforseveralreasons.Firstofall,C++checksthesyntaxofconststatementsimmediately.The#definedirectiveisnotcheckeduntilthemacroisused.Also,constusesC++syntax,while#definehasasyntaxallitsown.Finally,constfollowsnormalC++scoperules,whereasconstantsdefinedbya#definedirectivecontinueonforever.Inmostcasesaconststatementispreferredover#define.Herearetwowaysofdefiningthesameconstant.#defineMAX10//Defineavalueusingthepre-processor//(Thiscaneasilycauseproblems)constintMAX=10;//DefineaC++constantinteger//(Safer)The#definedirectiveislimitedtodefiningsimpleconstants.TheconststatementcandefinealmostanytypeofC++constantincludingthingssuchasstructureclasses.Forexample:structbox(intwidth,height;//Dimensionsoftheboxinpixels};Page157//Sizeofapinkboxtobeusedforinputconstboxpinkbox(1.0,4.5);The#definedirectiveis,however,essentialforthingssuchasconditionalcompilationandotherspecializeduses.ConditionalCompilationOneproblemprogrammershaveiswritingcodethatcanworkonmanydifferentmachines.Intheory,C++codeisportable;inactualpracticemanymachineshavelittlequirksthatmustbeaccountedfor.Forexample,thisbookcoversUNIX,MSDOS,andWindowscompilers.Althoughtheyarealmostthesame,therearesomedifferences,asyouwillseeinChapter25,PortabilityProblems.Thepreprocessorallowsyougreatflexibilityinchangingthewaycodeisgeneratedthroughtheuseofconditionalcompilation.Supposeyouwanttoputdebuggingcodeintheprogramwhileyouareworkingonitandthenremovethedebuggingcodeintheproductionversion.Youcould dothisbyincludingthecodeinan#ifdef-#endifsection.#ifdefDEBUGcout<<"Incompute_hash,value"<inyourprograms.Thistellsthepreprocessortotakethefileiostream.handinsertitinthecurrentprogram.Filesthatareincludedinotherprogramsarecalledheaderfiles.(Most#includedirectivescomeattheheadoftheprogram.)Theanglebracketsindicatethatthefileisastandardheaderfile.InUNIX,thesefilesareusuallylocatedin/usr/include.InMS-DOS/Windows,theyarelocatedintheTurbo-C++directory(installationdependent). Standardincludefilesareusedfordefiningdatastructuresandmacrosusedbylibraryroutines.Forexample,coutisastandardclassthat(asyouknowbynow)printsdataonthestandardoutput.Theostreamclassdefinitionusedbycoutanditsrelatedroutinesisdefinediniostream.h.Sometimesyoumaywanttowriteyourownsetofincludefiles.Localincludefilesareparticularlyusefulforstoringconstantsanddatastructureswhenaprogramspansseveralfiles.Theyareespeciallyusefulforinformationsharingwhenateamofprogrammersisworkingonasingleproject.(SeeChapter23,ModularProgramming.)Localincludefilesmaybespecifiedbyusingdoublequotationmarks(")aroundthefilename.#include"defs.h"Thefilename("defs.h")canbeanyvalidfilename.Thiscanbeasimplefile,"defs.h";arelativepath,called"../../data.h";oranabsolutepath,called"/root/include/const.h".(InMS-DOS/Windowsyoushouldusebackslash()insteadofslash(/)asadirectoryseparator.)Page160Includefilesmaybenested.Thiscancauseproblems.Supposeyoudefineseveralusefulconstantsinthefileconst.h.Ifthefilesdata.handio.hbothincludeconst.handyouputthefollowinginyourprogram:#include"data.h"#include"io.h"yougenerateerrorsbecausethepreprocessorsetsthedefinitionsinconst.htwice.Definingaconstanttwiceisnotafatalerror;however,definingadatastructureoruniontwiceisanerrorandmustbeavoided.Onewayaroundthisproblemistohaveconst.hchecktoseewhetherithasalreadybeenincludedandnotdefineanysymbolsthathavealreadybeendefined.Lookatthefollowingcode:#ifndef_CONST_H_INCLUDED_/*Defineconstants*/#define_CONST_H_INCLUDED_#endif/*_CONST_H_INCLUDED_*/Whenconst.hisincluded,itdefinesthesymbol_CONST_H_INCLUDED_.Ifthatsymbolisalreadydefined(becausethefilewasincludedearlier),the#ifdefconditionalhidesalltheotherdefinessotheydon'tcausetrouble.NOTEItispossibletoputcodeinaheaderfile.Thisisconsideredpoorprogrammingpractice.Byconvention,codegoesin.ccfilesanddefinitions,declarations,macros,andinlinefunctionsgointhe.h files.ParameterizedMacrosSofarwehavediscussedonlysimple#definesormacros.Macroscantakeparameters.Thefollowingmacrocomputesthesquareofanumber:#defineSQR(x)((x)*(x))/*Squareanumber*/Whenused,themacroreplacesxbythetextofitsargument.SQR(5)expandsto((5)*(5)).Itisagoodrulealwaystoputparenthesesaroundtheparametersofamacro.Example10-7illustratestheproblemsthatcanoccurifthisruleisnotfollowed:Example10-7.sqr/sqr.cc#include#defineSQR(x)(x*x)main()Page161Example10-7.sqr/sqr.cc(Continued){intcounter;//Councerforloopfor(counter=0;counter<5;++counter){cout<<"x"<#defineSQR(x)((x)*(x))main(){intcounter;/*Counterforloop*/counter=0;while(counter<5)cout<<"x<#defineRECIPROCAL(number)(1.0/(number))Page162Example10-9.rec/rec.cc(Continued)main()}floatcounter;for(counter=0.0;counter<10.0;counter+=1.0)cout<<"1/"<0;--counter)C++allowsyoutocomputearesultandthrowitaway.Forthisstatement,theprogramcheckstoseewhethercounteris10anddiscardstheanswer.Removingthe=fromthedefinitionwillcorrecttheproblem.Answer10-3:Aswiththepreviousproblem,thepreprocessordoesnotrespectC++syntaxconventions.Inthiscasetheprogrammerusedasemicolontoendthestatement,butthepreprocessorincludeditaspartofthedefinitionforsize.Theassignmentstatementforsize,expanded,is:size=10;-2;;Thetwosemicolonsattheenddonothurtanything,buttheoneinthemiddleisakiller.ThislinetellsC++todotwothings:1)assign10tosizeand2)computethevalue-2andthrowitaway(thisresultsinthenulleffectwarning).Removingthesemicolonswillfixtheproblem.Answer10-4:Theoutputofthepreprocessorlookslike:voidexit();main(){intvalue;value=1;if(value<0)cout<<"FatalError:Abort ";exit(8);cout<<"Wedidnotdie ";return(0); }Page165Theproblemisthattwostatementsfollowtheifline.Normallytheywouldbeputontwolines.Ifweproperlyindentthisprogramweget:Example10-10die3/die.cc#include#includemain(){intvalue;//Arandomvaluefortestingvalue=1;if(value<0)cout<<"FatalError:Abort ";exit(8);cout<<"Wedidnotdie ";return(0);}Fromthisitisobviouswhywealwaysexit.Thefactthatthereweretwostatementsaftertheifwashiddenbyusingasinglepreprocessormacro.Thecureforthisproblemistoputcurlybracesaroundallmultistatementmacros.#defineDIE{cout<<"FatalError:Abort ";exit(8);}Answer10-5:TheproblemisthatthepreprocessordoesnotunderstandC++syntax.Themacrocall:SQR(counter+l)expandsto:(counter+l*counter+l)Theresultisnotthesameas((counter+l)*(counter+1)).Toavoidthisproblem,useinlinefunctionsinsteadofparameterizedmacros.inlineintSQR(intx){return(x*x);}Ifyoumustuseparameterizedmacros,encloseeachuseoftheparameterinparentheses.#defineSQR(x)((x)*(x))Answer10-6:Theonlydifferencebetweenaparameterizedmacroandonewithoutparametersistheparenthesesimmediatelyfollowingthemacroname.Inthiscase,aspacefollowsthedefinitionofRECIPROCAL,soitisnotaparameterizedmacro.InsteaditisasimpletextreplacementmacrothatreplacesRECIPROCALwith:(number)(1.0/number) RemovingthespacebetweenRECIPROCALand(number)correctstheproblem.Page16711BitOperationsInThisChapter:·BitOperators·TheANDOperator·BitwiseOR·TheBitwiseExclusiveOR·TheOnes·Complement·Operator·TheLeftandRightShiftOperators·Setting,Clearing,andTestingBits·BitmappedGraphics·Exercises·AnswerstoQuestionsTobeornottobe,thatisthequestion.—ShakespeareonBooleanAlgebraThischapterdiscussesbit-orientedoperations.Abitisthesmallestunitofinformation.Normallyitisrepresentedbythevalues1and0.(Otherrepresentationsincludeon/off,true/false,andyes/no.)Bitmanipulationsareusedtocontrolthemachineatthelowestlevel.Theyallowtheprogrammertoget''underthehood"ofthemachine.Manyhigher-levelprogramswillneverneedbitoperations.Lowlevelcodingsuchaswritingdevicedriversorpixel-levelgraphicprogrammingrequiresbitoperations.Ifyouplantoprogramonlyatahigherlevel,thischaptermaybesafelyskipped.Eightbitstogetherformabyte,representedbytheC++datatypechar.Abytemightcontainthefollowingbits:01100100.Thiscanalsobewrittenasthehexadecimalnumber0x64.(C++usestheprefix"Ox"toindicateahexadecimal(base16)number.)Hexadecimalisconvenientforrepresentingbinarydatabecauseeachhexadecimaldigitrepresents4binarybits.Table11-1givesthehexadecimal(hex)tobinaryconversion: Table11-1.HexandBinaryHexBinaryHexBinary0000081000100019100120010A101030011B1011Page168Table11-1.HexandBinary(Continued)HexBinaryHexBinary40100C110050101D110160110E111070111F1111Sothehexadecimalnumber0xAFrepresentsthebinarynumber10101111.BitOperatorsBit,orbitwise,operatorsallowtheprogrammertoworkonindividualbits.Forexample,ashortintegerholds16bits(onmostmachines).Thebitoperatorstreateachoftheseasanindependentbit.Bycontrast,anaddoperatortreatsthe16bitsasasingle16-bitnumber.Bitoperatorsallowyoutoset,clear,test,andperformotheroperationsonbits.ThebitoperatorsarelistedinTable11-2.Table11-2BitOperatorsOperatorMeaning&BitwiseANDIBitwiseOR^BitwiseexclusiveOR-Complement<>ShiftrightTheseoperatorsworkonanyintegerorcharacter-datatype.TheANDOperator(&)TheANDoperatorcomparestwobits.Iftheybothare1,theresultis1.TheresultsoftheANDoperatoraredefinedinTable11-3.Table11-3ANDOperatorBit1Bit2Bit1&Bit2O00010100111Page169Whentwoeight-bitvariables(charvariables)are"ANDed"together,theANDoperatorworksoneachbitindependently.Thefollowingprogramsegmentillustratesthisoperation:intc1,c2;cl=0x45;c2=0x71;cout<<"Resultof"<main(){inti1,i2;//Tworandomintegersil=4;i2=2;//Setvalues//Nicewayofwritingtheconditionalif((il!=0)&&(i2!=0))cout<<"Botharenotzero#1 ";//Shorthandwayofdoingthesamething//CorrectC++code,butrottenstyleif(il&&i2)cout<<"Botharenotzero#2 ";//IncorrectuseofbitwiseANDresultinginanerrorif(il&i2)cout<<"Botharenotzero#3 ";Page170Example11-1and/andcc(Continued)return(0);}Question:Whydoestest#3failtoprintBotharenotzero#3?Answer:Theoperator&isabitwiseAND.TheresultofthebitwiseANDiszero.il=400000100i2=200000010&00000000TheresultofthebitwiseANDis0,andtheconditionalisfalse.Iftheprogrammerhadusedthefirstform:if((i1!=0)&&(i2!=0))andmadethemistakeofusing&insteadof&&:if((i1!=0)&(i2!=0)) theprogramwouldstillhaveexecutedcorrectly.(i1!=0)istrue(result=1)(i2!=0)istrue(result=1)1bitwiseAND1is1,sotheexpressionistrue.NOTESoonafterdiscoveringthebugillustratedbythisprogramItoldmyofficemate,"InowunderstandthedifferencebetweenANDandANDAND),andheunderstoodme.Howweunderstandlanguagehasalwaysfascinatedme,andthefactthatIcoulduttersuchasentenceandhavesomeoneunderstanditwithouttroubleamazedme.YoucanusethebitwiseANDoperatortotestwhetheranumberisevenorodd.Inbase2,thelastdigitofallevennumbersiszeroandthelastdigitofalloddnumbersisone.ThefollowingfunctionusesthebitwiseANDtopickoffthislastdigit.Ifitiszero(anevennumber),theresultofthefunctionistrue.inlineinteven(constintvalue){return((value&1)==0);}Page171BitwiseOR(|)TheinclusiveORoperator(alsoknownasjusttheORoperator)comparesitstwooperands.Ifoneortheotherbitisa1,theresultis1.Table11-4liststhetruthtablefortheORoperator.Table11-4.BitwiseORBit1Bit2BitIBit2000011101111Onabytethiswouldbe:il=0x4701000111i2=0x5301010011|5701010111 TheBitwiseExclusiveOR(^)TheexclusiveOR(alsoknownasXOR)operatorresultsina1wheneitherofitstwooperandsisa1,butnotboth.ThetruthtablefortheexclusiveORoperatorislistedinTable11-5.Table11-5ExclusiveORBit1Bit2Bit1^Bit2000011101110Onabytethiswouldbe:il=0x4701000111i2=0x5301010011^1400010100TheOnesComplementOperator(NOT)(~)TheNOToperator(alsocalledtheinvertoperatororbitflip)isaunaryoperatorthatreturnstheinverseofitsoperand,asshowninTable11-6.Table11-6NOTOperatorBit~Bit0110Page172Onabytethisis:c=0x4501000101~c=0xBA10111010TheLeftandRightShiftOperators(<<,>>) Theleftshiftoperatormovesthedataleftaspecifiednumberofbits.Anybitsthatareshiftedouttheleftsidedisappear.Newbitscominginfromtherightarezeros.Therightshiftdoesthesamethingintheotherdirection.Forexample:c=0xlC00011100c<<1c=0x3800111000c>>2c=0x070000011Shiftingleftbyone(x<<1)isthesameasmultiplyingby2(x*2).Shiftingleftbytwo(x<<2)isthesameasmultiplyingby4(x*4,orx*22).Youcanseeapatternforminghere.Shiftingleftbynplacesisthesameasmultiplyingby2n.Whyshiftinsteadofmultiply?Shiftingisfasterthanmultiplication,soi=j<<3;//Multiplyjby8(2**3)isfasterthan:i=j*8;Oritwouldbefasterifcompilersweren'tsmartenoughtoturn"multiplybypoweroftwo"into"shift."Manycleverprogrammersusethistricktospeeduptheirprogramsatthecostofclarity.Don'tyoudoit.Thecompilerissmartenoughtoperformthespeedupautomatically.Thismeansthatputtinginashiftgainsyounothingattheexpenseofclarity.Theleftshiftoperatormultiplies;therightshiftdivides.So:q=i>>2;isthesameas:q=i/4;Again,thisclevertrickshouldnotbeusedinmoderncode.RightShiftDetailsRightshiftsareparticularlytricky.Whenavariableisshiftedtotheright,C++needstofillthespaceontheleftsidewithsomething.Forsignedvariables,C++Page173usesthevalueofthesignbit.Forunsignedvariables,C++useszero.Table11-7illustratessometypicalrightshifts.Table11-7RightShiftExamplesSignedSignedCharacterUnsignedCharacterCharacterExpression9>>2-8>>2248>>2Binaryvalue>>2000010102>>2111110002>>2111110002>>2 Binaryvalue>>2000010102>>2111110002>>2111110002>>2Result??0000102??1111102>>2??1111102>>2FillSignbit(0)Signbit(1)ZeroFinalresult(binary)000000102111111102001111102Finalresult(shortint)2-262Setting,Clearing,andTestingBitsAcharactercontainseightbits.Eachofthesecanbetreatedasaseparateflag.Bitoperationscanbeusedtopackeightsingle-bitvaluesinasinglebyte.Forexample,supposeyouarewritingalow-levelcommunicationsprogram.Youaregoingtostorethecharactersinan8Kbufferforlateruse.Witheachcharacteryouwillalsostoreasetofstatusflags.TheflagsarelistedinTable11-8.Table11-8CommunicationsStatusValuesNameDescriptionERRORTrueifanyerrorissetFRAMING_ERRORAframingerroroccurredforthischaracterPARITY_ERRORCharacterhadthewrongparityCARRIER_LOSTThecarriersignalwentdownCHANNELDOWNPowerwaslostonthecommunicationdeviceYoucouldstoreeachflaginitsowncharactervariable.Thatwouldmeanthatforeachcharacterbuffered,youwouldneedfivebytesofstatusstorage.Foralargebuffer,thataddsup.Byinsteadassigningeachstatusflagitsownbitwithinaneight-bitstatuscharacter,youcutstoragerequirementsdownto1/5oftheoriginalneed.YoucanassigntheflagsthebitnumberslistedinTable11-9.Table11-9.BitAssignmentsBitName0ERROR1FRAMING_ERROR2PARITY_ERRORPage174 Table11-9BitAssignments(Continued)BitName3CARRIER_LOST4CHANNEL_DOWNBitsarenumbered76543210byconvention.TheconstantsforeachbitaredefinedinTable11-10.Table11-10BitValuesBitBinaryValueHexConstant7100000000x806010000000x4050001000000x204000100000x103000010000x0820000001000x041000000100x020000000010x01Thedefinitionscouldbe://TrueifanyerrorissetconstintERROR=0x01;//AframingerroroccurredforthischaracterconstintFRAMING_ERROR=0x02;//CharacterhadthewrongparityconstintPARITY_ERROR=0x04;//ThecarriersignalwentdownconstintCARRIER_LOST=0x08;//PowerwaslostonthecommunicationdeviceconstintCHANNEL_DOWN=0x10;Thismethodofdefiningbitsissomewhatconfusing.Canyoutell(withoutlookingatthetable)whichbitnumberisrepresentedbytheconstant0x10?Table11-11showshowyoucanusetheleftshiftoperator(<<)todefinebits. Table11-11.TheLeftShiftOperatorandBitDefinitionC++RepresentationBase2EquivalentResult(Base2)BitNumber1<<0000000012<<0000000012Bit01<<1000000012<<1000000102Bit11<<2000000012<<2000001002Bit2Page175Table11-11TheLeftShiftOperatorandBitDefinition(Continued)C++RepresentationBase2EquivalentResult(Base2)BitNumber1<<3000000012<<3000010002Bit31<<4000000012<<4000100002Bit41<<5000000012<<5001000002Bit51<<6000000012<<6010000002Bit61<<7000000012<<7100000002Bit7Althoughitishardtotellwhatbitisrepresentedby0x10,it'seasytotellwhatbitismeantby1<<4.Theflagscanbedefinedas://TrueifanyerrorissetconstintERROR=(1<<0);//AframingerroroccurredforthischaracterconstintFRAMING_ERROR=(1<<1);//CharacterhadthewrongparityconstintPARITY_ERROR=(1<<2);//ThecarriersignalwentdownconstintCARRIER_LOST=(1<<3);//PowerwaslostonthecommunicationdeviceconstintCHANNEL_DOWN=(1<<4);Nowthatyouhavedefinedthebits,youcanmanipulatethem.Tosetabit,usethe|operator.Forexample:charflags=0;//Startallflagsat0flags|=CHANNEL_DOWN;//Channeljustdied Totestabit,usethe&operatorto"maskout"thebits.if((flags&ERROR)!=0)cerr<<"Errorflagisset ";elsecerr<<"Noerrordetected ";Clearingabitisalittleharder.SupposeyouwanttoclearthebitPARITY_ERROR.Inbinarythisbitis00000100.Youwanttocreateamaskthathasallbitssetexceptforthebityouwanttoclear(11111011).ThisisdonewiththeNOToperator(~).ThemaskisthenANDedwiththenumbertoclearthebit.PARITY_ERROR00000100~PARITY_ERROR11111011Page176flags00000101flags&~PARITY_ERROR00000001InC++thisis:flags&=~PARITY_ERROR;//WhocaresaboutparityQuestion11-1:Inthefollowingprogram,theHIGH_SPEEDflagworks,buttheDIRECT_CONNECTflagdoesnot.Why?#includeconstintHIGH_SPEED=(1<<7);/*modemisrunningfast*///weareusingahardwiredconnectionconstintDIRECT_CONNECT=(1<<8);charflags=0;//startwithnothingmain(){flags|=HIGH_SPEED;//wearerunningfastflags|=DIRECT_CONNECT;//becausewearewiredtogetherif((flags&HIGH_SPEED)!=0)cout<<"Highspeedset ";if((flags&DIRECT_CONNECT)!=0)cout<<"Directconnectset ";return(0);}BitmappedGraphicsMoreandmorecomputersnowhavegraphics.ForthePC,therearegraphicsdeviceslikeEGAandVGAcards.ForUNIX,thereistheXwindowingsystem. Inbitmappedgraphics,eachpixelonthescreenisrepresentedbyasinglebitinmemory.Forexample,Figure11-1showsa14-by-14bitmapasitappearsonthescreenandenlargedsoyoucanseethebits.Supposewehaveasmallgraphicdevice—a16-by-16pixelmonochromedisplay.Wewanttosetthebitat4,7.ThebitmapforthisdeviceisshownasanarrayofbitsinFigure11-2.Butwehaveaproblem.ThereisnodatatypeforanarrayofbitsinC++.Theclosestwecancomeisanarrayofbytes.Our16-by-16arrayofbitsnowbecomesa2-by-16arrayofbytes,asshowninFigure11-3.Tosetthepixelatbitnumber4,7weneedtosetthefourthbitofbyte0,7.Tosetthisbitwewouldusethestatement:bit_array[0][7]|=(0x80>>(4));Page177Figure11-1.Bitmap,actualsizeandenlarged Figure11-2.ArrayofbitsPage178Figure11-3ArrayofbytesTheconstant0x80istheleftmostbit.Wecangeneralizethisprocesstoproduceamacrothatturnsonthebit(pixel)locatedat(x,y).Weneedtocomputetwovalues:thecoordinateofthebyteandthenumberofthebitwithinthebyte.Ourbitaddressis(x,y).Bytesaregroupsofeightbits,sothatmeansthatourbyteaddressis(x/8,y).Thebitwithinthebyteisnotsosimple.Wewanttogenerateamaskconsistingofthesinglebit wewanttoset.Fortheleftmostbitthisshouldbe100000002,or0x80.Thisoccurswhen(x%8)==0.Thenextbitis010000002,or(0x80>>1),andoccurswhen(x%8)==1.Sotogenerateourbitmaskweusetheexpression(0x80>>(x%8)).Nowthatwehavethebytelocationandthebitmask,allwehavetodoissetthebit.Thefollowingfunctionsetsagivenbitinabitmappedgraphicsarraynamedgraphics.voidinlineset_bit(constintx,constinty){graphics[(x)/8][y]|=(0x80>>((x)%8))}Page179Example11-2drawsadiagonallineacrossthegraphicsarrayandthenprintsthearrayontheterminal.Example11-2.graph/graph.cc#includeconstintX_SIZE=40;//SizeofarrayintheXdirectionconstintY_SIZE=60;//SizeofarrayintheYdirection/**WeuseX_SIZE/8sincewepack8bitsperbyte*/chargraphics[X_SIZE/8][Y_SIZE];//Thegraphicsdata/*******************************************************set_bit--setabitinthegraphicsarray****Parameters**x,y--locationofthebit*******************************************************/inlinevoidset_bit(constintx,constinty){graphics[(x)/8][y]|=(0x80>>((x)%8));}main(){intloc;//Currentlocationwearesettingvoidprint_graphics(void);//Printthedatafor(loc=0;loc0;bit=(bit>>1))if((graphics[x][y]&bit)!=0)Page180Example11-2graph/graphcc(Continued)cout<<'X';elsecout<<'.';}}cout<<' ';}}Theprogramdefinesabitmappedgraphicsarray:chargraphics[X_SIZE/8][YSIZE];//ThegraphicsdataTheconstantX_SIZE/8isusedsincewehaveX_SIZEbitsacross,whichtranslatestoX_SIZE/8bytes.Themainforloop:for(loc=0;loc0;bit=(bit>>1))whichusesanunusualloopcounter.Thisloopcausesthevariablebittostartwithbit7(the leftmostbit).Foreachiterationoftheloop,thebitismovedtotherightonebitbybit=(bit>>1).Whenwerunoutofbits,theloopexits.Theloopcountercyclesthrough.Finally,attheheartoftheloopsisthecode:BinaryHex00000000100000000x8000000000010000000x40Page181BinaryHex00000000001000000x2000000000000100000x1000000000000010000x0800000000000001000x0400000000000000100x0200000000000000010x01if((graphics[x][y]&bit)!=0)cout<<"X";elsecout<<".";Thistestsanindividualbitandwrites''X"ifthebitissetor"."ifthebitisnotset.Question11-2:InExample11-3thefirstloopworks,butthesecondfails.Why?Example11-3loop/loop.cc#includemain(){shortinti;//Worksfor(i=0x80;i!=0;i=(i>>1)){cout<<"iis"<>1)) cout<<"chis"<>1is110000002.Thevariableiworkseventhoughitissignedbecauseitis16bitslong.So0x80in16bitsis00000000100000002.Noticethatthebitwe'vegotsetisnowherenearthesignbit.Thesolutiontotheproblemistodeclarechasanunsignedvariable.Page183IIIAdvancedTypesandClassesPage185 12AdvancedTypesInThisChapter:·Structures·Unions·typedef·enumType·BitFieldsorPackedStructures·ArraysofStructures·ProgrammingExercisesTotalgrandeurofatotaledifice.Chosenbyaninquisitorofstructures—WallaceStevensC++providesarichsetofdatatypes.Throughtheuseofstructures,unions,enum,andclasstypes,theprogrammercanextendthelanguagewithnewtypes.StructuresSupposeyouarewritinganinventoryprogramforawarehouse.Thewarehouseisfilledwithbinseachcontainingabunchofparts.Allthepartsinabinareidentical,soyoudon'thavetoworryaboutmixedbinsorpartials.Foreachbinyouneedtoknow:·Thenameofthepartitholds(characterstring30long).·Thequantityonhand(integer).·Theprice(integercents).Inpreviouschaptersyouhaveusedarraysforstoringagroupofsimilardatatypes,butinthisexampleyouhaveamixedbag:twointegersandastring.Insteadofanarray,youwilluseanewdatatypecalledastructure.Inanarray,alltheelementsareofthesametypeandarenumbered.Inastructure,eachelement,orfield,isnamedandhasitsowndatatype.Page186Thegeneralformofastructuredefinitionis:structstructure-name{field-typefield-name//Comment field-typefield-name//Comment....}variable-name;Forexample,youwanttodefineabintoholdprintercables.Thestructuredefinitionis:structbin{charname[30];//Nameofthepartintquantity;//Howmanyareinthebinintcost;//Thecostofasinglepart(incents)}printer_cable_box;//WhereweputtheprintcablesThisdefinitionactuallytellsC++twothings.Thefirstiswhatastructbinlookslike.Thisstatementdefinesanewdatatypethatcanbeusedindeclaringothervariables.Thisstatementalsodeclaresthevariableprinter_cable_box.Sincethestructureofabinhasbeendefined,youcanuseittodeclareadditionalvariables:structbinterminal_cable_box;//PlacetoputterminalcablesThestructure-namepartofthedefinitionmaybeomitted.struct{charname[30];//Nameofthepartintquantity;//Howmanyareinthebinintcost;//Thecostofasinglepart(incents)}printer_cable_box;//WhereweputtheprintcablesThevariableprinter_cable_boxisstilltobedefined,butnodatatypeiscreated.Thedatatypeforthisvariableisananonymousstructure.Thevariable-namepartalsomaybeomitted.Thiswoulddefineastructuretypebutnovariables.structbin{charname[30];//Nameofthepartintquantity;//Howmanyareinthebinintcost;//Thecostofasinglepart(incents)};Inanextremecase,boththevariable-nameandthestructure-namepartsmaybeomitted.Thiscreatesasectionofcorrectbuttotallyuselesscode.Oncethestructuretypehasbeendefinedyoucanuseittodefinevariables:structbinprinter_cable_box;//DefinetheboxholdingprintercablesC++allowsthestructtobeomitted,soyoucanusethefollowingdeclaration:binprinter_cable_box;//DefinetheboxholdingprintercablesPage187Youhavedefinedthevariableprinter_cable_boxcontainingthreenamedfields:name,quantity,andcost.Toaccessthemyouusethesyntax:variable.fieldForexample,ifyoujustfoundoutthatthepriceofthecableswentupto$12.95,youwoulddo thefollowing:printer_cable_box.cost=1295;//$12.95isthenewpriceTocomputethevalueofeverythinginthebin,youcansimplymultiplythecostbythenumberofitemsusingthefollowing:total_cost=printer_cable_box.cost*printer_cable_box.quantity;Structuresmaybeinitializedatdeclarationtimebyputtingthelistofelementsincurlybraces({})./**Printercables*/structbin{charname[30];//Nameofthepartintquantity;//Howmanyareinthebinintcost;//Thecostofasinglepart(incents)};structbinprinter_cable_box={"PrinterCables",//Nameoftheiteminthebin0,//Startwithemptybox1295//Cost--$12.95};Thedefinitionofthestructurebinandthevariableprinter_cable_boxcanbecombinedinonestep:structbin{charname[30];//Nameofthepartintquantity;//Howmanyareinthebinintcost;//Thecostofasinglepart(incents)}printer_cable_box={"PrinterCables",//Nameoftheiteminthebin0,//Startwithemptybox1295//Cost--$12.95};Page188UnionsAstructureisusedtodefineadatatypewithseveralfields.Eachfieldtakesupaseparatestoragelocation.Forexample,thestructurestructrectangle{intwidth;intheight;};appearsinmemoryasshowninFigure12-1.Aunionissimilartoastructure;however,itdefinesasinglelocationthatcanbegivenmanydifferentfieldnames.unionvalue{ longinti_value;//Longintegerversionofvaluefloatf_value;//Floatingversionofvalue}Figure12-1StructureandunionlayoutThefieldsi_valueandf_valuesharethesamespace.Youmightthinkofastructureasalargeboxdividedupintoseveraldifferentcompartments,eachwithitsownname.Aunionisabox,notdividedatall,withseveraldifferentlabelsplacedonthesinglecompartmentinside.Inastructure,thefieldsdonotinteract.Changingonefielddoesnotchangeanyothers.Inaunion,allfieldsoccupythesamespace,soonlyonemaybeactiveatatime.Inotherwords,ifyouputsomethingini_value,assigningsomethingtof_valuewipesouttheoldvalueofi_value.Page189Thefollowingshowshowaunionmaybeused:/**Defineavariabletoholdanintegeror*arealnumber(butnotboth)*/unionvalue{longinti_value;//Therealnumberfloatf_value;//Thefloatingpointnumber}data;inti;//Randomintegerfloatf;//Randomfloatingpointnumbermain(){data.f_value=5.0;data.i_value=3;//Data.f_valueoverwritteni=data.i_value;//Legalf=data.f_value;//Notlegal;willgenerateunexpectedresultsdata.f_value=5.5;//Putsomethinginf_value/clobberi_valuei=data.i_value;//Notlegal;willgenerateunexpectedresults Supposeyouwanttostoretheinformationaboutashape.Theshapecanbeanystandardshapesuchasacircle,rectangle,ortriangle.Theinformationneededtodrawacircleisdifferentfromthedataneededtodrawarectangle,soyouneedtodefinedifferentstructuresforeachshape:structcircle{intradius;//Radiusofthecircleinpixels};structrectangle{intheight,width;//Sizeoftherectangleinpixels};structtriangle{intbase;//Lengthofthetriangle'sbaseinpixelsintheight;//Heightofthetriangleinpixels};Nowyoudefineastructuretoholdthegenericshape.Thefirstfieldisacodethattellsyouwhattypeofshapeyouhave.Thesecondisaunionthatholdstheshapeinformation:constintSHAPE_CIRCLE=0;//ShapeisacircleconstintSHAPE_RECTANGLE=1;//ShapeisarectangleconstintSHAPE_TRIANGLE=2;//Shapeisatrianglestructshape{intkind;//Whatkindofshapeisstoredunionshape_union{//Uniontoholdshapeinformationstructcirclecircle_data;//DataforacirclePage190structrectanglerectangle_data;//Dataforarectanglestructtriangletriangle_data;//Dataforatriangle}data;};Graphicallyyoucanrepresentshapeasalargebox.Insidetheboxisthesingleintegerkindandourunionshape_union.Theunionisaboxwiththreelabelsonit.Thequestioniswhichoneisthe"real"label.Youcan'ttellfromlookingattheunion,butthat'swhyyoudefinedkindIttellsuswhichlabeltoread.ThelayoutoftheshapestructureisillustratedbyFigure12-2.Figure12-2"shape"layoutNowyoucanstoreacircleinthegenericshape: structshapea_shape;//...a_shape.kind=SHAPE_CIRCLE;a_shape.data.circle_data.radius=5.0;//DefinetheradiusofthecircletypedefC++allowsyoutodefineyourownvariabletypesthroughthetypedefstatement.ThisprovidesawayforyoutoextendC++'sbasictypes.Thegeneralformofthetypedefstatementis:typedeftype-declarationThetype-declarationisthesameasavariabledeclarationexceptatypenameisusedinsteadofavariablename.Forexample:typedefintwidth;//Defineatypethatisthewidthofanobjectdefinesanewtype,width,thatisthesameasaninteger.Sothedeclaration:widthbox_width;Page191isthesameas:intbox_width;Atfirstglance,thisisnotmuchdifferentfrom:#definewidthintwidthbox_width;However,typedefscanbeusedtodefinemorecomplexobjectswhicharebeyondthescopeofasimple#definestatement,suchas:typedefintgroup[10];Groupisnowanewtypedenotinganarrayof10integers.Forexample:main(){typedefintgroup[10];//Createanewtype"group"grouptotals;//Usethenewtypeforavariable//Initializeeachelementoftotalfor(i=0;i<10;++i)totals[i]=0;enumTypeTheenumerated(enum)datatypeisdesignedforvariablesthatcancontainonlyalimitedsetofvalues.Thesevaluesarereferencedbyname(tag).Thecompilerassignseachtaganinteger valueinternally,suchasthedaysoftheweek.Youcouldusethedirectiveconsttocreatevaluesforthedaysoftheweek(day_of_the_week)asfollows:typedefintday_of_the_week;//DefinethetypefordaysoftheweekconstintSUNDAY=0;constintMONDAY=1;constintTUESDAY=2;constintWEDNESDAY=3;constintTHURSDAY=4;constintFRIDAY=5;constintSATURDAY=6;/*Nowtouseit*/day_of_the_weektoday=TUESDAY;Page192Thismethodiscumbersome.Abettermethodistousetheenumtype:enumday_of_the_week{SUNDAY,MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY};/*Nowuseit*/enumday_of_the_weektoday=TUESDAY;Thegeneralformofanenumstatementis:enumenum-name{tag-1,tag-2,...}variable-nameAswithstructures,theenum-nameorthevariable-namemaybeomitted.ThetagsmaybeanyvalidC++identifier;however,tagsareusuallyalluppercase.AnadditionaladvantageofusinganenumtypeisthatC++willrestrictthevaluesthatcanbeusedtotheoneslistedintheenumdeclaration.Thefollowingwillresultinacompilererror:today=5;//5isnotaday_of_the_weekOnedisadvantageofusingenumisthatenumvariablescannotbeusedtoindexanarray.Thefollowingwillresultinanerror:enumdayoftheweektoday=TUESDAY;//Definestringversionsofourdaysoftheweekcharday_names[7][]={"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"}:.../**Thefollowinglinegeneratesawarning *becausetodayisnotaninteger*/cout<<"Todayis"<DesigningaStackYoustartastackdesignbydesigningthedatastructure.Thisstructurewillneedaplacetoputthedata(calleddata)andacountofthenumberofitemscurrentlypushedonthestack(calledcount):constintSTACK_SIZE=100;//Maximumsizeofastack//Thestackitselfstructstack{intcount;//Numberofitemsinthestackintdata[STACK_SIZE];//Theitemsthemselves};Nextyouneedtocreatetheroutinestohandlethepushandpopoperations.Thepushfunctionstorestheitemonthestackandthenincreasesthedatacount.inlinevoidstack_push(structstack&the_stack,constintitem){the_stack.data[the_stack.count]=item;++the_stack.count;}Note:Thisversionoftheprogramdoesnotcheckforstackoverfloworothererrorconditions.Later,inChapter14,MoreonClasses,you'llseehowyoucanusethissimplestacktomakeasafer,morecomplexone.Poppingsimplyremovesthetopitemanddecreasesthenumberofitemsinthestack.inlineintstackpop(structstack&the_stack){//Stackgoesdownbyone--the_stack.count;Page199//Thenwereturnthetopvaluereturn(the_stack.data[the_stack.count]);}Thereisoneitemyou'veoverlooked:initializingthestack.Youseeyoumustsetupthestackbeforeyoucanuseit.Keepingwiththespiritofputtingeverythinginastack_xxxxroutine getthestack_initfunction.inlinevoidstack_init(structstack&the_stack){the_stack.count=0;//Zerothestack}Noticethatyoudon'tneedtozerothedatafieldinthestack,sincetheelementsofdataareoverwrittenbythepushoperation.Youarenowfinished.Toactuallyusethestackyoudeclareitwithastructstatement.Nextyoumustmakesurethatyouinitializeit,andthenyoucanpushandpoptoyourheart'scontent(oratleastwithinthelimitsofthestack).structstacka_stack;//Declarethestackstack_init(a_stack);//Initializethestack//StackisreadyforuseExample13-1containsacompleteimplementationofthestructureversionofthestackandashorttestroutine.Example13-1.stack_s/stack_s.cc/*********************************************************Stack**Asetofroutinestoimplementasimpleinteger**stack.****Procedures**stack_init--initializethestack**stack_push--putanitemonthestack**stack_pop--removeanitemfromthestack*********************************************************/#include#includeconstintSTACK_SIZE=100;//Maximumsizeofastack//Thestackitselfstructstack{intcount;//Numberofitemsinthestackintdata[STACK_SIZE];//Theitemsthemselves};/**********************************************************stack_init--initializethestack*Page200Example13-1stack_s/stack_scc(Continued)***Parameters**the_stack--stacktoinitialize**********************************************************/ inlinevoidstack_init(structstack&the_stack){the_stack.count=0;//Zerothestack}/**********************************************************stack_push--pushanitemonthestack****Warning:Wedonotcheckforoverflow****Parameters**the_stack--stacktouseforstoringtheitem**item--itemtoputinthestack**********************************************************/inlinevoidstack_push(structstack&the_stack,constintitem){the_stack.data[the_stack.count]=item;++the_stack.count;}/**********************************************************stack_pop--getanitemoffthestack****Warning:Wedonotcheckforstackunderflow****Parameters**the_stack--stacktogettheitemfrom****Returns**thetopitemfromthestack**********************************************************/inlineintstackpop(structstack&the_stack){//Stackgoesdownbyone--the_stack.count;//Thenwereturnthetopvaluereturn(the_stack.data[the_stack.count]);}//Ashortroutinetotestthestackmain(){structstacka_stack;//Stackwewanttousestack_init(astack);//Pushthreevaluesonthestackstack_push(a_stack,1);Page201Example13-1.stack_s/stack_s.cc(Continued)stack_push(a_stack,2);stack_push(a_stack,3);//Poptheitemsfromthestack cout<<"Expecta3->"<"<"<#includeconstintSTACK_SIZE=100;//Maximumsizeofastack/*********************************************************Stackclass****Memberfunctions**init--initializethestack**push--putanitemonthestack**pop--removeanitemfromthestack*********************************************************/ //Thestackitselfclassstack{private:intcount;//Numberofitemsinthestackintdata[STACK_SIZE];//Theitemsthemselvespublic://Initializethestackvoidinit(void);//Pushanitemonthestackvoidpush(constintitem);//Popanitemfromthestackintpop(void);};/*********************************************************stack::init--initializethestack********************************************************/inlinevoidstack::init(void){count=0;//Zerothestack}/*********************************************************stack::push--pushanitemonthestack****Warning:Wedonotcheckforoverflow****Parameters**item--itemtoputinthestack*********************************************************/inlinevoidstack::push(constintitem){data[count]=item;++count;}/*********************************************************stack::pop--getanitemoffthestack***Page205Example13-2.stack_c/stack_c.cc(Continued)*Warning:Wedonotcheckforstackunderflow****Returns**thetopitemfromthestack*********************************************************/inlineintstack::pop(void){//Stackgoesdownbyone--count;//Thenwereturnthetopvaluereturn(data[count]);} //Ashortroutinetotestthestackmain(){stacka_stack;//Stackwewanttousea_stack.init();//Pushthreevaluesonthestacka_stack.push(l);a_stack.push(2);a_stack.push(3);//Poptheitemsfromthestackcout<<"Expecta3->"<"<"<main(){intthing_var;//DefineavariablePage231Example15-1.thing/thing.cc(Continued)int*thing_ptr;//Defineapointerthing_var=2;//Assigningavalueto"thing" cout<<"Thing"<#includeconstintARRAY_SIZE=10;//Numberofcharactersinarray//Arraytoprintchararray[ARRAY_SIZE]="012345678";main(){intindex;/*Indexintothearray*/for(index=0;indexintarray[10]={4,5,8,9,8,1,0,1,9,3};intindex;main(){index=0;while(array[index]!=0)++index;cout<<"Numberofelementsbeforezero"<intarray[10]={4,5,8,9,8,1,0,1,9,3};int*array_ptr;main(){array_ptr=array;while((*array_ptr)!=0)++array_ptr;cout<<"Numberofelementsbeforezero<<(array_ptr-array)<<' ';return(0);}Thefirstprogramusestheexpression(array[index]!=0).Thisrequiresthecompiler togenerateanindexoperation,whichtakeslongerthanasimplepointerde-reference:((*array_ptr)!=0).Theexpressionattheendofthisprogram,array_ptr-array,computeshowfararray_ptrisintothearray.Whenpassinganarraytoaprocedure,C++willautomaticallychangethearrayintoapointer.Infact,ifyouputan&beforethearray,C++willissueawarning.Example15-5illustratesarraypassing.Example15-5.tnit-a/init-a.ccconstintMAX=10;/********************************************************init_array_1--Zerooutanarray****Parameters**data--thearraytozero********************************************************/voidinit_array_1(intdata[]){intindex;for(index=0;index#include#includemain(){ charline[80];//Theinputlinechar*first_ptr;//Pointerwesettopointtothefirstnamechar*lastptr;//Pointerwesettopointtothelastnamecout<<"Enterstring ";cin.getline(line,sizeof(line));last_ptr=line;//Lastnameisatbeginningoflinefirst_ptr=strchr(line,'/');//Findslash//Checkforanerrorif(first_ptr==NULL)cerr<<'Error:Unabletofindslashin"<#include/*********************************************************tmp_name--returnatemporaryfilename****Eachtimethisfunctioniscalled,anewnamewill**bereturned***Page240Example15-7.tmp-name/tmp-name.cc(Continued)*Returns**pointertothenewfilename*********************************************************/char*tmp_name(void){charname[30];//Thenamewearegeneratingstaticintsequence=0;//Sequencenumberforlastdigit++sequence;//Movetothenextfilenamestrcpy(name,"tmp");//Putinthesequencedigitname[3]=sequence+'0';//Endthestringname[4]='';return(name);}intmain(){cout<<"Name:"<][-o][filel][file2]...Inthisline,-vsetsverboseoptions,whichturnsonalotofprogressinformationmessages.Theoption-lsetsthepagesizetolines(default=66)and-osetstheoutputfileto(default=print.out).Alistoffilestoprintfollowstheseoptions([fiel],[file2],etc.).Ifnofilesarespecified,thenprintthefileprint.in.Thewhileloopcyclesthroughtheoptions.Theactualloopis:while((argc>1)&&(argv[1][0]=='-')){Thereisalwaysoneargument,theprogramname.Theexpression(argc>1)checksforadditionalarguments.Thefirstonewillbenumbered1.Thefirstcharacterofthefirstargumentisargv[1][0].Ifthischaracterisadashyouhaveanoption.Attheendoftheloopisthecode:--argc;++argv;}Thisconsumesanargument.Thenumberofargumentsisdecrementedtoindicateonelessoption,andthepointertothefirstoptionisincremented,shiftingthelisttotheleftoneplace.(Note:Afterthefirstincrement,argv[0]nolongerpointstotheprogramname.)Theswitchstatementisusedtodecodetheoptions.Character0oftheargumentisthehyphen(-).Character1istheoptioncharacter,soyouusetheexpression: switch(argv[1[1]){todecodetheoption.Page243Theoption-vhasnoarguments;itjustcausesaflagtobeset.The-1optiontakesanintegerargument.Thelibraryfunctionatoiisusedtoconvertthestringintoaninteger.Fromthepreviousexampleyouknowthatargv[1][2]startsthestringcontainingthenumber.Thisstringispassedtoatoi.Theoption-otakesafilename.Ratherthancopythewholestring,yousetthecharacterpointerout_filetopointtothenamepartofthestring.Bythistimeyouknowthat:argv[1][0]='-'argv[1][1]='o'argv[l][2]=startofthefilenameYousetout_filetopointtothestringwiththestatement:out_file=&argv[1][2];Finallyalltheoptionsareparsedandyoufallthroughtotheprocessingloop.Thismerelyexecutesthefunctiondo_fileforeachfileargument.Example15-8containsthecompleteoption-decodingprogram.Example15-8print/printcc/*********************************************************Print--formatfilesforprinting*********************************************************/#include#includeintverbose=0;//Verbosemode(default=false)char*out_file="print.out";//Outputfilenamechar*program_name;//Nameoftheprogram(forerrors)intline_max=66;//Numberoflinesperpage/*********************************************************do_file--dummyroutinetohandleafile****Parameter**name--nameofthefiletoprint*********************************************************/voiddo_file(char*name){cout<<"Verbose"<Numberoflines ";cerr<<"-oSetoutputfilename ";exit(8);}main(intargc,char*argv[]){//Savetheprogramnameforfutureuseprogram_name=argv[0];/**Loopforeachoption*Stopifwerunoutofarguments*orwegetanargumentwithoutadash*/while((argc>1)&&(argv[1][0]=='-')){/**argv[l][1]istheactualoptioncharacter*/switch(argv[1][1]){/**-vverbose*/case'v':verbose=1;break;/**-ooutputfile*[0]isthedash*[1]isthe"o"*[2]startsthename*/case'o':out_file=&argv[1][2];break;/**-1setmaxnumberoflines*/case'1':line_max=atoi(&argv[1][2]);break;default:cerr<<"Badoption"<1)do_file(argv[1]);++argv;--argc;}}return(0);}Thisisonewayofparsingtheargumentlist.Theuseofthewhileloopandswitchstatementissimpleandeasytounderstand.Thismethoddoeshavealimitation.Theargumentmustimmediatelyfollowtheoptions.Forexample,-odata.outwillwork,but-odata.outwillnot.Animprovedparserwouldmaketheprogrammorefriendly,butthisworksforsimpleprograms.(Seeyoursystemdocumentationforinformationonthegetoptfunction.)ProgrammingExercisesExercise15-1:Writeaprogramthatusespointerstoseteachelementofanarraytozero.Exercise15-2:Writeafunctionthattakesasinglestringasitsargumentandreturnsapointertothefirstnonwhitecharacterinthestring.AnswerstoChapterQuestionsAnswer15-1:Theproblemisthatthevariablenameisatemporaryvariable.Thecompilerallocatesspaceforthenamewhenthefunctionisenteredandreclaimsthespacewhenthefunctionexits.Thefunctionassignsnamethecorrectvalueandreturnsapointertoit.However,thefunctionisover,sonamedisappearsandyouhaveapointerwithanillegalvalue.Thesolutionistodeclarenamestatic.Consequently,itisapermanentvariableandwillnotdisappearattheendofthefunction. Page246Question15-2:Afterfixingthefunction,youtryusingitfortwofilenames.Example15-9shouldprintout:Name:tmplName:tmp2butitdoesn't.Whatdoesitprintandwhy?Example15-9.tmp2/tmp2.cc#include#include/*******************************************************tmp_name--returnatemporaryfilename****Eachtimethisfunctioniscalled,anewnamewill**bereturned****Warning:Thereshouldbeawarninghere,butifwe**putitinwewouldanswerthequestion.****Returns**pointertothenewfilename********************************************************char*tmp_name(void){staticcharname[30];//Thenamewearegeneratingstaticintsequence=0;//Sequencenumberforlastdigit++sequence;//Movetothenextfilenamestrcpy(name,"tmp");//Putinthesequencedigitname[3]=sequence+'0';//Endthestringname[4]='';return(name);}intmain(){char*namel;//Nameofatemporaryfilechar*name2;//Nameofatemporaryfilename1=tmp_name();name2=tmp_name();cout<<"Namel:<.Normallycinisassignedtothekeyboardandcout,cerr,andclogareassignedtothescreen.MostoperatingsystemsallowyoutochangetheseassignmentsthroughI/Oredirection(seeyouroperatingsystemmanualfordetails).Forexample,thecommand my_prog.NOTETheifstreamclassisactuallyderivedfromtheistreamclass.Similarly,ofstreamisderivedfromostreamandfstreamisderivedfromiostream.You'lllearnaboutderivedclassesinChapter21,AdvancedClasses.Supposeyouwanttoreadaseriesof100numbersfromthefilenumbers.dat.Youstartbydeclaringtheinputfilevariable:ifstreamdata_file;//FilewearereadingthedatafromNextyouneedtotellC++whatdiskfiletouse.Thisisdonethroughtheopenmemberfunction:data_file.open("numbers.dat");Page253Nowyoucanreadthefileusingthesamestatementsyou'vebeenusingtoreadcin:for(i=0;i<100;++i)data_file>>data_array[i];FinallyyouneedtotelltheI/Osystemthatyouaredonewiththefile:data_file.close();Closingthefilefreesresourcesthatcanthenbeusedagainbytheprogram.C++allowstheopencalltobecombinedwiththeconstructor.Forexample,insteadofwriting:ifstreamdata_file;//Filewearereadingthedatafromdata_file.open("numbers.dat");youcanwrite:ifstreamdata_file("numbers.dat");//FilewearereadingthedatafromAdditionally,thedestructorautomaticallycallsclose.Butwhatifthefilenumbers.datismissing?Howcanyoutellifthereisaproblem?Thememberfunctionbadreturns"true"ifthereisaproblem,and"false"otherwise.Sototestforproblemsallyouneedis:if(data_file.bad()){ cerr<<"Unabletoopennumbers.dat ";exit(8);}AbetterversionoftheprogramforreadingnumbersisExample16-1.Example16-1.read/read.cc/**********************************************************Read--readin100numbersandsumthem****Usage:**read****Numbersareinthefile"numbers.dat"****Warning:Nocheckismadeforafilewithfewerthan**100numbersinit*********************************************************/#include#include#includemain(){constintDATA_SIZE=100;//Numberofitemsinthedataintdata_array[DATASIZE];//ThedataPage254Example16-1.read/read.cc(Continued)ifstreamdata_file("numbers.dat");//Theinputfileinti;//Loopcounterif(data_file.bad(){cerr<<"Error:Couldnotopennumbers.dat ";exit(8);}for(i=0;i>data_array[i];inttotal;//Totalofthenumberstotal=0;for(i=0;i#includenumber=Ox3FF;cout<<"Numberis"<.Table16-4containsthefulllistofI/Omanipulators.Table16-4.I/OManipulatorsManipulatorDescriptionsetiosflags(longflags)Setselectedconversionflags.resetiosflags(longflags)Resetselectedflags.decOutputnumbersindecimalformat.hexOutputnumbersinhexadecimalformat.octOutputnumbersinoctalformat.setbase(intbase)Setconversionbaseto8,10,or16.Sortofageneralizeddec,hex,oct.setw(intwidth)Setthewidthoftheoutput.setprecision(intprecision)SettheprecisionoffloatingpointoutputPage259Table16-4I/OManipulators(Continued)ManipulatorDescriptionsetfill(charch)Setthefillcharacter.wsSkipwhitespaceoninput.endlOutputend-of-lineendsOutputend-of-string('').flushForceanybufferedoutputout.(SeeChapter17,DebuggingandOptimization,foranexplanationofhowtousethisfunction). Example16-2showshowsomeoftheI/Omanipulatorsmaybeused.Example16-2io/io.cc#include#includemain()#{intnumber=12;//Anumbertooutputfloatreal=12.34;//Arealnumbercout<<"123456789012345678901234567890 ";//Outputrulercout<>operator.TheASCIIcharacter"0"hasthevalue48,"1"thevalue49,andsoon.WhenyouwanttoconvertasingledigitfromASCIItointeger,youmustsubtractthisvaluenumber: intinteger;charch;ch='5';integer=ch-48;cout<<"Integer<topositiontheprintheadattheleftmargin,andtomovethepaperuponeline.Thatwaythe"printed"whiletheprintheadwasracingbacktotheleftmargin.Whentheearlycomputerscameout,somedesignersrealizedthatusingtwocharactersfor end-of-linewastedstorage(atthistimestoragewasveryexpensive).Somepickedfortheirend-of-line,andsomechose.Someofthedie-hardsstayedwiththetwo-charactersequence.UNIXusesforend-of-line.Thenew-linecharacter iscode0xA(LFor).MS-DOS/Windowsusesthetwocharacters.CompilerdesignershadproblemsindealingwiththeoldCprogramsthatthoughtnew-linewasjust?ThesolutionwastoaddcodetotheI/OlibrarythatstrippedoutthecharactersfromASCIIinputfilesandchangedtoonoutput.InMS-DOS/Windows,whetherornotafileisopenedasASCIIorbinaryisimportanttonote.Theflagios::binaryisusedtoindicateabinaryfile://OpenASCIIfileforreadingascii_file.open("name",ios::in);//Openbinaryfileforreadingbinary_file.open("name",ios::in|ios::binary);Question16-1:Thememberfunctionputcanbeusedtowriteoutasinglebyteofabinaryfile.Thefollouingprogramwritesnumbers0to127toafilecalledtest.out.Page262ItworksjustfineinUNIX,creatinga128-bytelongfile;however,inMSDOS/Windows,thefilecontains129bytes.Why?Example16-3.wbin/wbin.cc#include#include#includemain(){intcur_char;//Currentcharactertowriteofstreamout_file;//Outputfileout_file.open("test.out",ios::out);if(out_file.bad()){(cerr<<"Cannotopenoutputfile ");exit(8);}for(cur_char=0;cur_char<128;++cur_char)out_file<#include#include#ifdef_MSDOS_//IfweareMS-DOS#include//GettheMS-DOSincludefileforrawI/O#else/*_MSDOS_*/#include//GettheUNIXincludefileforrawI/OPage265#endif/*_MSDOS_*/intfile_descriptor;file_descriptor=open(name,flags);//Existingfilefile_descriptor=open(name,flags,mode);//Newfilefile_descriptorAnintegerthatisusedtoidentifythefilefortheread,writeandclosecalls.Iffile_descriptorislessthan0anerroroccurred.nameNameofthefile.flagsDefinedinthefcntl.hheaderfile.OpenflagsaredescribedinTable16-5.Table16-5OpenFlagsFlagMeaningO_RDONLYOpenforreadingonlyO_WRONLYOpenforwritingonlyO_RDWROpenforreadingandwritingO_APPENDAppendnewdataattheendofthefileO_CREATCreatefile(modefilerequiredwhenthisflagispresent)O_TRUNCIfthefileexists,truncateitto0lengthO_EXCLFailiffileexistsO_BINARYOpeninbinarymode(olderUNIXsystemsmaynothavethisflag) modeProtectionmodeforthefile.Normallythisis0666formostfiles.Forexample,toopentheexistingfiledata.txtintextmodeforreading,youusethefollowing:data_fd=open("data.txt",O_RDONLY);Thenextexampleshowshowtocreateafilecalledoutput.datforwritingonly:out_fd=open("output.dat",O_CREAT|O_WRONLY,0666);NoticethatyoucombinedflagsusingtheOR(|)operator.Thisisaquickandeasywayofmergingmultipleflags.Whenanyprogramisinitiallyrun,threefilesarealreadyopened.ThesearedescribedinTable16-6.Page266Table16-6.StandardUnbufferedFilesFileNumberDescription0Standardin1Standardout2StandarderrorTheformatofthereadcallis:read_size=read(filedescriptor,buffer,size);read_sizeTheactualnumberofbytesread.A0indicatesend-of-fileandanegativenumberindicatesanerror.file_descriptorFiledescriptorofanopenfile.bufferPointertotheplacetoreadthedata.sizeSizeofthedatatoberead.Thisisthesizeoftherequest.Theactualnumberofbytesreadmaybelessthanthis.(Forexample,youmayrunoutofdata.)Theformatofawritecallis:write_size=write(file_descriptor,buffer,size); write_sizeActualnumberofbyteswritten.Anegativenumberindicatesanerror.file_descriptorFiledescriptorofanopenfile.bufferPointertothedatatobewritten.sizeSizeofthedatatobewritten.Thesystemwilltrytowritethismanybytes,butifthedeviceisfullorthereissomeotherproblem,asmallernumberofbytesmaybewritten.Finally,theclosecallclosesthefile:flag=close(file_descriptor)flag0forsuccess,negativeforerror.file_descriptorFiledescriptorofanopenfile.Page267Example16-4copiesafile.UnbufferedI/Oisusedbecauseofthelargebuffersize.ItmakesnosensetousebufferedI/Otoread1Kofdataintoabuffer(usinganifstream)andthentransferitintoa16Kbuffer.Example16-4copy.2/copy2.cc/*****************************************Copy--copyonefiletoanother****Usage**copy****--thefiletocopyfrom**--thefiletocopyinto*****************************************/#include#include#include#include#include#ifdef_MSDOS_//IfweareMS-DOS#include//GettheMS-DOSincludefileforrawI/O#else/*_MSDOS_*/#include//GettheUNIXincludefileforrawI/O#endif/*_MSDOS_*/constintBUFFER_SIZE=(16*1024);//Use16Kbuffersmain(intargc,char*argv[]) {charbuffer[BUFFER_SIZE];//Bufferfordataintin_file;//Inputfiledescriptorintout_file;//Outputfiledescriptorintread_size;//Numberofbytesonlastreadif(argc!=2){cerr<<"Error:Wrongnumberofarguments ";cerr<<"Usageis:copy ";exit(8);}in_file=open(argv[1],O_RDONLY);if(in_file<0){cerr<<"Error:Unabletoopen"<.Thedeclarationforafilevariableis:FILE*file_variable,/*Comment*/ Example:#includeFILE*in_file;/*Filecontainingtheinputdata*/Page271Beforeafilecanbeused,itmustbeopenedusingthefunctionfopen.fopenreturnsapointertothefilestructureforthefile.Theformatforfopenis:filevariable=fopen(name,mode);file_variableAfilevariable.nameActualnameofthefile(data.txt,temp.dat,etc.).modeIndicateswhetherthefileistobereadorwritten.Modeis"w"forwritingand"r"forreading.Thefunctionfcloseclosesthefile.Theformatoffcloseis:status=fclose(file_variable);Thevariablestatuswillbezeroifthefclosewassuccessfulornon-zeroforanerror.Cprovidesthreepreopenedfiles.ThesearelistedinTable16-7.Table16-7.StandardFilesFileDescriptionstdinStandardinput(openforreading).EquivalenttoC++'scin.stdoutStandardoutput(openforwriting).EquivalenttoC++'scout.stderrStandarderror(openforwriting).EquivalenttoC++'scerr.ThereisnoCfileequivalenttoC++'sclog.Thefunctionfgetcreadsasinglecharacterfromafile.IfthereisnomoredatainthefilethefunctionreturnstheconstantEOF(EOFisdefinedinstdio.h).Notethatfgetcreturnsaninteger,notacharacter.ThisisnecessarybecausetheEOFflagmustbeanoncharactervalue.Example16-5countsthenumberofcharactersinthefileinput.txt.Example16-5.copy/copy.cc#include#include/*ANSIStandardCfile*/#include constcharFILE_NAME[]="input.txt";//Nameoftheinputfilemain(){intcount=0;//NumberofcharactersseenPage272Example16-5copy/copycc(Continued)FILE*in_file;//Inputfileintch;//CharacterorEOFflagfrominputin_file=fopen(FILE_NAME,"rb");if(in_file==NULL){cerr<<"Cannotopen"<main(){intanswer;answer=2+2;printf("Theansweris%d ");return(0);}Page275 Question16-3:Whydoes21/7=O?(Yourresultsmayvary.)[File:float3/float3.c]#includemain(){floatresult;result=21.0/7.0;printf("Theresultis%d ",result);return(0);Thefunctionfprintfissimilartoprintfexceptthatittakesoneadditionalparameter,thefiletoprintto.fprintf(file,format,parameter-1,parameter-2,...);Anotherflavoroftheprintffamilyisthesprintfcall.Thefirstparameterofsprintfisastring.Thefunctionformatstheoutputandstorestheresultinthegivenstring.sprintf(string,format,parameter-1,parameter-2,...);Forexample:charstring[40];/*Thefilename*//*Currentfilenumberforthissegment*/intfile_number=0;sprintf(string,"file.%d",file_number);++file_number;out_file=fopen(string,"w");Warning:Thereturnvalueofsprintfdiffersfromsystemtosystem.TheANSIstandarddefinesitasthenumberofcharactersstoredinthestring;however,someimplementationsofUNIXCdefineittobeapointertothestring.Readingisaccomplishedthroughthescanffamilyofcalls.Thescanffunctionhassimilarsisterfunctions:fscanfandsscanf.Theformatforfscanfis:number=fscanf(file,format,¶meter-l,...);numberNumberofparameterssuccessfullyconvertedfieAfileopenedforreadingformatDescribesthedatatobereadPage276parameter-1 FirstparametertobereadWARNINGIfyouforgettoput&infrontofeachvariableforscanf,theresultcanbea"Segmentationviolationcoredumped"or"Illegalmemoryaccess"error.Insomecasesarandomvariableorinstructionwillbemodified.ThisisnotcommononUNIXmachines,butMS-DOS/Windows,withitslackofmemoryprotection,cannoteasilydetectthisproblem.InMS-DOS/Windows,omitting&cancauseasystemcrash.Thereisoneproblemwiththisscanf:It'snexttoimpossibletogettheend-oflinehandlingright.However,there'sasimplewaytogetaroundthelimitationsofscanf—don'tuseit.Insteadusefgetsfollowedbythestringversionofscanf,thefunctionsscanf:charline[100];//Linefordatafgets(line,sizeof(line),stdin);//Readnumberssscanf(line,"%d%d",&numberl,&number2);Finally,thereisafileversionofscanf,thefunctionfscanf.Againthisfunctionisextremelydifficultandshouldnotbeused.Usefgetsandsscanfinstead.C-StyleBinaryI/OBinaryI/Oisaccomplishedthroughtworoutines:freadandfwrite.Thesyntaxforfreadis:read_size=fread(dataptr,1,size,file);read_sizeSizeofthedatathatwasread.Ifthisislessthansize,thenanend-of-fileorerroroccurred.data_ptrPointertothedatatoberead.sizeNumberofbytestoberead.fileInputfile.Example:struct{intwidth;intheight;Page277}rectangle; if(fread((char*)&rectangle,1,sizeof(rectangle),in_file)!=sizeof(rectangle)){fprintf(stderr,"Unabletoreadrectangle ");exit(8);}Inthisexampleyouarereadinginthestructurerectangle.The&operatormakesthestructureintoapointer.Thecast"(char*)"turns&rectangleintotheproperparametertype,andthesizeofoperatorisusedtodeterminehowmanybytestofreadinaswellastocheckthatreadwassuccessful.fwritehasacallingsequencesimilartofread:write_size=fwrite(data_ptr,1,size,file);NOTETomakeprogrammingsimplerandeasier,Ialwaysuse1asthesecondparametertofreadandfwrite.ForafulldescriptionofthesefunctionsseeyourCreferencemanual.Question16-4:Nomatterwhatfilenameyougivethefollowingprogram,ourprogramcan'tfindit.Why?[File:fun-file/fun-file.c]#include#includeintmain(){charname[100];/*Nameofthefiletouse*/FILE*in_file;/*Fileforinput*/printf("Name?");fgets(name,sizeof(name),stdin);in_file=fopen(name,"r");if(in_file==NULL){(void)fprintf(stderr,"Couldnotopenfile ");exit(8);}printf("Filefound ");fclose(in_file);return(0);}Page278ProgrammingExercisesExercise16-1:Writeaprogramthatreadsafileandcountsthenumberoflinesinit.Exercise16-2:Writeaprogramtocopyafile,expandingalltabstomultiplespaces.Exercise16-3:Writeaprogramthatreadsafilecontainingalistofnumbersandwritestwo files,onewithallthenumbersdivisibleby3andanothercontainingalltheothernumbers.Exercise16-4:WriteaprogramthatreadsanASCIIfilecontainingalistofnumbersandwritesabinaryfilecontainingthesamelist.Writeaprogramthatgoestheotherwaysoyoucancheckyourwork.Exercise16-5:Writeaprogramthatcopiesafileandremovesallcharacterswiththehighbitset(((ch&0x80)!=0).)Exercise16-6:Designafileformattostoreaperson'sname,address,andotherinformation.Writeaprogramtoreadthisfileandproduceasetofmailinglabels.AnswerstoChapterQuestionsAnswer16-1:TheproblemisthatyouarewritinganASCIIfile,butyouwantedabinaryfile.InUNIX,ASCIIisthesameasbinary,sotheprogramrunsfine.InMSDOS/Windows,theend-of-lineissuecausesproblems.Whenyouwriteanew-linecharacter(OxOa)tothefile,acarriagereturn(OxOD)isaddedtothefile.(Rememberthatend-of-lineinMS-DOS/Windowsis,orOxOd,OxOa.)Becauseofthisediting,yougetanextracarriagereturn(OxOd)intheoutputfile.Towritebinarydata(withoutoutputediting)youneedtoopenthefilewiththebinaryoption:out_file.open("test.out",ios::out|ios::binary);Answer16-2:Theprintfcalldoesnotcheckforthecorrectnumberofparameters.Thestatement:printf("Theansweris%d ");tellstheprintftoprintthestring"Theansweris"followedbytheanswer.Theproblemisthattheparametercontainingtheanswerwasomitted.Whenthishappensprintfgetstheanswerfromarandomlocationandprintsgarbage.Properlywritten,theprintfstatementis:printf("Theansweris%d ",answer);Page279Answer16-3:Theprintfcalldoesnotcheckthetypeofitsparameters.Youtelltheprintfcalltoprintanintegernumber(%d)andsupplyitwithafloatingpointparameter(result).Thismismatchcausesunexpectedresultssuchasprintingthewronganswer.Whenprintingafloatingpointnumberyouneeda%fconversion.Properlywritten,ourprintfstatementis:printf("Theansweris%f ",result);Answer16-4:Theproblemisthatfgetsgetstheentirelineincludingthenew-linecharacter( ).Ifyouhaveafilenamedsam,theprogramreadssam andtriestolookforafilebythatname.Becausethereisnosuchfile,theprogramreportsanerror.Thefixistostripthenew-linecharacterfromthename: name[strlen(name)-1]='';/*Getridoflastcharacter*/Theerrormessageinthiscaseispoorlydesigned.True,youdidnotopenthefile,buttheprogrammercouldsupplytheuserwithmoreinformation.Areyoutryingtoopenthefileforinputoroutput?Whatisthenameofthefileyouaretryingtoopen?Youdon'tevenknowwhetherthemessageyouaregettingisanerror,awarning,orjustpartofthenormaloperation.Abettererrormessageis:fprintf(stderr,"Error:Unabletoopen%sforinput ",name);Noticethatthismessagewouldalsohelpusdetecttheprogrammingerror.Whenyoutypedin''sam"theerrorwouldbe:Error:UnabletoopensamforinputThisclearlyshowsusthatyouaretryingtoopenafilewithanew-lineinitsname.Page28117DebuggingandOptimizationInThisChapter:·Debugging·DivideandConquer·Debug-OnlyCode·DebugCommand-LineSwitch·InteractiveDebuggers·DebuggingaBinarySearch·RuntimeErrors·TheConfessionalMethodofDebugging·HowtoOptimize·CaseStudy·Exercises·AnswerstoQuestionsBloodyinstructionswhich,beinglearned,returntoplaguetheinventor.—Shakespeare,onDebuggingDebugging Thehardestpartofaprogramisnotthedesignandwriting,butthedebuggingphase.Itisherethatyoufindouthowyourprogramreallyworks(insteadofhowyouthinkitworks).Toeradicateabug,youneedtwothings:awayofreproducingthebugandinformationfromtheprogramthatletsyoulocateandcorrecttheproblem.Insomecases,findingthebugiseasy.Youdiscoverthebugyourself,thetestdepartmentproducesaclearandeasytestthatdisplaysthebug,ortheoutputalwayscomesoutbad.Insomecases,especiallywithinteractiveprograms,reproducingthebugmaybe90percentoftheproblem.Thisisespeciallytruewhendealingwithbugreportssentinbyusersinthefield.Atypicalcallfromausermightbe:User:Thatdatabaseprogramyougavemeisbroken.Programmer:What'swrong?User:SometimeswhenI'mdoingasort,itgetsthingsinthewrongorder.Page282Programmer:Whatcommandwereyouusing?User:Thesortcommand.Programmer:Tellmeexactlywhatyoutyped,keystrokebykeystroke,togetittofail.User:Idon'trememberitexactly.Iwasdoingalotofsorts.Programmer:IfIcomeovercanyoushowmethebug?User:Ofcourse.Fiveminuteslatertheprogrammerisintheuser'sofficeanduttersthefatalwords,"Showme."Theusertypesawayandtheprogramstubbornlyworks,nomatterwhattheuserdoestoit.Theprogrammergivesupandgoesbacktohisofficeonlytofindamessagefromtheuser:"Itfailedfiveminutesafteryouleft."Example17-1isashortdatabaselookupprogram.Itaskstheuserforinputandcheckstheinputagainstahard-codedlistofnames.Althoughitisverysimple,theprogram'sstructureistypicalofmuchlargerandmorecomplexinteractiveprograms.Example17-1.base/base.cc /*********************************************************Database--averysimpledatabaseprogramto**lookupnamesinahard-codedlist****Usage:**database**Programwillaskyouforaname.**Enterthename;itwilltellyouwhether**thenameisinthelist.****Ablanknameterminatestheprogram.*********************************************************/constintSTRING_LENGTH=80;/*Lengthoftypicalstring*/#include#includemain(){charname[STRING_LENGTH];//AnametolookupPage283Example17-1.base/base.cc(Continued)intlookup(char*);//Lookupanamewhile(1){cout<<"Entername:";cin.getline(name,sizeof(name));//Checkforblanknameif(strlen(name)<=0)break;if(lookup(name))cout<#include/**Themainprogramwillopenthisfileif-Sison*thecommandline.*/ofstreamsave_file;//Filetouseforsavinginputintsave_file_open=0;//Savefiledefaultstonotopen/*********************************************************extended_getline--getalinefromtheinputfile**andrecorditinasavefileifneeded* ***Parameters**line--thelinetoread**size--sizeof(line)--maximumnumberof**characterstoread**file--filetoreaddatafrom**(normallystdin)****Returns**NULL--errororend-of-fileinread**otherwiseline(justlikegetline)*********************************************************/istream&extended_getline(char*line,intsize,ifstream&file){istream*result;/*Resultofgets*/result=&file.getline(line,size);//Didsomeoneaskforasavefile?if(save_file_open){Page285Example17-2xgets/xgets.cc(Continued)save_file<]****-SSpecifysavefilefor**debuggingpurposes****Programwillaskyouforaname.**Enterthename;itwilltellyouwhether**thenameisinthelist.****Ablanknameterminatestheprogram.*********************************************************/#include#include#include ofstreamsave_file;//Savefileifanyintsave_file_open=0;//Savefileopenflagchar*extended_getline(char*line,intsize,istream&file);main(intargc,char*argv[]){charname[80];//Anametolookupchar*save_file_name;//Nameofthesavefileintlookup(char*name);//lookupanamewhile((argc>1)&&(argv[l][0]=='-'))switch(argv[1][1]){case'S':save_file_name=&argv[1][2];save_file.open(save_file_name,ios::out);if(save_file.bad())cerr<<"Warning:Unabletoopensavefile"<John"isnot.Inthiscasewefoundtheerrorbyinspectingtheinput;however,morecomplexprogramshavemuchmorecomplexinput.Wecouldtypeallthatinwhendebugging,orwecouldaddanotherfeaturetoextended_getlinethatwouldaddaplaybackfiletoit.Whentheplaybackfile isenabled,inputwillnotbetakenfromthekeyboard,butinsteadwillbetakenfromthefile.Example17-4xgets/xgets2.cc#include#include#ofstreamsave_file;//Saveinputinthisfileintsave_file_open=0;//Savefilehasbeenopenedifstreamplayback_file;//Playbackdatafromthisfileintplayback_file_open=0;//Playbackfileopenflag/**********************************************************extended_getline--getalinefromtheinputfile**andrecorditinasavefileifneeded****Parameters**line--thelinetoread**size--sizeof(line)--maximumnumberof**characterstoread**file--filetoreaddatafrom*Page287Example17-4.xgets/xgets2.cc(Continued)*(normallystdin)****Returns**NULL--errororend-of-fileinread**otherwiseline(justlikegetline)*********************************************************/istream&extended_getline(char*line,intsize,istream&file){istream*result;//Rresultofgetlineif(playback_file_open)result=&playback_file.getline(line,size);if(file==cin)//Echotheinputtothestandardout//sotheuserseesitcout<-P]****-SSpecifysavefilefor**debuggingpurposes****-PSpecifyplaybackfilefor**debuggingordemonstration****Programwillaskyouforaname.**Enterthename;itwilltellyouwhether**thenameisinthelist.****Ablanknameterminatestheprogram.*********************************************************/Page288Example17-5.base/base3.cc(Continued)#include#include#includeofstreamplayback_file;//Playbackdataintsave_file_open=0;//Savefileopenflagifstreamsave_file;//Savefileifanyintplaybackfile_open=0;//Trueifplaybackinprogresschar*extended_getline(char*line,intsize,istream&file);main(intargc,char*argv[]){charname[80];//Anametolookupchar*save_file_name;//Nameofthesavefilechar*playback_file_name;//Nameoftheplaybackfileintlookup(char*name);//lookupanamewhile((argc>1)&&(argv[1][0]=='-'))switch(argv[1][1]){case'S':save_file_name=&argv[1][2];save_file.open(save_file_name,ios::out);if(save_file.bad())cerr<<"Warning:Unabletoopensavefile<1)&&(argv[l][0]=='-'))switch(argv[1][1]){/*....normalswitch....*///Debugswitchcase'Z':debug_ptr=&argv[1][2];//Loopforeachletterwhile(*debug_ptr!='){debug[*debug_ptr]=1;++debug_ptr;}break;}--argc;++argv;} /*Restofprogram*/}*GhostscriptisaPostscriptÔ-lkeinterpreteravailablefromtheFreeSoftwareFoundationforaminimalcopyingchargeTheycanbereachedat.FreeSoftwareFoundation.Inc,675MassAve,Cambridge.MA02139,phone(617)876-3296.Page292Thisisusedinsidetheprogramby:if(debug['p'])cout<<"Startingnewpath ";Ghostscriptisalargeprogram(some25.000lines)andratherdifficulttodebug.Thisformofdebuggingallowstheusertogetagreatdealofinformationeasily.GoingThroughtheOutputEnablingdebugprintoutisanicewayofgettinginformation,butmanytimesthereissomuchdatathattheinformationyouwantcaneasilygetlost.Theshellorcommand-lineinterpreterallowsyoutoredirectwhatwouldnormallygotothescreentoafilethroughtheuseofthe">file"option.Forexample:buggy-D9>tmp.outwillruntheprogrambuggywithahighlevelofdebugsetandsendtheoutputtothefiletmp.out.Thetexteditoronyoursystemalsomakesagoodfilebrowser.Youcanuseitssearchcapabilitiestolookfortheinformationyouwanttofind.InteractiveDebuggersMostcompilermanufacturersprovideaninteractivedebugger.Theygiveyoutheabilitytostoptheprogramatanypoint,examineandchangevariables,and"single-step"throughtheprogram.Becauseeachdebuggerisdifferent,adetaileddiscussionisnotpossible.However,wearegoingtodiscussonedebuggergdb.ThisprogramisavailableformanyUNIXmachinesfromtheFreeSoftwareFoundation.Turbo-C++hasitsownbuilt-indebugger.Althoughtheexactsyntaxusedbyyourdebuggermaybedifferent,theprinciplesshownherewillworkforalldebuggers.BasicGDBcommandsare:runStartexecutionofaprogram.breakline-numberInsertabreakpointatthegivenlinenumber.Whenarunningprogramreachesabreakpoint,executionstopsandcontrolreturnstothedebugger. breakfinction-nameInsertabreakpointatthefirstlineofthenamedfunction.Commonly,thecommandbreakinmainisusedtostopexecutionatthebeginningoftheprogram.Page293contContinueexecutionafterabreakpoint.printexpressionDisplaythevalueofanexpression.stepExecuteasinglelineintheprogram.Ifthecurrentstatementcallsafunction,thefunctionissinglestepped.nextExecuteasinglelineintheprogram,buttreatfunctioncallsasasingleline.Thiscommandisusedtoskipoverfunctioncalls.listListthesourceprogram.wherePrintthelistofcurrentlyactivefunctions.statusPrintalistofbreakpoints.deleteRemoveabreakpoint.Wehaveaprogramthatshouldcountthenumberofthreesandsevensinaseriesofnumbers.Theproblemisitkeepsgettingthewronganswerforthenumberofsevens.OurprogramisshowninExample17-6.Example17-6.seven/countcc1#include2intseven_count;/*Numberofseven'sinthedata*/3intdata[5];/*Thedatatocount3and7in*/4intthree_count;/*Numberofthreesinthedata*/56main(){7intindex;/*Indexintothedata*/8voidget_data(intdata[]);910seven_count=0;11three_count=0;12get_data(data);1314for(index=1;index<=5;++index){15if(data[index]==3)16++three_count; 17if(data[index]==7)18++seven_count;19}20cout<<"Threes"<>data[1]>>data[2]>>data[3]>>data[4]>>data[5];31}Whenwerunthisprogramwiththedata37302theresultsare:Threes3Sevens3Westartbyinvokingthedebugger(GDB)withthenameoftheprogramwearegoingtodebug(count).Thedebuggerinitializes,outputstheprompt(gdb),andwaitsforacommand.%gdbcountGDBisfreesoftwareandyouarewelcometodistributecopiesofitundercertainconditions;type"showcopying"toseetheconditions.ThereisabsolutelynowarrantyforGDB;type"showwarranty"fordetails.GDB4.12(m68k-sun-sunos4.0.3),Copyright1994FreeSoftwareFoundation,Inc...(gdb)Wedon'tknowwherethevariableisgettingchanged,sowe'llstartatthebeginningandworkourwaythroughuntilwegetanerror.Ateverystepwe'lldisplaythevariableseven_countjusttomakesureit'sokay.Weneedtostoptheprogramatthebeginningsowecansingle-stepthroughit.ThecommandbreakmaintellsGDBtosetabreakpointatthefirstinstructionofthefunctionmain.ThecommandruntellsGDBtostarttheprogram,whichwillrununtilithitsthefirstbreakpoint.(gdb)breakmainBreakpoint1at0x22c2:filecount.cc,line10.(gdb)Thenumber1isusedbyGDBtoidentifythebreakpoint.Nowweneedtostarttheprogram:(gdb)runStartingprogram:/usr/sdo/count/countBreakpoint1,main()atcount.cc:1010seven_count=0;(gdb) ThemessageBreakpoint1,main...indicatesthattheprogramencounteredabreakpointandhasnowturnedcontrolovertodebug.Page295Wehavereachedthepointwhereseven_countisinitialized.Thecommandnextwillexecuteasinglestatement,treatingfunctioncallsasonestatement.(Thenamesofthecommandforyourdebuggermaybedifferent.)Wegopasttheinitializationandchecktoseewhetheritworked:(gdb)next11three_count=0;(gdb)printseven_count$1=0(gdb)Itdid.Wetrythenextfewlines,checkingallthetime:(gdb)next12get_data(data);(gdb)printseven_count$2=0(gdb)nextEnter5numbers3730214for(index=1;index<=5;++index){(gdb)printseven_count$3=2(gdb)seven_countsomehowchangedthevalueto2.Thelaststatementweexecutedwasget_data(data);sosomethingisgoingoninthatfunction.Weaddabreakpointatthebeginningofget_data,getridoftheoneatmain,andstarttheprogramoverwiththeruncommand:(gdb)breakget_dataBreakpoint2at0x23b2:filecount.cc,line29.(gdb)infobreakpointsNumTypeDispEnbAddressWhat1breakpointkeepy0x000022c2inmainatcount.cc:102breakpointkeepy0x000023b2inget_data(int*)atcount.cc:29(gdb)delete1(gdb)runTheprogrambeingdebuggedhasbeenstartedalready.Startitfromthebeginning?(yorn)YStartingprogram:/usr/sdo/count/countBreakpoint2,get_data(data=0x208f8)atcount.cc:29(gdb)Wenowstartsingle-steppingagainuntilwefindtheerror:Breakpoint2,get_data(data=0x208f8)atcount.cc:2929cout<>data[1]>>data[2]>>data[3]>>data[4]>>data[5];(gdb)printseven_countPage296$6=0(gdb)nextEnter5numbers3730231}(gdb)printseven_count$7=2(gdb)list2222return(0);23}24/********************************************************25*get_data--get5numbersfromthecommandline*26********************************************************/27voidget_data(intdata[])28{29cout<<"Enter5numbers ";30cin>>data[1]>>data[2]>>data[3]>>data[4]>>data[5];31}Atline30thedatawasgood,butwhenwereachedline31,thedatawasbad,sotheerrorislocatedatline30oftheprogram,thecin.We'venarrowedtheproblemdowntoonestatement.Byinspectionwecanseethatweareusingdata[5],anillegalmemberofthearraydata.Butwhydoesseven_countgobad?Sincedataisonlyfiveelementslong,thereisnodata[5].However,thecin>>data[5]hastoputthedatasomeplace,soitdecidedtoputitinarandommemorylocation,inthiscaseseven_count.DebuggingaBinarySearchThebinarysearchalgorithmisfairlysimple.Youwanttoseewhetheragivennumberisinanorderedlist.Checkyournumberagainsttheoneinthemiddleofthelist.Ifitisthenumber,youwerelucky—stop.Ifyournumberwasbigger,thenyoumightfinditinthetophalfofthelist.Trythemiddleofthetophalf.Ifitwassmaller,trythebottomhalf.Keeptryinganddividingthelistinhalfuntilyoufindthenumberorthelistgetsdowntoasinglenumber.Example17-7usesabinarysearchtoseewhetheranumbercanbefoundinthefilenumbers.dat.Example17-7.search/searchO.cc/*********************************************************Search--searchasetofnumbers****Usage:**search**Youwillbeaskednumberstolookup*** ***Files:*Page297Example17-7.search/searchO.cc(Continued)*numbers.dat--numbers1perlinetosearch**(numbersmustbeordered)*********************************************************/#include#include#include#includeconstintMAX_NUMBERS=1000;//Maxnumbersinfileconstchar*constDATA_FILE="numbers.dat";//Filewithnumbersintdata[MAX_NUMBERS];//Arrayofnumberstosearchintmax_count;//Numberofvalidelementsindatamain()(ifstreamin_file;//Inputfileintmiddle;//Middleofoursearchrangeintlow,high;//Upper/lowerboundintsearch;//Numbertosearchforin_file.open(DATA_FILE,ios::in);if(in_file.bad())(cerr<<"Error:Unabletoopen"<>search;if(search==-1)Page298Example17-7search/search()cc(Continued)break;low=0;high=max_count;while(1){middle=(low+high)/2;if(data[middle]==search)cout<<"Foundatindex"<>data[max_count];performsthesamefunction.Theanswerissimple.Weusedsscanftocauseproblems.Withoutthepointererrorwewouldhavenothingtodebug.Thein_filestatementismorereliable,andreliablecodehasnoplaceinachapterondebugging.Thefirstnumberinourlistis4,sowetryit.Thistimeouroutputlookslike:Enternumbertosearchforor-1toquit:4Foundatindex0Foundatindex0NotfoundEnternumbertosearchforor-1toquit:^CTheprogramshouldfindthenumber,letusknowit'satindex0,andthenaskforanothernumber.Insteadwegettwofoundmessagesandonenotfoundmessage.Weknowthateverythingisrunningsmoothlyuptothetimewegetthefirstfoundmessage.Afterthatthingsgodownhill.Gettingbackintothedebugger,weusethelistcommandtolocatethefoundmessageandputabreakpointthere.%gdbsearchGDBisfreesoftwareandyouarewelcometodistributecopiesofitundercertainconditions;type"showcopying"toseetheconditions.ThereisabsolutelynowarrantyforGDB;type"showwarranty"fordetails.GDB4.12(m68k-sun-sunos4.0.3),Copyright1994FreeSoftwareFoundation,Inc...(gdb)list66,7766while(1)67middle=(low+high)/2;6869if(data[middle]==search){70cout<<"Foundatindex"<#include#include#includeconstintMAX_NUMBERS=1000;//Maxnumbersinfileconstchar*constDATA_FILE="numbers.dat";//Filewithnumbersintdata[MAX_NUMBERS];//Arrayofnumberstosearchintmax_count;//Numberofvalidelementsindatamain(){ifstreamin_file;//Inputfileintmiddle;//Middleofoursearchrangeintlow,high;//Upper/lowerboundintsearch;//Numbertosearchforin_file.open(DATA_FILE,ios::in);if(in_file.bad())cerr<<"Error:Unabletoopen"<>search;Page306Example17-8search/search4.cc(Continued)if(search==-1)break;low=0;high=max_count;while(1)if(low>=high)cout<<"Notfound ";break;}middle=(low+high)/2;if(data[middle]==search)cout<<"Foundatindex<main(){inti,j;/*Tworandomintegers*/i=1;j=0;cout<<"Starting ";cout<<"Beforedivide...";i=i/j;//Divide-by-zeroerrorcout<<"After ";return(0);}Whenrun,thisprogramoutputs:StartingFloatingexception(coredumped)Thismightleadyoutothinkthedividehadneverstarted,wheninfactithad.Whathappenedtothemessage''Beforedivide..."?Thecoutstatementexecuted,andputthemessageinabuffer,andthentheprogramdied.Thebuffernevergotachancetobeemptied.Byputtingexplicitflush-buffercommandsinsidethecode,wegetatruerpictureofwhatishappening,asshowninExample17-11.Example17-11.debug/flush2.cc#includemain(){inti,j;/*Tworandomintegers*/i=1;j=0;cout<<"Starting ";cout.flush();cout<<"Beforedivide...";cout.flush();i=i/j;//Divide-by-zeroerrorcout<<"After ";cout.flush();return(O);}TheflushstatementmakestheI/Olessefficient,butmorecurrent.Page309TheConfessionalMethodofDebuggingTheconfessionalmethodofdebuggingisonebywhichtheprogrammerexplainshisprogramto someone:aninterestedparty,anuninterestedparty,awall—itdoesn'tmatterwhomheexplainsittoaslonghetalksaboutit.Atypicalconfessionalsessiongoeslikethis:"Hey,Bill,couldyoutakealookatthis?Myprogramhasabuginit.Theoutputshouldbe8.0andI'mgetting-8.0.TheoutputiscomputedusingthisformulaandI'vecheckedoutthepaymentvalueandrateandthedatemustbecorrect,unlessthereissomethingwrongwiththeleap-yearcode,which—ThankyouBill,you'vefoundmyproblem."Billneversaidaword.Thistypeofdebuggingisalsocalledawalkthrough.Gettingotherpeopleinvolvedbringsafreshpointofviewtotheprocess,andfrequentlyotherpeoplecanspotproblemsyouhaveoverlooked.OptimizationAndnowawordonoptimization:Don't.Mostprogramsdonotneedtobeoptimized.Theyrunfastenough.Whocareswhetheraninteractiveprogramtakes0.5secondstostartupinsteadof0.2?Tobefair,therearealotofslowprogramsouttherethatcanbespedup.Thisisusuallydonenotbythesimpleoptimizationstepsshowninthischapter,butbyreplacingpoorlydesignedcorealgorithmswithmoreefficientones.Forawell-writtenprogram,thesimplestwaytogetyourprogramtorunfasteristogetafastercomputer.Manytimesitischeapertobuyamorepowerfulmachinethanitistooptimizeaprogram,becauseyoumayintroducenewerrorsintoyourcode.Don'texpectmiraclesfromoptimization.Usuallymostprogramscanonlybespedup10percentto20percent.Example17-12initializesamatrix(two-dimensionalarray).Example17-12.matrix/matrixl.ccconstintX_SIZE=60;constintY_SIZE=30;intmatrix[X_SIZE][Y_SIZE];voidinit_matrix(void){intx,y;//CurrentelementtoinitializePage310Example17-12matrix/matrix1.cc(Continued)for(x=0;xconstintX_SIZE=60;constintY_SIZE=30;intmatrix[X_SIZE][Y_SIZE];voidinit_matrix(void){memset(matrix,-1,sizeof(matrix));}Nowourfunctionconsistsofonlyasinglefunctioncall.Itseemsashametohavetocallafunctionjusttocallanotherfunction.Wehavetopayfortheoverheadoftwofunctioncalls.Itwouldbebetterifwecalledmemsetfromthemainfunction.Whydon'twerewritethecodeusingmemsetinsteadofinit_matrix?Becauseithasseveralhundredinit_matrixcallsandwedon'twanttodoallthatediting.Sohowdowegetridoftheoverheadofafunctioncall?Bymakingthefunctioninline.OurfinalversionofthefunctionusesinlinetoeliminateallthecalloverheadandcanbeseeninExample17-19.Page314Example17-19.matrix/matrix8.cc#includeconstintXSIZE=60;constintY_SIZE=30;intmatrix[X_SIZE][Y_SIZE];inlinevoidinit_matrix(void){memset(matrix,-1,sizeof(matrix));}Question17-1:Whydoesmemsetsuccessfullyinitializethematrixto-1,butwhenwetrytouseittoseteveryelementto1,wefail?#include constintX_SIZE=60;constintY_SIZE=30;intmatrix[X_SIZE][Y_SIZE];inlinevoidinit_matrix(void)memset(matrix,1,sizeof(matrix));}HowtoOptimizeOurmatrixinitializationfunctionillustratesseveraloptimizingstrategies.Theseare:RemovinginvariantcodeCodethatdoesnotneedtobeputinsidealoopshouldbeputoutsidetheloop.Forexample:for(i=0;i<10;++i)matrix[i]=i+j*10;canbewrittenas:j_times_10=j*10;for(i=0;i<10;++i)matrix[i]=i+j_times_10;Mostgoodoptimizingcompilerswilldothisworkforyouifpossible.LooporderingNestedloopsshouldbeorderedwiththesimplestloopoutermostandthemostcomplexloopsinnermost.Page315ReductioninstrengthThisisafancywayofsayingusecheapoperationsinsteadofexpensiveones.Table17-1liststherelativecostofcommonoperations.Table17-1RelativeCostofOperationsOperationRelativeCostFileinputandoutput(<>),includingtheCfunctions1,000printfandscanf.newanddelete800Trigonometricfunctions(sin,cos,...)500Floatingpoint(anyoperation)100Integerdivide30Integermultiply20Functioncall10 Functioncall10Simplearrayindex6Shifts5Add/subtract5Pointerde-reference2BitwiseAND,OR,NOT1LogicalAND,OR,NOT1NOTECformattingfunctionscalledusingscanf,printf,andsscanfareextremelycostlybecausetheyhavetogothroughtheformatstringonecharacteratatimelookingforaformatconversioncharacter(%).Theythenhavetodoacostlyconversionbetweenacharacterstringandanumber.Thesefunctionsshouldbeavoidedintime-criticalsectionsofcode.ReferenceparametersUseconstantreferenceparameters(consttype&)insteadofconstantparametersforstructures,unions,andclasses.Powersof2Useapowerof2whendoingintegermultiplyordivide.Mostcompilerswillsubstituteashiftfortheoperation.PointersPointersarefasterthanindexinganarray.Theyarealsomoretrickytouse.InlinefunctionsUsinginlinefunctionseliminatestheoverheadassociatedwithafunctioncall.Italsocanmakethecodebiggerandalittlemoredifficulttodebug.(Seecasehistorybelow.)Page316CaseStudy:InlineFunctionsVersusNormalFunctionsIonceworkedonwritingaword-processingprogramforalargecomputermanufacturer.Wehadafunctionnext_charthatwasusedtogetthenextcharacterfromthecurrentfile.Itwasusedinthousandsofplacesthroughouttheprogram.Whenwefirsttestedtheprogramwithnext_charwrittenasafunction,theprogramwasunacceptablyslow.Analyzingourprogramwefoundthat90percentofthetimewasspentinnext_char.Sowechangedittoaninlinefunction.Thespeeddoubled;however,ourcodesizewentup40percentandrequiredamemoryexpansioncardtowork.Sothespeedwasallright,butthesizewasunacceptable.Wefinallyhadtowritetheroutineasafunctioninhand-optimizedassemblylanguagetogetboththesizeandthespeedtoacceptablelevels. CaseStudy:OptimizingaColor-RenderingAlgorithmIoncewasaskedtooptimizeaprogramthatdidcolorrenderingforalargepicture.Theproblemwasthattheprogramtookeighthourstoprocessasinglepicture.Thislimitedustodoingonepictureaday.ThefirstthingIdidwasruntheprogramonamachinewithafloating-pointaccelerator.Thisbroughtthetimedowntoaboutsixhours.NextIgotpermissiontouseahigh-speedRISCcomputerthatbelongedtoanotherprojectbutwascurrentlysittingidle.Thatreducedthetimetotwohours.Isavedsixhourssolelybyusingfastermachines.Nocodehadchangedyet.Twofairlysimplefunctionswerebeingcalledonlyoncefromtheinnermostloop.Rewritingthesefunctionsasmacrossavedabout15minutes.NextIchangedallthefloating-pointoperationsIcouldfromfloating-pointtointeger.Thesavingsamountedto30minutesoutofa1:45run.ThenInoticedtheprogramwasspendingabout5minutesreadinganASCIIfilecontainingalonglistoffloating-pointnumbersusedintheconversionprocess.Knowingthatscanfisanextremelyexpensivefunction,Icuttheinitializationprocessdowntoalmostnothingbymakingthefilebinary.Totalruntimewasnowdownto1:10.BycarefullyinspectingthecodeandusingeverytrickIknew,Isavedanother5minutes,leavingme5minutesshortofmygoalofanhourperrun.AtthispointPage317myprojectwasrefocusedandtheprogramputinmothballsforuseatsomefuturedate.ProgrammingExercisesExercise17-1:Takeoneofyourpreviousprogramsandrunitusingtheinteractivedebuggertoexamineseveralintermediatevalues.Exercise17-2:Writeamatrix-multiplyfunction.Createatestprogramthatnotonlyteststhefunction,buttimesitaswell.Optimizetheprogramusingpointersanddeterminethetimesavings.Exercise17-3:Writeaprogramtosumtheelementsinanarray.Optimizeit.Exercise17-4:Writeaprogramthatcountsthenumberofbitsinacharacterarray.Optimizeitthroughtheuseofregister-integervariables.Timeitonseveraldifferentarraysofdifferentsizes.Howmuchtimedoyousave?Exercise17-5:Writeyourownversionofthelibraryfunctionmemcpy.Optimizeit.Mostimplementationsofmemcpyarewritteninassemblylanguageandtakeadvantageofallthequirksandtricksoftheprocessor.Howdoesyourmemcpycomparewiththeirs?AnswerstoChapterQuestions Answer17-1:Theproblemisthatmemsetisacharacterfillroutine.Anintegerconsistsof2or4bytes(characters).Eachbyteisassignedthevalue1.Soa2-byteintegerwillreceivethevalue:integer=0x0101;The1-bytehexvaluefor-1is0xFF.The2-bytehexvalueof-1is0xFFFF.Sowecantaketwosinglebyte-1values,putthemtogetherandcomeoutwith-1.Thisworksforzeroalso.Anyothernumberwillproducethewronganswer.Forexample,1is0x01.Twobytesofthisis0x0101,or257.Page31918OperatorOverloadingInThisChapter:·OperatorFunctions·OperatorMemberFunctions·FullDefinitionoftheComplexClass·ProgrammingExercises·AnswerstoChapterQuestionsOverloaded,undermanned,menttoflounder,weEuchredGodAlmighty'sstorm,bluffedtheEternalSea!—KiplingWeallknowwhathappenswhenweaddtwointegers.ButC++doesn'thaveabuilt-incomplextype,soitdoesn'tknowhowtoaddtwocomplexnumbers.However,throughaC++featurecalledoperatoroverloading,youcan''teach"C++howtohandlecomplexnumbers.Operatoroverloadingisusedtodefineasetoffunctionstoadd,subtract,multiplyanddividecomplexnumbersusingthenormaloperators+,-,*,and/.Inthissectionwedefineacomplexnumberclass.Let'sstartbydefiningthebasicC++complexclass.Acomplexnumberconsistsoftwoparts,therealandtheimaginary:classcomplex{protected:////Complexnumbersconsistoftwoparts// doublereal_part;//Therealpartdoubleimaginarypart;//Theimaginarypart//...Nextwedefineseveralmemberfunctions.Theseincludetheusualconstructorsanddestructorsaswellasroutinestogetattherealandimaginarypartsofthenumber.public://Defaultconstructorinitializesthenumberto(0+Oi)complex(void)Page320{realpart=0;imaginary_part=0;}//Copyconstructor-initializeonecomplexfromanothercomplex(constcomplex&other_complex){real_part=other_complex.real_part;imaginary_part=other_complex.imaginary_part;}//Constructacomplexfromtworeals//Ifonlyrealsuppliedassumetheimaginarypartis.0complex(doubleinit_real,doubleinit_imaginary=0.0){real_part=init_real;imaginary_part=init_imaginary;}//Destructordoesnothing-complex(){}////Functionstoreturnthepartsofthenumber//doublereal(void)const//"const"isdiscussedlater{return(real_part);}doubleimaginary(void)const{return(imaginary_part);}//Definefunctionstosetpartsofanumbervoidset_real(doublereal){real_part=real;}voidset_imaginary(doubleimaginary){imaginarypart=imaginary;}};NOTE Asyoumayrecall,theconstappearingaftersomefunctionswasdiscussedinChapter14,MoreonClasses.Nowwewanttouseourcomplexnumbers.Declaringvariablesissimple.Eveninitializingthemwithnumberssuchas(3+2i)iseasy.complexstart;//Startingpointforthegraphcomplexend(3.0,2.0);//EndingpointPage321Butwhathappenswhenwewanttoaddtwocomplexnumbers?Weneedtodefineafunctiontodoit://Version1ofthecomplexaddfunctioninlinecomplexadd(constcomplex&operl,constcomplex&oper2){complexresult(operl.real()+oper2.real(),operl.imaginary()+oper2.imaginary());return(result);}Afewthingsshouldbenotedaboutthisfunction.First,wedefinedittotaketwocomplexnumbersandreturnacomplexnumber.Thatwaywegroupadditions://Addthreecomplexnumbersanswer=add(first,add(second,third));Constantreferenceparametersareused(constcomplex&)forourtwoarguments.Thisisthemostefficientwayofpassingstructuresintoafunction.Finally,becauseitissuchasmallfunction,we'vedefineditasaninlinefunctionforefficiency.Inthisfunction,weexplicitlydeclarearesultandreturnit.Wecandobothinonestep://Version2ofthecomplexaddfunctioninlinecomplexadd(constcomplex&operl,constcomplex&oper2){return(complex(operl.real()+oper2.real(),operl.imaginary()+oper2.imaginary()));}Althoughitisalittlehardertounderstand,itismoreefficient.ItisimportanttounderstandwhatC++doesbehindyourback.Evensuchasimplestatementas:answer=add(first,second);callsaconstructor,anassignmentoperator,andadestructor-allinthatlittlepieceofcode.Inversion1oftheaddfunctionweexplicitlyallocatedavariablefortheresult.Inversion2,C++automaticallycreatesatemporaryvariablefortheresult.Thisnumberhasnonameanddoesn'treallyexistoutsidethereturnstatement.Creatingthetemporaryvariablecausestheconstructortobecalled.Thetemporaryvariableisthenassignedtoanswer;thuswehaveacalltotheassignmentfunction.Aftertheassignment, C++nolongerhasanyuseforthetemporaryvariableandthrowsitawaybycallingthedestructor.Page322OperatorFunctionsUsingtheaddfunctionforcomplexnumbersisalittleawkward.ItwouldbenicetobeabletoconvinceC++toautomaticallycallthisfunctionwheneverwetrytoaddtwocomplexnumberstogetherwiththe+operator.That'swhereoperatoroverloadingcomesin.Allwehavetodoistowritetheaddfunctionas:inlinecomplexoperator+(constcomplex&operl,constcomplex&oper2){return(complex(operl.real()+oper2.real(),operl.imaginary()+oper2.imaginary()));}andC++handlestherest.Note:Theoperatoroverloadingfunctionsshouldbeusedcarefully.Youshouldtrytodesignthemsotheyfollowcommon-senserules.Thatis,+shouldhavesomethingtodowithaddition;-,withsubtraction;andsoon.TheC++I/Ostreamsbreakthisrulebydefiningtheshiftoperators(<>)asinputandoutputoperators.Thiscanleadtosomeconfusion,suchas:cout<<8<<2;Doesthisoutput"8"followedby"2,"ordoesitoutputthevalueoftheexpression(8<<2)?Unlessyou'reanexpertyoucan'ttell.Inthiscasethenumbers"8"and"2"willbeoutput.You'veseenhowyoucanoverloadthe+operator.Nowlet'sexplorewhatotheroperatorsyoucanuse.BinaryArithmeticOperatorsBinaryoperatorstaketwoarguments,oneoneachsideoftheoperator.Forexample,multiplicationanddivisionarebinaryoperators:x*y;a/b;Unaryoperatorstakeasingleparameter.Unaryoperatorsincludeunary-andtheaddressof(&)operator;-x&yThebinaryarithmeticoperatorfunctionstaketwoconstantparametersandproducearesult.Oneoftheparametersmustbeaclassorstructure.Theresultcanbeanything.Forexample,thefollowingfunctionsarelegalforbinaryaddition:complexoperator+(complexvl,complexv2);complexoperator+(complexvl,realv2); Page323complexoperator+(realv1,complexv2);complexoperator+(realv1,realv2);We'vehadtodefinealotofdifferentfunctionsjusttosupporttheadditionofourcomplexclass.Suchdiarrheaofthedefinitionistypicalwhenoverloadingoperators.Table18-1liststhebinaryoperatorsthatcanbeoverloaded.Table18-1.BinaryOperatorsThatCanBeOverloadedOperatorMeaning+AdditionSubtraction*Multiplication/Division%Modulus^BitwiseexclusiveOR&BitwiseAND|BitwiseOR<>RightshiftRelationalOperatorsTherelationaloperatorsincludesuchthingsasequals(==)andnotequals(!=).Normallytheytaketwoconstantclassesandreturneithera0ora1.(Actuallytheycanreturnanything,butthatwouldviolatethespiritofrelationaloperators.)Theequalityoperatorforourcomplexclassis:inlineintoperator==(constcomplex&operl,constcomplex&oper2){return((operl.real()==oper2.real())&&(operl.imaginary()==oper2.imaginary()));}Table18-2liststherelationaloperators.Table18-2RelationalOperatorsOperatorMeaning==Equality !=InequalityGreaterthanPage324Table18-2RelationalOperators(Continued)OperatorMeaning<=Lessthanorequalto>=GreaterthanorequaltoUnaryoperatorsUnaryoperators,suchasnegative(-),takeasingleparameter.Thenegativeoperatorforourcomplextypeis:inlinecomplexoperator-(constcomplex&oper){return(complex(-oper.real(),-oper.imaginary()));}Table18-3liststheunaryoperators.Table18-3UnaryOperatorsOperatorMeaning+Positive-Negative*Dereference&Addressof-OnescomplementShortcutOperatorsOperatorssuchas+=and-=areshortcutsformorecomplicatedoperators.Butwhatarethereturnvaluesof+=and-=?AverycloseexaminationoftheC++standardrevealsthattheseoperatorsreturnthevalueofthevariableaftertheincreaseordecrease.Forexample:i=5; j=i+=2;//Don'tcodelikethisassignsjthevalue7.The+=functionforourcomplexclassis:inlinecomplex&operator+=(complex&operl,constcomplex&oper2){operl.set_real(operl.real()+oper2.real());operl.set_imaginary(operl.imaginary()+oper2.imaginary());return(oper1);}Notethatunliketheotheroperatorfunctionswe'vedefined,thefirstparameterisnotaconstant.Alsowe,returnareferencetothefirstvariable,notanewvariableoracopyofthefirstparameter.Page325Table18-4liststheshortcutoperators.Table18-4.SimpleShortcutOperatorsOperatorMeaning+=Increase-=Decrease*=Multiplyby/=Divideby%=Remainder^=ExclusiveORinto&=ANDinto|=ORinto<<=Shiftleft>>=ShiftrightIncrementandDecrementOperatorsTheincrementanddecrementoperatorshavetwoforms:prefixandsuffix.Forexample:i=5;j=i++;//j=5i=5;j=++i;//j=6Boththeseoperatorsuseafunctionnamedoperator++.Sohowdoyoutellthemapart?TheC++languagecontainsahacktohandlethiscase.Theprefixformoftheoperatortakesone argument,theitemtobeincremented.Thesuffixtakestwo,theitemtobeincrementedandaninteger.Theactualintegerusedismeaningless;it'sjustapositionholdertodifferentiatethetwoformsoftheoperation.Ifwedefine++forthecomplextypetomeanincrementtherealpart,thenourfunctionstohandlethetwoformsof++are://Prefixx=++cinlinecomplex&operator++(complex&oper){oper.set_real(oper.real()+1.0);return(oper);}//Suffixx=c++inlinecomplexoperator++(complexoper,int){complexresult(oper);//Resultbeforeweincrementedoper.set_real(oper.real()+1.0);Page326return(result);}Thisismessy.C++hasreducedustousingcutetricks:theunusedintegerparameter.Inactualpractice,Ineverusethesuffixversionofincrementandalwaysputtheprefixversiononalinebyitself.Thatway,Icanavoidmostoftheseproblems.Thechoice,prefixversussuffix,wasdecidedbylookingatthecodeforthetwoversions.Asyoucansee,theprefixversionismuchsimplerthanthesuffixversion.Sorestrictingyourselftotheprefixversionnotonlysimplifiesyourcode,butitalsomakesthecompiler'sjobalittleeasier.Table18-5liststheincrementanddecrementoperators.Table18-5IncrementandDecrementoperatorsOperatorMeaning++Increment--DecrementLogicalOperatorsLogicaloperatorsincludeAND(&&),OR(||),andNOT(!).Theycanbeoverloaded,butjustbecauseyoucandoitdoesn'tmeanyoushould.Intheory,logicaloperatorsworkonlyonBooleanvalues.Inpractice,becauseC++doesn'thaveaBooleantype,theyworkonintegers.Don'tconfusetheissuemorebyoverloadingthem.Table18-6liststhelogicaloperators. Table18-6LogicalOperatorsOperationMeaning||LogicalOR&&LogicalAND!LogicalNOTI/OOperatorsYou'vebeenusingtheoperators<>forinputandoutput.Actuallytheseoperatorsareoverloadedversionsoftheshiftoperators.ThishastheadvantageofmakingI/Ofairlysimple,atthecostofsomeminorconfusion.Wewouldliketobeabletooutputourcomplexnumbersjustlikeanyotherdatatype.Todothisweneedtodefinea<>(istream&in_file,complex&number)doublereal,imaginary;//Partsofthenumbercharl_paren,comma,r_paren;//Extracharactersoutputaspartof in_file>>l_paren>>real>>comma>>imaginary>>r_paren;number.set(real,imaginary);return(in_file);}Inpractice,it'snotsosimple.Firstofall,wemustcallaspecialmemberfunctionipfxtotelltheI/Osystemthatweareplanningaformattedread.inlineistream&operator>>(istream&in_file,complex&number){//...in_file.ipfx(l);//TelltheI/OsystemwearereadingformattedNextweskipanyleadingwhitespace.in_file>>ws;//SkipwhitespaceWeshouldnowbepointingtothe"("atthebeginningofthenumber.Butbeforewecanreadthischaracter,weneedtocheckfortroubleandabortifnecessary.if(in_file.bad())return(in_file);Page328Now,let'sgrabthe"(".Ofcourse,justtomakesure,wechecktoseethatwereallygeta"("andabortifnecessary.in_file>>ch;//Getcharacterafterwhitespaceif(ch!='('){in_file.set(ios::failbit);//Wehaveanerrorreturn(in_file);}Thefunctionsetisusedtosetaflagindicatingthattheinputoperationfoundaproblem.Thisallowsthecallertotesttoseewhethertheinputworkedbycallingthebadfunction.(Thisfunctioncanalsocauseanexceptiontobethrown.SeeChapter22,Exceptions,formoreinformation.)Wehavereachedthe"(".Let'sreadtherealpartofthenumber.in_file>>real;Nowwetakecareofthe","andrelatedwhitespacebetweenthenumbers.Ateachstepwecheckforerrors:if(in_file.bad())return(in_file);in_file>>ws>>ch;//Getfirstcharacterafternumberif(in_file.bad()return(in_file);if(ch!=','){in_file.set(ios::failbit);return(in_file);}Nextistheimaginarypart. in_file>>imaginary;Finally,wemakesurethatthenumberendswitha")".in_file>>ws>>ch;if(in_file.bad())return(in_file);if(ch!=')'){in_file.set(ios::failbit);return(in_file);}Thework'scomplete,sowestoretheresultandgetout.number.set(real,imaginary);return(in_file);}Thecompleteversionofthecomplexreader(punintended)appearsinExample18-1.Page329Example18-1inlineistream&operator>>(istream&in_file,complex&number){doublereal,imaginary;//Realandimaginarypartcharch;//Randomcharacterusedtoverifyinputnumber.set(0.0,0.0);//Initializethenumber(justincase)in_file.ipfx(1);//TelltheI/Osystemwearereadingformattedin_file>>ws;//Skipwhitespaceif(in_file.bad()return(in_file);in_file>>ch;//Getcharacterafterwhitespaceif(ch!='('){in_file.set(ios::failbit);//Wehaveanerrorreturn(in_file);}in_file>>real;if(in_file.bad()return(in_file);in_file>>ws>>ch;//Getfirstcharacterafternumberif(in_file.bad()return(in_file);if(ch!=','){in_file.set(ios::failbit);return(in_file);}in_file>>imaginary; in_file>>ws>>ch;if(in_file.bad())return(in_file);if(ch!=')'){in_file.set(ios::failbit);return(in_file);}number.set(real,imaginary);return(infile);}IndexOperator''[]"Theoperator[]isusedbyC++toindexarrays.AswewillseeinChapter20,AdvancedPointers,thisoperatorisveryusefulwhendefiningaclassthatmimicsanarray.Normally,thisfunctiontakestwoarguments,aclassthatsimulatesanarrayandanindex,andreturnsareferencetoaniteminthearray.double&operator[](array_class&array,intindex)Page330Wecoverthe[]operatorinmoredetailinChapter23,ModularProgramming.newanddeleteWe'llsayverylittleaboutoverloadingtheglobaloperatorsnewanddeleteatthistime.Firstofall,theyaren'tintroduceduntilChapter20,AdvancedPointers,soyoudon'tknowwhattheydo.Second,whenyouknowwhattheydo,youwon'twanttooverridethem.I'veseenonlyoneprogramwherethenewanddeleteoperatorswereoverridden(oratleasttheirCequivalents).Thatprogramwaswrittenbyaverycleverprogrammerwholikedtodoeverythingalittlestrangely.Theresultwascodethatwasanightmaretodebug.Sounlessyouareaverycleverprogrammer,leavenewanddeletealone.Andifyouareacleverprogrammer,pleaseleavenewanddeletealoneanyway.SomedayImighthavetodebugyourcode.ExoticOperatorsC++containsaveryrichsetofoperators.Someofthesearerarely,ifever,used.Theseinclude:()Allowsyoutodefineadefaultfunctionforaclass.,Commaoperator.Allowstwoexpressionstobeconcatenated.Itisrarelyusedandprobablyshouldnotbeoverloaded.->*Pointertomember.Rarelyused.->Classmember.AlloftheseoperatorsarediscussedinChapter28,C++'sDustierCorners. OperatorMemberFunctionsSofarwe'vebeenusingoperatoroverloadingfunctionsjustlikeordinaryfunctions.Theycanalsobedefinedasmemberfunctions.Theonlydifferenceisthatasmemberfunctionsthefirstargument,theclassitself,isimplied.So,forexample,youcanwritetheoperator+=asanordinaryfunctionorasamemberfunction.Here'stheordinaryversionthatyou'vealreadyseen.inlinecomplex&operator+=(complex&operl,constcomplex&oper2){operl.set_real(operl.real()+oper2.real());operl.set_imaginary(operl.imaginary()+oper2.imaginary());return(oper1);}Page331Here'sthememberfunction:classcomplex{//.....public:inlinecomplex&operator+=(constcomplex&oper2){real_part+=oper2.real();imaginary_part+=oper2.imaginary();return(*this);}Theonlytrickusedinthisfunctionisthekeywordthis.Thisisapredefinedvariablethatreferstothecurrentobject.Forexample,youcanaccessthedatamemberreal_partusingthestatement:real_part+=oper2.real();Thesamestatementcanbewrittenas:this->real_part+=oper2.real();Inmostcases,youdon'tneedtousethis.However,inafew,suchasthe+=operator,itcomesinhandy.Whichflavoroftheoperatoroverloadingfunctionsshouldyouuse?Theonethatmakesyourprogramtheclearestandeasiesttoread.Ingeneral,weusethestandardfunctionsforthesimpleoperators,suchas+,-,*,and/,whileIusememberfunctionsfortheshortcutandunaryoperators,suchas+=,-=,++,andunary-.Someoverloadedfunctionsonlyworkasmemberfunctions.Theseincludethecastingoperatorsaswellasclassspecificversionsofnewanddelete.CastingFinallywecometothecastoperators.Castingisawayofchangingonetypetoanother.Forexample,let'ssaythatwhenwecastourcomplextypetoadouble,wewanttherealpart.Wecandefineacastoperatorforthisfunctionas: classcomplex:public://(Wedidn'treallyputthisinourcomplexclass)doubleoperatordouble(){return(realpart);}C++automaticallycallsthisfunctionwheneveritwantstoturnacomplexintoadouble.Thetroubleisthatbydefiningacast,yougiveC++somethingelsethatitcancallbehindyourback.Personally,IliketoknowwheneverC++callssomething,soIavoidcreatingcastoperators.Unlessyouhaveaverygoodreasontodefineone,don'tcreateacastoperatorfunction.Page332FullDefinitionoftheComplexClassExample18-2liststheentirecomplexclass.Thebeginningoftheheaderfilesummarizesallthefunctionsthataredefined.IncreatingthisclassIdiscoveredthatitconsistedofmany(29tobeexact)littleone-andtwo-linefunctions.Commentingeachofthesewithafull-functioncommentblockwouldobscurethecode.Inotherwords,thisisoneofthefewcases(theveryfew)whereaddingcommentswouldcauseconfusion,somostofthesmallfunctionshavenocomments.Whencreatingthisclass,Inoticedthatalotofthefunctionshaveasimilarstructure.Forexample.+=looksalotlike-=andsoon.Asamatteroffact,Icreatedthe-=operatorbycopyingthe+=functionsandeditingalittle.C++containsarichoperatorsetthatcausesthissortofrepetitiontohappenwhenyou'retryingtodefineacompletesetofoperatorsforaclass.Finally,thesimpleoperationsaredefinedinthefilecomplex.hwhilethelongerfunctionsareleftinthefilecomplex.cc.Example18-2complex/complex.h,complex/complex.ccFile:complex.h#ifndef_complex_h_//Avoiddoubleincludes#define_complex_h__//Preventdoubleinclude#include#include/*********************************************************Complexclass****Membersdefined**complex()//Defaultconstructor**complex(real,imaginary)//Specifytwoparts**//forconstruction**complex(complex)//Copyconstructor****real()//Getrealpart**imaginary()//Getimaginarypart****set(real,imaginary)//Setbothpartsof#* *set_real(real)//Setrealpartof#**set_imaginary(imaginary)//Setimaginarypart****Operatormemberfunctions**c--acomplexnumber**s--ascalar(double)**c=c**c+=c;*Page333Example18-2.complex/complex.h,complex/complexcc(Continued)*c+=s;**c-=c;**c-=s;**c/=c;**c/=s;**c*=c;**c*=s;****Thefollowingfunctionsdon'treallymakealotof**senseforcomplexnumbers,buttheyaredefined**forthepurposeofillustration**c++**++c**c--**--c****Arithmeticoperatorsdefined**c=c+c;**c=s+c;**c=c+s;**c=c-c;**c=s-c;**c=c-s;**c=c*c;**C=s*c;**c=c*s;**c=c/c;**c=s/c;**c=c/s;**-c**+c**ostream<>c//Inputfunction*********************************************************/classcomplex{private:////Complexnumbersconsistoftwoparts//doublereal_part;//Therealpartdoubleimaginary_part;//Theimaginarypartpublic: //Defaultconstructor,zeroeverythingcomplex(void){real_part=0.0;imaginary_part=0.0;}//CopyconstructorPage334Example18-2.complex/complexh,complex/complex.cc(Continued)complex(constcomplex&other_complex){real_part=other_complex.real_part;imaginary_part=other_complex.imaginary_part;}//Constructacomplexoutoftworealnumberscomplex(doubleinit_real,doubleinit_imaginary=0.0){real_part=init_real;imaginary_part=init_imaginary;}//Destructordoesnothing-complex(){}////Functiontoreturnthepartsofthenumber//doublereal(void)const{return(real_part);}doubleimaginary(void)const{return(imaginary_part);}//Functionstosetpartsofanumbervoidset(doublereal,doubleimaginary)real_part=real;imaginary_part=imaginary;}voidset_real(doublereal)real_part=real;}voidset_imaginary(doubleimaginary){imaginary_part=imaginary;}complexoperator=(constcomplex&oper2)set(oper2.real_part,oper2.imaginary_part); return(*this);}complex&operator+=(constcomplex&oper2)real_part+=oper2.real();imaginary_part+=oper2.imaginary();return(*this);}Page335Example18-2.complex/complex.h,complex/complex.cc(Continued)complex&operator+=(doubleoper2)real_part+=oper2;return(*this);}complex&operator-=(constcomplex&oper2)real_part-=oper2.real();imaginary_part-=oper2.imaginary();return(*this);}complex&operator-=(doubleoper2)real_part-=oper2;return(*this);}complex&operator*=(constcomplex&oper2)//Placetoholdtherealpartoftheresult//whilewecomputetheimaginarypartdoublereal_result=real_part*oper2.real()-imaginary_part*oper2.imaginary();imaginary_part=real_part*oper2.imaginary()+imaginary_part*oper2.real();realpart=real_result;return*this;}complex&operator*=(doubleoper2)real_part*=oper2;imaginary_part*=oper2;return(*this);}complex&operator/=(constcomplex&oper2);complex&operator/=(doubleoper2)real_part/=oper2;imaginary_part/=oper2;return(*this);} //c++complexoperator++(int){complexresult(*this);real_part+=1.0;return(result);}//++cPage336Example18-2complex/complexh,complex/complex.cc(Continued)complex&operator++(void)real_part+=1.0;return(*this);}//c--complexoperator--(int){complexresult(*this);real_part-=1.0;return(result);}//--ccomplex&operator--(void){real_part-=1.0;return(*this);}};inlinecomplexoperator+(constcomplex&operl,constcomplex&oper2){returncomplex(operl.real()+oper2.real(),operl.imaginary()+oper2.imaginary());}inlinecomplexoperator+(constcomplex&operl,doubleoper2){returncomplex(operl.real()+oper2,operl.imaginary());}inlinecomplexoperator+(doubleoperl,constcomplex&oper2){returncomplex(operl+oper2.real(),oper2.imaginary());}inlinecomplexoperator-(constcomplex&operl,constcomplex&oper2){returncomplex(operl.real()-oper2.real(),operl.imaginary()-oper2.imaginary());}inlinecomplexoperator-(constcomplex&operl,doubleoper2) {returncomplex(operl.real()-oper2,operl.imaginary());}inlinecomplexoperator-(doubleoperl,constcomplex&oper2){returncomplex(operl-oper2real()Page337Example18-2.complex/complexh,complex/complex.cc(Continued)-oper2.imaginary());}inlinecomplexoperator*(constcomplex&operl,constcomplex&oper2){returncomplex(operl.real()*oper2.real()-operl.imaginary()*oper2.imaginary(),operl.real()*oper2.imaginary()+operl.imaginary()*oper2.real());}inlinecomplexoperator*(constcomplex&operl,constdoubleoper2){returncomplex(operl.real()*oper2,operl.imaginary()*oper2);}inlinecomplexoperator*(constdoubleoperl,constcomplex&oper2)}returncomplex(operl*oper2.real(),operl*oper2.imaginary());}externcomplexoperator(constcomplex&operl,constcomplex&oper2);inlinecomplexoperator/(constdouble&operl,constcomplex&oper2){return(complex(operl,0.0)/oper2);}inlinecomplexoperator/(constcomplex&operl,constdouble&oper2){return(operl/complex(oper2,0.0));}inlineintoperator==(constcomplex&operl,constcomplex&oper2){return((operl.real()==oper2.real())&&(operl.imaginary()==oper2.imaginary()));}inlineintoperator!=(constcomplex&operl,constcomplex&oper2){return(!(operl==oper2));}inlinecomplexoperator-(constcomplex&operl) {returncomplex(-operl.real(),-operl.imaginary());}inlinecomplexoperator+(constcomplex&operl){returncomplex(+operl.real(),+operl.imaginary());}Page338Example18-2.complex/complexh,complex/complex.cc(Continued)inlineostream&operator<<(ostream&out_file,constcomplex&number){out_file<<'('<>(istream&in_file,complex&number);#endif/*_complex_h_*///AvoiddoubleincludesFile:complex.cc#include"complex.h"/*********************************************************c=c/c--complexdivision****Parameters**operl,oper2--twooperandsofthedivide****Returns**resultofthedivide*********************************************************/complexoperator/(constcomplex&operl,constcomplex&oper2){//Denominatoroftheresultdoubleden=fabs(oper2.real())+fabs(oper2.imaginary());//Realpartoftheoperlfactordoubleoperl_real_den=operl.real()/den;//Imaginarypartoftheoperlfactordoubleoperl_imag_den=operl.imaginary()/den;//Realpartoftheoper2factordoubleoper2_real_den=oper2.real()/den;//Imaginarypartoftheoper2factordoubleoper2_imag_den=oper2.imaginary()/den;//Normalizationfactordoublenormalization=oper2_real_den*oper2_real_den+oper2_imag_den*oper2_imag_den;returncomplex((operl_real_den*oper2_real_den+operl_imag_den*oper2_imag_den)/normalization, (operl_imag_den*oper2_real_den-operl_real_den*oper2_imag_den)/normalization);}/*********************************************************c/=c--complexdivideby***Page339Example18-2complex/complex.h,complex/complex.cc(Continued)*Parameters**oper2--operatortodivideby****Returns**referencetotheresultofthedivide***********************************************************/complex&complex::operator/=(constcomplex&oper2){//Denominatoroftheresultdoubleden=fabs(oper2.real())+fabs(oper2.imaginary());//Denominator--operator1realpartdoubleoper1_real_den=real_part/den;//Denominator--operator1imaginarypartdoubleoperl_imag_den=imaginary_part/den;//Denominator--operator2realpartdoubleoper2_real_den=oper2.real()/den;//Denominator--operator2imaginarypartdoubleoper2_imag_den=oper2.imaginary()/den;//Normalizationfactordoublenormalization=oper2_real_den*oper2_real_den+oper2_imag_den*oper2_imag_den;real_part=(operl_real_den*oper2_real_den+operl_imag_den*oper2_imag_den)/normalization;imaginary_part=(operl_imag_den*oper2_real_den-operl_real_den*oper2_imag_den)/normalization;return(*this);}/*********************************************************istream>>complex--readacomplexnumber****Parameters**in_file--filetoread**number--placetoputthenumber****Returns**referencetotheinputfile******************************************************/istream&operator>>(istream&in_file,complex&number){ doublereal,imaginary;//Realandimaginarypartcharch;//Randomcharacterusedtoverifyinputnumber.set(0.0,0.0);//Initializethenumber(justincase)in_file.ipfx(1);//TelltheI/Osystemwearereadingformattedin_file>>ws;//SkipwhitespacePage340Example18-2complex/complexh.complex/complex.cc(Continued)if(in_file.bad())return(in_file);in_file>>ch;//Getcharacterafterwhitespaceif(ch!='('){in_file.setf(ios::failbit);//Wehaveanerrorreturn(in_file);}in_file>>real;if(in_file.bad())return(in_file);in_file>>ws>>ch;//Getfirstcharacterafternumberif(in_file.bad())return(in_file);if(ch!=','){in_file.setf(ios::failbit);return(in_file);}in_file>>imaginary;in_file>>ws>>ch;if(in_file.bad())return(in_file);if(ch!=')'){in_file.setf(ios::failbit);return(in_file);}number.set(real,imaginary);return(in_file);}Question18-1:WhydoesExample18-3fail?Whenrunitprintsout:CopyconstructorcalledCopyconstructorcalledoverandover.Hint.Reviewthesection''CopyConstructor"inChapter13.ThankstoJeffHewettforthisproblem.Example18-3.equal/equalcc1#include 23classtrouble{4public:5intdata;67trouble(void);8trouble(consttrouble&old);9troubleoperator=(troubleold_trouble);Page341Example18-3equal/equal.cc(Continued)10};1112trouble::trouble(void){13data=0;14}1516trouble::trouble(consttrouble&old){17cout<<"Copyconstructorcalled ";18*this=old;19}2021troubletrouble::operator=(troubleold_trouble){22cout<<"Operator=called ";23data=old_trouble.data;24return(*this);25}2627intmain()28{29troubletroublel;30troubletrouble2(troublel);3132return(0);33}ProgrammingExercisesExercise18-1:Writeaclasstohandlefractionssuchas"1/3."Defineaddition,subtraction,multiplication,anddivisionoperatorsforthesefractions.Forexample:1/3+1/2=5/6.Exercise18-2:Writeafixed-pointnumberclasstohandlenumbers.AllnumbersareoftheformDDDDD.D.Inotherwords,allnumbershaveonlyasingledigittotherightofthedecimalpoint.Useintegerstoimplementthisclass.Exercise18-3:Writeaclasstoimplementasparseintegerarray.Thisismuchlikeasimpleintegerarray:intsimple_array[100];Butunlikeasimplearray,theindicescangofrom0to1,000,000.That'sthebadnews.Thegoodnewsisthatatmost100elementswillbesetatanytime.Therestoftheelementswillbe zero.Exercise18-4:Writeatimeclass.Implementfunctionstoadd,subtract,read,andprinttimes.Exercise18-5:Writeadateclassthatallowsyoutoadd,subtract,read,andprintsimpledatesoftheformMM/DD.Assumeyearisnotaleapyear.Page342Exercise18-6:(Advanced)Writeafull-dateclassthatallowsyoutoadd,subtract,read,andprintdatesoftheformMM/DD/YY.AnswerstoChapterQuestionsAnswer18-1:Thecopyconstructorcallstheoperator=function.Theparameterlisttothisfunctionis:troubletrouble::operator=(troubleold_trouble){Theparametertothisfunctionisbeingpassedasacall-by-valueparameter.WhenC++seesthistypeofparameteritcallsthecopyconstructortoputtheparameteronthestack.SowehaveaninfiniteloopThecopyconstructorcallstheoperator=function.C++seesthecall-by-valueparameterandcallsthecopyconstructor,whichcallsoperator=andcausesthecopyconstructortobecalled.Thiskeepsupuntilthesystemrunsoutofstackspaceortheusergetsdisgustedandabortstheprogram.Thesolutionistopasstheparametertooperator=asareference.Thisnotonlyismoreefficient,butalsoworks.troubletrouble::operator=(consttrouble&old_trouble){Page34319FloatingPoint InThisChapter:·Floating-PointFormat·FloatingAddition/Subtraction·Multiplication·Division·OverflowandUnderflow·RoundoffError·Accuracy·MinimizingRoundoffError·DeterminingAccuracy1isequalto2forsufficientlylargevaluesof1.—AnonymousComputershandleintegersverywell.Thearithmeticissimple,exact,andfast.Floatingpointistheopposite.Computersdofloating-pointarithmeticonlywithgreatdifficulty.Thischapterdiscussessomeoftheproblemsthatcanoccurwithfloatingpoint.Inordertoaddresstheprinciplesinvolvedinfloating-pointarithmetic,wehavedefinedasimpledecimalfloating-pointformat.Wesuggestyouputasideyourcomputerandworkthroughtheseproblemsusingpencilandpapersoyoucanseefirsthandtheproblemsandpitfallsthatoccur.Theformatusedbycomputersisverysimilartotheonedefinedinthischapter,exceptthatinsteadofusingbase10,computersusebase2,8,or16.However,alltheproblemsdemonstratedhereonpapercanoccurinacomputer.Floating-PointFormatFloatingpointnumbersconsistofthreeparts:asign,afraction,andanexponent.Ourfractionisexpressedasafour-digitdecimal.Theexponentisasingle-decimaldigit.Soourformatis:±f.fffx10±ePage344where:±isthesign(plusorminus).f.fffisthefour-digitfraction.±eisthesingle-digitexponent.Zerois+0.000x10+0.Werepresentthesenumbersin"E"format:±f.fffE±e. Thisformatissimilartothefloating-pointformatusedinmanycomputers.TheIEEEhasdefinedafloating-pointstandard(#742),butnotallmachinesuseit.Table19-1showssometypicalfloating-pointnumbers.Table19-1.Floating-PointExamplesNotationNumber+1.000E+01.0+3.300E+533000.0-8.223E-3-0.008223+0.000E+00.0Thefloating-pointoperationsdefinedinthischapterfollowarigidsetofrules.Tominimizeerrorswemakeuseofaguarddigit.Thatisanextradigitaddedtotheendofthefractionduringcomputation.Manycomputersuseaguarddigitintheirfloating-pointunits.FloatingAddition/SubtractionToaddtwonumberslike2.0and0.3,thecomputermustperformthefollowingsteps:1.Startwiththenumbers.+2.000E+0Thenumberis2.0+3.000E-1Thenumberis0.32.Addguarddigitstobothnumbers.+2.0000E+0Thenumberis2.0+3.0000E-1Thenumberis0.33.Shiftthenumberwiththesmallestexponenttotherightonedigitandincrementitsexponent.Continueuntiltheexponentsofthetwonumbersmatch.+2.0000E+0Thenumberis2.0+0.3000E-0Thenumberis0.3Page345 4.Addthetwofractions.Theresulthasthesameexponentasthetwonumbers.+2.0000E+0Thenumberis2.0+0.3000E-0Thenumberis0.3+2.3000E+0Result2.35.Normalizethenumberbyshiftingitleftorrightuntilthereisjustonenonzerodigittotheleftofthedecimalpoint.Adjusttheexponentaccordingly.Anumberlike+0.1234E+0wouldbenormalizedto+1.2340E-1.Becausethenumber+2.3000E+0isalreadynormalized,wedonothing.6.Finally,iftheguarddigitisgreaterthanorequalto5,roundthenextdigitup.Otherwise,truncatethenumber.+2.3000E+0Roundlastdigit+2.300E+0Result2.37.Forfloating-pointsubtraction,changethesignofthesecondoperandandadd.MultiplicationWhenwewanttomultiplytwonumberssuchas0.12x11.0,thefollowingrulesapply.1.Addtheguarddigit.+1.2000E-1Thenumberis0.12+1.1000E+1Thenumberis11.02.Multiplythetwofractionsandaddtheexponents.(1.2x1.1=1.32)(-1+1=0)+1.2000E-1Thenumberis0.12+1.1000E+1Thenumberis11.0+1.3200E+0Theresultis1.323.Normalizetheresult.Iftheguarddigitisgreaterthanorequalto5,roundthenextdigitup.Otherwise,truncatethenumber.+1.3200E+0Thenumberis1.32Noticethatinmultiply,youdidn'thavetogothroughallthatshifting.Therulesfor multiplicationarealotshorterthanthoseforadd.Integermultiplicationisalotslowerthanintegeraddition.Infloatingpoint,multiplicationspeedisalotclosertothatofaddition.Page346DivisionTodividenumberslike100.0by30.0,wemustperformthefollowingsteps.1.Addtheguarddigit.+1.0000E+2Thenumberis100.0+3.0000E+1Thenumberis30.02.Dividethefractions,andsubtracttheexponents.+1.0000E+2Thenumberis100.0+3.0000E+1Thenumberis30.0+0.3333E+1Theresultis3.3333.Normalizetheresult.+3.3330E+0Theresultis3.3334.Iftheguarddigitislessthanorequalto5,roundthenextdigitup.Otherwise,truncatethenumber.+3.333E+0Theresultis3.333OverflowandUnderflowTherearelimitstothesizeofthenumberacomputercanhandle.Whataretheresultsofthefollowingcalculation?9.000E+9x9.000E+9Multiplyingitout,weget:8.1x1019However,wearelimitedtoasingle-digitexponent,toosmalltohold19.Thisisanexampleofoverflow(sometimescalledexponentoverflow).Somecomputersgenerateatrapwhenthisoccurs,thusinterruptingtheprogramandcausinganerrormessagetobeprinted.Othersarenot soniceandgenerateawronganswer(like8.100E+9).ComputersthatfollowtheIEEEfloating-pointstandardgenerateaspecialvaluecalled+Infinity.Underflowoccurswhenthenumbersbecometoosmallforthecomputertohandle.Example:1.OOOE-9x1.OOOE-9Theresultis:1.0x10-18Because-18istoosmalltofitintoonedigit,wehaveunderflow.Page347RoundoffErrorFloatingpointisnotexact.Everyoneknowsthat1+1is2,butdidyouknowthat1/3+1/3!=2/3?Thiscanbeshownbythefollowingfloating-pointcalculations:2/3asfloatingpointis6.667E-11/3asfloatingpointis3.333-1+3.333E-1+3.333E-1+6.666E-1,or0.6666whichisnot:+6.667E-1Everycomputerhasasimilarproblemwithitsfloatingpoint.Forexample,thenumber0.2hasnoexactrepresentationinbinaryfloatingpoint.Floatingpointshouldneverbeusedformoney.Becauseweareusedtodealingwithdollarsandcents,itistemptingtodefinetheamount$1.98as:floatamount=1.98;However,themorecalculationsyoudowithfloatingpoint,thebiggertheroundofferror.Banks,creditcards,andtheIRStendtobeveryfussyaboutmoney.GivingtheIRSacheckthat'salmostrightisnotgoingtomakethemhappy.Moneyshouldbestoredasanintegernumberofpennies.AccuracyHowmanydigitsofthefractionareaccurate?Atfirstglanceyoumightbetemptedtosayallfourdigits.Thoseofyouwhohavereadtheprevioussectiononroundofferrormightbetemptedtochangeyouranswertothree.Theansweris: Theaccuracydependsonthecalculation.Certainoperations,suchassubtractingtwonumbersthatareclosetoeachother,generateinexactresults.Considerthefollowingequation:1-1/3-1/3-1/31.000E+0-3.333E-1Page348-3.333E-1-3.333E-1or:1.000E+0-3.333E-1-3.333E-1-3.333E-10.0010E+0,or1.000E-3Thecorrectansweris0.000E+0andwegot1.000E-3.Theveryfirstdigitofthefractioniswrong.Thisisanexampleoftheproblemcalledroundofferrorthatcanoccurduringfloating-pointoperations.MinimizingRoundoffErrorTherearemanytechniquesforminimizingroundofferror.Guarddigitshavealreadybeendiscussed.Anothertrickistousedoubleinsteadoffloat.Thisgivesyouapproximatelytwicetheaccuracyaswellastwicetherange.Italsopushesawaytheminimizationproblemtwiceasfar.Butroundofferrorsstillcancreepin.Advancedtechniquesforlimitingtheproblemscausedbyfloatingpointcanbefoundinbooksonnumericalanalysis.Theyarebeyondthescopeofthistext.Thepurposeofthischapteristogiveyousomeideaofwhatsortofproblemscanbeencountered.Floatingpointbyitsverynatureisnotexact.Peopletendtothinkofcomputersasveryaccuratemachines.Theycanbe,buttheyalsocangivewildlywrongresults.Youshouldbeawareoftheplaceswhereerrorscanslipintoyourprogram.DeterminingAccuracyThereisasimplewayofdetermininghowaccurateyourfloatingpointis(forsimple calculations).Themethodusedinthefollowingprogramistoadd1.0+0.1,1.0+0.01,1.0+0.001,andsoonuntilthesecondnumbergetssosmallthatitmakesnodifferenceintheresult.TheoldClanguagespecifiedthatallfloating-pointnumbersweretobedoneindouble.C++removedthatrestriction,butbecausemanyC++compilersarePage349reallyfront-endstoaCcompiler,frequentlyC++arithmeticisdoneindouble.Thismeansthattheexpression:floatnumber1,number2;...while(number1+number2!=numberl)isequivalentto:while(double(numberl)+double(number2)!=double(numberl))Ifyouusethe1+0.001trick,theautomaticconversionoffloattodoublemaygiveadistortedpictureoftheaccuracyofyourmachine.(Inonecase,84bitsofaccuracywerereportedfora32-bitformat.)Example19-1computestheaccuracyofbothfloatingpointasusedinequationsandfloatingpointasstoredinmemory.Notethetrickusedtodeterminetheaccuracyofthefloating-pointnumbersinstorage.Example19-1float/float.cc#include#includemain(){//Twonumberstoworkwithfloatnumber1,number2;floatresult;//Resultofcalculationintcounter;//Loopcounterandaccuracychecknumber1=1.0;number2=1.0;counter=0;while(number1+number2!=numberl)++counter;number2=number2/10.0;}cout<#include#include"linked.h"/********************************************************Find--lookforadataiteminthelist****Parameters**name--nametolookforinthelist****Returns**1ifnameisfound**0ifnameisnotfound**********************************************************/intlinked_list::find(char*name){/*Currentstructurewearelookingat*/linked_list_element*current_ptr;current_ptr=firstptr;while((strcmp(current_ptr->data,name)!=0)&&(current_ptr!=NULL))current_ptr=current_ptr->next_ptr;/**Ifcurrent_ptrisnull,wefellofftheendofthelistand*didn'tfindthename*/return(current_ptr!=NULL);}Question20-1:Whydoesrunningthisprogramsometimesresultinabuserror?Othertimesitwillreport"found"(return1)foranitemthatisnotinthelist.Inourfindprogramwehadtousethecumbersomenotation(*currentptr).datatoaccessthedatafieldofthestructure.C++providesashorthandforthisconstructusingthe->operator.Thedot(.)operatormeansthefieldofastructure,andthestructurepointeroperator(->)indicatesthefieldofastructurepointer.Thefollowingtwoexpressionsareequivalent:(*currentptr).data=value;current_ptr->data=value;OrderedLinkedListsSofarwehaveonlyaddednewelementstotheheadofalinkedlist.Supposewewanttoaddelementsinorder.Figure20-5isanexampleofanorderedlinkedlist. Page363Figure20-5OrderedlistFigure20-6showsthestepsnecessarytoaddanewelement,"53,"tothelist.Thefollowingmemberfunctionimplementsthisalgorithm.Thefirststepistolocatetheinsertionpoint.Thefirst_ptrpointstothefirstelementofthelist.Theprogrammovesthevariablebefore_ptralongthelistuntilitfindstheproperplacefortheinsertion.Thevariableafter_ptrissettopointtothepreviousvalue.Thenewelementwillbeinsertedbetweentheseelements.voidlinked_list::enter(intitem){linked_list_item*beforeptr;//Insertbeforethiselementlinked_list_item*after_ptr;//Insertafterthiselement/**Warning:Thisroutinedoesnottake*careofthecasewheretheelementis*insertedattheheadofthelist*/before_ptr=first_ptr;while(1)beforeptr=after_ptr;after_ptr=afterptr->next_ptr;//Didwehittheendofthelist?if(after_ptr==NULL)break;//Didwefindtheplace?if(item>=afterptr->data)break;}Page364 Figure20-6.Addingelement''53"toanorderedlistNowweknowwheretoinsertthenewelement.Allwemustdoisinsertit.Westartattheelementbeforethenewone(before_ptr).Thiselementshouldpointtothenewelement,so:before_ptr->nextptr=new_ptr;Page365Nextisthenewelement(new_ptr).Itneedstopointtotheelementafterit,orafter_ptr.Thisisaccomplishedwiththecode:new_ptr->next_ptr=after_ptr;Theelementafter_ptrneedstopointtotherestofthechain.Becauseitalreadydoes,weleaveitalone.Thefullcodeforinsertingthenewelementis://Createnewitemnew_ptr=newlinked_list_item; new_ptr->data=item;//Linkinthenewitembefore_ptr->next_ptr=newptr;new_ptr->next_ptr=after_ptr;}Double-linkedListAdouble-linkedlistcontainstwolinks.Onelinkpointsforwardtothenextelement;theotherpointsbackwardtothepreviouselement.Double-linkedlistsareusefulwheretheprogramneedstogothroughthelistbothforwardandbackward.Theclassesforadouble-linkedlistare:classdouble_list{private:classdouble_list_element{public:intdata;//Dataitemprivate:double_list_element*next_ptr;//Forwardlinkdouble_list_element*previous_ptr;//Backwardlinkfriendclassdouble_list;};public:double_list_element*head_ptr;//Headofthelistdouble_list(void){head_ptr=NULL;}//...OthermemberfunctionsThisisshowngraphicallyinFigure20-7.Toinsertanitemintothelist,wefirstlocatetheinsertionpoint:voiddouble_list::enter(intitem){double_list_element*insert_ptr;//Insertbeforethiselement/**Warning:ThisroutinedoesnottakePage366 Figure20-7Double-linkedlist*careofthecasewheretheelementis*insertedattheheadofthelist*ortheendofthelist*/insert_ptr=head_ptr;while(1)(insert_ptr=insert_ptr->next;//Havewereachedtheend?if(insert_ptr==NULL)break;//Havewereachedtherightplace?if(item>=insertptr->data)break;}Noticethatwedonothavetokeeptrackofthevariableafter_ptr.Thepointerinsert_ptr->previous_ptrisusedtolocatethepreviouselement.Toinsertanewelement,wemustadjusttwosetsofpointers.Firstwecreatethenewelement://Createnewelementnew_ptr=newdouble_list_element;Nextwesetuptheforwardpointerforthenewitem:new_ptr->next_ptr=insert_ptr;GraphicallythisisrepresentedbyFigure20-8.Nextweconnectthelinktothepreviouselementusingthecode:new_ptr->previous_ptr=insert_ptr->previous_ptr;Graphically,thisisrepresentedinFigure20-9.Page367 Figure20-8.Double-linkedlistinsert,part#1Thelinksaresetupforthenewelement.Nowallwehavetodoisbreaktheoldlinksbetweenitems11and36andconnectthemtothenewitem(27).Gettingtoitem11isabitofatrick.Weonlyhaveapointertoitem36(insert_ptr).However,ifwefollowthepreviouslinkback(insert_ptr->previous_ptr),wegettheitem(11)thatwewant.Nowallwehavetodoisfixthenext_ptrforthisitem.TheC++codeforthisissurprisinglysimple:insert_ptr->previous_ptr->next_ptr=new_ptr;VisuallywecanseethisoperationinFigure20-9.Wehaveonlyoneremaininglinktofix:theprevious_ptroftheinsert_ptr.InC++thecodelookslike:insert_ptr->previous_ptr=new_ptr;GraphicallythisoperationisrepresentedbyFigure20-11.Insummary,toinsertanewiteminadouble-linkedlist,youmustsetfourlinks:1.Thenewitem'spreviouspointer:new_ptr->previous_ptr=insert_ptr->previous_ptr;Page368 Figure20-9Double-linkedlistinsert,part#22.Thenewitem'snextpointer:newptr->nextptr=insertptr;3.Thepreviouspointeroftheitemthatwillfollowthenewitem:insert_ptr->previous_ptr->next_ptr=new_ptr;4.Thenextpointeroftheitemthatwillprecedethenewitem:insert_ptr->previous_ptr=new_ptr;TreesSupposewewanttocreateanalphabetizedlistofthewordsthatappearinafile.Wecouldusealinkedlist,butsearchingalinkedlistisslowbecausewemustcheckeachelementuntilwefindthecorrectinsertionpoint.Byusingadatatypecalledatree,wecanreducethenumberofcomparisonstremendously.AbinarytreestructurelookslikeFigure20-12.Eachboxiscalledanodeofthetree.Theboxatthetopistherootandtheboxesatthebottomaretheleaves.*Eachnodecontainstwopointers:aleftpointerandarightpointer,whichpointtotheleftandrightsubtrees.Page369 Figure20-10.Double-linkedlistinsert,part3Thestructureforatreeis:classtree{classnode{public:char*data;//Wordforthistreeprivate:node*right;//Treetotherightnode*left;//Treetotheleftfriendclasstree;};public:node*root;//Topofthetree(theroot)tree(void){root=NULL;);/...Othermemberfunction};Treesareoftenusedforstoringasymboltable(alistofvariablesusedinaprogram).Inthischapterwewilluseatreetostorealistofwordsandthento*ProgrammingtreesarewrittenwiththerootatthetopandtheleavesatthebottomCommonsensetellsyouthatthisisupsidedownIncaseyouhaven'tnoticed,commonsensehasverylittletodowithprogrammingPage370 Figure20-11Double-linkedlistinsert,Part4Figure20-12.Treeprintthelistalphabetically.Theadvantageofatreeoveralinkedlististhatsearchingatreetakesconsiderablylesstime.Page371Inthisexample,eachnodestoresasingleword.Theleftsubtreestoresallthewordslessthanthecurrentword,andtherightsubtreestoresallthewordsgreaterthanthecurrentword.Forexample,Figure20-13showshowwedescendthetreetolookfortheword"orange."Wewouldstartattheroot,"lemon."Because''orange">"lemon,"wewoulddescendtherightlinkandgoto"pear."Because"orange"<"pear,"wedescendtheleftlink,wherewefind"orange." Figure20-13.TreesearchRecursionisextremelyusefulwithtrees.Ourrulesforrecursionare1)thefunctionmustmakethingssimplerand2)theremustbesomeendpoint.Thealgorithmforinsertingawordinatreeis:1.Ifthisisanulltree(orsubtree),createaone-nodetreewiththisword.2.Ifthisnodecontainstheword,donothing.3.Otherwise,enterthewordintheleftorrightsubtree,dependingonthevalueoftheword.Doesthisalgorithmsatisfyourrecursionrules?Thefunctionhastwodefiniteendpoints:1.Amatchisfound.2.Wehaveanullnode.Otherwise,weenterthewordintoasubtree(whichissimplerthanthewholetree).Page372Toseehowthisworks,considerwhathappenswhenweinserttheword"fig"intothetree.Firstwechecktheword"fig"against"lemon.""Fig"issmaller,sowegoto"apple.''Because"fig"isbigger,wegoto"grape."Because"fig"issmallerthan"grape,"wetrytheleftlink.ItisNULL,sowecreateanewnode.Thiscodemakesuseofanewfunction:strdup.Thisfunctioncreatesacopyofastringontheheapandreturnsapointertothenewstring.Thestringmaylaterbereturnedtotheheapusingthedeleteoperator.*Thefunctiontoenteravalueintoatreeis:voidtree::enter_one(node*&tree_node,char*word){intresult;//Resultofstrcmp//Seeifwehavereachedtheendif(tree_node==NULL){ tree_node=newnode;tree_node->left=NULL;tree_node->right=NULL;tree_node->word=strdup(word);}result=strcmp(node->word,word);if(result==0)return;if(result<0)enter_one(tree_node->right,word);elseenter_one(tree_node->left,word);}Andthefunctiontokickitoffis:voidtree::enter(char*word)enter_one(root,word);};Thisfunctionpassesapointertotherootofthetreetoenter_one.IftherootisNULL,enter_onecreatesthenode.Becausewearechangingthevalueofapointer,wemustpassareferencetothepointer.*ThetunctionstrdupisnotpartoftheproposedANSIstandardforC++.Itis,however,availableinallthecompilersl'veseenItappearstobepartofanunwrittenstandardPage373PrintingaTreeDespitethecomplexnatureofatreestructure,itiseasytoprint.Againweuserecursion.Theprintingalgorithmis:1.Forthenulltree,printnothing.2.Printthedatathatcomesbeforethisnode(lefttree).3.Printthisnode.4.Printthedatathatcomesafterthisnode(righttree).Thecodeforprintingthetreeis:voidtree::print_one(node*top){if(top==NULL)return;//Shorttreeprint_one(top->left);cout<word<<' ';print_one(top->right);}voidtree::print(void) print_one(root);}TheRestoftheProgramNowthatwehavethedatastructuredefined,allweneedtocompletetheprogramisafewmorefunctions.Themainfunctionchecksforthecorrectnumberofargumentsandthencallsthescannerandtheprint_oneroutine.Thescanfunctionreadsthefileandbreaksitintowords.Itusesthestandardmacroisalpha.Themacroreturns1ifitsargumentisaletterand0otherwise.Itisdefinedinthestandardincludefilectype.h.Afterawordisfound,thefunctionenteriscalledtoputthewordinthetree.strdupcreatesthespaceforastringontheheapandthenreturnsthepointertoit.Example20-3isthelistingofwords.cc.Example20-3.words/words.cc/*********************************************************Words--scanafileandprintoutalistofwords**inASCIIorder****Usage:**words*********************************************************/#includePage374Example20-3words/words.cc(Continued)#include#include#include#includeclasstree{private://Thebasicnodeofatreeclassnode{private:node*right;//Treetotherightnode*left;//Treetotheleftpublic:char*word;//Wordforthistreefriendclasstree;};//Thetopofthetreenode*root;//Enteranewnodeintoatreeorsubtreevoidenter_one(node*&node,char*word);//Printasinglenode voidprint_one(node*top);public:tree(void){root=NULL;}//Addanewwordtothetreevoidenter(char*word){enter_one(root,word);}//Printthetreevoidprint(void)print_one(root);}};statictreewords;//Listofwordswearelookingfor/*********************************************************Scan--scanthefileforwords******Parameters**name--nameofthefiletoscan*********************************************************/voidscan(char*name){charword[100];//Wordweareworkingonintindex;//IndexintothewordPage375Example20-3.words/words.cc(Continued)intch;//Currentcharacterifstreamin_file;//Inputfilein_file.open(name,ios::in);if(in_file.bad()){cerr<<"Error:unabletoopen<left=NULL;new_node->right=NULL;new_node->word=strdup(word);}result=strcmp(new_node->word,word);if(result==0)return;if(result<0)enter_one(new_node->right,word);elseenter_one(new_node->left,word); /*******************************************************tree::print_one--printoutthewordsinatree****Parameters**top--therootofthetreetoprint*******************************************************/voidtree::print_one(node*top){if(top==NULL)return;//Shorttreeprint_one(top->left);cout<word<<' ';print_one(top->right);}Question20-2:Ioncemadeaprogramthatreadthedictionaryintomemoryusingatreestructureandthenuseditinaprogramthatsearchedformisspelledwords.Althoughtreesaresupposedtobefast,thisprogramwassoslowyouwouldthinkIusedalinkedlist.Why?Hint:Graphicallyconstructatreeusingthewords"able,""baker,"''cook,""delta,"and"easy"andlookattheresult.Page377DataStructuresforaChessProgramAclassicprobleminartificialintelligenceisthegameofchess.Sofar,inspiteofallouradvancesincomputerscience,noonehasbeenabletocreateaprogramthatplayschessbetterthanthebestgrandmasters.Wearegoingtodesignadatastructureforachess-playingprogram.Inchessthereareseveralmovesyoucanmake.Youropponenthasmanyresponses,towhichyouhavemanyanswers,andsoonbackandforthforseverallevelsofmoves.Ourdatastructureisbeginningtolooklikeatree.Butthisisnotabinarytree,becausewehavemorethantwobranchesforeachnode(Figure20-14).Figure20-14.ChesstreeWearetemptedtousethefollowingdatastructure: classchess{public:classboard_classboard;//Currentboardpositionclassnext_class{classmove_classmove;//Ournextmoveclasschess*chess_ptr;//Pointertotheresultingposition}next[MAX_MOVES];};Theproblemisthatthenumberofmovesfromanygivenpositionvariesdramatically.Forexample,inthebeginningyouhavelotsofpiecesrunningaround.**Triviaquestion.Whatarethe21movesyoucanmakeinchessfromthestartingposition?(Youcanmoveeachpawnupone(8moves)ortwo(8more),andtheknightscanmoveouttotheleftandright(4more)(8+8+4=20))What'sthe21stmove?Page378Thingslikerooks,queens,andbishopscanmoveanynumberofsquaresinastraightline.Whenyoureachtheendgame(inanevenlymatchedgame),eachsideprobablyhasonlyafewpawnsandonemajorpiece.Thenumberofpossiblemoveshasbeengreatlyreduced.Wewanttobeasefficientinourstorageaspossiblebecauseachessprogramstressesthelimitsofourmachine.Wecanreducestoragerequirementsbychangingthenext-movearrayintoalinkedlist.Theresultingstructureis:classnext_class{classmove_classmove;//Ournextmoveclassnext_class*chess_ptr;//Pointertotheresultingposition};structchess{classboard_classboard;//Currentboardpositionclassnext_class*listptr;//Listofmoveswecanmakefromhereclassnext_classthis_move;//Themovewearemaking};Graphically,thislookslikeFigure20-15.Figure20-15Revisedchessstructure Thenewversionaddsalittlecomplexity,butsavesagreatdealofstorage.ProgrammingExercisesExercise20-1:Writeacross-referenceprogram.Exercise20-2:Writeafunctiontodeleteanelementofalinkedlist.Exercise20-3:Writeafunctiontodeleteanelementofadouble-linkedlist.Page379Exercise20-4:Writeafunctiontodeleteanelementofatree.AnswerstoChapterQuestionsAnswer20-1:Theproblemiswiththestatement:while((current_ptr->data!=value)&&(current_ptr!=NULL))current_ptr->dataischeckedbeforewechecktoseewhethercurrent_ptrisavalidpointer(!=NULL).IfitisNULLwecaneasilycheckarandommemorylocationthatcouldcontainanything.Thesolutionistocheckcurrent_ptrbeforecheckingwhatitispointingto:while(currentptr!=NULL){if(current_ptr->data==value)break;Answer20-2:Theproblemwasasfollows:becausethefirstwordinthedictionarywasthesmallest,everyotherwordusedtheright-handlink.Infact,becausetheentirelistwasordered,onlytheright-handlinkwasused.Althoughthiswasdefinedasatreestructure,theresultwasalinkedlist.SeeFigure20-16. Figure20-16DictionarytreePage380Someofthemoreadvancedbooksondatastructures,suchasWirth'sAlgorithms+DataStructures=Programs,discusswaysofpreventingthisbybalancingabinarytree.TriviaAnswer:Yougiveup.That'sright,the21stmoveistoresign.Page38121AdvancedClassesInThisChapter:·DerivedClasses·VirtualFunctions·VirtualClasses·FunctionHidinginDerivedClasses·ConstructorsandDestructorsinDerivedClasses·Summary·ProgrammingExercises·AnswerstoChapterQuestions QuestionsTherulingideasofeachagehaveeverbeentheideasofitsrulingclass—KarlMarxManifestooftheCommunistPartyDerivedClassesThestackclassthatwasdefinedinExample13-1containsonemajorlimitation:itdoesnotcheckforbaddata.Forexample,thereisnothingthatpreventstheuserfrompushingtoomanythingsontothestack.Weneedtodefineanewbounds-checkingstack(b_stack).Thisnewstackdoeseverythingasimplestackdoesbutalsoincludesboundschecking.C++allowsyoutobuildnewclassesonoldones.Inthiscasewewillbebuildingourbounds-checkingstack(b_stack)ontheexistingsimplestack(stack).Technicallywewillbeusingtheclassstackasabaseclasstocreateanewderivedclass,thebounds-checkingstack.WestartbytellingC++thatwearecreatingb_stackoutofstack.classb_stack:publicstack(ThekeywordpublictellsC++tomakeallthemembersofstackaccessibletotheoutsideworld.Ifwedeclaredstackasprivatethenthepublicandprotectedmembersofstackwouldbeaccessibleonlyinsideb_stack.ThisdeclarationtellsC++thatwearegoingtousestackasabaseforb_stack.Figure21-1showshowC++viewsthiscombination.Nowweneedtodefinethenewversionofthepushmemberfunction.Wefirstchecktoseewhetherthere'sroominthestack.Ifthere'snomoreroom,weprintPage382Figure21-1Derivedclassh_stackandbaseclassstackanerrormessageandaborttheprogram.Otherwisewepushtheitemontothestack.Here'salimitedversionofpush.inlinevoidb_stack::b_push(constintitem){if(count>=STACK_SIZE)cout<<"Error:Pushoverflowsstack ";exit(8);}//Thiscallsthepushmemberfunctionofthestackclass push(item);}Wehavebeenverycarefulinselectingthenameofthismemberfunction.Itiscalledb_pushinsteadofpushforareason.Wewouldliketocallitpush,butthenthecode:inlinevoidb_stack::push(constintitem){if(count>=STACK_SIZE)cout<<"Error:Pushoverflowsstack ";exit(8);}//Thenextlinewronglycallsb_stack::push(thisfunction),//notstack::pushpush(item);}wouldcallthememberfunctionpushintheclassb_stacknotstack'spushaswewant.Theresultisthatwecallb_stack'spush,whichperformsalimitcheckandthencallspush.Thispushbelongstob_stack,soweperformaboundscheckandcallpush,andsoon.Theresultisthatpushwillcallitselfoverandoveruntilthesystemrunsoutofstackspace.Thisisnotwantwewant.WewanttotellC++thatwewanttocallthepushinstack.Thiscanbeaccomplishedbyusingthescopeoperator"::".Thenewversionofb_stack::pushlookslike:inlinevoidb_stack::push(constintitem){if(count>=STACKSIZE){Page383cout<<"Error:Pushoverflowsstack ";exit(8);}stack::push(item);}Thefulldefinitionforboththestackandb_stackclassesisshowninExample21-1.Example21-1.stack_c/stack_dl.cc/*********************************************************Stack**afileimplementingasimplestackclass*********************************************************/#include#includeconstintSTACK_SIZE=100;//Maximumsizeofastack/*********************************************************Stackclass****Memberfunctions**stack--initializethestack* *push--putanitemonthestack**pop--removeanitemfromthestack*********************************************************///Thestackitselfclassstack{protected:intcount;//Numberofitemsinthestackprivate:intdata[STACK_SIZE];//Theitemsthemselvespublic://Initializethestackstack(void);//-stack()--defaultdestructor//Copyconstructordefaults//Pushanitemonthestackvoidpush(constintitem);//Popanitemfromthestackintpop(void);};/*********************************************************stack::stack--initializethestack*********************************************************inlinestack::stack(void){count=0;//Zerothestack}Page384Example21-1stack_c/stack_d1.cc(Continued)/*********************************************************stack::push--pushanitemonthestack****Warning:Wedonotcheckforoverflow****Parameters**item--itemtoputinthestack*********************************************************/inlinevoidstack::push(constintitem){data[count]=item;++count;}/*********************************************************stack::pop--removeitemfromstack****Warning:Wedonotcheckforstackunderflow****Returns**thetopitemfromthestack*********************************************************/inlineintstack::pop(void){ //Stackgoesdownbyone--count;//Thenwereturnthetopvaluereturn(data[count]);}/*********************************************************b_stack--boundcheckingstack****Memberfunction**push--pushanitemonthestack**pop--removeanitemfromthestack*********************************************************/classb_stack:publicstack{public://bstack--defaultconstructor//~b_stack--defaultdestructor//Copyconstructordefaults//Pushanitemonthestackvoidpush(constintitem);//Removeanitemfromthestackintpop(void);};/*********************************************************b_stack::push--pushanitemonthestack***Page385Example21-1.stack_c/stack_dl.cc(Continued)*Parameters**item--itemtoputinthestack*********************************************************/inlinevoidb_stack::push(constintitem){if(count>=STACK_SIZE)cerr<<"Error:Pushoverflowsstack ";exit(8);}stack::push(item);}/*********************************************************b_stack::pop--getanitemoffthestack****Returns**thetopitemfromthestack**********************************************************/inlineintb_stack::pop(void){if(count<=0)cerr<<"Error:Popcausesstackunderflow ";exit(8);} return(stack::pop());}Eventhoughthesetwoclassesarerelativelysimple,theyillustratesomeimportantfeaturesoftheC++language.Firstwehavedeclaredcountasaprotectedmembervariable.Thismeansthatthisvariablecanbeusedonlywithintheclassstackandinanyclassesderivedfromstack,suchasb_stack.Theb_stackfunctionspushandpopcanusecounttodotheirwork.However,anyoneoutsideofstackandb_stackcannotusethevariable.Becauseb_stackisderivedfromstack,youcanuseab_stacktypevariablewhereverastacktypevariableisused.Inthefollowingexample,wecreateab_stacknamedbound_stackthatisusedasaparametertothefunctionpush_things,whichtakesanormal,unboundedstackasaparameter.voidpush_things(stack&a_stack){a_stack.push(l);a_stack.push(2);}//...b_stackbounded_stack;//Arandomstack//p....push_things(bounded_stack);Page386Thefunctionpush_thingstakesastackasaparameter.Eventhoughthevariablebounded_stackisab_stacktypevariable,C++turnsitintoastackwhenpush_thingsiscalled.Onewaytoexplainthisisthatalthoughbounded_stackisoftypeb_stack,whenitisusedbypush_thingsthefunctionislookingthroughapeepholethatallowsittoseeonlythestackpartofthevariableasshowninFigure21-2.Figure21-2How''push_things"seesab_stackLet'simprovethebasicstacksothatinsteadofalwaysallocatingafixed-sizestack,weallocatethestackdynamically.Thenewstackstartswith:classstack{private:int*data;//Pointertothedatainthestackprotected:intcount;//Currentitemonthestackpublic:stack(constunsignedintsize)data=newint[size]; count=0;};virtual~stack(void)deletedata;data=NULL;}//...(Wediscussthekeywordvirtuallaterinthischapter.)Thisstackismoreflexible.Tousethenewstackwemustgiveitasizewhenwedeclarethestackvariable.Forexample:stackbig_stack(1000);stacksmall_stack(10);stackbad_stack;//Illegal,sizerequiredBacktothebound-checkingstack.Somehowweneedtocallthebaseclassconstructor(stack)withaparameter.Page387Thewaywedothisistoputthebase-constructorunitizationjustafterthedeclarationoftheconstructorforthederivedclass:Butthisflexibilitycreatessomeproblemsforthebound-checkingstack:theconstructorforstackcontainsaparameter.Howisthebound-checkingstacktoinitializethesimplestack?Thesolutionistouseasyntaxsimilartoinitializingaconstantdatamember.classb_stack:publicstack{private:constunsignedintstack_size;//Sizeofthesimplestackpublic:b_stack(constunsignedintsize):stack(size),stack_size(size)}Inthisexample,thebaseclassisstackandthederivedclassisb_stack.Theconstructorforb_stacktakesasingleparameter,thesizeofthestack.Itneedstopassthisparametertostack.Theline:b_stack::b_stack(contunsignedintsize):stack(size),doesthisthroughthestack(size)syntax.NOTEBecausethenewversionofstackusesdynamicmemory(newanddelete),itisvitalthatwedefinethe"bigfour"memberfunctions:theconstructor,thedestructor,thecopyconstructor,andtheassignmentoperator(=).VirtualFunctionsTodaytherearemanydifferentwaysofsendingaletter.WecanmailitbytheUnitedStates PostalService,senditviaFederalExpress,senditCertifiedMail,orevenfaxit.Allofthesemethodsgetthelettertotheperson(mostofthetime),buttheydifferincostandspeed.Let'sdefineaclasstohandlethesendingofaletter.Westartbydefininganaddressclassandthenusethisclasstodefineaddressesforthesenderandthereceiver.(Thedefinitionoftheaddressclassis"justasimplematterofprogramming"andislefttothereader.)classmail{public:addresssender;//Who'ssendingthemail(returnaddress)?addressreceiver;//Who'sgettingthemail?//SendtheletterPage388voidsend_it(void)//...Somemagichappenshere};};Thereis,however,onelittleproblemwiththisclass.We'redependingon"magic"togetourletterssent.Theprocessforsendingaletterisdifferentdependingonwhichserviceweareusing.Onewaytohandlethisistohavesend_itcalltheappropriateroutinedependingonwhatserviceweareusing:voidmail::send_it(void)switch(service){casePOST_OFFICE:put_in_local_mailbox();break;caseFEDERAL_EXPRESS:fill_out_waybill();call_federal_for_pickup();break;caseUPS:put_out_upsyes_sign();give_package_to_driver();break;//...andsoonforeveryserviceintheuniverseThissolutionisabitclunky.Ourmailclassmustknowaboutallthemailingservicesintheworld.Alsoconsiderwhathappenswhenweaddanotherfunctiontotheclass:classmail{public://Returnsthecostofmailingincentsintcost(void){//...moremagic}Dowecreateanotherbigswitchstatement?Ifwedo,we'llhavetwobigswitchstatementstoworryabout.What'sworse,thesendinginstructionsandcostforeachservicearenowspreadoutovertwofunctions.ItwouldbeniceifwecouldgroupallthefunctionsforthePostalServiceinoneclass,allofFederalExpressinoneclass,andsoon. Forexample,aclassforthePostalServicemightbe:classpost_office:publicmail{public://Sendthelettervoidsend_it(void)put_in_local_mailbox();};//Costreturnscostofsendingaletterincentsintcost(void){//Costs32centstomailaletterPage389return(32);//WARNING:Thiscaneasilybecomedated}};Nowwehavetheinformationforeachsingleserviceinasingleclass.Theinformationisstoredinaformatthatiseasytounderstand.Theproblemisthatitisnoteasytouse.Forexample,let'swritearoutinetosendaletter:voidget_address_and_send(mail&letter){letter.from=my_address;letter.to=gettoaddress();letter.send();}//..classpost_officesimple_letter;get_address_and_send(simple_letter);Thetroubleisthatletterisamailclass,sowhenwecallletter.send()wecallthesendofthebaseclassmail.WhatweneedisawayoftellingC++,"Pleasecallthesendfunctionofthederivedclassinsteadofthebaseclass."Thevirtualkeywordidentifiesamemberfunctionthatcanbeoverriddenbyamemberfunctioninthederivedclass.Ifweareusingaderivedclass,thenC++willlookformembersinthederivedclassandtheninthebaseclass,inthatorder.Ifweareusingabaseclassvariable(eveniftheactualinstanceisaderivedclass),thenC++willsearchonlythebaseclassforthememberfunction.Theexceptioniswhenthebaseclassdefinesavirtualfunction.Inthiscase,thederivedclassissearchedandthenthebaseclass.Table21-1illustratesthevarioussearchalgorithms.Table21-1.MemberFunctionSearchOrderClassTypeMemberFunctionTypeSearchOrderDerivedNormalDerived->baseBaseNormalBaseBasevirtualDerived->base Example21-2illustratestheuseofvirtualfunctions.Example21-2.virt/virt.cc//Illustratestheuseofvirtualfunctions#includeclassbase{public:voida(void){cout<<"base::acalled ";}Page390Example21-2virt/virtcc(Continued)virtualvoidb(void){cout<<"base::bcalled ";}virtualvoidc(void){cout<<"base::ccalled ";}};classderived:publicbase{public:voida(void){cout<<"derived::acalled ";}voidb(void){cout<<"derived::bcalled ";}};voiddo_base(base&a_base){cout<<"Callfunctionsinthebaseclass ";a_base.a();a_base.b();a_base.c();}main(){deriveda_derived;cout<<"Callingfunctionsinthederivedclass ";a_derived.a();a_derived.b();a_derived.c();do_base(a_derived);return(0);}Thederivedclasscontainsthreememberfunctions.Twoofthemareself-defined:aandb.Thethird,c,isinheritedfromthebaseclass.Whenwecalla,C++looksatthederivedclasstoseewhetherthatclassdefinesthefunction.Inthiscaseitdoes,sotheline: a_derived.a();outputs:derived::acalledWhenbiscalledthesamethinghappens,andweget:derived::bcalledItdoesn'tmatterwhetherthebaseclassdefinesaandbornot.C++callsthederivedclassandgoesnofurther.Page391However,thederivedclassdoesn'tcontainamemberfunctionnamedc.Sowhenwereachtheline:a_derived.c();C++triestofindcinthederivedclassandfails.Thenittriestofindthememberfunctioninthebaseclass.Inthiscaseitsucceedsandweget:base::ccalledNowlet'smoveontothefunctiondo_base.Becauseittakesabaseclassasitsarguments,C++restrictsitssearchformemberfunctionstothebaseclass.Sotheline:a_base.a();outputsbase::acalledButwhathappenswhenthememberfunctionbiscalled?Thisisavirtualfunction.ThattellsC++thatthesearchrulesarechanged.C++firstcheckswhetherthereisabmemberfunctioninthederivedclass,andthenC++checksthebaseclass.Inthecaseofb,thereisabinthederivedclass,sotheline:a_base.b();outputs:derived::bcalledThememberfunctioncisalsoavirtualfunction.Therefore,C++startsbylookingforthefunctioninthederivedclass.Inthiscaseit'snotdefinedthere,soC++thenlooksinthebaseclass.Itisdefinedthere,soweget:base::ccalledNowgettingbacktoourmail.Weneedasimplebaseclassthatdescribesthebasicmailingfunctionsforeachdifferenttypeofservice.classmail{public:addresssender;//Whoissendingthemail(returnaddress)? addressreceiver;//Whoisgettingthemail?//Sendthelettervirtualvoidsend_it(void){cout<<"Error:send_itnotdefinedinderivedclass. "exit(8);};//Costofsendingaletterinpenniesvirtualintcost(void){cout<<"Error:costnotdefinedinderivedclass. "Page392exit(8);};};Nowwecandefineaderivedclassforeachdifferenttypeofservice.Forexample:classpostoffice:publicmail{public:voidsend_it(void){put_letter_inbox();}intcost(void)return(29);}};Nowwecanwritearoutinetosendaletterandnothavetoworryaboutthedetails.Allwehavetodoiscallsend_itandletthevirtualfunctiondothework.Themailclassisanabstractionthatdescribesageneralizedmailer.Toassociatearealmailingservice,weneedtouseitasthebaseforaderivedclass.Butwhathappensiftheprogrammerforgetstoputtherightmemberfunctionsinthederivedclass?Forexample:classfederal_express:publicmail{public:voidsend_it(void){put_letter_in_box();}//Somethingismissing};WhenwetrytofindthecostofsendingaletterviaFederalExpress,C++willnoticethatthere'snocostfunctioninfederal_expressandcalltheoneinmail.Thecostfunctioninmailknowsthatitshouldneverbecalled,soitspitsoutanerrormessageandabortstheprogram.Gettinganerrormessageisnice,butgettingitatcompilationratherthanduringtherunwouldbebetter.C++allowsyoutospecifyvirtualfunctionsthatmustbeoverriddeninaderivedclass.Forthisexample,thenew,improved,abstractmaileris:classmail{public:addresssender;//Whoissendingthemail(returnaddress)? addressreceiver;//Whoisgettingthemail?//Sendthelettervirtualvoidsend_it(void)=0;//Costofsendingaletterinpenniesvirtualintcost(void)=0;};Page393The"=0"tellsC++thatthesememberfunctionsarepurevirtualfunctions.Thatis,theycanneverbecalleddirectly.Anyclasscontainingoneormorepurevirtualfunctionsiscalledanabstractclass.Ifyoutriedtouseanabstractclassasanordinarytype,suchas:voidsend_package(void)maila_mailer;//Attempttouseanabstractclassyouwouldgetacompile-timeerror.VirtualClassesLet'sdesignsomeclassestohandleataxform.Intheupperrightcornerofeachformisablankforyourname,address,andSocialSecuritynumber.Alltheformscontainthissameinformation,sowe'lldefineaclassforthiscoreroftheform.classname{public:char*name;//Nameofthetaxpayer//...Restoftheclass};Nowlet'susethisclasstodesignanotherclassforthe1040form.classform_1040:publicname{public:intincome;//Wages,tips,andotherincome//...};OurclassstructuresofarisillustratedbyFigure21-3.Figure21-3.1040classstructureUnfortunatelyourtaxreturnsconsistofmorethanoneform.FordeductionsweneedScheduleA,solet'sdefineaclassforit.classschedule_a:publicname{public:inthome_interest;//Interestdeductionforhomemortgage //...Restofclass};Page394Puttingthetwoformstogether,wegetasimplereturn.classtax_return:publicform_1040,schedule_a{//...Restofclass};Figure21-4illustratesthisclassstructure.Figure21-4.TaxreturnstructureTheproblemwiththisstructureisthatwehavetwonameclasses.Butthetaxpayer'snamedoesn'tchangefromoneformtoanother.WhatwewantistheclassstructureshowninFigure21-5.Figure21-5.BettertaxreturnstructureDeclaringabaseclassvirtualtellsC++tocombinecommonbaseclasses.Redefiningtax_returnusingvirtualbaseclassesweget:classform_1040:virtualpublicname{public:intincome;//Wages,tips,andotherincome//...};classschedule_a:virtualpublicname{public:inthome_interest;//InterestdeductionforhomemortgagePage395 //...Restofclass};classtax_return:publicform_1040,schedule_a{//...Restofclass};Noticethattheclassnameisusedasthebasefortwoderivedclasses;derivedclassescausetheirbaseclass'sconstructortobecalledtoinitializetheclass.Doesthismeanthattheconstructorfornamewillbecalledtwice?Theanswerisno.C++issmartenoughtoknowthatnameisusedtwiceandtoignorethesecondinitialization.FunctionHidinginDerivedClassesExample21-3definesabaseclasswiththeoverloadedfunctiondo_it,whichcomesinbothanintegerversionandafloating-pointversion.Theprogramalsodefinesaderivedclassthatcontainsthesingleintegerdo_it.Example21-3.doit/doit.ccclasssimple{public:intdo_it(inti,intj){return(i*j);}floatdo_it(floatf){return(f*2);}};classderived:publicsimple{public:intdo_it(inti,intj){return(i+j);}};Clearly,whenweareusingthederivedclassandwecalltheintegerversionofdo_it,wearecallingtheoneinthederivedclass.Butwhathappensifwecallthefloating-pointversion?Thederivedclasshasnofloatingpointdo_it.Normally,ifwedon'thaveamemberfunctioninthederivedclass,C++willlooktothebaseclass.However,sinceaversionofdo_itisdefinedinthederivedclass,C++willlooktothederivedclassforallflavorsofdo_it.Inotherwords,ifoneformofdo_itisdefinedinthederivedclass,thenthatlocksoutallformsofthefunction.main(){derivedtest;//Defineaclassforourtestinginti;//Testvariablefloatf;//Testvariablei=test.do_it(l,3);//Legal;returns4(1+3)f=test.do_it(4.0);//Illegal;"do_it(float)"notdefinedin//theclass"derived"Page396ConstructorsandDestructorsinDerivedClassesConstructorsanddestructorsbehavedifferentlyfromnormalmemberfunctionsespeciallywhenusedwithderivedclasses.Whenaderived-classvariableiscreated,theconstructorfor thebaseclassiscalledfirst,followedbytheconstructorforthederivedclass.Example21-4definesasimplebaseclassandusesittocreateaderivedclass.Example21-4cons/classcc#includeclassbaseclass{public:base_class()cout<<"base_classconstructorcalled ";}-base_class(){cout<<"base_classdestructorcalled ";}};classderived_class:publicbase_class{public:derived_class()cout<<"derived_classconstructorcalled ";}~derived_class(){cout<<"derived_classdestructorcalled ";}};Nowwhenweexecutethecode:derived_class*sampleptr=newderived_class;theprogramprints:base_classconstructorcalledderivedclassconstructorcalledAfterthevariableisdestroyed,thedestructorsarecalled.Thedestructorforthederivedclassiscalledfirst,followedbythedestructorforthebaseclass.Sowhenwedestroythevariablewiththestatement:deletesample_ptr;sample_ptr=NULL;weget:derivedclassdestructorcalledbase_classdestructorcalledPage397ButC++hasasurpriselurkingforus.Rememberthatderivedclassescanoperateasbaseclasses.Forexample:base_class*base_ptr=newderived_class;isperfectlylegal.However,thereisaproblemwhenthevariableisdeleted:deletebase_ptr; base_ptr=NULL;Yousee,base_ptrisapointertoabaseclass.Atthispointallthecodecanseeisthebaseclass.ThereisnowayforC++toknowthatthereisaderivedclassoutthere.Sowhenthevariableisdeleted,C++failstocallthederivedclassdestructor.Theoutputofthedeletestatementis:base_classdestructorcalledWehavejusttrickedC++intodeletingaclasswithoutcallingtheproperdestructor.WeneedsomewaytotellC++,''Hey,thereisaderivedclassoutthereandyoumightwanttocallitsdestructor."Thewaywedothisistomakethedestructorforthebaseclassavirtualfunction.classbase_class{public:base_class(){cout<<"base_classconstructorcalled ";}virtual~base_class(){cout<<"base_classdestructorcalled ";}};Thekeywordvirtualnormallymeans,"Callthefunctioninthederivedclassinsteadoftheoneinthebaseclass."Forthedestructor,ithasaslightlydifferentmeaning.WhenC++seesavirtualdestructor,itwillcallthedestructorofthederivedclassandthencallthedestructorofthebaseclass.Sowiththevirtualdestructorinplace,wecansafelydeletethebase_classvariableandtheprogramwilloutputtheproperinformation:derived_classdestructorcalledbase_classdestructorcalledQuestion21-1:WhydoesExample21-5failwhenwedeletethevariablelist_ptr?Theprogramseemstogetupsetwhenittriestocallclearatline20.Page398Example21-5.blow/blow.cc1#include2#include34classlist{5private:6intitem;//Currentitemnumber78public:9virtualvoidclear()=0;1011voidnext_item(void){12++item; 13}1415list(void){16item=0;17}1819virtual~list(){20clear();21}22};2324classlist_of_integers:publiclist{25public:26intarray[100];//Placetostoretheitems2728voidclear(void){29inti;//Arrayindex3031for(i=0;i<100;++i)32array[i]=0;33}34};3536main()37{38list_of_integers*list_ptr=newlist_of_integers;3940//Causeproblems41deletelist_ptr;42list_ptr=NULL;43return(0);44}SummarySinceprogrammingbegan,programmershavebeentryingtofindwaysofbuildingre-usablecode.C++,throughtheuseofderivedclasses,allowsyoutoPage399buildclassesontopofexistingcode.Thisprovidesagreatdealofflexibilityandmakesthecodeeasiertoorganizeandmaintain.ProgrammingExercisesExercise21-1:CombinethecheckbookclassofExercise13-2withthequeueclassofExercise13-3toimplementacheckbookclassthatcanprintoutthelasttenentriesofyourcheckbook.Exercise21-2:Definea"string-match"baseclass.classstring_matcher{public://Returnstrueifstringmatches,falseifnotintmatch(constchar*conststring); ...Definederivedclassesthatmatchwords,numbers,andblankstrings.Exercise21-3:Defineabaseclassshapethatcandescribeanysimpleshapesuchasasquare,circleorequilateraltriangle.Thesizeofalltheseshapescanbereducedtoasingledimension.Definederivedclassesforeachofthethreeshapes.Createavirtualfunctioninthebaseclassthatreturnstheareaofeachshape.Note:Youwillneedtomorepreciselydefinewhatdimensionsarestoredinthebaseclass.(Isthesizeinthebaseclassforcircle,theradius,orthediameter?)Exercise21-4:Writeabaseclasscalledpersonthatdescribesapersonofeithergender.Definetwoderivedclassescalledmanandwomanthatdefinegenderspecificitems.Writepurevirtualfunctionsinthebaseclassforoperationsthatarecommontobothsexesyetarehandledindifferentwaysbyeachofthem.Exercise21-5:Writeabaseclassnumberthatholdsasingleintegervalueandcontainsonememberfunction,print_it.Definethreederivedclassestoprintthevalueinhex,octal,anddecimal.AnswerstoChapterQuestionsAnswer21-1:Rememberthatdestructorsarecalledintheorderofderivedclassfirstandthenbaseclass.Inthiscase,thedestructorforthederivedclass,list_of_integers,iscalledtodestroytheclass.Theclassisgone.Next,thedestructorforthebaseclasslistiscalled.Itcallsthefunctionclear.Thisapurevirtualfunction,soC++mustcalltheclearfunctioninthederivedclass.Butthederivedclassisgone.Thereisnoclearfunction.ThisPage400makesC++veryupsetanditabortstheprogram.(Actually,onlygoodcompilerswillcauseaprogramtoabort.Othersmaydosomethingreallystrangetoyourprogram.)Youshouldnevercallpurevirtualfunctionsfromadestructor.Page401VOtherLanguageFeaturesPage403 22ExceptionsInThisChapter:·StackExceptions·RuntimeLibraryExceptions·ProgrammingExercisesHowgloriousitis—andalsohowpainful—tobeanexception—AlfreddeMussetAirplanesflyfromoneplacetoanotherand99.9%ofthetimethere'snotrouble.Butwhenthereistroublesuchasastuckwheeloranenginefire,pilotsaretrainedtohandletheemergency.Let'sexamineindetailwhathappensduringanairborneemergencysuchasanenginecatchingfire.Thisisanexceptiontonormalflight.Afirealarmgoesoffinthecockpit.Thiscatchesthepilots'attentionandtheystartgoingthroughthefire-emergencyprocedure.Thisisanextensivelistofthingstodoincaseoffire.Theairlinepreparedthislistaheadoftimeandthepilotshavethelistmemorized.Thepilotsdowhat'snecessarytohandletheexception:activatethefireextinguisher,shutdowntheengine,landveryquickly,etc.Let'sbreakdownthisprocedureintoC++pseudocode.Whenthepilotstakeofftheyaregoingtotrytoflytheplanefromonepointtoanotherwithoutproblems.TheC++"code"forthisis:try{fly_from_point_a_to_point_b();}Thetrykeywordindicatesthatwearegoingtoattemptanoperationthatmaycauseanexception.Page404Butwhathappenswhenwegetanexception?Weneedtohandleit.TheC++codeforthisis:catch(fire_emergency&fire_info)active_extinguisher(fire_info.engine);turn_off(fire_info.engine);land_at_next_airport();}Thekeywordcatchindicatesthatthissectionofcodehandlesanexception.Inthiscasetheexceptionhandledisafire_emergency.Thisisthetypeofemergency.Itcouldbeafirein enginenumber1,enginenumber2,orenginenumber3(assumingathree-engineplane).Whichengineisonfireisstoredinthevariablefire_info.Thefire_emergencyclassdescribeswhattypeoffireoccurred.Itsdefinitionis:classfire_emergency{public:intengine;//Whichengineisonfire//Otherinformationaboutthefire};We'vecoveredeverythingbuttheactualdetectionofthefire.Buriedwithineachengineisafiresensor.Thecodeforthissensoris://Watchforfireinengine#2voidsensor_2(void){while(engine_running())if(engineonfire()){fire_emergencyfire_info;fire_info.engine=2;throw(fire_info);}}}Whenthiscodesensesafire,itputstheinformationinafire_emergencyvariablenamedfire_infoandtriggersanexceptionwiththethrowstatement.Whenthethrowstatementisexecuted,normalprocessingisstopped.Afterall,whenafireoccurs,normalflyingisstopped.Executionistransferredtothecatchstatementforthefire_emergency.Tosummarize,exceptionhandlingconsistsof:·Adescriptionofapossibleproblem,inthiscasethefire_emergencyclass.·Asectionofcodeinwhichtheexceptionmayoccur,whichisenclosedinatrystatement.Inthiscase,thestatementisfly_from_point_atopointb().Page405·Somethingthatcausesanexceptionandtriggerstheemergencyproceduresthroughathrowstatement.·Exception-handlingcodeinsideacatchblock.StackExceptionsInChapter21,AdvancedClasses,wedefinedastackwithboundschecking.Iftheuserattemptedtopushtoomuchdataonthestackortopoptoomuchoff,theclasswouldissueanerrormessageandabort.Thisisnotagoodwaytohandleanexception.Thinkofhowthepilotswouldfeeliftheplanedisplayedanerrormessageandshutdowneverytimetherewasafire. Thefirstthingweneedtodoisdecidewhattypeofexceptionswearegoingtohandleanddescribethemasclasses.Inourstackexample,theonlyexceptionweexpectisanout-of-boundserror.We'lldescribethiserrorwithasimplestring.Theclassforanout-of-boundserroris:constintWHAT_MAX=80;//Longestpossibleerrormessageclassbound_err{public:charwhat[WHAT_MAX];//Whatcausedtheerror//Initializethebounderrorwithamessagebound_err(char*_what){//WARNING:Thisdoesnotcheckfor"_what"beingtoolongstrcpy(what,_what);}//bound_err(bound_err)--defaultcopyconstructor//~bound_err--defaultdestructor};Exceptioncheckingstartswiththekeywordtry.ThistellsC++thatexceptionsmaybegeneratedinthesectionofcodethatfollowsandthattheywillbehandledimmediatelyafterthetryblock.Forexample,ifwearetryingtoperformabigstackoperation,thecodemightlooklike:try{do_big_stack_operation();};Immediatelyafterthetryblock,weneedtotellC++whatproblemswewillhandle,byusingacatchstatement.Thesyntaxforthisstatementis:catch(problem_type¶meter){statements;}Page406Theproblem_typeistheclassthatdescribeswhathappened.Fortheout-of-boundserror,thecatchstatementlookslike:catch(bound_err&what_happened){cerr<<"Error:Boundsexceeded ";cerr<<"Reason:"<=STACK_SIZE)bounderroverflow("Pushoverflowsstack");throwoverflow;}stack::push(item);}Actuallywedon'tneedaspecialvariableforoverflow.Thecodecanbeconsolidated.Inthepreviousexampleweusedtwostatementstoexplicitlyshowwhatisgoingon.Thefollowingcodeperformsthesameoperation:inlinevoidb_stack::push(constintitem){if(count>=STACK_SIZE)throwbound_err("Pushoverflowsstack");}stack::push(item);}Thebasicfunctiondefinitionwe'vebeenusingsofartellsC++,"Expectanyexceptiontobethrownatanytime."Thepushfunctioncanonlythrowabound_errexception.C++allowsyoutolistallthepossibleexceptionsinafunctionbyputtingathrowdirectiveattheendofthefunctiondeclaration:inlinevoidb_stack::push(constintitem)throw(bound_err){Page407Butwhathappensifwethrowanexceptionthat'snotinthelistofexceptions?C++willturnthisintoacalltothefunctionunexpected().Example22-1containsanewversionofthebound-checkingstackwithexceptions.Example22-1.stack_c/stack_el.cc/*******************************************************Stack**afileimplementingasimplestackclass*******************************************************/#include#includeconstintSTACK_SIZE=100;//Maximumsizeofastack/*******************************************************Stackclass****Memberfunctions**stack--initializethestack**push--putanitemonthestack* *pop--removeanitemfromthestack*******************************************************///Thestackitselfclassstack{protected:intcount;//Numberofitemsinthestackprivate:intdata[STACK_SIZE];//Theitemsthemselvespublic://Initializethestackstack(void);//~stack()--defaultdestructor//Copyconstructordefaults//Pushanitemonthestackvoidpush(constintitem);//Popanitemfromthestackintpop(void);};/*******************************************************stack::stack--initializethestack*******************************************************/*inlinestack::stack(void){count=0;//Zerothestack}/*******************************************************stack::push--pushanitemonthestack***Page408Example22-1.stack_c/stack_el.cc(Continued)*Warning:Wedonotcheckforoverflow****Parameters**item--itemtoputinthestack********************************************************/inlinevoidstack::push(constintitem){data[count]=item;count++;}/*******************************************************stack::pop--getanitemoffthestack****Warning:Wedonotcheckforstackunderflow****Parameters**the_stack--stacktoinitialize****Returns**thetopitemfromthestack*******************************************************/ inlineintstack::pop(void){//Stackgoesdownbyonecount--;//Thenwereturnthetopvaluereturn(data[count]);}constintWHAT_MAX=80;//Largestpossibleerrormessage/******************************************************bound_err--aclassusedtohandleout-of-bounds**exceptions.******************************************************/classbound_err{public:charwhat[WHAT_MAX];//Whatcausedtheerror//Initializethebounderrorwithamessagebound_err(char*_what){if(strlen(_what)<(WHAT_MAX-1))strcpy(what,_what);elsestrcpy(what,"Internalerror:_whatistoolong");}//bound_err(bound_err)--defaultcopyconstructor//~bound_err--defaultdestructor};/********************************************************b_stack--bound-checkingstack*Page409Example22-1.stack_c/stack_el.cc(Continued)***Memberfunction**push--pushanitemonthestack**pop--removeanitemfromthestack********************************************************/classb_stack:publicstack{public://bstack--defaultconstructor//~b_stack--defaultdestructor//Copyconstructordefaults//Pushanitemonthestackvoidpush(constintitem)throw(bound_err);//Removeanitemfromthestackintpop(void)throw(bound_err);};/********************************************************b_stack::push--pushanitemonthestack****Parameters* *item--itemtoputinthestack**********************************************************/inlinevoidb_stack::push(constintitem)throw(bound_err){if(count>=STACK_SIZE)bound_erroverflow("Pushoverflowsstack");throwoverflow;}stack::push(item);}/********************************************************b_stack::pop--getanitemoffthestack****Returns**thetopitemfromthestack********************************************************/inlineintb_stack::pop(void)throw(bound_err){if(count<=0)throwbound_err("Popcausesstackunderflow");}return(stack::pop());}b_stacktest_stack;//Defineastackfortheboundscheckingvoidpush_a_lot(void){inti;//Pushcounterfor(i=0;i<5000;i++)test_stack.push(i);Page410Example22-1stack_c/stack_el.cc(Continued)}}main(){try{push_a_lot();}catch(bound_err&err)cerr<<"Error:Boundsexceeded ";cerr<<"Reason:"</*Numberoftimesthroughtheloop*/externintcounter;/*Routinetoincrementthecounter*/externvoidinc_counter(void);main(){intindex;/*Loopindex*/for(index=0;index<10;++index)inc_counter();cout<<"Counteris<Variable/functionisdefinedinthisfile(public)andcanbeusedinotherfiles.staticVariable/functionislocaltothisfile(private)Noticethatthekeywordstatichastwomeanings.(ItisthemostoverworkedmodifierintheC++language.ForacompletelistofthemeaningsofstaticseeTable14-1.)Fordatadefinedglobally,staticmeans"privatetothisfile."Fordatadefinedinsideafunction,itmeans"variableisallocatedfromstaticmemory(insteadofthetemporarystack)."C++isveryliberalinitsuseoftherulesforstatic,extern,andmodifiers.Itispossibletodeclareavariableasexternatthebeginningofaprogramandlaterdefineitas.externsam;intsam=1;//ThisislegalThisabilityisusefulwhenyouhaveallyourexternalvariablesdefinedinaheaderfile.Theprogramincludestheheaderfile(anddefinesthevariablesasextern),andthendefinesthevariableforreal.Anotherproblemconcernsdeclaringavariableintwodifferentfiles.File:main.ccintflag=0;//Flagisoffmain(){cout<<"Flagis"<#include#include#include"ia.h"//Getcommondefinitions/*********************************************************operator[]--findanelementofaninfinitearray****Parameters**index--indexintothearray****Returns**referencetotheelementinthearray*********************************************************/ int&infinite_array::operator[](constunsignedintindex){//Pointertothecurrentbucketclassinfinite_array*current_ptr;intcurrent_index;//Indexweareworkingwithcurrent_ptr=this;current_index=index;while(current_index>=BLOCK_SIZE){if(current_ptr->next==NULL){current_ptr->next=newinfinite_array;if(current_ptr->next==NULL){cerr<<"Error:Outofmemory ";exit(8);}}current_ptr=current_ptr->next;current_index-=BLOCK_SIZE;}return(current_ptr->data[current_index]);}/*********************************************************~infinite_array--destroytheinfinitearray*********************************************************/infinite_array::-infinite_array(void)Page420Example23-3ia/ai.cc(Continued){/**Note:Weuseacutetrickhere.**Becauseeachbucketintheinfinitearrayis*aninfinitearrayitself,whenwedestroy*next,itwilldestroyallthatbucket's"next"s*andsoonrecursivelyclearingtheentirearray.*/if(next!=NULL)deletenext;next=NULL;}}TheMakefileforMultipleFilesTheutilitymakeisdesignedtoaidtheprogrammerincompilingandlinkingprograms.Beforemake,theuserhadtoexplicitlytypecompilecommandseachtimetherewasachangeintheprogram:g++-Wall-g-ohellohello.ccNOTE InthischapterweusethecommandsfortheGNUg++compiler.TheC++compileronyoursystemmayhaveadifferentnameandaslightlydifferentsyntax.Asprogramsgrow,thenumberofcommandsneededtocreatethemgrows.Typinginaseriesof10or20commandsistiresomeanderror-prone,soprogrammersstartedwritingshellscripts(or,inMS-DOS,.BATfiles).Thenalltheprogrammerhadtotypewasdo-itandthecomputerwouldcompileeverything.Thiswasoverkill,however,becauseallthefileswererecompiledregardlessofneed.Asthenumberoffilesinaprojectgrew,thisrecompilingbecameasignificantproblem.Changingonesmallfile,startingthecompilation,andthenhavingtowaituntilthenextdaywhilethecomputerexecutedseveralhundredcompilecommandswasfrustrating—especiallywhenonlyonecompilewasreallyneeded.Theprogrammakewascreatedtodointelligentcompiles.Itspurposeistofirstdecidewhatcommandsneedtobeexecutedandthenexecutethem.ThefileMakefile(upper/lowercaseisimportantinUNIX)containstherulesusedbymaketodecidehowtobuildtheprogram.TheMakefilecontainsthefollowingsections:Page421·Comments·Macros·Explicitrules·DefaultrulesAnylinebeginningwitha#isacomment.Amacrohastheformat:name=dataNameisanyvalididentifier.Dataisthetextthatwillbesubstitutedwhenevermakesees$(name).Example:##VerysimpleMakefile#MACRO=DoingAllall:echo$(MACRO)Explicitrulestellmakewhatcommandsareneededtocreatetheprogram.Theserulescantakeseveralforms.Themostcommonis:target:source[source2][source3] command[command][command]...Targetisthenameofafiletocreate.Itis''made,"orcreated,outofthesourcefilesource.Ifthetargetiscreatedoutofseveralfiles,theyarealllisted.Thecommandusedtocreatethetargetislistedonthenextline.Sometimesittakesmorethanonecommandtocreatethetarget.Commandsarelistedoneperline.Eachisindentedbyatab.Forexample,therule:hello:hello.ccg++-Wall-g-ohellohello.cctellsmaketocreatethefilehellofromthefilehello.ccusingthecommand:g++-Wall-g-ohellohello.ccPage422Makewillcreatehelloonlyifnecessary.Thefilesusedinthecreationofhello,arrangedinchronologicalorder(bymodificationtimes),areshowninTable23-2.Table23-2FileModificationTimesUNIXMS-DOS/WindowsModificationTimehello.ccHELLO.CPPOldesthellooHELLOOBJOldhelloHELLO.EXENewestIftheprogrammerchangesthesourcefilehello.cc,thefile'smodificationtimewillbeoutofdatewithrespecttotheotherfiles.makewillsensethisandre-createtheotherfiles.Anotherformoftheexplicitruleis:source:command[command]Inthiscase,thecommandsareexecutedeachtimemakeisrun,unconditionally.Ifthecommandsareomittedfromanexplicitrule,makeusesasetofbuilt-inrulestodeterminewhatcommandtoexecute.Forexample,therule:hist.o:ia.hhist.cctellsmaketocreatehist.ofromhist.ccandia.h,usingthestandardruleformaking.ofrom.cc.Thisruleis: g++$(CFLAGS)-cfile.CC(makepredefinesthemacro$(CFLAGS).)Wearegoingtocreateamainprogramhist.ccthatcallsthemoduleia.cc.Bothfilesincludetheheaderia.h,sotheydependonit.TheUNIXMakefilethatcreatestheprogramhistfromhist.ccandia.ccislistedinExample23-4.Example23-4ia/Makefile#MakefileneedsdebuggingCFLAGS=-g-WallSRC=ia.cchist.ccOBJ=ia.ohist.oall:histhist:$(OBJ)g++$(CFLAGS)-ohist$(OBJ)Page423Example23-4ia/Makefile(Continued)hist.o:ia.hhist.ccg++$(CFLAGS)-chist.ccia.o:ia.hia.ccg++$(CFLAGS)-cia.ccclean:rmhistio.ohist.oThemacroSRCisalistofalltheC++files.OBJisalistofalltheobject(.o)files.Thelines:hist:$(OBJ)g++$(CFLAGS)-ohist$(OBJ)tellmaketocreatehistfromtheobjectfiles.Ifanyoftheobjectfilesareoutofdate,makewillre-createthem.Theline:hist.o:ia.htellsmaketocreatehist.ofromia.handhist.cc(hist.ccisimplied).Becausenocommandisspecified,thedefaultisused.Example23-5showstheMakefileforMS-DOS/Windows,usingTurbo-C++.Example23-5.ia/Makefile.dos##MakefileforBorland'sTurbo-C++compiler#CC=tcc# #Flags#-N--Checkforstackoverflow#-v--Enabledebugging#-w--Turnonallwarnings#-ml--Largemodel#-A--ForceANSIcompliance#CFLAGS=-N-v-w-ml-A#SRCS=hist.cia.cOBJS=hist.objia.objia:$(OBJS)$(CC)$(CFLAGS)-oia.exe$(OBJS)hist.obj:hist.cppia.h$(CC)$(CFLAGS)-chist.cppPage424Example23-5ia/Makefile.dos(Continued)ia.obj:ia.cia.h$(CC)$(CFLAGS)-cia.cppThisfileissimilartotheUNIXMakefileexceptthatTurbo-C++makedoesnotprovideanydefaultrules.Thereisonebigdrawbackwithmake.Itonlycheckstoseewhetherthefileshavechanged,nottherules.IfyouhavecompiledallyourprogramwithCFLAGS=-gfordebuggingandneedtoproducetheproductionversion(CFLAGS=-0),makewillnotrecompile.Thecommandtouchchangesthemodificationdateofafile.(Itdoesn'tchangethefile,itjustmakestheoperatingsystemthinkitdid.)Ifyoutouchasourcefilesuchashello.ccandthenrunmake,theprogramwillbere-created.Thisisusefulifyouhavechangedthecompile-timeflagsandwanttoforceare-compilation.Makeprovidesarichsetofcommandsforcreatingprograms.Onlyafewhavebeendiscussedhere.*UsingtheInfiniteArrayThehistogramprogram(hist)isdesignedtousetheinfinitearraypackage.Ittakesonefileasitsargument.Thefilecontainsalistofnumbersbetween0and99.Anynumberofentriesmaybeused.Theprogramprintsahistogramshowinghowmanytimeseachnumberappears.(Ahistogramisagraphicrepresentationofthefrequencyofdata.)Thisfilecontainsanumberofinterestingprogrammingtechniques.Thefirstoneis:Letthecomputerdotheworkwheneverpossible.Forexample,don'tprogramlikethis:constintLENGTH_X=300;//WidthoftheboxindotsconstintLENGTH_Y=400;//HeightoftheboxindotsconstintAREA=12000;//TotalboxareaindotsInthiscase,theprogrammerhasdecidedtomultiply300x400tocomputethearea.Hewould bebetterservedbylettingthecomputerdothemultiplying:constintLENGTH_X=300;//WidthoftheboxindotsconstintLENGTH_Y=400;//HeightoftheboxindotsconstintAREA=(LENGTH_X*LENGTH_Y);//Totalboxareaindots*Ifyouaregoingtocreateprogramsthatrequiremorethan10or20sourcefiles,itissuggestedyoureadthehookManagingProJectswithmake(O'Reilly&Associates,Inc)Page425Thatway,ifeitherLENGTH_XorLENGTH_Yischanged,AREAchangesautomatically.Also,thecomputerismoreaccurateinitscomputations.(Ifyounoticed,theprogrammermadeanerror:hisAREAistoosmallbyafactorof10.)Inthehistogramprogram,thenumberofdatapointsineachoutputlineiscomputedbythedefinition:constfloatFACTOR=((HIGH_BOUND-LOW_BOUND)/(float)(NUMBER_OF_LINES));Theusershouldbehelpedwheneverpossible.Inthehistprogram,iftheuserdoesnottypethecorrectnumberofparametersonthecommandline,amessageappearstellingwhatiswrongandhowtocorrectit.Theprogramusesthelibraryroutinememsettoinitializethecountersarray.Thisroutineishighlyefficientforsettingallvaluesofanarraytozero.Theline:memset(counters,'',sizeof(counters));zerostheentirearraycounters.sizeof(counters)makessurethatallthearrayiszeroed.Example23-6containsaprogramthatusestheinfinitearrayforstoringdatausedtoproduceahistogram.Example23-6.ia/hist.ccFile:hist.cc/*********************************************************hist--generateahistogramofanarrayofnumbers****Usage**hist****Where**fileisthenameofthefiletoworkon*********************************************************/#include#include#include#include#include#include"ia.h" /**Thefollowingdefinitionsdefinethehistogram*/constintNUMBER_OFLINES=50;//#linesintheresultconstintLOW_BOUND=0;//LowestnumberwerecordconstintHIGH_BOUND=99;//Highestnumberwerecord/**ifwehaveNUMBEROFLINESdatato*outputtheneachitemmustusePage426Exampe2-6.ia/histcc(Continued)*thefollowingfactor*/constfloatFACTOR=((HIGH_BOUND-LOW_BOUND)/(float)(NUMBER_OF_LINES);//NumberofcharacterswidetomakethehistogramconstintWIDTH=60;//Arraytostorethedatainstaticinfinite_arraydata_array;//Numberofitemsinthearraystaticintdata_items;main(intargc,char*argv[]){voidread_data(char*name);//Getthedataintothearrayvoidprint_histogram(void);//Printthedataif(argc!=2){cerr<<"Error:Wrongnumberofarguments ";cerr<<"Usageis: ";cerr<<"hist ";exit(8);}data_items=0;read_data(argv[1]);print_histogram();return(0);}/*********************************************************read_data--readdatafromtheinputfileinto**thedataarray****Parameters**name--thenameofthefiletoread*********************************************************/voidread_data(char*name){ifstreamin_file(name);//Inputfileintdata;//Datafrominputif(infile.bad(){ cerr<<"Error:Unabletoopen"<>data;//Ifwegetaneofweranoutofdatainlastreadif(in_file.eof())break;Page427Example23-6ia/hist.cc(Continued)data_array[data_items]=data;++data_items;}}/*********************************************************print_histogram--printthehistogramoutput*********************************************************/voidprint_histogram(void){//Upperboundforprintoutintcounters[NUMBER_OF_LINES];intlow;//Lowerboundforprintoutintout_of_range=0;//Numberofitemsoutofboundsintmax_count=0;//Biggestcounterfloatscale;//Scaleforoutputtingdotsintindex;//Indexintothedatamemset(counters,'',sizeof(counters));for(index=0;indexHIGH_BOUND))++outof_range;else{//Indexintocountersarrayintcount_index;count_index=int(float(data-LOW_BOUND)/FACTOR);++counters[count_index];if(counters[count_index]>max_count)max_count=counters[count_index];}}scale=float(max_count)/float(WIDTH);low=LOW_BOUND; for(index=0;indexd2)return(dl);return(d2);}Page436NOTEEachlineexceptthelastoneendsinabackslash().A#definemacrospansasingleline,sothebackslashturnsourfivelinesinto one.Byputtingthebackslashesinthesamecolumnwecaneasilytellifwemissone.Thismacrogeneratesnocode.Itmerelyprovidesthedefinitionthatisusedinthenextphasetogeneratethefunctionswewant.Thisiscalledthegenerationphase.define_max(int);define_max(float);define_max(char);Finally,somewhereinthecodeweusethefunctionswe'vejustdefined.(Thisiscalledtheusephase,ofcourse.)main(void){floatf=max(3.5,8.7);inti=max(100,800);charch=max('A','Q');Figure24-1showsthesourcecodeforthe#definestyletemplatesandthecodegeneratedbythem.Thismethodworksadequatelyforsimplefunctionslikemax.Itdoesn'tworkwellforlargerfunctions.Onedrawbacktothissystemisthatwemustinvokethemacrodefine_maxforeachdatatypewewanttouse.ItwouldbeniceifC++wouldcalldefine_maxautomatically.Templatesallowyoutodefineagenericfunction.C++thenusesthistemplatetogenerateaspecificinstanceofthefunctionasneeded.Forexample,todefinethefunctionmaxasatemplate,wewrite:templatekindmax(kinddl,kindd2)if(dl>d2)return(dl);return(d2);}NOTETheconstructtellsC++thatthewordkindcanbereplacedbyanytype.(Note:Thekeywordclassisusedinthiscontexttoindicatethatkindcanbeanytype:notonlyclasses,butsimpletypesaswell.)Thetemplatedeclarationcorrespondstothedefinitionoftheparameterizedmacro.Liketheparameterizedmacro,itgeneratesnocode:itmerelyprovidesadefinitionforthenextphasePage437 Figure24-1.Codegeneratedby#definestyletemplatesNowwecanusethetemplate,muchlikeweusedthefunctionsdefinedbytheparameterizedmacro:main(void){floatf=max(3.5,8.7);inti=max(100,800);charch=max('A','Q');inti2=max(600,200);Youmayhavenoticedthatweskippedthegenerationphase.That'sbecauseC++automaticallyperformsthegenerationforus.Inotherwords,C++looksattheline:floatf=max(3.5,8.7);Page438andseesthatitusesthefunctionmax(float,float).Itthencheckstoseewhetherthecodeforthisfunctionhasbeengeneratedandgeneratesitifnecessary.Inotherwords,everythingisautomatic.(Therearepracticallimitstowhatcanbedoneautomatically,asyouwillseeinthesectiononimplementation.)Figure24-2showsthecodegeneratedbythetemplateimplementationofmax.Fromthisyoucanseethatthefirsttimemaxisusedforafloatitgeneratesthefloatingpointversionofmax.Nextweusemaxforint,andtheintversionofmaxiscreated.Notethatthelast line:inti2=max(600,200);doesnotgenerateanyfunction.Thisisbecausewe'vealreadygeneratedtheintegerversionmaxanddon'tneedtodoitagain.Figure24-2TemplatecodegenerationPage439FunctionSpecializationTemplatesgoabitfurtherthansimplecodegeneration.Theycanhandlespecialcasesaswell.Supposewewanttousethefunctionmaxtocomparestringsaswell:char*namel="Able";char*name2="Baker";cout<d2)comparesthevalueofthepointers,notthedatathat'spointedto.Whatwewanttodoistell C++,''Usethenormalcomparisonexceptwhenthedatatypeisastring,andthenusestrcmp."Thisisdonethroughaprocesscalledspecialization.Wedeclareaspecialversionofthemaxfunctionjustforstrings:char*max(char*dl,char*d2)if(strcmp(dl,d2)<0)return(dl);return(d2);}WhenC++firstseestheuseofthefunctionmaxitlooksthroughthelistofsimplefunctionsbeforeitlooksthroughitslistoftemplates.Thuswhenwehave:cout<#include//Atemplateforthe"max"functiontemplatekindmax(kinddl,kindd2)if(dl>d2)return(d1);return(d2);}Page440Example24-1max-t/max.cc(Continued).//Aspecializationforthe"max"function//becausewehandlechar*alittledifferentlychar*max(char*dl,char*d2){if(strcmp(dl,d2)>0)return(dl);return(d2);}main(){//Let'stestmaxcout<<"max(1,2)"<#includeconstintSTACK_SIZE=100;//Maximumsizeofastack/********************************************************Stackclass****Memberfunctions**stack--initializethestack**push--putanitemonthestack***pop--removeanitemfromthestack********************************************************///Thestackitselftemplateclassstack{private:intcount;//Numberofitemsinthestackkinddata[STACK_SIZE];//Theitemsthemselvespublic://Initializethestackstack(void){count=0;//Zerothestack}Page441Example24-2.max-t/stack1.cc(Continued).//Pushanitemonthestackvoidpush(constkinditem){data[count]=item;++count;}//Popanitemfromthestackkindpop(void){//Stackgoesdownbyone--count;//Thenwereturnthetopvaluereturn(data[count]);}};Thereisaproblem,however.Tousethisclassweneedtodeclareaninstanceofthisclass.Inthepast,we'vebeenabletodeclareastackwiththestatement: stacka_stack;//Thiswon'tworkTheproblemisthatstackisnowagenerictemplate.Thestackcannowcontainanything.WhenC++seesthisdeclaration,it'sgoingtoask,"Astackofwhat?"Wemustspecifythetypeofdatawearestoring.Thenewdeclarationis:stacka_stack;//AstackofintegersThetellsC++touse"int"for"kind"throughoutthestack.Wecannowusethenewclassvariable:a_stack.push(l);x=a_stack.pop();Inthestackclass,wedefinedallthememberfunctionsinsidetheclassdefinition.Wecouldjustaswellhavespecifiedtheproceduresoutsidetheclass.Todoso,wemustputthetemplateclausetemplateinfrontofeachprocedureandputthetemplateparameter()inthenameoftheclass.Forexample,thepushroutinewouldlooklike:/**************************************************stack::push--pushanitemonthestack****Warning:Wedonotcheckforoverflow****Parameters**item--itemtoputonthestack**************************************************/templateinlinevoidstack::push(constkinditem){Page442data[count]=item;++count;}ClassSpecializationYoucanthinkofaclasstemplatesuchastemplatestack{...asinstructionsthattellC++howtogenerateasetofclassesnamedstack,stack,stack,andsoon.C++willalsogenerateautomaticallythememberfunctions:stack::push,stack::push,andstack::push.However,ifyouexplicitlydeclareamemberfunctionyourself,C++willuseyourdefinitionbeforegeneratingitsown.Supposewewanttohaveastackstorestrings(char*).Wedon'twanttostorethepointers;wewanttostoretheactualstrings.Todothis,weneedaspecialversionofthepushfunctionthatduplicatesthestringbeforepushingitontothestack:inlinevoidstack::push(constchar*item){ data[count]=strdup(item);++count;}Notethatwedidn'tusetemplateatthebeginningofthefunction.ThetemplatekeywordtellsC++:"Thisisagenericclass.Generatespecificversionsfromit."Withnotemplate,wearetellingC++:"Thisistherealthing.Useitdirectly."ImplementationDifficultiesTheAnnotatedC++ReferenceManualbyEllisandStroustrupisconsideredthedefaultstandardoftheC++language.Itcontainsacompletedefinitionofthesyntaxfortemplates.However,itdoesnotexplainhowcompilersshouldimplementthem.Asyoushallsee,implementingtemplatesisnoteasy.Forexample,supposeweputthestacktemplateinamodule.Thefilestack.hdefinestheclassandthefilestack.ccdefinesthememberfunctions.(Wewillassumethatnoneofthememberfunctionsareinline.)Nowwewanttousethetemplateforanintegerstack(stack)inthefilemain.cc.Figure24-3showsthesource-codelayout.Thisiswherethecompilerimplementorsstartpullingtheirhairout.Page443Figure24-3.Source-codelayoutforusingastacktemplateWeknowthatinmain.cc,we'regoingtousestack.Asamatteroffact,thefilestack.hdefinedprototypesforthetwomemberfunctionspushandpop.Sowhenthecompilerseesstack,itshouldautomaticallygeneratethecodeforpushandpop.Buthow?Thebodiesofthesetwomemberfunctionsaretuckedawayinthefilestack.cc.Thecompilerisworkingonmain.cc.Itdoesn'tknowanythingaboutanyotherfile,soitdoesn'tknowhowtogeneratepushandpop.Butcouldn'tthecompilergeneratepushandpopwhenitcompilesstack.cc?Yes,ifitknewthatsomeonehaddeclaredastackvariable.Buttheonlyonewhodidthatismain.ccandthecompilerisn'tworkingonthatfilejustnow.Managerscallthissituation"technicallychallenging."Programmerscallit"anightmare."Theproblemsassociatedwithtemplategenerationarenotsimpletosolve.Differentcompilermakershavechosendifferentapproaches.Theproblemisthatalltheseapproachesarenot compatible.Codewrittenforonecompilermaynotworkonanother.Insomecases,evencodewrittenforoneversionofacompilermightnotworkinanotherversion.TemplatesaretheleadingedgeofC++compilertechnologyand,likeallnewprograms,therearejustafewbugstoworkout.Inthefollowingsections,wediscussthevariouswayscompilermakershaveattemptedtosolvetheproblemsassociatedwithtemplates.Compilertechnologyandstandardsareconstantlyevolving,sotheinformationinthissectionmaynotbeuptodate.Microsoft'sImplementationAsofthispublicationdate,theMicrosoftC++andVisualC++compilersdonothavetemplates.Althoughextremelysimple,thisformof"implementation"isveryPage444limited.Ontheotherhand,I'veneverhadanytroublewithtemplatesusingaMicrosoftcompiler.Turbo-C++andGNUg++TemplatesTheTurbo-C++andtheGNUg++compilerstakeasimilarapproach.Ifyouplantousestack,thenyoumusthaveastackinthefilethatdefinesthememberfunctions:stack.cc.Atthebeginningofthestack.ccfile,youwillneedtheline:typedefstackfloating_point_stack;Actuallyyouneverhavetousethetypefloating_point_stack.Thetypedefistherejusttotellthecompilertogeneratetheneededmemberfunctions.Bothcompilersalsohaveswitchesthattellthecompilerwhattodoaboutinlinefunctionsthatcan'tbehandledinline.Supposeyoudefinethefunction:templateinlinekindmax(kinddl,kindd2){if(dl>d2)return(dl);return(d2);}intheheaderfilemax.handthenproceedtousethemaxfunctioninthreedifferentfiles.Alsosupposethatthefunctionissocomplexthatthecompilerdecidedtoignoretheinlinedirective.(Iknowthat'salotofsupposing,butit'stheonlywayyougettothismess.)Whenyourthreefilesarecompiled,threecopiesofmaxaregenerated.TheTurbo-C++linkerissmartenoughtodetectthisfactandwillthrowtwoofthemaway.TheGNUg++linkerisnotsosmart,andyou'llwindupwiththreecopiesofthesameroutineinyourcode.BothTurbo-C++andGNUprovideyouwithcompileroptionsthathelpsolvethisproblem.Ifyouputtheline:#pragmainterface//GNUg++onlyoption inyourcode,ittellsGNU:"Don'tgeneratethebodyforanytemplatefunctionsfoundinthisheader."Later,inoneofyourfiles,youmustputthedirective:#pragmaimplementation//GNUg++onlyoptionThistellsGNU,"Here'swhereyougeneratethefunctionbodies."Turbo-C++usessimilarpragmas.However,the"interface"directiveis:#pragmaoption-Jgx//Turbo-C++onlyoptionPage445andthe"implementation"directiveis:#pragmaoption-Jg//Turbo-C++onlyoptionTheoptionsareclunky,nonportable,anddifficulttouse.Theyaremeanttosolveanimplementationproblemthathasnotbeenproperlysolvedyet.CFront-BasedCompilersCFrontisthenameoftheAT&TC++toCtranslatorthatwasthebasisofthefirstC++compiler.MostC++compilermakersconsiderthemselvesstandardiftheyarecompatiblewiththelatestversionofCFront.CFronthandlestheproblemoftemplategenerationbyputtingitoffuntillinktime,soyouonlycompileandlinkthefilemain.cc.Atlinktime,CFrontnoticesthatmain.ccusesstack.Itthenlooksforafilenamedstack.cc.(Note:Yourfilemustbenamed.cc.)Thisfileisusedtogeneratethetemplates.Althoughthismethodseemssimpleenough,therearealotofdetailstotakecareof.Forexample,thefilestack.hisautomaticallyincludedwhenthelinkertriestocompilestack.cc.What'sworse,ifyouincludeityourselfwitha#include"stack.h",thecompilergetsconfused.TheCFrontapproachisagoodattemptatsolvingthetemplateproblem,buttherearestillmanybugstoworkout.WritingPortableTemplatesHowcanyouwriteaportabletemplate?Thesimpleansweris,"Don'tusethem."However,thebestwaytocreateatrulyportabletemplateistowriteeverythingasinlinefunctionsandputallyourfunctionsinasingle-headerfile.AsfarasIcantell,thismethodworksforeverycompilerthathastemplates.Itmaynotbethemostefficientwayofdoingthings,butitisthemostportable.SummaryTemplatesprovideaconvenientwayofwritinggenericclassesandfunctions.However,implementationoftemplatesisstillundergoingrefinement.Asapracticalmatter,youmaywanttowaituntilthelanguagesettlesdownalittlebeforeusingthem. ProgrammingExercisesExercise24-1:Writeatemplateminthatreturnstheminimumoftwovalues.Makesureyouhandlestringscorrectly.Page446Exercise24-2:Writeatemplateclasstoimplementanarraywithboundschecking.Exercise24-3:Defineatemplateclassthatimplementsaset.Theclassallowsyoutoset,clear,andtestelements.(AnintegerversionofthisclasswaspresentedinExercise13-4.)Page44725PortabilityProblemsInThisChapter:·Modularity·WordSize·Byte-OrderProblem·AlignmentProblem·NULL-PointerProblem·FilenameProblems·FileTypes·Summary·AnswerstoChapterQuestionsWhereinIspakeofmostdisastrouschanges,Ofmovingaccidentsbyfloodandfield,Ofhair-breadth'scapesi'theimminentdeadlybreadth—ShakespeareonProgramPortingOthello,Act1,Scene3You'vejustcompletedworkonyourgreatmasterpiece,aray-tracingprogramthatrenderscomplexthree-dimensionalshadedgraphicsonaCraysupercomputerusing30MBofmemoryand5GBofdiskspace.WhatdoyoudowhensomeonecomesinandasksyoutoportthisprogramtoanIBMPCwith640Kofmemoryand100MBofdiskspace?Killinghimisout.Notonlyisitillegal,butitalsoisconsideredunprofessional.Youronlychoiceistowhimperandstarttheport.Itisduringthisprocessthatyouwillfindthatyournice,workingprogramexhibitsallsortsofstrangeandmysteriousproblems. C++programsaresupposedtobeportable.However,C++containsmanymachine-dependentfeatures.Also,becauseofthevastdifferencebetweenUNIXandMS-DOS/Windows,systemdependenciescanfrequentlybefoundinmanyprograms.Thischapterdiscussessomeoftheproblemsassociatedwithwritingtrulyportableprogramsaswellassomeofthetrapsyoumightencounter.ModularityOneofthetrickstowritingportableprogramsistoputallthenonportablecodeintoaseparatemodule.Forexample,screenhandlingdiffersgreatlyinMSDOS/WindowsandUNIX.Todesignaportableprogram,you'dhavetowritemachine-specificscreen-updatemodules.Page448Forexample,theHP-98752AterminalhasasetoffunctionkeyslabeledF1-F8.ThePCalsohasafunction-keyset.Theproblemisthatthesekeysdon'tsendoutthesamesetofcodes.TheHPsends"p"forF1andthePCsends"".Inthiscase,youwouldwanttowriteaget_coderoutinethatgetsacharacter(orfunctionkeystring)fromthekeyboardandtranslatesfunctionkeys.Becausethetranslationisdifferentforbothmachines,amachine-dependentmoduleisneededforeachone.FortheHPmachine,youwouldputtogethertheprogramwithmain.ccandhp-tty.cc,whileforthePCyouwouldusemain.ccandpc-tty.cc.WordSizeAlongintis32bits,ashortintis16*bits,andanormalintcanbe16or32bitsdependingonthemachine.Thiscanleadtounexpectedproblems.Forexample,thefollowingcodeworksona32-bitUNIXsystem,butfailswhenportedtoMS-DOS/Windows:intzip;zip=92126;cout<<"ipcode"</*UNIXversionofthefile*/#else_MSDOS_#include/*DOSversionofthefile*/#endif__MSDOS_Question25-1:WhydoesExample25-1workonUNIX,butwhenwerunitinMSDOS/Windowswegetthemessage:ootewable:filenotfoundExample25-1.ifstreamin_file#ifndef__MSDOS_#defineNAME"/root/new/table"#else__MSDOS_#defineNAME"root ewtable"#endif__MSDOS_in_file.open(NAME);if(in_file.bad){ cout<, is,andtis.Whatwereallyhaveforanameis:ootewableThenameshouldbespecifiedas:#defineNAME"\root ew\table"NOTEThe#includeusesafilename,notaC++string.Whileyoumustusedoublebackslashes(\)inaC++string,youusesinglebackslashesinan#include.Thefollowingtwolinesarebothcorrect:#defineNAME"\root ew\table"#include"root ewdefs.h"Page45526PuttingItAllTogetherInThisChapter:·Requirements·CodeDesign·Coding·FunctionalDescription·Testing·Revisions·AFinalWarning·ProgramFiles·ProgrammingExercises ExercisesForthereisn'tajobonthetopoftheearththebeggardon'tknow,nordo—KiplingInthischapterwecreateacompleteprogram.Everystepoftheprocessiscovered,fromsettingforththerequirementstotestingtheresult.RequirementsBeforewestart,weneedtodecidewhatitiswearegoingtodo.Thisisaveryimportantstepandisleftoutoffartoomanyprogrammingcycles.Thischapter'sprogrammustfulfillseveralrequirements.First,itmustbelongenoughtodemonstratemodularprogramming,butatthesametimebeshortenoughtofitinsideasinglechapter.Second,itmustbecomplexenoughtodemonstrateawiderangeofC++features,butbesimpleenoughforanoviceC++programmertounderstand.Finally,itmustbeuseful.Thisisnotsosimpletodefine.What'susefultoonepersonmightnotbeusefultoanother.Wedecidedtorefinethisrequirementandrestateitas"ItmustbeusefultoC++programmers."TheprogramwehaveselectedreadsC++sourcefilesandgeneratessimplestatisticsonthenestingofparentheses,andtheratioofcommentstocodelines.Thespecificationforourstatisticsprogramis:PreliminarySpecificationforaC++StatisticsGatheringProgramSteveOuallineFebruary10,1995Page456TheprogramstatgathersstatisticsaboutC++sourcefilesandprintsthem.Thecommandlineis:statfileswherefilesisalistofsourcefiles.Thefollowingshowstheoutputoftheprogramonashorttestfile.Example26-1.stat/stat.out.1(0{0#include2(0{0/*******************************************************3(0{0*calc--asimple4-functioncalculator*4(0{0*******************************************************/5(0{0intresult;//Theresultofthecalculations6(0{0charoper_char;//User-specifiedoperator7(0{0intvalue;//Valuespecifiedaftertheoperator8(0{0main()9(0{1{10(0{1result=0;//Initializetheresult11(0{112(0{1while(1){ 14(0{2cout<<"Result:"<>oper_char>>value;18(0{219(1{2if((oper_char=='q')||20(0{2(oper_char=='Q'))21(0{2break;22(0{223(0{3switch(oper_char){24(0{3case'+':25(0{3result+=value;26(0{3break;27(0{3case'-':28(0{3result-=value;29(0{3break;30(0{3case'*':31(0{3result*=value;32(0{3break;33(0{3case'/':34(0{4if(value==0){35(0{4cout<<"Error:Dividebyzero ";36(0{4cout<<"operationignored ";37(0{3}else38(0{3result/=value;39(0{3break;40(0{3default:41(0{3cout<<"Unknownoperator"<<42(0{3oper_char<<' ';43(0{3break;44(0{2}45(0{1}Page457Example26-1.stat/stat.out(Continued).46(0{1return(0);47(0{0}Totalnumberoflines:47Maximumnestingof():2Maximumnestingof{}:4Numberofblanklines.................4Numberofcommentonlylines..........4Numberofcodeonlylines.............36Numberoflineswithcodeandcomments4Commenttocoderatio20.5%CodeDesignThereareseveralschoolsofcodedesign.Instructuredprogramming,youdividethecodeupintomodulesandthendividethemoduleintosubmodules,dividethesub-modulesintosub-submodules,andsoon.Thisisalsoknownasprocedure-orientedprogramming.Inobject-orientedprogramming,youtrytothinkoftheproblemasacollectionofdatathatyoumanipulatethroughmemberfunctions. Therealsoareotherapproaches,suchasstatetablesandtransitiondiagrams.Allofthesehavethesamebasicprincipleatheart:"Arrangetheprogram'sinformationintheclearestandsimplestwaypossibleandthentrytoturnitintoC++code."Ourprogrambreaksdownintoseverallogicalmodules.First,thereisatokenscanner,whichreadsrawC++codeandturnsitintotokens.Actually,thisfunctionsub-dividesintotwosmallermodules.Thefirstreadstheinputstreamanddetermineswhattypeofcharacterwehave.Thesecondtakesincharacter-typeinformationandusesittoassembletokens.Theothermodulecontainsthestatisticsgatheringandasmallmainprogram.TokenModuleOurprogramscansC++sourcecodeandusesthetokenstogeneratestatistics.Atokenisagroupofcharactersthatformasingleword,number,orsymbol.Forexample,theline:answer=(123+456)/89;//Computesomesortofresultconsistsofthetokens:T_IDTheword"answer"T_OPERATORThecharacter"="T_L_PARENLeftParenthesisT_NUMBERThenumber123T_OPERATORThecharacter"+"Page458T_NUMBERThenumber456T_R_PARENRightparenthesisT_OPERATORThedivideoperatorT_NUMBERThenumber89T_OPERATORThesemicolonT_COMMENTThe//commentT_NEWLINETheend-of-linecharacterOurtokenmoduleneedstoidentifygroupsofcharacters.Forexample,anidentifierisdefinedasaletterorunderscore,followedbyanynumberoflettersordigits.Soourtokenizerneedstocontainthepseudocode:Ifthecurrentcharacterisaletterthenscanuntilwegetacharacterthat'snotaletterordigitAsyoucanseefromthepseudocode,ourtokenizerdependsagreatdealoncharactertypes,soweneedamoduletohelpuswiththetypeinformation.Character-typeModuleThepurposeofthecharacter-typemoduleistoreadcharactersanddecodetheirtypes.Sometypesoverlap.Forexample,C_ALPHA_NUMERICincludestheC_NUMERICcharacterset.ThismodulestoresmostofthetypeinformationinanarrayandrequiresonlyalittlelogictohandlethespecialtypeslikeC_ALPHA_NUMERIC.StatisticsClass Inthisprogram,astatisticisanobjectthatconsumestokensandoutputsstatistics.Westartbydefininganabstractclassforourstatistics.Thisclassisusedasthebasisforthestatisticswearecollecting.TheclassdiagramcanbeseeninFigure26-1.Figure26-1StatisticsclasshierarchyOurdefinitionofastatisticis"somethingthatusestokenstocollectstatistics."Thesestatisticsmaybeprintedatthebeginningofeachlineorattheendofthefile.Page459Ourfourstatisticsaremorespecific.Forexample,theclassparen_countercountsthenestingofparenthesisaswellasthemaximumnesting.Thecurrentnestingisprintedatthebeginningofeachline(the"("number).Themaximumnestingleveliswrittenoutattheendofthefile.Theotherclassesaredefinedinasimilarmanner.Theonlytrickusedhereisthatwe'vemadethelinenumberingastatistic.ItcountsthenumberofT_NEW_LINEtokensandoutputsthatcountatthestartofeachline.CodingThecodingprocesswasfairlysimple.Theonlyproblemthatcameupwasgettingtheend-of-linecorrect.FunctionalDescriptionThissectiondescribesalltheclassesandmajorfunctionsinourprogram.Foramorecompleteanddetaileddescription,takealookatthelistingsattheendofthischapter.char_typeClassThechar_typeclasssetsthetypeofacharacter.Forthemostpart,thisisdonethroughatablenamedtype_info.Sometypes,suchasC_ALPHA_NUMERIC,includetwodifferenttypesofcharacters,C_ALPHAandC_DIGIT.Therefore,inadditiontoourtable,weneedalittlecodeforthespecialcases.in_putfileClassThisclassreadsdatafromtheinputfileonecharacteratatime.Itbuffersupalineandoncommandwritesthelinetotheoutput.tokenClass Wewantaninputstreamoftokens.Wehaveaninputstreamconsistingofcharacters.Themainfunctionofthisclass,next_token,turnscharactersintotokens.Actually,ourtokenizerisrathersimple,becausewedon'thavetodealwithmostofthedetailsthatafullC++tokenizermusthandle.Thecodingforthisfunctionisfairlystraightforward,exceptforthefactthatitbreaksupmultilinecommentsintoaseriesofT_COMMENTandT_NEW_LINEtokens.Page460Oneclevertrickisusedinthissection.TheTOKEN_LISTmacroisusedtogenerateanenumeratedlistoftokentypesaswellasastringarraycontainingthenamesofeachofthetokens.Let'sexaminehowthisisdoneinmoredetail.ThedefinitionoftheTOKEN_LISTclassis:#defineTOKEN_LISTT(T_NUMBER),/*Simplenumber(floatingpointorinteger)*/T(T_STRING),/*Stringorcharacterconstant*/T(TCOMMENT),/*Comment*/T(T_NEWLINE),/*Newlinecharacter*/T(T_OPERATOR),/*Arithmeticoperator*/T(T_L_PAREN),/*Character"("*/T(T_R_PAREN),/*Character")"*/T(T_L_CURLY),/*Character"{"*/T(T_R_CURLY),/*Character"}"*/T(T_ID),/*Identifier*/T(T_EOF)/*EndofFile*/Wheninvoked,thismacrowillgeneratethecode:T(T_NUMBER),T(T_STRING),//..andsoonIfwedefineaTmacro,itwillbeexpandedwhentheTOKEN_LISTmacroisexpanded.WewouldliketousetheTOKEN_LISTmacrotogeneratealistofnames,sowedefinetheTmacroas:#defineT(x)x//DefineT()asthenameNow,ourTOKEN_LISTmacrowillgenerate:T_NUMBER,T_STRING,//..andsoonPuttingallthistogetherwithalittlemorecode,wegetawaytogenerateaTOKEN_TYPEenumlist:#defineT(x)x//DefineT()asthenameenumTOKEN_TYPE{TOKEN_LIST};#undefT//Removeoldtemporarymacro LaterweredefineTsoitgeneratesastring:#defineT(x)#x//DefinexasastringThisallowsustouseTOKEN_LISTtogeneratealistofstringscontainingthenamesofthetokens:#defineT(x)#x//Definexasastringconstchar*constTOKEN_NAMES[]={Page461TOKEN_LIST};#undefT//RemoveoldtemporarymacroWhenexpanded,thismacrogenerates:constchar*constTOKEN_NAMES[]={"T_NUMBER","T_STRING",//....Usingtrickslikethisisacceptableinlimitedcases.However,suchtricksshouldbeextensivelycommentedsothemaintenanceprogrammerwhohastofixyourcodecanunderstandwhatyoudid.statClassstatclassisanabstractclassthatisusedasabasisforthefourrealstatisticswearecollecting.Itstartswithamemberfunctiontoconsumetokens.Thisfunctionisapurevirtualfunction,whichmeansthatanyderivedclassesmustdefinethefunctiontake_token.classstat{public:virtualvoidtake_token(TOKEN_TYPEtoken)=0;Thefunctiontake_tokengeneratesstatisticsfromtokens.Weneedsomewayofprintingthem.Weprintstatisticsintwoplaces.Thefirstisatthebeginningofeachlineandthesecondisattheendofthefile.Ourabstractclasscontainstwovirtualfunctionstohandlethesetwocases:virtualvoidline_start(void){};virtualvoideof(void){};};Unliketake_token,thesefunctionshavedefaultbodies-emptybodies,butbodiesjustthesame.Whatdoesthismean?Ourderivedclassesmustdefinetake_token.Theydon'thavetodefineline_startoreof.line_counterclassThesimpleststatisticwecollectisacountofthenumberoflinesprocessedsofar.Thiscountingisdonethroughtheline_counterclass.TheonlytokenitcaresaboutisT_NEW_LINE.Atthebeginningofeachlineitoutputsthelinenumber(thecurrentcountofthe T_NEW_LINEtokens).Attheendoffile,thisclassoutputsnothing.Asamatteroffact,theline_counterclassdoesn'tevendefineaneoffunction.Instead,weletthedefaultinthebaseclass(stat)dothe"work."Page462brace_counterclassThisclasskeepstrackofthenestinglevelofthecurlybraces{}.Wefeedtheclassastreamoftokensthroughthetake_tokenmemberfunction.Thisfunctionkeepstrackoftheleftandrightcurlybracesandignoreseverythingelse.//Consumetokens,countthenestingof{}voidbrace_counter::take_token(TOKEN_TYPEtoken)switch(token){caseT_L_CURLY:++cur_level;if(cur_level>max_level)max_level=cur_level;break;caseT_R_CURLY:--cur_level;break;default://Ignorebreak;}}Theresultsofthisstatisticareprintedintwoplaces.Thefirstisatthebeginningofeachline.Thesecondisattheendoffile.Wedefinetwomemberfunctionstoprintthesestatistics://Outputstartoflinestatistics//namelythecurrentlinenumbervoidbrace_counter::line_start(void){cout.setf(ios::left);cout.width(2);cout<<'{'<#include"ch_type.h"//Definethetypeinformationarraychar_type::CHAR_TYPEchar_type::type_info[256];********************************************************fill_range--fillinarangeoftypesforthe*Page466Example26-4.stat/chtypecc(Continued)*charactertypeclass* ***Parameters**start,end--rangeofitemstofillin**type--typetouseforfilling********************************************************/voidchar_type::fill_range(intstart,intend,CHARTYPEtype){intcur_ch;for(cur_ch=start;cur_ch<=end;++cur_ch){type_info[cur_ch]=type;}}/**********************************************************char_type::char_type--initializethechartypetable**********************************************************/char_type::char_type(){fill_range(0,255,C_WHITE);fill_range('A','Z',C_ALPHA);fill_range('a','z',C_ALPHA);type_info['_']=C_ALPHA;fill_range('0','9',C_DIGIT);type_info['!']=C_OPERATOR;type_info['#']=C_OPERATOR;type_info['$']=C_OPERATOR;type_info['%']=C_OPERATOR;type_info['^']=C_OPERATOR;type_info['&']=C_OPERATOR;type_info['*']=C_OPERATOR;type_info['-']=C_OPERATOR;type_info['+']=C_OPERATOR;type_info['=']=C_OPERATOR;type_info['|']=C_OPERATOR;type_info['~']=C_OPERATOR;type_info[',']=C_OPERATOR;type_info[':']=C_OPERATOR;type_info['?']=C_OPERATOR;type_info['.']=C_OPERATOR;type_info['<']=C_OPERATOR;type_info['>']=C_OPERATOR;type_info['/']=C_SLASH;type_info[' ']=C_NEWLINE;type_info['(']=C_L_PAREN;type_info[')']=C_R_PAREN;Page467Example26-4.stat/ch_type.cc(Continued)type_info['{']=C_L_CURLY; type_info['}']=C_R_CURLY;type_info['"']=C_DOUBLE;type_info[''']=C_SINGLE;}intchar_type::is(intch,CHAR_TYPEkind){if(ch==EOF)return(kind==C_EOF);switch(kind){caseC_HEX_DIGIT:if(type_info[ch]==C_DIGIT)return(1);if((ch>='A')&&(ch<='F'))return(1);if((ch>='a')&&(ch<='f'))return(1);return(0);caseC_ALPHA_NUMERIC:return((type_info[ch]==C_ALPHA)||(type_info[ch]==C_DIGIT));default:return(type_info[ch]==kind);}};char_type::CHAR_TYPEchar_type::type(intch)if(ch==EOF)return(C_EOF);return(type_info[ch]);}Thetoken.fileExample26-5.stat/token.h/*********************************************************token--tokenhandlingmodule****Functions:**next_token--getthenexttokenfromtheinput*********************************************************//**Alistoftokens*Note,howthislistisuseddependsondefiningthemacroT.*Thismacroisusedfordefiningthetokenstypesthemselves*aswellasthestringversionofthetokens.*/#defineTOKEN_LISTPage468Example26-5.stat/token.h(Continued)T(T_NUMBER),/*Simplenumber(floatingpointorinteger)*/T(T_STRING),/*Stringorcharacterconstant*/ T(T_COMMENT),/*Comment*/T(T_NEWLINE),/*Newlinecharacter*/T(TOPERATOR),/*Arithmeticoperator*/T(T_L_PAREN),/*Character"("*/T(T_R_PAREN),/*Character")*/T(T_L_CURLY),/*Character"{"*/T(T_R_CURLY),/*Character"}"*/T(T_ID),/*Identifier*/T(T_EOF)/*EndofFile*//**Definetheenumeratedlistoftokens.*ThismakesuseofatrickusingtheTmacro*andourTOKEN_LIST*/#defineT(x)x//DefineT()asthenameenumTOKEN_TYPE{TOKENLIST};#undefT//Removeoldtemporarymacro//Alistofthenamesofthetokensexternconstchar*constTOKEN_NAMES[];constintLINE_MAX=500;//Longestpossibleline/********************************************************input_file--datafromtheinputfile****Thecurrenttwocharactersarestoredin**curcharandnext_char****Thememberfunctionread_charmoveseveryoneup**onecharacter.****Thelineisbufferedandoutputeverytimeanewline**ispassed.*********************************************************/classinput_file:publicifstream{private:charline[LINE_MAX];//Currentlinechar*char_ptr;//Currentcharacteronthelinepublic:intcur_char;//Currentcharacter(canbeEOF)intnext_char;//Nextcharacter(canbeEOF)/**Initializetheinputfileandreadthefirst2*characters.*/Page469Example26-5.stat/token.h(Continued)input_file(constchar*constname):ifstream(name){ if(bad())return;cur_char=get();next_char=get();char_ptr=line;}/**Writethelinetothescreen*/voidflushline()*char_ptr='';cout<#include#include"ch_type.h"#include"token.h"/**Definethetokennamelist*ThismakesuseofatrickusingtheTmacro*andourTOKENLIST*/#defineT(x)#x//Definexasastringconstchar*constTOKEN_NAMES[]={TOKENLIST};#undefT//Removeoldtemporarymacrostaticchar_typechar_type;//Charactertypeinformation/********************************************************read_comment--readinacomment****Parameters**infile--filetoread****Returns**Tokenread.CanbeaT_COMMENTorTNEW_LINE**dependingonwhatweread.****Multi-linecommentsaresplitintomultiple**tokens.********************************************************/TOKEN_TYPEtoken::read_comment(input_file&in_file){Page471Example26-6stat/token.cc(Continued) if(in_file.cur_char==' '){in_file.read_char();return(T_NEWLINE);}while(1)in_comment=TRUE;if(in_file.cur_char==EOF)cerr<<"Error:EOFinsidecomment ";return(T_EOF);}if(in_file.cur_char==' ')return(T_COMMENT);if((in_file.cur_char=='*')&&(in_file.next_char=='/'))in_comment=FALSE;//Skippasttheending*/in_file.read_char();in_file.read_char();return(T_COMMENT);}in_file.read_char();}}/*********************************************************next_token--readthenexttokeninaninputstream****Parameters**infile--filetoread****Returns**nexttoken*********************************************************TOKEN_TYPEtoken::next_token(input_file&in_file){if(need_to_readone)in_file.read_char();need_to_read_one=0;if(in_comment)return(read_comment(in_file));while(char_type.is(in_file.cur_char,char_type::C_WHITE)){in_file.read_char();}if(in_file.cur_char==EOF)return(T_EOF);switch(char_type.type(in_file.cur_char)){casechar_type::C_NEWLINE:in_file.read_char();Page472Example26-6stat/token.cc(Continued) return(TNEWLINE);casechar_type::C_ALPHA:while(chartype.is(in_file.cur_char,char_type::C_ALPHA_NUMERIC))in_file.read_char();return(TID);casechar_type::C_DIGIT:in_file.read_char();if((in_file.cur_char=='X')||(in_file.cur_char=='x')){in_file.read_char();while(char_type.is(in_file.cur_char,char_type::C_HEX_in_file.read_char();return(T_NUMBER);}while(char_type.is(in_file.cur_char,char_type::CDIGIT))in_file.read_char();return(T_NUMBER);casechar_type::C_SLASH://Checkfor/*charactersif(in_file.next_char=='*'){return(read_comment(in_file));}//Nowcheckfordoubleslashcommentsif(in_file.next_char=='/')while(1){//Commentstartingwith//andendingwithEOFislegaif(in_file.cur_char==EOF)return(T_COMMENT);if(in_file.cur_char==' ')return(T_COMMENT);in_file.read_char();}}//Fallthroughcasechar_type::C_OPERATOR:in_file.read_char();return(TOPERATOR);casechar_type::C_L_PAREN:in_file.read_char();return(T_L_PAREN);casechar_type::C_R_PAREN:in_file.readchar();return(TR_PAREN);casechar_type::C_L_CURLY:in_file.read_char();return(T_L_CURLY);casechar_type::C_R_CURLY:in_file.readchar();return(TR_CURLY);casechar_type::C_DOUBLE:while(1){in_file.read_char();Page473 Example26-6.stat/token.cc(Continued)//Checkforendofstringif(in_file.cur_char=='"')break;//Escapecharacter,thenskipthenextcharacterif(in_file.cur_char=='\')in_file.read_char();}in_file.read_char();return(T_STRING);casechar_type::C_SINGLE:while(1){in_file.read_char();//Checkforendofcharacterif(in_file.cur_char=='')break;//Escapecharacter,thenskipthenextcharacterif(in_file.cur_char=='\')in_file.read_char();}in_file.read_char();return(T_STRING);default:cerr<<"Internalerror:Verystrangecharacter ";abort();}cerr<<"Internalerror:Weshouldnevergethere ";abort();return(T_EOF);//Shouldnevergethereeither}Thestat.ccfileExample26-7stat/stat.cc/***********************************************************stat**Producestatisticsaboutaprogram****Usage:**stat[options]*************************************************************/#include#include#include#include#include#include"chtype.h"#include"token.h"Page474 Example26-7.stat/stat.cc(Continued)/***********************************************************stat--generalpurposestatistic****Memberfunctions:**take_token--receivestokenandusesitto**computestatistic**line_start--outputstatatthebeginningof**aline**eof--outputstatattheendofthefile***********************************************************/classstat{public:virtualvoidtake_token(TOKEN_TYPEtoken)=0;virtualvoidline_start(void){};virtualvoideof(void){};//Defaultconstructor//Defaultdestructor//Copyconstructordefaultsaswell(probablynotused)};/*********************************************************line_counter--handlelinenumber/linecount**stat.****CountsthenumberofT_NEW_LINEtokensseenand**outputsthecurrentlinenumberatthebeginning**oftheline.****AtEOFitwilloutputthetotalnumberoflines*********************************************************/classline_counter:publicstat{private:intcur_line;//Linenumberforthecurrentlinepublic://Initializethelinecounter--tozeroline_counter(void){cur_line=0;};//Defaultdestructor//Defaultcopyconstructor(probablynevercalled)//Consumetokens,countthenumberofnewlinetokensvoidtake_token(TOKEN_TYPEtoken)if(token==T_NEWLINE)++cur_line;}//Outputstartoflinestatistics//namelythecurrentline_numbervoidline_start(void){cout<max_level)max_level=cur_level;break;caseT_R_PAREN:--cur_level;break;default://Ignorebreak;}}}//Outputstartoflinestatistics//namelythecurrentlinenumbervoidline_start(void){cout.setf(ios::left);Page476 Example26-7.stat/stat.cc(Continued)cout.width(2);cout<<'('<max_level)max_level=cur_level;break;caseT_R_CURLY:--cur_level;break;default:Page477 Example26-7stat/stat.cc(Continued)//Ignorebreak;}}//Outputstartoflinestatistics//namelythecurrentlinenumbervoidline_start(void){cout.setf(ios::left);cout.width(2);cout<<'{'<take_token(cur_token);#ifdefDEBUGcout<<""<line_start();in_file.flush_line();break;caseTEOF:for(cur_stat=stat_list;*cur_stat!=NULL;++cur_stat)(*cur_stat)->eof();return;default://Donothingbreak;}}}Page480 Example26—7.stat/statcc(Continued)main(intargc,char*argv[]){char*prog_name=argv[0];//Nameoftheprogramif(argc==1)cerr<<"Usageis"< ";exit(8);}for(/*argcset*/;argc>1;--argc)do_file(argv[1]);++argv;}return(0);}UNIXMakefileforCC(GenericUnix)Example26-8stat/makefile.unx##MakefileformanyUNIXcompilersusingthe#"standard"commandnameCC#CC=CCCFLAGS=-gOBJS=stat.och_type.otoken.oall:stat.outstatstat.out:statstat../calc3/calc3.cc>stat.outstat:$(OBJS)$(CC)$(CCFLAGS)-ostat$(OBJS)stat.o:stat.cctoken.h$(CC)$(CCFLAGS)-cstat.ccch_type.o:ch_type.ccch_type.h$(CC)$(CCFLAGS)-cch_type.cctoken.o:token.cctoken.hch_type.h$(CC)$(CCFLAGS)-ctoken.ccclean:rmstatstat.och_type.otoken.oPage481UNIXMakefileforg++Example26-9.stat/makefile.gnu ##MakefilefortheFreeSoftwareFoundation'sg++compiler#CC=g++CFLAGS=-g-WallOBJS=stat.och_type.otoken.oall:stat.outstatstat.out:statstat../calc3/calc3.cc>stat.outstat:$(OBJS)$(CC)$(CCFLAGS)-ostat$(OBJS)stat.o:stat.cctoken.h$(CC)$(CCFLAGS)-cstat.ccch_type.o:ch_type.ccch_type.h$(CC)$(CCFLAGS)-cch_type.cctoken.o:token.cctoken.hchtype.h$(CC)$(CCFLAGS)-ctoken.ccclean:rmstatstat.och_type.otoken.oTurboC++MakefileExample26-10.stat/makefile.tcc##MakefileforBorland'sTurbo-C++compiler#CC=tcc##Flags#-N--Checkforstackoverflow#-v--Enabledebugging#-w--Turnonallwarnings#-ml--Largemodel#CFLAGS=-N-v-w-mlOBJS=stat.objch_type.objtoken.objall:stat.outstat.exestat.out:stat.exePage482Example26-10.stat/makefile.tcc(Continued)stat..calc3calc3.cpp>stat.out stat.exe:$(OBJS)$(CC)$(CCFLAGS)-estat$(OBJS)stat.obj:stat.cpptoken.h$(CC)$(CCFLAGS)-cstat.cppch_type.obj:ch_type.cppch_type.h$(CC)$(CCFLAGS)-cch_type.cpptoken.obj:token.cpptoken.hch_type.h$(CC)$(CCFLAGS)-ctoken.cppclean:erasestat.exestat.objch_type.objtoken.objBorland-C++MakefileExample26-11stat/makefile.bcc##MakefileforBorland'sBorland-C++compiler#CC=bcc##Flags#-N--Checkforstackoverflow#-v--Enabledebugging#-w--Turnonallwarnings#-ml--Largemodel#CFLAGS=-N-v-w-mlOBJS=stat.objch_type.objtoken.objall:stat.outstat.exestat.out:stat.exestat..calc3calc3.cpp>stat.outstat.exe:$(OBJS)$(CC)$(CCFLAGS)-estat$(OBJS)stat.obj:stat.cpptoken.h$(CC)$(CCFLAGS)-cstat.cppch_type.obj:ch_type.cppch_type.h$(CC)$(CCFLAGS)-cch_type.cpptoken.obj:token.cpptoken.hch_type.h$(CC)$(CCFLAGS)-ctoken.cppPage483Example26-11stat/makefile.bcc(Continued)clean: erasestat.exestat.objch_type.objtoken.objMicrosoftVisualC++MakefileExample26-12stat/makefile.msc##MakefileforMicrosoftVisualC++#CC=cl##Flags#AL--Compileforlargemodel#Zi--Enabledebugging#W1--Turnonwarnings#CFLAGS=/AL/Zi/W1OBJS=stat.objch_type.objtoken.objall:stat.outstat.exestat.out:stat.exestat..calc3calc3.cpp>stat.outstat.exe:$(OBJS)$(CC)$(CCFLAGS)$(OBJS)stat.obj:stat.cpptoken.h$(CC)$(CCFLAGS)-cstat.cppch_type.obj:ch_type.cppch_type.h$(CC)$(CCFLAGS)-cch_type.cpptoken.obj:token.cpptoken.hch_type.h$(CC)$(CCFLAGS)-ctoken.cppclean:erasestat.exestat.objch_type.objtoken.objProgrammingExercisesExercise26-1:Writeaprogramthatchecksatextfilefordoubledwords.Exercise26-2:Writeaprogramthatremovesfour-letterwordsfromafileandreplacesthemwithmoreacceptableequivalents.Page484Exercise26-3:Writeamailinglistprogram.Thisprogramwillread,write,sortandprintmailinglabels.Exercise26-4:Updatethestatisticsprogrampresentedinthischaptertoaddacross-referencecapability.Exercise26-5:Writeaprogramthattakesatextfileandsplitseachlonglineintotwosmaller lines.Thesplitpointshouldbeattheendofasentenceifpossible,orattheendofawordifasentenceistoolong.Page48527FromCtoC++InThisChapter:·Overview·K&R-Functions·struct·mallocandfree·TurningStructuresintoClasses·setjmpandlongmp·Summary·ProgrammingExerciseNodistinctionsolittleexcitesenvlasthatwhichisderivedfromancestorsbyalongdescent.—FrançiosDeSalignacDeLaMotheFénclonOverviewC++wasbuiltontheolderlanguageC,andthere'salotofCcodestillaround.That'sbothablessingandacurse.It'sacursebecauseitmeansyou'llprobablyhavetodealwithalotofancientcode.Ontheotherhand,therewillalwaysbeworkforyou.ThischapterdescribessomeofthedifferencesbetweenCandC++aswellashowtomigratefromonetotheother.K&R-StyleFunctionsClassicC(alsocalledK&RCafteritsauthors,BrianKernighanandDennisRitchie)usesafunctionheaderthat'sdifferentfromtheoneusedinC++.InC++theparametertypesandnamesareincludedinsidethe()definingthefunction.InClassicC,onlythenamesappear.Typeinformationcomeslater:intdo_it(char*name,intfunction)//C++functiondefinition{//Bodyofthefunctionintdo_it(name,function)//ClassicCdefinitionchar*name;intfunction;{//Bodyofthefunction Page486WhenC++camealong,theANSICcommitteedecideditwouldbeagoodideaifCusedthenewfunctiondefinitions.However,becausetherewasalotofcodeoutthereusingtheoldmethod,C++acceptsbothtypesoffunctions.ClassicCdoesnotrequireprototypes.Inmanycases,prototypesaremissingfromCprograms.Afunctionthatdoesnothaveaprototypehasanimpliedprototypeof:intfunct(...);//DefaultprototypeforClassicCfunctionsAlso,ClassicCprototypeshavenoparameterlists.Theymerelyconsistof''(),"suchasintdo_it();//ClassicCfunctionprototypeThistellsCthatdo_itreturnsanintandtakesanynumberofparameters.Cdoesnottype-checkparameters,sothefollowingarelegalcallstodo_it:i=do_it();i=doit(1,2,3);i=do_it("Test",'a');C++requiresfunctionprototypes,soyouhavetoputthemin.TherearetoolsouttheresuchastheGNUprototizeutilitythathelpyoubyreadingyourcodeandgeneratingfunctionprototypes.Otherwise,youwillhavetodoitmanually.structInC++,whenyoudeclareastruct,youcanusethestructureasatypename.Forexample:structsample{inti,j;//Dataforthesample};samplesample_var;//LastsampleseenCismorestrict.Youmustputthekeywordstructbeforeeachvariabledeclaration:structsamplesample_var;//LegalinCsamplesample_var;//IllegalinCmallocandfreeInC++,youusethenewoperatortogetmemoryfromtheheapandusedeletetoreturnthememory.Chasnobuilt-inmemory-handlingoperations.Instead,itmakesuseoftwolibraryroutines:mallocandfree.Thefunctionmalloctakesasingleparameter—thenumberofbytestoallocate—andreturnsapointertothem(asachar*orvoid*).ButhowdoweknowPage487howbigastructureis?That'swherethesizeofoperatorcomesin.Itreturnsthenumberofbytesinthestructure.Sotoallocateanewvariableoftypestructfooweusethecode: foo_var=(structfoo*)malloc(sizeof(structfoo));Notethatwemustuseacasttoturnthepointerreturnedbymallocintosomethinguseful.TheC++syntaxforthesameoperatorismuchcleaner:foo_var=newfoo;Supposewewanttoallocateanarrayofthreestructures.Thenweneedtomultiplyourallocationsizeby3,resultingin:foo_var=(structfoo*)malloc(sizeof(structfoo)*3);TheC++equivalentis:foo_var=newfoo[3];Thefunctioncallocissimilartomallocexceptthatittakestwoparameters:thenumberofelementsinthearrayofobjectsandthesizeofasingleelement.Usingourarrayofthreefoosexample,weget:foo_var=(structfoo*)calloc(3,sizeof(foo));Theotherdifferenceisthatcallocinitializesthestructuretozero.ThustheC++equivalentis:foo_var=newfoo[3];memset(foo_var,'',sizeof(foo)*3);ProgramscanfreelymixC-stylemallocsandC++newcalls.TheCmemoryallocatorsaremessy,however,andshouldbeconvertedtoC++wheneverpossible.ThereareanumberoftrapsconcerningC-stylememoryallocation.Supposewetakeourstructurefooandturnitintoaclass.Wecanbutshouldn'tusetheCmemoryroutinestoallocatespacefortheclass:classfoo{...};foo_var=(structfoo*)malloc(sizeof(structfoo));//Don'tcodelikethisBecauseC++treatsstructasaspecialformofclassmostcompilerswon'tcomplainaboutthiscode.Theproblemisthatourmallocstatementallocatesspaceforfooandthat'sall.Noconstructoriscalled,soit'squitepossiblethattheclasswillnotgetsetupcorrectly.Cusesthefunctionfreetoreturnmemorytotheheap.Thefunctionfreetakesasinglecharacterpointerasaparameter(thusmakingalotofcastingnecessary):free((char*)foo_var);foo_var=NULL;Page488InC++thiswouldbe:deletefoovar;foo_var=NULL; forasimplevariableand:delete[]foo_array;foo_array=NULL;whenfoo_arraypointstoanarray.Again,youmustbecarefulwhenturningfoointoaclass.Thefreefunctionjustreturnsthememorytotheheap.Itdoesnotcallthedestructorforfoo.C-stylememoryallocationismessyandrisky.WhenconvertingtoC++youprobablyshouldgetridofallmalloc,calloc,andfreecallswheneverpossible.WARNINGAccordingtotheANSICdraftstandard,memoryallocatedbymallocmustbedeallocatedbyfree.Similarly,memoryallocatedbynewmustbedeallocatedbydelete.However,mostofthecompilersI'veseenimplementnewasacalltomallocanddeleteasacalltofree.Inotherwords,mixingnew/freeormalloc/freecallswillusuallywork.Toavoiderrors,youshouldfollowtherulesandavoidmixingCandC++operations.TurningStructuresintoClassesFrequentlywhenexaminingCcodeyoumayfindanumberofstructstatementsthatlookliketheyshouldbeclasses.Actually,astructureisreallyjustadata-onlyclasswithallthememberspublic.Cprogrammersfrequentlytakeadvantageofthefactthatastructureonlycontainsdata.Oneexampleofthisisreadingandwritingastructuretoabinaryfile.Forexample:a_structstruct_var;//Astructurevariable//Performarawreadtoreadinthestructureread_size=read(fd,(char*)&struct_var,sizeof(struct_var));//Performarawwritetosendthedatatoafilewrite_size=write(fd,(char*)&struct_var,sizeof(struct_var));Turningthisstructureintoaclasscancauseproblems.C++keepsextrainformation,suchasvirtualfunctionpointers,inaclass.Whenyouwritetheclasstodiskusingarawwrite,youareoutputtingallthatinformation.What'sworse,whenyoureadtheclassinyouoverwritethisbookkeepingdata.Page489Forexample,supposewehavetheclass:classsample{public:constintsample_size;//Numberofsamplesintcur_sample;//Currentsamplenumbersample(void):sample_size(100){}//Setupclass virtualvoidget_sample();//Routinetogetasample};Internally,thisclassconsistsofthreemembervariables:aconstant,sample_size(whichC++won'tallowyoutochange);asimplevariable,cur_sample;andapointertotherealfunctiontobeusedwhenget_sampleiscalled.Allthreeofthesearewrittentodiskbythecall:samplea_sample;//...write_size=write(fd,(char*)&a_sample,sizeof(a_sample));Whenthisclassisread,allthreemembersarechanged.Thatincludestheconstant(whichwearen'tsupposedtochange)andthefunctionpointer(whichnowprobablypointstosomethingstrange).Cprogrammersalsomakeuseofthememsetfunctiontosetallthemembersofastructuretozero.Forexample:structa_struct{...}a_structstruct_var;//...memset(&struct_var,'',sizeof(struct_var));Again,becarefulwhenturningastructureintoaclass.Ifwehadusedtheclassa_sampleinsteadofthestructurestruct_var,wewouldhavezeroedtheconstantsample_sizeaswellasthevirtualfunctionpointer.Theresultwouldprobablybeacrashifweevertriedtocallget_sample.setjmpandlongjmpChasitsownwayofhandlingexceptionsthroughtheuseofsetjmpandlongjmp.Thesetjmpfunctionmarksaplaceinaprogram.Thelongjmpfunctionjumpstotheplacemarkedbysetjmp.Normallysetjmpreturnsazero.Thistellstheprogramtoexecutenormalcode.Whenanexceptionoccurs,thelongjmpcallreturnstothelocationofthesetjmpfunction.Theonlydifferencetheprogramcanseebetweenarealsetjmpcallandafakesetjmpcallcausedbyalongjmpisthatanormallysetjmpreturnsazero.Whensetjmpis"called"bylongjmp,thereturnvalueiscontrolledbyaparametertolongjmp.Page490Thedefinitionofthesetjmpfunctionis:#includeintsetjmp(jmp_bufenv);where:envistheplacewheresetjmpsavesthecurrentenvironmentforlaterusebylongjmp Returns0NormalcallNonzeroNon-zeroreturncodesaretheresultofalongjmpcall.Thedefinitionofthelongjmpcallis:voidlongjmp(jmp_bufenv,intreturn_code);where:envistheenvironmentinitializedbyaprevioussetjmpcallreturn_codeisthereturncodethatwillbereturnedbythesetjmpcallFigure27-1illustratesthecontrolflowwhenusingsetjmpandlongjmpThereisoneproblemhere,however.Thelongjmpcallreturnscontroltothecorrespondingsetjmp.Itdoesnotcallthedestructorsofanyclassesthatare"destroyed"intheprocess.InFigure27-1wecanseethatinthesubroutinewedefineaclassnameda_list.Normallywewouldcallthedestructorfora_listattheendofthefunctionoratareturnstatement.However,inthiscaseweuselongjmptoexitthefunction.SincelongjmpisaCfunctionitknowsnothingaboutclassesanddestructorsanddoesnotcallthedestructorfora_list.Sowenowhaveasituationwhereavariablehasdisappearedbutthedestructorhasnotbeencalled.Thetechnicalnameforthissituationisa"foul-up."WhenconvertingCtoC++,changeallsetjmp/longjmpcombinationsintoexceptions.Page491 Figure27-1.setjmp/longjmpcontrolflowSummaryWhatyoumustdotogetCtocompilewithaC++compiler:1.ChangeK&R-stylefunctionheadersintostandardC++headers.2.Addprototypes.3.Changesetjmp/longjmpcallsintocatch/throwoperations.FollowingthesethreestepsyouhaveaC+½program.Itworks,butit'sreallyaCprograminC++'sclothing.ToconvertittoarealC++programyouneedtodothefollowing:4.Changemallocintonew.5.Changefreeintodeleteordelete[]calls.6.Turnprintfandscanfcallsintocoutandcin.7.Whenturningstructdeclarationsintoclassvariables,becarefulofread,write,andmemsetfunctionsthatusetheentirestructureorclass.ProgrammingExerciseExercise27-1:TherearealotofCprogramsoutthere.TurnoneintoC++.Page49328 C++'sDustierCornersInThisChapter:·do/while·goto·The?:Construct·TheCommaOperator·Overloadingthe()Operator·PointerstoMembers·VampireFeatures·AnswerstoChapterQuestionsTherebeofthemthathaveleftanamebehindthem.—EcclesiasticusXLIV,1ThischapterdescribesthefewremainingfeaturesofC++thatarenotdescribedinanyofthepreviouschapters.ItistitledC++'sDustierCornersbecausethesestatementsarehardlyeverusedinrealprogramming.do/whileThedo/whilestatementhasthefollowingsyntax:do{statement;statement;}while(expression);Theprogramloops,teststheexpression,andstopsiftheexpressionisfalse(0).NOTEThisconstructalwaysexecutesatleastonce.do/whileisnotfrequentlyusedinC++becausemostprogrammersprefertouseawhile/breakcombination.gotoAllthesampleprogramsinthisbookwerecodedwithoutusingasinglegoto.InactualpracticeIfindIuseagotostatementaboutonceeveryotheryear.Forthoseraretimesthatagotoisnecessary,itssyntaxis:gotolabel;Page494 wherelabelisastatementlabel.Statementlabelsfollowthesamenamingconventionasvariablenames.Labelingastatementisdoneasfollows:label:statement;Forexample:for(x=0;x#includemain(){charline[10];while(1){cout<<"Enteradd(a),delete(d),quit(q):";cin.getline(line,sizeof(line));switch(line[0]){case'a':cout<<"Add ";break;case'd':cout<<"Delete ";break;case'q':cout<<"Quit ";exit(0);defualt:cout<*data_ptr<<' ';Thesyntaxforpointerstomembersisalittleconvolutedandnotterriblyuseful.I'veonlyseenitusedoncebyanextremelycleverprogrammer.(Thefirstmaintenanceprogrammerwhogotthecodeimmediatelyrippeditoutanyway.)VampireFeaturesThissectiondiscussesfeaturesthathavebeendefinedinthedraftC++standard*buthavenotyetbeenimplementedinanyofthecurrentlyavailablecompilers.**''Vampirefeatures"arethosefeaturesofalanguagethathaveyettoseethelightofday.BecauseI'vebeenunabletoactuallyusethesefeatures,theinformationpresentedhereisabitsketchy.boolBooleantypethatcanbeeithertrueorfalseconst_castAnewversionofacastthatmakestheresultconstantdynamic_castAnewcastingoperatorthatmakesuseofruntime-typeinformationtoallowsafecastingbetweentypesfalseNewconstantforusewiththebooltypemutableModifierthatindicatesthatamemberofaconstantinstanceofaclasscanbechangednamespaceThiskeywordallowstheprogrammertobetterdivideuptheprogramintodifferentnamespacesorsortsofmodulesreinterpret_castAcastthathelpstheprogrammersafelycastfromabaseclasstoaderivedclass*WorkingPaperforDraftProposedInternationalStandardforinformationSystems—ProgrammingLanguageC++(20September1994),AmericanNationalStandardsInstitute.**Turbo-C++,BorlandC++Version45,SunProCCVersion4.0,g++Version2.5.8Page498static_castAnothernewcastingoperatortrueNewconstantforusewiththebooltypetypeidAllowstheprogrammertogettypeinformationfrominsidetheprogramatruntime NOTEManyheaderfilesdefinemacrosfor"bool,""true,"and"false."Thisdoesnotpresentaproblemwithcompilersthathavenotyetimplementedthebooltype.However,assoonasthecompilermakerscatchupwiththestandard,suchmacroswillcauseproblems.AnswerstoChapterQuestionsAnswer28-1:Thecompilerdidn'tseeourdefaultlinebecausewemisspelled"default"as"defualt."Thiswasnotflaggedasanerrorbecause"defualt"isavalidgotolabel.That'swhywhenwecompiletheprogramwegetthewarning:def.c(26):warning:defualtunusedinfunctionmainwhichmeanswedefinedalabelforagoto,butneverusedit.Page49929ProgrammingAdagesInThisChapter:·General·Design·Declarations·switchStatement·Preprocessor·Style·Compiling·TheTenCommand-mentsforC++Programmers·FinalNote·AnswerstoChapterQuestionsSecondthoughtsareeverwiser—EuripidesGeneral·Comment,comment,comment.Putalotofcommentsinyourprogram.Theytellotherprogrammerswhatyoudid.Theyalsotellyouwhatyoudid. ·Usethe"KISS"principle(KeepItSimple,Stupid).Clearandsimpleisbetterthancomplexandwonderful.·Avoidsideeffects.Use++and--onlinesbythemselves.·Neverputanassignmentinsideaconditional.Neverputanassignmentinsideanyotherstatement.·Knowthedifferencebetween=and==.Using=for==isaverycommonmistakeandisdifficulttofind.·Neverdo"nothing"silently.//Don'tprogramlikethisfor(index=0;data[index] main(){intnumber;cout<<"Enteranumber:";cin>>number;if(number=!2)cout<<"Numberisnottwo ";elsecout<<"Numberistwo ";return(0);}Page503AnswerstoChapterQuestionsAnswer29-1:Thestatement(number=!2)isnotarelationalequation,butanassignmentstatement.Itisequivalentto:number=(!2);(Because2isnonzero,!2iszero.)Theprogrammeraccidentlyreversedthenotequals!=soitbecame=!.Thestatementshouldread:if(number!=2)Page505VIAppendixesPage507AASCIITableTableA-1.ASCIICharacterChartDec.Oct.Hex.Char.Dec.Oct.Hex.Char.000000NUL2302717ETB 100101SOH2403018CAN200202STX2503119EM300303ETX260321ASUB400404EOT27033BESC500505ENQ28034CFS600606ACK290351DGS700707BEL30036ERS801008BS310371FUS901109HT3204020SP10012OANL3304121'11013OBVT3404222"120140CNP3504323#130150DCR3604424$140160ESO3704525%150170FSI3804626&1602010DLE3904727.1702111DC14005028(1802212DC24105129)1902313DC3420522A*2002414DC4430532B+2102515NAK440542C'2202616SYN450552D-Page508TableA-1.ASCIICharacterChart(Continued)Dec.Oct.Hex.Char.Dec.Oct.Hex.Char.460562E.8212252R470572F/8312353S 480603008412454T490613118512555U500623228612656V510633338712757W520643448813058X530653558913159Y54066366901325AZ55067377911335B[56070388921345C57071399931355D]580723A:941365EA590733B;951375F_600743C<9614060'610753D=9714161a620763E>9814262b630773F?9914363c6410040@10014464d6510141A10114565e6610242B10214666f6710343C10314767g6810444D10415068h6910545E10515169i7010646F1061526Aj7110747G1071536Bk7211048H1081546C17311149I1091556Dm741124AJ1101566En751134BK1111576Fo761144CL11216070p 771154DM11316171q781164EN11416272r791174FO11516373s8012050P11616474t8112151Q11716575uPage509TableA-1.ASCIICharacterChart(Continued)Dec.Oct.Hex.Char.11816676v11916777w12017078x12117179y1221727Az1231737B{1241747C|1251757D}1261767E~1271777FDELPage511BRangesTablesB-1andB-2listtherangesofvariousvariabletypes.TableB-1.32-bitUNIXMachineNameBitsLowValueHighValueAccuracyint32-2,147,483,6482,147,483,647 int32-2,147,483,6482,147,483,647shortint16-32,76832,767longint32-2,147,483,6482,147,483,647unsignedint3204,294,967,295unsignedshortint16065,535unsignedlongint3204,294,967,295char8SystemDependentunsignedchar80255float32-3.4E+383.4E+386digitsdouble64-1.7E+3081.7E+30815digitslongdouble64-1.7E+3081.7E+30815digitsTableB-2Turbo-C++,BorlandC++,andMostOther16-bitSystemsNameBitsLowValueHighValueAccuracyint16-32,76832,767shortint16-32,76832,767longint32-2,147,483,6482,147,483,647unsignedint16065,535Page512TableB-2.Turbo-C++,BorlandC++,andMostOther16-bitSystems(Continued)NameBitsLowValueHighValueAccuracyunsignedshortint16065,535unsignedlongint3204,294,967,295char8-128127unsignedchar80255float32-3.4E+383.4E+386digitsdouble64-1.7E+3081.7E+30815digitslongdouble80-3.4E+49323.4E+493217digits Page513COperatorPrecedenceRulesPracticalSubsetoftheOperatorPrecedenceRulesTableC-1.PracticalOperatorPrecedenceRulesPrecedenceOperator1*(multiply)/%2+–Putparenthesesaroundeverythingelse.StandardRulesTableC-2.StandardC++PrecedenceRulesPrecedenceOperators1()[]->.::::*->*.*2!~++--(type)-(unary)*(de-reference)&(addressof)sizeof3*(multiply)/%4+-5<<>>6<<=>>=7==!=8&(bitwiseAND)Page514TableC-2.StandardC++PrecedenceRules(Continued) TableC-2.StandardC++PrecedenceRules(Continued)PrecedenceOperators9^10|11&&12||13?:14=+=-=etc.15,Page515DComputingsineUsingaPowerSeriesThisprogramisdesignedtocomputethesinefunctionusingapowerseries.Averylimitedfloating-pointformatisusedtodemonstratesomeoftheproblemsthatcanoccurwhenusingfloatingpoint.Theprogramcomputeseachterminthepowerseriesanddisplaystheresult.Itcontinuescomputingtermsuntilthelasttermissosmallthatitdoesn'tcontributetothefinalresult.Forcomparisonpurposes,theresultofthelibraryfunctionsinisdisplayedaswellasthecomputedsine.Theprogramisinvokedby:sinevaluewherevalueisanangleinradians.Forexample,tocomputesin(0)weusethecommand:%sine0x**lO.OOOE+001!1.OOOE+00x**1/1!O.OOOE+001termcomputedsin(O.OOOE+00)=0.OOOE+00Actualsin(0)=0Andtocomputesin(p)weusethecommand:%sine3.141x**13.141E+001!1.OOOE+00x**1/1!3.141E+00 total3.141E+00x**33.099E+013!6.000E+00Page516x**3/3!5.165E+00total-2.024E+00x**53.057E+025!1.200E+02x**5/5!2.548E+00total5.239E-01x**73.016E+037!5.040E+03x**7/7!5.985E-01total-7.457E-02x**92.976E+049!3.629E+05x**9/9!8.201E-02total7.438E-03x**112.936E+0511!3.992E+07x**11/1!7.355E-03total8.300E-05x**132.897E+0613!6.227E+09x**13/13!4.652E-04total5.482E-04x**152.858E+0715!1.308E+12x**15/15!2.185E-05total5.263E-04x**172.819E+0817!3.557E+14x**17/17!7.927E-07total5.271E-04x**192.782E+0919!1.217E+17x**19/19!2.287E-08total5.271E-04x**212.744E+1021!5.109E+19x**21/21!5.371E-1011termcomputedsin(3.141E+00)=5.271E-04Actualsin(3.141)=0.000592654 Page517MakefileMakefileforUNIXExampleD-1.sin/Makefilesine:sine.ccg++-g-Wall-osinesine.cc-lmclean:rmsineMakefileforTurbo-C++[File:sin/Makefile.dos]##MakefileforBorland'sTurbo-C++compiler#CC=tcc##Flags#-N--Checkforstackoverflow#-v--Enabledebugging#-w--Turnonallwarnings#-ml--Largemodel#-A--ForceANSIcompliance#CFLAGS=-N-v-w-ml-A#sine.exe:sine.c$(CC)$(CFLAGS)-esinesine.cProgram:sine.ccExampleD-2.sine/sinecc/*********************************************************sine--computesineusingverysimplefloating**arithmetic****Usage:**sine****isanangleinradians****Formatusedinf.fffe+X****f.fffisa4-digitfraction**+isasign(+or-)**Xisasingle-digitexponent****sin(x)=x-x**3+x**5-x**7**-------------....**3!5!7!*** Page518ExampleD-2sine/sine.cc(Continued)*Warning:Thisprogramisintendedtoshowsomeof**problemswithfloatingpoint.Itisnot**intendedtobeusedtoproduceexactvaluesfor**thesinefunction.****Note:Eventhoughwespecifyonlyonedigitforthe**exponent,twoareusedforsomecalculations.**Thisisduetothefactthatprintfhasno**formatforasingle-digitexponent.*********************************************************/#include#include#include#includemain(intargc,char*argv[]){floattotal;//Totalofseriessofarfloatnew_total;//Newerversionoftotalfloatterm_top;//Toppartoftermfloatterm_bottom;//Bottomofcurrenttermfloatterm;//Currenttermfloatexp;//Exponentofcurrenttermfloatsign;//+1or-1(changesoneachterm)floatvalue;//Valueoftheargumenttosinintindex;//Indexforcountingtermschar*float_2_ascii(floatnumber);//TurnfloatingpointtoASCIIfloatfix_float(floatnumber);//Roundtocorrectdigitsfloatfactorial(floatnumber);//Computen!if(argc!=2){cerr<<"Usageis: ";cerr<<"sine ";exit(8);}value=fix_float(atof(&argv[1][0]));total=0.0;exp=1.0;sign=1.0;for(index=0;/*Takecareofbelow*/;++index)term_top=fix_float(pow(value,exp));term_bottom=fix_float(factorial(exp));term=fix_float(term_top/term_bottom);cout<Usedtoobtainamemberfromaclassorstructurepointer.->*Indicatestheitempointedtobya"pointertomember."/Symbolforthedivideoperator.Greater-thanrelationaloperator.>=Greater-than-or-equal-torelationaloperator.>>1.Symbolfortherightshiftoperator.2.Usedbytheiostreampackageforinput.'' End-of-stringcharacter(theNULLcharacter).#defineAC++preprocessordirectivethatdefinesasubstitutetextforaname.#endifTheclosingbrackettoapreprocessormacrosectionthatbeganwithan#ifdefdirective.#ifdefPreprocessordirectivethatcheckstoseewhetheramacronameisdefined.Ifdefined,thecodefollowingitisincludedinthesource.#ifndefPreprocessordirectivethatcheckstoseewhetheramacronameisundefined.Ifitiscurrentlyundefined,thecodefollowingisincludedinthemacroexpansion.#includeApreprocessordirectivethatcausesthenamedfiletobeinsertedinplaceofthe#include.#undefApreprocessordirectivethatcancelsa#define.Page523_ptrAconventionusedinthisbook.Allpointervariablesendwiththeextension_ptr.AabstractclassAclasscontainingoneormorepurevirtualfunctions.accuracyAquantitativemeasurementoftheerrorinherentintherepresentationofarealnumber.addressAvaluethatidentifiesastoragelocationinmemory.ANDABooleanoperationthatyields0ifeitheroperandis0and1ifbothoperandsare1.ANSICAnyversionofCthatconformstothespecificationsoftheAmericanNationalStandardsInstituteCommitteeX3J.ANSIC++AnyversionofC++thatconformstothespecificationsoftheAmericanNationalStandardsInstitute.Atthetimeofthiswriting,thestandardsexistonlyindraftformandtherearestillalotofdetailstobeworkedout.array Acollectionofdataelementsarrangedtobeindexedinoneormoredimensions.InC++,arraysarestoredincontiguousmemory.ASCIIAmericanStandardCodeforInformationInterchange.Acodetorepresentcharacters.assignmentstatementAnoperationthatstoresavalueinavariable.autoAC++keywordusedtocreatetemporaryvariables.automaticvariableSeetemporaryvariable.BbaseclassAclassthatisusedasthebaseforaderivedclass.bitBinarydigit;eitherofthedigits0or1.Page524bitfieldAgroupofcontiguousbitstakentogetherasaunit.ThisC++languagefeatureallowstheaccessofindividualbits.bitflipTheinversionofallbitsinanoperand.Seealsocomplement.bitoperatorSeebitwiseoperator.bitmappedgraphicsComputergraphicswhereeachpixelinthegraphicoutputdeviceiscontrolledbyasinglebitoragroupofbits.bitwiseoperatorAnoperatorthatperformsBooleanoperationsontwooperands,treatingeachbitinanoperandasindividualbitsandperformingtheoperationbitbybitoncorrespondingbits.blockAsectionofcodeenclosedincurlybraces.BorlandC++AversionoftheC++languageforpersonalcomputersdevelopedbyBorland.Thisisthehigh-endversionofBorland'sTurbo-C++product.boxing(acomment)Thetechniqueofusingacombinationofasterisks,verticalandhorizontalrules,andothertypographiccharacterstodrawaboxaroundacommentinordertosetitofffromthecode. breakAstatementthatterminatestheinnermostexecutionoffor,while,switch,anddo/whilestatements.breakpointAlocationinaprogramwherenormalexecutionissuspendedandcontrolisturnedovertothedebugger.bufferedI/OInput/outputwhereintermediatestorage(abuffer)isusedbetweenthesourceanddestinationofanI/Ostream.byteAgroupofeightbits.CCAgeneral-purposecomputerprogramminglanguagedevelopedin1974atBellLaboratoriesbyDennisRitchie.Cisconsideredtobeamedium-tohigh-levellanguage.Page525C++AlanguagebasedonCinventedin1980byBjarneStroustrup.Firstcalled''Cwithclasses,"ithasevolvedintoitsownlanguage.C++codeComputerinstructionswrittenintheC++language.C++compilerSoftwarethattranslatesC++sourcecodeintomachinecode.C++syntaxSeesyntax.callbyreferenceAparameter-passingmechanismwheretheactualparameterisnotpassedtoafunction,butinsteadapointerisusedtopointtoit.(Seealsocallbyvalue.)callbyvalueAprocedurecallwheretheparametersarepassedbypassingthevaluesoftheparameters.(Seealsocallbyreference.)caseActsasalabelforoneofthealternativesinaswitchstatement.castToconvertavariablefromonetypetoanothertypebyexplicitlyindicatingthetypeconversion.cerr StandarderrorstreamforC++.(CorrespondstoC'sstderr.)CFrontAprogramtotranslateC++codeintoCcode.ThisprogramwasthebasisforthefirstC++compilers.Currentlynotusedformostcompilers,asmanynativeC++compilersnowexist.CGAColorgraphicsadapter.AcommoncolorgraphicscardfortheIBMPC.charAC++keywordusedtodeclarevariablesthatrepresentcharactersorsmallintegers.cinCharacterin.StandardinputstreamforC++.(CorrespondstoC'sstdin.)classAdatastructureconsistingofdifferentdatatypes,protectionsforthemembers,andfunctionstomanipulatethem.Page526class(ofavariable)Seestorageclass.clearabitTheoperationofsettinganindividualbittozero.ThisisnotadefinedoperationinC++.clogStandardlogfileforC++.codedesignAdocumentthatdescribesingeneraltermshowtheprogramistoperformitsfunction.codingTheactofwritingaprograminacomputerlanguage.command-lineoptionsOptionstodirectthecourseofaprogram,suchasacompiler,thatareenteredfromthecomputerconsole.commentTextincludedinacomputerprogramforthesolepurposeofprovidinginformationabouttheprogram.Commentsareaprogrammer'snotestohimselfandfutureprogrammers.Thetextisignoredbythecompiler.commentblockAgroupofrelatedcommentsthatconveygeneralinformationaboutaprogramorasectionofprogram.compilationThetranslationofsourcecodeintomachinecode. compilerAsystemprogramthatdoescompilation.compilingSeecompilation.complementAnarithmeticorlogicaloperation.AlogicalcomplementisthesameasaninvertorNOToperation.computerlanguageSeeprogramminglanguage.conditionalcompilationTheabilitytoselectivelycompilepartsofaprogrambasedonthetruthofconditionstestedinconditionaldirectivesthatsurroundthecode.Page527continueAflowcontrolstatementthatcausesthenextexecutionofalooptobegin.controlstatementAstatementthatdetermineswhichstatementistobeexecutednextbasedonaconditionaltest.controlvariableAvariablethatissystematicallychangedduringtheexecutionoftheloop.Whenthevariablereachesapredeterminedvalue,theloopisterminated.conversionspecificationACstringusedbytheprintffamilyoffunctionsthatspecifieshowavariableistobeprinted.coutStandardoutputforC++programs.(CorrespondstoC'sstdout.)curlybracesOneofthecharacters{or}.TheyareusedinC++todelimitgroupsofelementstotreatthemasaunit.DdebuggingTheprocessoffindingandremovingerrorsfromaprogram.decisionstatementAstatementthattestsaconditioncreatedbyaprogramandchangestheflowoftheprogrambasedonthatdecision.declarationAspecificationofthetypeandnameofavariabletobeusedinaprogram. defaultServesasacaselabelifnocasevaluematchisfoundwithinthescopeofaswitch.definestatementSee#define.deleteAdirectivethatreturnsaclassorvariablecreatedbynewtotheheap.de-referencingoperatorTheoperatorthatindicatesaccesstothcvaluepointedtobyapointervariableoranaddressingexpression.Seealso*derivedclassAclassbuiltontopofanother,baseass.Page528directiveAcommandtothepreprocessor(asopposedtoastatementtoproducemachinecode).doubleAC++languagekeywordtodeclareavariablethatcontainsarealnumber.Thenumberusuallyrequirestwiceasmuchstorageastypefloat.doublelinkedlistAlinkedlistwithbothforwardandbackwardpointers.Seealsolinkedlist.doublequotationmarkASCIIcharacter34.UsedinC++todelimitcharacterstrings.EEGAEnhancedgraphicsadapter.AcommongraphicscardfortheIBMPC.elseAclauseinanifstatementspecifyingtheactiontotakeintheeventthatthestatementfollowingtheifconditionalisfalse.enumAC++keywordthatdefinesanenumerateddatatype.enumerateddatatypeAdatatypeconsistingofanamedsetofvalues.TheC++compilerassignsanintegertoeachmemberoftheset.EOFEnd-of-filecharacterdefinedinstdio.h.escapecharacterAspecialcharacterusedtochangethemeaningofthecharacter(s)thatfollow.ThisisrepresentedinC++bythebackslashcharacter,. exclusiveORABooleanoperationthatyields0ifbothoperandsarethesameand1iftheyaredifferent.executablefileAfilecontainingmachinecodethathasbeenlinkedandisreadytoberunonacomputer.exponentThecomponentofafloating-pointnumberthatrepresentstheintegerpowertowhichthenumberbaseisraisedinordertodeterminetherepresentednumber.exponentoverflowAconditionresultingfromafloating-pointoperationwheretheresultisanexponenttoolargetofitwithinthebitfieldallottedtotheexponent.Page529exponentunderflowAconditionresultingfromafloating-pointoperationwheretheresultisanexponenttoolargeinnegativevaluetofitwithinthebitfieldallottedtotheexponent.externC++keywordusedtoindicatethatavariableorfunctionisdefinedoutsidethecurrentfile.FfastprototypingAtop-downprogrammingtechniquethatconsistsofwritingthesmallestportionofaspecificationthatcanbeimplementedthatwillstilldosomething.fcloseAfunctionthatclosesafile.FromtheoldC-styleI/Opackagestdio.fflushAroutinetoforcetheflushingofabuffer.FromtheoldC-styleI/Opackagestdio.fgetcAfunctionthatreadsasinglecharacter.FromtheoldC-styleI/Opackagestdio.fgetsAstreaminputlibraryfunctionthatreadsasingleline.FromtheoldC-styleI/Opackagestdio.FILEAmacrodefinitioninstdiothatdeclaresafilevariable.FromtheoldC-styleI/Opackagestdio.fileAgroupofrelatedrecordstreatedasaunit.floatAC++keywordtodeclareavariablethatcanholdarealnumber.floatingpoint Anumberingsystemrepresentedbyafractionandanexponent.Thesystemhandlesverylargeandverysmallnumbers.floating-pointexception(coredumped)Anerrorcausedbyadivide-by-0orotherillegalarithmeticoperation.Itisasomewhatmisleadingerrorbecauseitiscausedbyintegeraswellasfloating-pointerrors.floating-pointhardwareCircuitrythatcanperformfloating-pointoperationsdirectlywithoutresortingPage530tosoftware.Inpersonalcomputers,itisfoundinthemathcoprocessor.Moreadvancedprocessorssuchasthe80486havefloating-pointunitsbuiltin.fopenAfunctionthatopensafileforstreamI/O.FromtheoldC-styleI/Opackagestdio.fprintfAfunctiontoconvertbinarydatatocharacterdataandwriteittoafile.FromtheoldC-styleI/Opackagestdio.fputcAfunctionthatwritesasinglecharacter.FromtheoldC-styleI/Opackagestdio.fputsAfunctionthatwritesasingleline.FromtheoldC-styleI/Opackagestdio.freadAbinaryI/Oinputfunction.FromtheoldC-styleI/Opackagestdio.freeACfunctionthatreturnsdatatothememorypool.ObsoleteinC++.ThishasbeenreplacedbytheC++deleteoperatorSeealsomalloc.FreeSoftwareFoundationAgroupofprogrammerswhocreateanddistributehigh-qualitysoftwareforfree.AmongtheirproductsaretheeditoremacsandtheC++compilerg++.Theiraddressis:FreeSoftwareFoundation,Inc.,675MassachusettsAve.,Cambridge,MA02139,(617)876-3296.friendAfunctionthatalthoughnotamemberofaclassisabletoaccesstheprivatemembersofthatclass.fscanfAninputroutinesimilartoscanf.FromtheoldC-styleI/Opackagestdio.fstream.hTheC++packageforfileI/O.functionAprocedurethatreturnsavalue. fwriteAbinaryI/Ooutputfunction.FromtheoldC-styleI/Opackagestdio.GgenericpointerApointerthatcanpointtoanyvariablewithoutrestrictionastotypeofvariable.Apointertostoragewithoutregardtocontent.Page531GhostscriptAPostscriptÔ-likeinterpreterthatisfreelyavailablefromtheFreeSoftwareFoundation.globalvariablesVariablesthatareknownthroughoutanentireprogram.guarddigitAnextradigitofprecisionusedinfloating-pointcalculationstoensureagainstlossofaccuracy.HheaderfileSeeincludefile.heapAportionofmemoryusedbynewtogetspaceforthestructuresandclassesreturnedbynew.Spaceisreturnedtothispoolbyusingthedeleteoperator.hexadecimalnumberAbase-16number.high-levellanguageAlevelofcomputerlanguagethatisbetweenmachinelanguageandnatural(human)language.II/OmanipulatorsFunctionsthatwhen"output"or"input"causenoI/O,butsetvariousconversionflagsorparameters.IEEEfloating-pointstandardIEEEstandard754,whichstandardizesfloating-pointformat,precision,andcertainnon-numericalvalues.ifAstatementthatallowsselectiveexecutionofpartsofaprogrambasedonthetruthofacondition. implementationdependenceThesituationwheretheresultobtainedfromtheoperationofcomputerorsoftwareisnotstandardizedbecauseofvariabilityamongcomputersystems.Aparticularoperationmayyielddifferentresultswhenrunonanothersystem.includefileAfilethatismergedwithsourcecodebyinvocationofthepreprocessordirective#include.Alsocalledaheaderfile.InclusiveORSeeOR.Page532indexAvalue,variable,orexpressionthatselectsaparticularelementofanarray.indirectoperatorSeede-referencingoperator.informationhidingAcodedesignsystemthattriestominimizetheamountofinformationpassedbetweenmodules.Theideaistokeepasmuchinformationaspossiblehiddeninsidethemodulesandmakeinformationpubliconlyifabsolutelynecessary.instructionAgroupofbitsorcharactersthatdefinesanoperationtobeperformedbythecomputer.intC++keywordfordeclaringaninteger.integerAwholenumber.interactivedebuggerAprogramthataidsinthedebuggingofprograms.invertoperatorAlogicaloperatorthatperformsaNOT.iostreamr.hStandardC++I/Opackage.LleftshiftTheoperationofmovingthebitsinabitfieldleftbyaspecifiedamountandfillingthevacatedpositionswithzeros.libraryAcollectionoffiles. linkedlistAcollectionofdatanodes.Eachnodeconsistsofavalueandapointertothenextiteminthelist.localincludefilesFilesfromaprivatelibrarythatcanbeinsertedbythepreprocessoratthedirective#include"filename".localvariableAvariablewhosescopeislimitedtotheblockinwhichitisdeclared.Page533logicalANDABooleanoperationthatreturnstrueifitstwoargumentsarebothtrue.Whenusedonintegers,eachbitisoperatedonseparately.logicaloperatorAC++operatorthatperformsalogicaloperationonitstwooperandsandreturnsatrueorafalsevalue.logicalORABooleanoperationthatreturnstrueifanyoneofitstwoargumentsistrue.Whenusedonintegers,eachbitisoperatedonseparately.longAqualifiertospecifyadatatypewithlongerthannormalaccuracy.MmachinecodeMachineinstructionsinabinaryformatthatcanberecognizeddirectlybythemachinewithoutfurthertranslation.machinelanguageSeemachinecode.macroAshortpieceoftext,ortexttemplate,thatcanbeexpandedintoalongertext.macroprocessorAprogramthatgeneratescodebyreplacingvaluesintopositionsinadefinedtemplate.magnitude(ofanumber)Thevalueofanumberwithoutregardtosign.maintenance(ofaprogram)Modificationofaprogrambecauseofchangingconditionsexternaltothecomputersystem.makeAutilityofbothUNIXandMS-DOS/Windowsthatmanagesthecompilationofprograms. MakefileThefilethatcontainsthecommandsfortheutilitymake.mallocACprocedurethatmanagesamemoryheap.Thisfunctionisnowobsolete.TheC++operatornewsupersedesthisfunction.maskApatternofbitsforcontrollingtheretentionoreliminationofanothergroupofbits.Page534memberAnelementofaclassorstructure.moduleOnelogicalpartofaprogram.MS-DOSAnoperatingsystemforIBMpersonalcomputersdevelopedbyMicrosoft.NnewC++operatortogetanewvariablefromtheheap.new-linecharacterAcharacterthatcausesanoutputdevicetogotothebeginningofanewline.nonsignificantdigitsLeadingdigitsthatdonotaffectthevalueofanumber(0sforapositivenumber,Isforanegativenumberincomplementform).normalizationTheshiftingofafloating-pointfraction(andadjustmentoftheexponent)sotherearenoleadingnonsignificantdigitsinthefraction.NOTABooleanoperationthatyieldsthelogicalinverseoftheoperand.NOT1yieldsa0andNOT0yieldsa1.notanumberAspecialvaluedefinedinIEEE754tosignalaninvalidresultfromafloating-pointoperationNULLAconstantofvalue0thatpointstonothing.nullpointerApointerwhosebitpatternisallzeros.Thisindicatesthatthepointerdoesnotpointtovaliddata. Oobject-orienteddesignAdesignmethodologywheretheprogrammerbaseshisorherdesignondataobjects(classes)andtheconnectionsbetweenthem.octalnumberAbase-eightnumber.onescomplementAnoperationthatflipsallthebitsinainteger.Onesbecomezerosandzerosbecomeones.operatorAsymbolthatrepresentsanactiontobeperformed.Page535ORABooleanoperationthatyieldsa1ifeitheroftheoperandsisa1oryieldsazeroifbothoftheoperandsare0.overflowerrorAnarithmeticerrorcausedbytheresultofanarithmeticoperationbeinggreaterthanthespacethecomputerprovidestostoretheresult.PpackedstructureAdata-structuretechniquewherebybitfieldsareonlyaslargeasneeded,regardlessofwordboundaries.padbyteAbyteaddedtoastructurewhosesolepurposeistoensurememoryalignment.parameterAdataitemtowhichavaluemaybeassigned.Oftenmeanstheargumentsthatarepassedbetweenacallerandacalledprocedure.parameterizedmacroAmacroconsistingofatemplatewithinsertionpointsfortheintroductionofparameters.parametersofamacroThevaluestobeinsertedintotheparameterpositionsinthedefinitionofamacro.Theinsertionoccursduringtheexpansionofthemacro.permanentvariableAvariablethatiscreatedbeforetheprogramstarts,isinitializedbeforetheprogramstarts,andretainsitsmemoryduringtheentireexecutionoftheprogram.pixelThesmallestelementofadisplaythatcanbeindividuallyassignedintensityandcolor. FromPictureElement.pointerAdatatypethatholdstheaddressofalocationinmemory.pointerarithmeticC++allowsthreearithmeticoperationsonpointers:1.Anumericvaluecanbeaddedtoapointer.2.Anumericvaluecanbesubtractedfromapointer.3.Onepointercanbesubtractedfromanotherpointer.pointervariableSeepointer.Page536PortableCcompilerACcompilerwrittenbyStephenJohnsonmakingitrelativelyeasytoadaptthecompilertodifferentcomputerarchitectures.precisionAmeasureoftheabilitytodistinguishbetweennearlyequalvalues.preprocessorAprogramthatperformspreliminaryprocessingwiththepurposeofexpandingmacrocodetemplatestoproduceC++code.preprocessordirectiveAcommandtothepreprocessor.printfAClibraryroutinethatproducesformattedoutput.FromtheoldC-styleI/Opackagestdio.privateAC++keywordindicatingthatthemembersthatfollowaretobeaccessibleonlyfrominsidetheclassorbyfriendsoftheclass.procedureAprogramsegmentthatcanbeinvokedfromdifferentpartsofaprogramorprograms.Itdoesnotreturnavalue(functionoftypevoid).programAgroupofinstructionsthatcauseacomputertoperformasequenceofoperations.programheaderThecommentblockatthebeginningofaprogram.programspecificationAwrittendocumentthatstateswhataprogramistodo.programmer Anindividualwhowritesprogramsforacomputer.programming(acomputer)Theprocessofexpressingthesolutiontoaprobleminalanguagethatrepresentsinstructionsforacomputer.programminglanguageAschemeofformalnotationusedtopreparecomputerprograms.protectedAC++keywordindicatingthatthemembersthatfollowareaccessibleinsidetheclass,insidetheclass'sfriends,orinsideanyderivedclasses,butarenotaccessibletotheoutsideworld.Page537pseudocodeAcodingtechniquewhereprecisedescriptionsofproceduresarewrittenineasy-to-readlanguageconstructswithoutthebotherofpreciseattentiontothesyntaxrulesofacomputerlanguage.publicAC++keywordindicatingthatthememberstofollowareaccessibleoutsidetheclass.purevirtualfunctionAvirtualfunctionthatdoesnothaveadefaultbody.Theclasscontainingapurevirtualfunctioncannotbeuseddirectlybutmustbethebaseforanotherclass.(Seealsoderivedclassesandabstractclasses.)QqualifierAwordusedtomodifythemeaningofadatadeclaration.RradixThepositiveintegerbywhichtheweightofthedigitplaceismultipliedtoobtaintheweightofthenexthigherdigitinthebaseofthenumberingsystem.realnumberAnumberthatmayberepresentedbyafiniteorinfinitenumeralinafixedradixnumberingsystem.recursionRecursionoccurswhenafunctioncallsitselfdirectlyorindirectly.(Forarecursivedefinition,seerecursion.)redirectThecommand-lineoption>fileallowstheusertodirecttheoutputofaprogramintoafileinsteadoftothescreen.Asimilaroption,(classmember)operator,330>(greaterthan)operator,86->(structurepointer)operator,362->*(pointertomember)operator,330>=(greaterthanorequalto)operator,86,324>(greaterthan)operator,323>>(character-to-number)operator,260>>(input)operator,67,322,326-329>>(rightshift)operator,172,323>>=(shiftright)shortcutoperator,325?construct,495[](index)operator,329(backslash)asescapecharacter,59inpreprocessordirectives,152character,64,237b(backspacecharacter),59 f(form-feedcharacter),59 (newlinecharacter),59r(returncharacter),59t(tabcharacter),59^(exclusiveOR)operator,171,323A=(exclusiveORinto)operator,325{}(curlybraces),69,86andstructures,187|(bitwiseOR)operator,171,323tomergeflags,265|=(ORinto)operator,325||(logicalOR)operator,86,326~(bitwiseNOT)operator,171,324~(tilde)inclassdestructornames,206Aabstractclasses,393,458stat,461accuracyoffloating-pointarithmetic,347-352floatversusdoubledatatypes,350addfunction(forcomplexnumbers),321addingcomplexnumbers,321elementtolinkedlist,360floating-pointnumbers,344addition(+)operator,52,323addressof(&)operator,229,322,324(seealsopointers)addresses,variable,228 alignmentproblemsandportability,449ampersand(&)forreferencevariables,75(seealsoANDoperator)AND(&&)operator,logical,86,326AND(&)operator,binary,168-170,323ANDinto(&=)operator,325apostrophe(seequotationmark)argcandargvarguments,241arguments,command-line,241arrays,63-64ofbits(seebitmappedgraphics)indexoperator[],329infinite,modulefor(example),413-429initializing,69,71,195multidimensional,70-71,141asparameters,141andpointers,232-237optimizing,315ofstructures,195(seealsostructures)ASCIIcharacters,59ASCIIfiles(seefiles,ASCII)assemblylanguage,10assignment(=)operator,56forclasses,211versus==(equalto)operator,95assignmentstatements,5,56-57placementof,92 author,commentsabout,39autoqualifier,132autovariableclass,77automaticgenerationofmemberfunctions,210variables,132Bbackslash()asescapecharacter,59inpreprocessordirectives,152backspacecharacter(b),59badmemberfunction,253Page545baseclasses,381initializing,386searchorder,389binaryfiles,260withmultiplestructures,270binaryI/O,262,276binaryoperations(seebits)binaryoperators,322-(subtraction),323%(modulus),323&(AND),168-170,323versuslogicalAND(&&),169*(multiplication),323+(addition),323/(division),323<<(leftshift),172,323 >>(rightshift),172,323^(exclusiveOR),171,323|(OR),171,323tomergeflags,265~(NOT),171,324binarysearch,debugging,296binarytrees,368-373nodes,368recursionwith,371bitfields,193bitflipoperator-(seeNOToperator,binary)bitmappedgraphics,176-181bits,55operationson,167-182muliplicationversusshifting,172setting,clearing,andtesting,173-176bitwiseoperators(seebinaryoperators)modifier,415blocks,129stackof,131(seealsolocalvariables)boldfaceincomments,38Booleanoperators(seebits,operationson)BorlandC++compiler,15Makefilefor,104bottom-upprogramming,147brackets{}(seecurlybraces)branchingstatements,85ifstatements,85-88 switchstatements,120-125breakcommand(debugger),292(seealsogdbdebugger)breakstatements,91,125inswitchstatements,121,123browsers,class,109byteorderandportability,448bytes,55,167pad,450C%cconversion,274Clanguage,3binaryIO,276andC++language,485-491compiler,151conversionroutines,273I/O(input/output),270handlingexceptionsin,489programmingtoolsfor,109C++compilerBorland,15g++,15MicrosoftVisual,15Turbo,15UNIXCC.14C++fileI/O,252-256C++language,4comparedwithClanguage.485-491programmingtoolsfor,109 standardfunctionsin,5C++preprocessor,151-165#definedirective,151-157#includedirective.159callbyaddress,141,146callbyvalue,135,138,146andcopyconstructors,209callbackfunctions.144character,261caselabels(seeswitchstatements)casesensitivity,42,54castoperators,192,331catchkeyword,404cerr(consoleerror)classvariable,252CFronttemplates.445charvariabletype,73,77character(s)ASCII,59constants.59(seealsostrings)data(seefiles,ASCII)Page546character(s)(continued)special,59treatedasbits,173-176variables,73character-to-number(>>)operator,260character-typemodules,458cin(consoleinput)classvariable.67-69,252 classkeyword,203classmember(->)operator,330class,variable(seevariables,classesof)classes,4,197-216,355()operatorfor,330abstract,393,458accessingmembersof,203assignment(=)operatorfor,211base,381browsersfor,109complex,332-341constantmembersof,220constructorsanddestructors,205-211copyconstructors,208-210defaultconstructors,210derived,381-387friendsof(seefriendclasses)hierarchyof,458I/Ostream,51memberfunctions,210membervariables,202membersofstatic,222andpointers,355problemsreading,489programmingstylefor,212-214purevirtualfunctions,461searchorderof,389standard,51stat,461 andstructures,488templatesof,440-442virtual,393-395clearingbits,173-176clog(consolelog)classvariable,252closememberfunction,253closesystemcall,266COBOL,11code(seeprograms;sourcefiles)comma(,)operator,330,495command-linearguments,241debuggingswitch,290commentboxes,37comments,36,110inheaders,39,50markingvariableunits,41stylesfor,38comparingstrings(seestrcmpfunction)compilerBorlandC++,15constructionof,431g++,15,420MicrosoftVisualC++,15Turbo-C++,15UNIXCC,14compiling,conditional,157-159complexclass,332-341complexnumbers,319-341 adding,321concatenatingexpressions(,)operator,330concatenatingstrings(seestrcatfunction)conditionalbreakpoints,307clauses(seebranchingstatements)compilation,157-159statements(see:construct;?construct;switchstatements)confessionalmethodofdebugging,309constkeyword,220versus#definedirective,156constparameters,136reference,139constvariabletype,74constantcallbyvalue,146constantscharacter,59classmembersas,220declaring,74,151-157#defineversusconst,156hexadecimal,78naming,42octal,78pointersas,232constructors,class,205-211copy,208-210default,210inderivedclasses,396-398Page547 overloading,207parameterized,207contcommand(debugger),293(seealsogdbdebugger)continuestatements,92,125controlstatements,5controlvariables,118-120(seealsoforstatements)conversionflags,256integer-to-floating-point,58routinesfor,256C-styleI/O,270,273copyconstructors,208-210copyingstrings(seestrcpyfunction)corefiles,307cout(consoleout)class,51,53,252fordebugging,290diagnosticuseof,106temporary,290inTurbo-C++,251cross-references,109ctype.hincludefile,373curlybraces{},69,86andstructures,187D%dconversion,273datainputting,67-69 protecting,201stacksof(seestacks)datatypes,511changing(seecastoperators)classes,201-216definingspecial,190enum(enumerated),191-193,221pointers,227-247stacks,197-203structures,185-187unions,188-190debuggerasbrowser,110debugging,35,99,106-108,281-309binarysearch,296confessionalmethodof,309divide-and-conquermethod,290interactively(seeinteractivedebugging)playbackfile,287savingkeystrokes,284withtexteditor,292usingaprogramswitch,290withinprogramcode,290decI/Omanipulator,258decimalnumbers,256decimalplacesfornumbers,74declaringconstants,74,151-157#defineversusconst,156filevariables,270 functions,133pointers,229structures,187styleof,500templates,436variables,41,54,132decrease(-=)operator,79,325decrement(--)operator,79,80,325defaultconstructors,210parameters,143statements,inswitchstatements(seeswitchstatements)#definedirective,151-157,501versusconstkeyword.156versusenumstatement,191versustypedefstatement,191definingvariabletypes,190deletefunction,486deleteoperator,330,358usingbrackets[]with,358deletingderivedclasses,397dereference(*)operator,229,324derivedclasses,381-387constructorsanddestructors,396-398deleting,397hidingmembersfunctionsin,395searchorder,389designingfileformats,268-270 modules,433programs,457-459,500destructors,205-207,210callingvirtualfunctionsfrom,397inderivedclasses,396-398namesfor,206virtual,397Page548diagnosticcout,106diskfiles,IOwith,252divideby0error,307divideinto(/=)operator,79,325divide-and-conquerdebuggingmethod,290dividingfloating-pointnumbers,58,346division()operator,52,58,323dowhileloops(seewhileloops)documentation,Oualline'slawof,39dot()operator,362doublekeyword,348doublequalifier,74,77versusfloatdatatype,350doublequote(seequotationmark)double-linkedlists,365E%econversion,274elements,array,63-64elsestatements,87#endifdirective,157,501endlI/Omanipulator,259 end-of-linepuzzle,261end-of-stringcharacter,237end-of-stringmarker,64endsI/Omanipulator,259enum(enumerated)datatype,191-193,221equalto(==)operator.86,323versus=(assignment)operator,95errorseliminatingfromcode(seedebugging)handlingwithinprograms,403–411infiniterecursion,148roundoff(floating-point),347runtime(seeruntimeerrors)stackoverflow,131escapecharacter(),59evaluationorder,79-81exceptions,403-411inC,489runtimelibrary,410exclusiveOR(^)operator,171,323exclusiveORinto(^=)operator,325executableprograms,12exponentialnotation,57expressions,simple,51extendedprecision(seelongdoublequalifier)externmodifier,414-416externvariableclass,77F%fconversion,274 "//fallthrough"comment,123fastprototyping,102fclose(fileclose)function,271fgetc(getcharacter)function,271fgets(getstring)function,272fileformats,commentson,40filenames,portabilityof,451filesASCII,251-261binary,260withmultiplestructures,270changingmodificationdateof,424core,307designingformatsfor,268-270directingdebugginginformationinto,292disk,252header,159I/Owith(seeI/O)identificationnumbersfor,270include(seeincludefiles)multiple(seemodules)object(seeobjectfiles)playback,fordebugging,287source(seesourcefiles)standardunbuffered,265typesof,andportability,452variablesfor,270findfunction(linkedlists),361 flagsconversion,256open,265floatdatatype,74,77versusdoubledatatype,350floatkeyword,57floathincludefile,350floating-pointnumbers,57-59,74arithmetic,343-352accuracyof,347-352guarddigit,344overflowandunderflow,346Page549floating-pointnumbers(continued)arithmetic(continued)roundofferror,347,348speedof,350convertingtointegers,58dividing,58versusintegers,316flushcommand.308flushI/Omanipulator,259,264fopen(fileopen)function,271forstatements,117-120formattingfiles,268-270floating-pointnumbers,343programs,43-45form-feedcharacter(f),59 FORTRAN,11fputc(putcharacter)function,272fputs(putstring)function,272fractionalnumbersfreadroutine,276freefunction(Clanguage),486-488friendclasses,217-219frienddirective.218fscanffunction,275fstreamclass.252fstream.hfile,252functions,133-146callback,144asclassmembers,203inline,144,313versusparameterizedmacros,162K&Rstyle,485lengthof,45asoperators,322-330overloading,142parametersof,133-146arraysas,141const,136reference,137-141recursive,148-149static,223templatesof,436-440virtual,387-393pure,393 functions,standard(seestandardfunctions)fwriteroutine,276G-g(compileroption),14g++compiler,15,420Makefilefor,104templatesin,444gdbdebugger,292-296exampleofusing,298-307generatingtemplates,436getlinememberfunction,254globalvariables,129-131gotostatements,493programmingwithout.43graphics,bitmapped,176-181greaterthan(>)operator,86,323greaterthanorequalto(>=)operator,86,324guarddigits,344(seealsofloating-pointnumbers)Hheaderfiles,159headers,416-418commentsin.39,50help,onlineUNIX,32hexI/Omanipulator,258hexadecimalnumbers,59,78,167,256hidingmemberfunctions,395hierarchy,class,458high-levellanguages.11 hyphen(-)forcommand-lineoptions,242II/O(inputoutput),251-279binary,262C-style,276C++filepackage,252-256conversionroutines,256C-style,270withdiskfiles.252manipulators,258operators<<(output),326-329>>(input),326-329unbuffered,264-268I/Ostreamclasses,51Page550IDE(integrateddevelopmentenvironment),13ifstatements,85-88withelsestatement,87(seealso?construct;:construct;switchstatements)#ifdefdirective,501#ifndefdirective,157ifstream::bad,253::close,253:.open,252implementingtemplates,442-445#includedirective,159includefiles,159,416-418 ctype.h,373float.h,350fstream.h,252iomanip.h,258iostream.h,252local,159nested,160stdio.h,270inclusiveORoperator(seeORoperator)increase(+=)operator,79,325increment(++)operator,79,80,325indentation,43,86stylesof,44toolsfor,109index[]operator,329index,array,63infinitearrays,modulefor(example),413-429infiniterecursionerror,148infocommand(debugger),295(seealsogdbdebugger)initfunction,202initializingarrays69,71,195baseclasses,386stacks,199,202automatically,205strings,70structures,187temporaryvariables,131 variables,69inlinedirective,andclasses,211inlinefunctions,144,313,315-316versusparameterizedmacros,162input(>>)operator,67,322,326-329inputtingdata,67-69int(integer)keyword,54intnumbertype,77longversusshort,72(seealsosizequalifiers,variables)integers,55convertingtofloating-pointnumbers,58dividing,58signedversusunsigned,72integrateddevelopmentenvironment(IDE),13interactivedebugging,292-296conditionalbreakpointtrick,307invert(-)operator(seeNOToperator,binary)iomanip.hfile,258ios::appflag,255::ateflag,255::binaryflag,256,261::decflag,257::fixedflag,257::hexflag,257::inflag,255:internalflag,257 ::leftflag,256::nocreateflag,256::noreplaceflag,256::octflag,257::outflag,255::rightflag,257::scientificflag,257:.showbaseflag,257::showpointflag,257:showposflag,257::skipwsflag,256::stdioflag,257::truncflag,256::unitbufflag,257::uppercaseflag,257iostreamclass,252::fill,258::precision,258:-setf,256::unsetf,256iostream.hincludefile,51,159,252Page551ipfxmemberfunction,327isalphamacro,373istreamclass,252:·getline,254··ipfx,327 italicsincomments,38Jjustification,256KK&R-stylefunctions,485LLcharacter,forlongintegers,72labelsforgotostatements,494languagesassembly(machine),10C(seeClanguage)C++(seeC++language)otherhigh-level,11%1dconversion,274leftshift(<<)operator,172,323lengthfunction,66lessthan(<)operator,86,323lessthanorequalto(<=)operator,86,324letters(seecharacterconstants)libraries,standard,12,51LIFO(last-in-first-out)order,197linearprograms,85character,261linkedlists,356,359-368double-linked,365ordered,362linkers,12listcommand(debugger),293(seealsogdbdebugger) lists,linked(seelinkedlists)localincludefiles,159localvariables,129-131static,131logicaloperators,326!(NOT),86,326&&(AND),86,326versusbitwiseAND,169||(OR),86,326andrelationaloperators,86longdoublequalifier,74longintkeyword,61longinttype,72longqualifier,77longjmpfunction(Clanguage),489loopingstatements,85,88-92andbreakstatements,91controlvariablesin(seecontrolvariables)forstatements,117-120optimizingorderof,310,314whileloops,88-93,493%luconversion,274Mmachinelanguage,10macrosparameterized,160-162replacement,152magicnumbers,270,449mainfunction,133 makeprogram,103-105,420-424Makefile,103-105.501formultiplefiles,420-424mallocfunction(Clanguage),486-488manpages(UNIX),32manipulators,I/O(seeI/Omanipulators)markers,end-of-string,64memberfunctionsautomaticallygenerated,210hiding,395inline,211operatorsas,330-331static,223membervariables,202accessprivilegesto,202constant,220static,222memoryleak,359memsetlibraryroutine,313,425mergingflags,265MicrosoftC++compiler,15templates,443modificationdate,changing,424modules,5,413-434character-type,458Page552modules(continued)designguidelinesfor,433dividingtaskinto,429 Makefilefor,420-424fornonportablecode,447privateversuspublicparts,414token,457modulus(%)operator,52,323modulusinto(%=)operator,79,325morethan(seegreaterthan)Morsecode,80multidimensionalarrays,70-71asparameters,141multiplication(*)operator,52,323multiplyby(*=)operator,79,325multiplyingfloating-pointnumbers,345versusshifting,172Nnamingclassdestructors,206constants,42functions,142variables,41,54,500negative(-)operator,324negatives(seesignedqualifier)nestedincludefiles,160newfunction,486newoperator,330,355-357newlinecharacter( ),59nextcommand(debugger),293(seealsogdbdebugger) nodes,tree,368NOT(!)operator,logical,86,326NOT(~)operator,binary,171,324notequalto(!=)operator,86,323NULcharacter,64,237nulleffectwarning,52NULLpointers,232andportability,450numberscomplex(seecomplexnumbers)conversionsfor,256determiningparityof,with&,170floating-point(seefloating-pointnumbers)hexadecimal(seehexadecimal)numberofdecimalplacesfor,74octal(seeoctalnumbers)signof,77number-to-character(<<)operator,256O%oconversion,274O_APPENDopenflag,265O_BINARYopenflag,265O_CREATopenflag,265O_EXCLopenflag,265O_RDONLYopenflag,265O_RDWRopenflag,265O_TRUNCopenflags,265O_WRONLYopenflag,265objectfiles,12,14 object-orienteddesign(OOD),4octI/Omanipulator,258octalcharactercodes,59octalnumbers,78,256ofstreamclass,252openflags,255onescomplementoperator~(seeNOToperator,binary)openflags,265openmemberfunction,252opensystemcall,264operationcost,315operatorfunctions,322-330operatormemberfunctions,330-331operatorprecedence,513operatorsbinary(seebinaryoperators)bitwise(seebinaryoperators)I/O(seeI/Ooperators)logical(seelogicaloeprators)overloading,319-342relational(seerelationaloperators)unary(seeunaryoperators)optimizingprograms,309-317calculationspeed,350consideringoperationcosts,315consideringpowersoftwo,311-314inlinefunctions,315-316integersversusfloating-pointnumbers,316looporder,310,314 pointersversusarrays,315Page553options,command-linecommand,242OR(^)operator,exclusive,171OR(|)operator,binary,171,323tomergeflags,265OR(||)operator,logical,86,326ORinto(|=)operator,325orderofoperations,79-81orderedlinkedlists,362ostreamclass,252parameter,327::read,262::write,262Oualline'slawofdocumentation,39output(<<)operator,53,273,322,326-329outputfiles,255outputredirection,292overflowerror,131overflow,floating-point,346overloading()(defaultclassfunction)operator,495classconstructors,207functions,142operators,319-342Ppackedstructures,193 padbytes,450parametersinclassconstructors,207default,143function,133-146arraysas,141reference,137-141inmacros,160-162versusinlinefunctions,162typesof,146unused,143parentheses()insimpleoperators,52withmacroparameters,160parity,determiningwith&,170PASCAL,11permanentvariables,131-132playbackfile,287pointers,227-247,355-380->*operator,330andarrays,232-237optimizing,315binarytrees(seebinarytrees)andclasses,355constant,232NULL,232tootherpointers,230printingvalueof,233andstructures,240,355 popfunction,203poppingstacks(removingdata),197-201portability,447-453alignmentproblems,449byteorder,448offiletypes,452filenames,451andmodularity,447NULLpointers,450oftemplates,445wordsize,448positive(+)operator,324powerseries,351sinefunctioncomputedas,515-520powersoftwo,311-314#pragmainterface(GNUg++),444-Jgxoption(Turbo-C++),444precedence,operator,513precision(decimalplaces)ofnumbers,74precisionoffloating-pointarithmetic,347-352prefixoperator(seedecrementoperator;incrementoperator)preprocess(#)operator,162preprocessordirectives,C++,151-165backslash()in,152#define,151-157#include,159parentheses()with,500 semicolons(;)with,152printcommand(debugger),293(seealsogdbcommand)printffunctions,273printingbinarytrees,373Page554printing(continued)debugginginformation,292pointervalues,233privatemembervariables,202moduleparts,414programs,5,12basicstructureof,50changingcontrolvariables,118debugging,35,99,106-108,281-309switchfor,290decision-makingin(seebranchingstatements)definingspecialdatatypes,190designing,457-459,500fordifferentmachines,157-159formatof,43-45handlingerrorsin,403-411minimizingroundofferror,348optimizing,309-317calculationspeed,350placementofassignmentstatements,92portabilityof,447-453 revisingandupdating,99,108,464specificationsfor,97,100splittingintomodules,413-434templates,435-446testing,99,105,463toolsfor,109workingwithUNIXoperatingsystem,99wrapper,12writingstyle(seestyle,programming)protectedmembervariables,202protectingdatainstacks,201pseudocode,101_ptrextension(seepointers)publicmemberfunctions,434moduleparts,414publicmembervariables,202purevirtualfunctions,393,461pushfunction,203pushingstacks(enteringdata),197-201,382putmemberfunction,261Qqualifiers,76auto,132quotationmark('),59quotationmark(''),59withincludefiles,159forstrings,60,65R rangesof,511readmemberfunction,262readingstrings,272realnumbers(seefloating-pointnumbers)recursion,148-149withbinarytrees,371infinite,148redirectingoutput,292redirectionI/O,252referenceparameters,137-141const,139referencevariables,75references,incomments,39registerqualifier,310registervariableclass,76relationaloperators,86,323!=(notequalto),86,323<(lessthan),86,323<=(lessthanorequalto),86,324==(equalto),86,323>(greaterthan),86,323>=(greaterthanorequalto),86,324andlogicaloperators,86remainder(seemodulus)replacementmacros,152reservedwords,54resetiosflagsI/Omanipulator,258returncharacter(r),59returnstatement,134-139 (seealsofunctions)return(0),50revisingprograms,99,108,464revisionhistoryincomments,40rightshift(>>)operator,172,323roundofferror(floating-point),347,348runcommand(debugger),292(seealsogdbdebugger)Page555runtimeerrors,307-308runtimeexeceptions,410S%sconversion,274savingkeystrokesfordebugging,284scanffunction,275scientificnotation,57scope(:)operator,382,496scope,variable,129-131searchorder,virtualfunctions,389search,binary,296searchingbinarytrees.369segmentationfault(coredumped),298SegmentationViolationerror,307semicolon(;),51withif-elsestatements,87andpreprocessordirectives,152setbaseI/Omanipulator,258setfmemberfunction,256setfillI/Omanipulator,259 setiosflagsI/Omanipulator,258setjmpfunction(Clanguage),489setprecisionI/Omanipulator,258settingbits,173-176setwI/Omanipulator,258shiftoperatorsleft(<<),172left(<<=)shortcut,325right(>>),172right(>>=)shortcut,325shortinttype,72shortqualifier,77sideeffects,79signedintegers,72signedqualifier,77simplevariables,5sinefunction,powerseries,515-520singlequote(seequotationmark)single-precisionfloating-pointnumbers(seefloatdatatype)sizequalifiers,variables,77sizeofoperator,254sourcefiles(sourcecode),12specialcharacters,59specializedclasstemplates,442specializedtemplatefunctions,439specifications,program,97,100speedoffloating-pointcalculations,350splittingstrings.237-240spreadsheets,432 sscanffunction,275stackoverflowerror,307stacktrace,299stacks,131,197-203,381classdatatype(seeclasses)exceptionsfor,405-410initializing,199,202structuresversusclasses.201standardclasses,51cin(consoleinput),67-69cout(seecoutclass)standardfilesC,271unbuffered,265standardfunctions,C++,5standardlibraries,12statclass,461statementsassignment(seeassignmentstatements)branching(seebranchingstatements)declaration(seedeclaringvariables)looping(seeloopingstatements)staticdefinitionof,224memberfunctions,223membervariables,222variables,131statickeyword,224,416staticmodifier,415 staticvariableclass,76stderr(standarderror)file,271stdin(standardinput)file,271stdio.hincludefile,270stdout(standardoutput)file,271stepcommand(debugger),293(seealsogdbdebugger)storageclass,variable,131-132strcat(stringconcatenate)function,65strchrfunction,237strcmp(stringcompare)function,65,66,88strcpy(stringcopy)function,65streams,252stringhlibrary,65Page556strings,60,64-67comparing(seestrcmpfunction)concatenating(seestrcatfunction)copying(seestrcpyfunction)end-of-stringcharacter,237end-of-stringmarkers,64functionsfor,65gettinglengthof(seelengthfunction)initializing,70reading,272splitting,237-240variable-length,65strlen(stringlength)function,65structkeyword,186 inCversusC++,486structurepointer(->)operator,362structuredprogrammingtechniques,146-147structures,5,185-187,355arraysof,195andclasses,488initializing,187packed,193andpointers,240,355stacks(seestacks)versusclasses,201(seealsounions)style,programming,35-47,97-113,499-503classes,212-214commenting.38structuredprogrammingtechniques,146-147subtractingfloating-pointnumbers,344subtraction(-)operator,52,323suffixoperator(seedecrementoperator;incrementoperator)switchstatements,120-125,500switches,command-linecommand,242Ttabcharacter(t),59templates.435-46CFront-style,445ofclasses,440-442offunctions,436-440 ing++compiler,444implementing,442-445inMicrosoftC++compiler,443portable,445specialized,439inTurbo-C++compiler,444inVisualC++compiler,443temporaryvariables,131-132testingbits,173-176programs,99,105,463text(seecharacterconstants;strings)texteditordebuggingwith,292modulesof,430texteditorasbrowser,110things,227thiskeyword,331tilde(~)inclassdestructornames,206tokenmodules,457tokens,431top-downprogramming,147touchcommand,424trees,356trees,binary,368-373nodes,368recursionwith,371trykeyword,405Turbo-C++compiler,15 cout,handlingin,251Makefilefor,104templates,444typecastoperation,192typedefstatements,190types,variable,53U%uconversion,274unaryoperators,322,324-(negative),324&(addressof),324*(dereference),324+(positive),324~(onescomplement),324unbufferedI/O,264-268#undefdirective,501underflow,floating-point,346unequalto(!=)operator,86,323unions,188-190Page557unitsforvariables,41UNIXonlinehelpfor,32workingwith,99UNIXCCcompiler,14-Dswitch,158Makefilefor,103unpackedstructures(seepackedstructures)unsetfmemberfunction,256 unsignedintegers,72unsignedqualifier,77unusedparameters,143updatingprograms,99,108upgradingprograms,35Vvariabletypes,53variable-lengthstrings,65variables,41addressesof,228automatic,132changingdatatypes(seecastoperators)character,73classesof,76control(seecontrolvariables)conversionsfornumbers,256declaring,54,132definingspecialdatatypes,190forfiles,270global,129-131initializing,69local,129-131member(seemembervariables)naming,54,500permanentversustemporary,131-132pointers,227-247reference,75andreservedwords,54scopeof,129-131 signedversusunsigned,77simple,5sizequalifiers,77static,131storageclassof,131-132unchanging(seeconstants)(seealsodatatypes)versioninformationindatafiles,269virtualclasses,393-395destructors,397functions,387-393calledfromdestructor,397pure,393,461searchorder,389virtualkeyword,389,397VisualC++compilertemplates,443volatilekeyword,76Wwalkthroughdebugging,309warning,nulleffect,52wherecommand(debugger),293(seealsogdbdebugger)whileloops,88-93,493andassignmentstatements.93andbreakstatements,91andcontinuestatements,92versusforstatements,117whitespace,43,67,256,259 (seealsoformattingprograms)wildcards,command-line,241wordsizeandportability,448wrapperprograms,12writememberfunction,262writesystemcall.266writingprograms(seeprograms)wsI/Omanipulator,259X%xconversion,274x++vs.++x,80XORoperator(seeexclusiveOR)operator,171Page583AbouttheAuthorSteveOuallinewrotehisfirstprogramwhenhewaseleven.Ithadabuginit.Sincethattimehehasstudiedpracticalwaysofwritingprogramssothattheriskofgeneratingabugisreduced.HehasworkedforMotorolaandCelerityComputing,andiscurrentlyaspecialconsultantforHewlettPackard,workingintheresearchdepartmentoftheirInk-Jetdivision.ColophonTheanimalonthecoverofPracticalC++ProgrammingisanEasternchipmunk,astripedgroundsquirrelfoundmostlyineasternNorthAmerica.Easternchipmunkshavefivedarkandtwolightstripesontheirbacks,extendingfromheadtorump,andtwostripesontheirlong,bushytails.Theyaredistinguishedfromothergroundsquirrelsbythewhitestripesaboveandbelowtheireyes.ThecolorationofchipmunksthroughoutNorthAmericavaries,butisquiteuniformwithinregions.Chipmunksoftenmaketheirhomesinsparseforestsorfarms,wheretheycanbuildtheentrancestotheirlodgesinstonewalls,brokentrees,orthickunderbrush.Thelodgesconsistofamazeoftunnelsleadingtoalargeleaf-linednest.Chipmunksspendmostofthedaylighthoursoutdoors,butheadfortheirlodgesbeforenightfall.Althoughtheyareexcellentclimbers, chipmunksliveprimarilyontheground.Chipmunkseatnuts,seeds,insects,andoccasionallybirds'eggs.Likeallgroundsquirrels,theyhavelargecheekpouches,sometimesextendingasfarbackastheirshoulders,inwhichtheycanstorefood.Theycollectandstorenutsandseedsthroughthesummerandfall.Whentheweatherstartstogetcool,allthechipmunksinaregionwillsuddenlydisappearintotheirlodgeswheretheybeginhibernation.Onwarmwinterdaysonecanoftenseechipmunkpawprintsinthesnow,astheywillsometimeswakeupandleavetheirlodgesforbriefperiodswhenthetemperaturerises.MatingseasonforEasternchipmunksismid-MarchtoearlyApril.Thegestationperiodis31days,afterwhichalitterofthreetosixisborn.Babychipmunksleavethelodgeafteronemonth,andarematurebyJuly.Thechipmunkmostlikelygotitsnamefromthenoiseitmakes,whichsoundslikealoud"cheep."Youcanoccasionallyseeachipmunkhangingupsidedownfromatreebranch"cheeping"itscall.Page584EdieFreedmandesignedthecoverofthisbook,usinga19th-centuryengravingfromtheDoverPictorialArchive.ThecoverlayoutwasproducedwithQuarkXPress3.3usingtheITCGaramondfont.Wheneverpossible,ourbooksuseRepKoverÔ,adurableandflexiblelay-flatbinding.IfthepagecountexceedsRepKover'slimit,perfectbindingisused.TheinsidelayoutwasdesignedbyEdieFreedman,withmodificationsbyNancyPriest,andimplementedinFrameMakerbyMikeSierra.ThetextandheadingfontsareITCGaramondLightandGaramondBook.TheillustrationsthatappearinthebookwerecreatedinAldusFreehand5.0byChrisReilleyandMichelleWilley.ThiscolophonwaswrittenbyClairemarieFisherO'Leary.

当前文档最多预览五页,下载文档查看全文

此文档下载收益归作者所有

当前文档最多预览五页,下载文档查看全文
温馨提示:
1. 部分包含数学公式或PPT动画的文件,查看预览时可能会显示错乱或异常,文件下载后无此问题,请放心下载。
2. 本文档由用户上传,版权归属用户,天天文库负责整理代发布。如果您对本文档版权有争议请及时联系客服。
3. 下载前请仔细阅读文档内容,确认文档内容符合您的需求后进行下载,若出现内容与标题不符可向本站投诉处理。
4. 下载文档时可能由于网络波动等原因无法下载或下载错误,付费完成后未能成功下载的用户请联系客服处理。
关闭