a book on c

376

Upload: stephanie-koronidou

Post on 22-Nov-2014

152 views

Category:

Documents


8 download

TRANSCRIPT

... A BookonC Programming inC FourthEdition AIKelley/Ira Pohl University of Caljfornia SantaCruz TT ADDISON-WESLEY Boston San Francisco New York Toronto jIy[ontreal London Munich Paris Madrid Capetown Sydney' Tokyo Singapore Mexico Cit:J1Many of thedesignations used by manufacturers and sellers todistinguish their productsare claimed as trademarks, Where thosedesignatiousappear in this book, and wewereaware of a trademark claim, the designations have been printed ininitial capital letters or inall capitals. The author and publisher have taken carein the preparation of thisbook, but make noexpressedor implied warranty of anykind and assume noresponsibility for errorsor omissions. No liability is assumed for incidental or consequential damages in connection with or arising out of the use of the information or programs contained herein. The publisher offers discounts on this book when ordered in quantity for special sales. For more informa-tion, please contact: Pearson Education Corporate Sales Division 201W.103rd Street Indianapolis, IN 46290 (800)428-5331 [email protected] Visit AWon the Web:www.awl.com/cseng/ Librmy of Congress Cataloging-in-Publication Data Kelley,Al A book on C:programming in C I Al Kelley, Ira Pohl. -4thed. p.cm. Includes bibliographical references and index ISBN 0-201-18399-4 1.C(Computer program language)1. Poh!, Ira,II. Title. QA76.73.C15K441997 005.13'3--dc21 Copyright 1998 by Addison-Wesley 97-44551 CIP Allrights reserved. No part of thispublication may be reproduced, stored ina retrieval system, or transmitted, in any form, or by anymeans, electronic, mechanical, photocopying, recording, or other-wise, without the prior consent of the publisher. Printed intheUnited States of America. Published simultaneouslyin Canada. Text printed on recycled and acid-free paper. ISBN0201183994 91011121314MA04030201 9thPrintingNovember 2001 For our Parents Contents Preface Chapter 0 StartingfromZero 0.1Why C? 0.2ANSIC Standard 0.3FromC to C++ 0.4FromC andC++to Java Chapter1 AnOverview of C 1.1ProgrammingandPreparation 1.2ProgramOutput 1.3Variables,Expressions,andAssignment 1.4TheUseof #defi neand#i ncl ude 1.5TheUseof pri ntfO andscanfO 1.6Flow of Control 1.7Functions Call-by-Value 1.8Arrays,Strings,andPointers Arrays Strings Pointers 1.9Files xvii 1 2 3 3 4 5 5 6 10 1 3 18 21 29 35 36 37 39 42 47 viii.,Contents 1.10OperatingSystemConsiderations WritingandRunninga C Program Interrupting a Program Chapter 2 TypinganEnd-of-fileSignal Redirectionof theInput andtheOutput Summary Exercises lexical Elements, Operators, andtheC System 2.1CharactersandlexicalElements 2.2SyntaxRules 2.3Comments 2.4Keywords 2.5Identifiers 2.6Constants 2.7StringConstants 2.8Operators andPunctuators 2.9PrecedenceandAssociativity of Operators 2.10Increment andDecrement Operators 2.11Assignment Operators 2.12AnExample:ComputingPowersof 2 2.13TheC System Chapter 3 ThePreprocessor TheStandardlibrary Summary Exercises TheFundamentalData Types 3.1Declarations,Expressions,andAssignment 3.2TheFundamentalData Types 3.3CharactersandtheData Typechar 3.4TheData Typei nt 3.5TheIntegral Typesshort, long, andunsi gned 3.6TheFloating Types 3.7TheUseof typedef 3.8Thesi zeof Operator 3.9TheUseof getcharOandputcharO 3.10MathematicalFunctions TheUseof abs 0andfabs 0 UNIXandtheMathematicslibrary 53 53 56 56 56 58 60 69 70 73 75 77 78 79 80 81 83 85 87 89 91 91 92 96 98 107 107 110 111 116 117 119 122 122 124 127 130 130 .,Contentsix 3.11ConversionsandCasts131 TheIntegralPromotions131 TheUsualArithmetic Conversions131 Casts133 3.12HexadecimalandOctalConstants134 e13Summary137 Exercises138 Chapter 4 Flow of Control147 4.1Relational,Equality,andlogical Operators147 4.2RelationalOperators andExpressions149 4.3Equality OperatorsandExpressions152 4.4logical OperatorsandExpressions154 Short-circuit Evaluation157 4.5TheCompoundStatement157 4.6TheExpressionandEmpty Statement158 4.7Theif andthei f-el seStatements159 4.8The whi 1 e Statement163 4.9Thefor Statement167 4.10AnExample:BooleanVariables169 4.11TheComma Operator171 4.12ThedoStatement172 4.13AnExample:FibonacciNumbers174 4.14Thegoto Statement178 4.15Thebreak andconti nueStatements179 4.16Theswi tch Statement181 4.17TheConditionalOperator182 Summary184 Exercises185 Chapter5 Functions197 5.1FunctionDefinition197 5.2Thereturn Statement200 5.3FunctionPrototypes201 FunctionPrototypesin C++202 5.4AnExample:Creatinga Tableof Powers203 5.5FunctionDeclarationsfromthe Compiler's Viewpoint204 limitations205 5.6AnAlternate Stylefor FunctionDefinition Order206 5.7FunctionInvocation andCall-by-Value207 x "Contents 5.8Developinga LargeProgram WhatConstitutes a LargeProgram? 5.9UsingAssertions 5.10ScopeRules ParallelandNestedBlocks Usinga Blockfor Debugging 5.11StorageClasses TheStorageClassauto TheStorageClassextern TheStorageClassreg; ster TheStorageClassstat; c 5.12StaticExternalVariables 5.13Default Initialization 5.14Recursion Efficiency Considerations 5.15AnExample:TheTowersof Hanoi Summary Exercises Chapter 6 Arrays,Pointers,andStrings 6.1One-dimensionalArrays 6.2 6.3 6.4 6.5 6.6 6.7 6.8 6.9 6.10 6.11 6.12 Initialization Subscripting Pointers Call-by-Reference TheRelationshipBetweenArraysandPointers Pointer Arithmetic andElement Size ArraysasFunction Arguments AnExample:BubbleSort DynamicMemory AllocationWithcall oc 0andmall oc 0 Offsetting thePointer AnExample:MergeandMergeSort Strings String-HandlingFunctionsintheStandardLibrary Multidimensional Arrays Two-dimensionalArrays TheStorageMappingFunction FormalParameter Declarations Three-dimensionalArrays Initialization TheUseof typedef 6.13Arraysof Pointers 209 212 212 213 215 216 216 216 217 219 220 221 223 223 227 228 233 235 245 245 246 247 248 252 253 255 256 257 259 262 263 270 272 277 278 279 279 280 281 282 284 6.14Arguments to ma; nO 6.15RaggedArrays 6.16FunctionsasArguments "Contents Functions asFormalParametersinFunctionPrototypes 6.17AnExample:UsingBisectionto FindtheRootof a Function TheKeplerEquation 6.18Arraysof Pointersto Function 6.19The TypeQualifiersconst andvol at; 1 e Summary Exercises Chapter 7 BitwiseOperatorsandEnumeration Types 7.1BitwiseOperators andExpressions BitwiseComplement Two'sComplement BitwiseBinary LogicalOperators Left andRight Shift Operators 7.2Masks 7.3Software Tools:Printingan; nt Bitwise 7.4PackingandUnpacking Multibyte Character Constants 7.5Enumeration Types 7.6AnExample:TheGameof Paper,Rock,Scissors Summary Exercises Chapter 8 The Preprocessor 8.1TheUseof #i ncl ude 8.2TheUseof #def; ne 8.3 8.4 8.5 8.6 8.7 8.8 8.9 8.10 8.11 8.12 8.13 Syntactic Sugar Macroswith Arguments TheTypeDefinitions andMacrosinstddef.h AnExample:Sorting with qsortO AnExample:Macroswith Arguments TheMacrosinstdio.h andctype.h ConditionalCompilation ThePredefinedMacros TheOperators# and## TheassertOMacro TheUseof #error and#pragma LineNumbers xi 290 292 293 296 296 300 302 307 309 311 331 331 333 333 334 335 337 338 341 344 345 348 356 357 365 365 366 367 368 371 372 377 382 384 387 387 388 389 390 xii .,Contents 8.14CorrespondingFunctions 8.15AnExample:Quicksort Summary Exercises Chapter 9 StructuresandUnions 9.1Structures 9.2AccessingMembersof a Structure 9.3Operator PrecedenceandAssociativity:A FinalLook 9.4UsingStructureswithFunctions 9.5Initialization of Structures 9.6AnExample:PlayingPoker 9.7Unions 9.8BitFields 9.9AnExample: AccessingBitsandBytes 9.10The ADT Stack Chapter10 Summary Exercises Structures andListProcessing 10.1Self-referentialStructures 10.2LinearLinkedLists Storage Allocation 10.3List Operations 10.4SomeList ProcessingFunctions Insertion Deletion 10.5Stacks 10.6AnExample:PolishNotation andStackEvaluation 10.7Queues 10.8Binary Trees Binary TreeTraversal Creating Trees 10.9GeneralLinkedLists Traversal TheUseof callocO andBuilding Trees Summary Exercises 390 391 394 396 407 407 411 415 416 418 419 424 427 429 430 435 437 447 447 449 450 451 455 458 459 460 464 471 475 477 478 479 482 482 484 485 .,Contentsxiii Chapter11 Input/Output andthe OperatingSystem493 11.1TheOutput Functionpri ntfO493 11.2TheInput FunctionscanfO499 11.3TheFunctionsfpri ntfO, fscanfO, spri ntfO, andsscanfO503 11.4TheFunctionsfopenOandfcloseO505 11. 5AnExample:Double Spacinga File507 11.6Using Temporary FilesandGracefulFunctions510 11.7Accessinga FileRandomly513 11.8FileDescriptor Input/Output514 11.9FileAccessPermissions517 11.10ExecutingCommands from Within a C Program518 11. 11UsingPipesfromWithina C Program520 11.12Environment Variables521 11.13TheC Compiler522 11.14Using theProfiler524 11.15Libraries526 11.16How to TimeC Code528 11.17TheUseof make532 11.18TheUseof touch538 11.19Other Useful Tools539 Summary541 Exercises542 Chapter12 AdvancedApplications555 12.1Creatinga Concurrent ProcesswithforkO555 12.2Overlayinga Process:theexec ... 0Family558 Usingthespawn ... 0Family560 12.3InterprocessCommunicationUsingpi peO561 12.4Signals564 12.5AnExample:TheDiningPhilosophers567 12.6Dynamic Allocationof Matrices571 Why Arraysof ArraysAreInadequate571 BuildingMatrices with Arraysof Pointers572 AdjustingtheSubscript Range575 Allocating AlltheMemory at Once577 12.7ReturningtheStatus579 Summary585 Exercises586 xiv...Contents Chapter13 MovingfromC to C++ 13.1Output 13.2Input 13.3Functions 13.4ClassesandAbstractData Types 13.5Overloading 13.6ConstructorsandDestructors 13.7Object-orientedProgramming andInheritance 13.8Polymorphism 13.9Templates 13.10C++Exceptions 13.11Benefitsof Object-orientedProgramming Summary ExerCises Chapter14 Moving fromC to Java 14.1Output 14.2VariablesandTypes 14.3Classesand Abstract Data Types 14.4Overloading 14.5ConstructionandDestructionof ClassTypes 14.6Object-orientedProgrammingandInheritance 14.7PolymorphismandOverridingMethods 14.8Applets 14.9JavaExceptions 14.1 0Benefitsof JavaandOOP Summary Exercises AppendixA TheStandardLibrary A.1Diagnostics: A.2Character Handling: Testinga Character Mapping a Character A.3Errors: A.4FloatingLimits: A.SIntegralLimits: A.6Localization: A. 7Mathematics: 593 594 595 599 601 603 606 608 610 612 614 615 617 619 625 626 627 629 631 631 632 633 635 636 638 639 640 641 641 642 642 643 643 644 645 645 646 ...Contentsxv A.8NonlocalJumps:649 A.9SignalHandling:650 A.10VariableArguments:651 A.llCommonDefinitions:652 653A.12Input/Output: .... 655Opening,Closing,and. a File 656AccessingtheFilePositionIndicator Error Handling658 Character Input/Output658 FormattedInput/Output660 Direct Input/Output662 Removingor Renaminga File662 A.13GeneralUtilities:663 Dynamic Allocationof Memory663 SearchingandSorting664 PseudoRandom-Number Generator665 Communicating withtheEnvironment665 Integer Arithmetic666 StringConversion666 Multibyte Character Functions668 Multibyte StringFunctions669 670LeavingtheProgram. 670A.14Memory andStringHandling: Memory-HandlingFunctions671 String-HandlingFunctions671 A.15DateandTime:675 AccessingtheClock676 Accessingthe Time676 A.16Miscellaneous680 FileAccess680 UsingFileDescriptors681 Creatinga Concurrent Process681 Overlayinga Process682 InterprocessCommunication683 SuspendingProgramExecution683 AppendixB Language Syntax685 B.lProgram685 B.2FunctionDefinition686 B.3Declaration686 B.4Statement688 B.5Expression689 7 x ~C o n ~ n ~ B.6 B.7 B.8 Constant Stringliteral Preprocessor AppendixC ANSIC Comparedto Traditional C e.lTypes e.2Constants e.3Declarations CAInitializations e.5ExpresSions e.6Functions e.7Conversions e.8Array Pointers e.9StructuresandUnions e.l0Preprocessor e.l1Header Files e. 12Miscellaneous Appendix0 ASCIICharacter Codes AppendixE Operator PrecedenceandAssociativity Index 690 691 692 693 693 694 695 695 696 696 698 698 699 700 701 701 703 705 707 Preface ABook onC conveys an appreciation for both the elegant simplicity and the power of this general-purpose programming language. Bypresenting interactive running pro-grams from many application areas,this book describes the ANSIversion of the C lan-guage.The complete language is presented in astep-by-step manner,along with many complete working programs. Whereappropriate, wediscussthedifferencesbetween traditional C and ANSIe. (Traditional C still remains in wide use.) Dozensof example programsare availableto illustrateeach important language feature,and many tablessummarize key informa-tion and provide easy access for later reference. Each chapter ends with a summary and exercises.Thesummary reviews key elements presented in the chapter, and the exer-cises augment and extend the text. This book assumes a general-purpose knowledge of the C language. It is intended for use in either a firstor second programming course. However,it can be readily used in conjunction with courses on topicssuch as comparative programming languages, com-putationallinguistics,data structures, databasesystems,fractal geometry,graphicS, numerical analysis, operating systems, programming methodology, and scientific appli-cations. C is suitable for applications from each of these domains,and allfeaturesof C needed tocode such applicationsareexplained. This book isappropriate foradata structurescourse becauseadvanced data structuring featuressuch asenumeration types,unions,self-referential structures,and ragged arraysarediscussed. For operat-ing systems courses concerned with UNIXor Windows 95/NT,the book explores the file structure andsystems routinesthat enabletheC programmer toadd toexisting sys-tems libraries and understand the C code underlying the operating system. For applica-tionsprogramming andscientificprogramming,there isdiscussion of how to write sample function libraries.Statistics,root finding,sorting,text manipulation,filehan-dling,and game playing are all represented with working code. xviiil'Preface New Java Section. In Chapter 14,"Moving from C to Java," wediscuss how the C pro-grammer can very naturally and easily begin programming in Java,a language of inter-est for work on the Internet. The Java programming language borrows ideas from both C and c++ and isdesigned to run in a machine- and system-independent manner. This makes it suitable for Internet work,such as writing applets for Webpages that get used by browsers. Because Java isan extension of C and C++,it is readily learned by the C programmer. Complete ANSI C Language. Computer profesSionals will have accesstoacomplete treatment of the language, including enumeration types, list processing, and the operat-ing system interface.Chapter 1,"An Overview of C,"presents an overview of the lan-guage. After reading this chapter,the professional willalready be ableto writeC code. Sincethe chapters are self-contained,the knowledgeable reader can skip to particular sections as needed. Chapter 11,"Input/Output and the Operating System," givesa thor-ough introduction totheconnections totheoperating system.This information will benefit the professional systems programmer needing to use C towork 'vi thin an MS-DOSor UNIXenvironment. Interactive Environment.Thisbook is written entirely with the modern interactive environment in mind. Experimentation is encouraged throughout. Keyboard and screen input/output is taken asthe norm, and its attendant concerns are explained.Thus,the book is appropriate for users of small home and business computers as well asto users of large interactive systems. Weassume that the reader will have access toan interac-tiveANSIC system. During the writing of this book, we used anumber of different C systems: various Borland and Microsoft compilers running on IBM-compatible Pentium machines,the GNUgee compiler and native compilers running on various workstations from DEC,SGI,and Sun,and the C compiler that runs on the Cray supercomputer in San Diego. WorkingCode.Our approach to describing the language is to use examples,explana-tion,and syntax. Working code isemployed throughout. Small but useful examples are provided todescribe important technical points.Small because small iscomprehensi-ble.Useful because programming is based on a hierarchy of building blocks and ulti-mately is pragmatic. The programs and functionsdeSCribedin the book can be used in actual systems. The authors' philosophy is that one should experiment and enjoy. Dissections.Weuse highlighted"dissections"on many programsand functions throughout the book Dissection is a unique pedagogical tool first developed by the authors in 1984 to illUminate key featuresof working code. A dissection issimilar toa structured walk-through of thecode.Itsjntention istoexplain tothe reader newly encountered programming elements and idioms found in working code. 'fPrefacexix ...bk is constructed to be very flexible in its use. Chapte: I, Flexible :his00rtsThe first part explains the crucial programmmg "AnOverview of C,Is:n two"/tutmaterial that must be understood by techniques needed for mteractIve the entire language and will be com-alLThe second part ?f Chapter 1 goe.f'liar with comparable features from other prehensible to expenenced programmersamJd,afirstprogramming course.Caution: sThissecond part can be postpone111language.ldostone the second part of Chapter 1. Beginning programmers shoupp.d the C Sstem" describes the lexical level Chapter 2,"Lexical to illustrate C lan-of the language and sy.ntact!cru es,to teach Backus-Naur-Form (BNF)notation guage constructs. The mstructor ma\ 't'thout any loss of continuity. The book uses asdescribed in Chapter 2 ,or ,mayonn1 t student can learn thisstandard form of BNF-stylesyntacticso :ha dd'tionlanguage componentsarethoroughly programming language descnptIOn.naI,' described by example and ordinary explanatIOn. ..dsined to be avaluable referencetothe C language. Reference Work.ThISbook ISeillustrate key areas of the language. The Throughout the book, many tables 1 its associated header files,isdescribed in complete AN.S1CSections in theappendix aredevoted to the AppendIX A,TheStanareader filessuch as etype.h,stdio.h, and string.h. Where explaining each of theto illustrate the use of a particular construct or appropriate,examplecode ISgIven function."'de the complete syntax of the C language . B"Lnguage Syntaxwe proVl. In AppenLUll.,a'd.Td't'IC " welistthe major dIfferences .C"ANSIC Comparetora1IOna,.d Cand traditional C.Finally, special care has been taken to make the mex easy to use and suitable for a reference work. hers 3through 10 cover theC language feature TheComplete ANSI C C that may be omitted on first reading by feature.Manyadvanced .dFor exampleenumeration typesare rela-without loss of comprehensIOn, IhSO,esrre.beomI'tted' in afirstcourse. Machine-hIgeand telf use can_. tivelynew toteangua,.'dtions and floating-pointrepresentatIOn dl'atures such as word SIzeconslera depenehnt.edbut many of the details need not concern the beginner. are empaSIze, "Processor" is devoted entirely to the preproces-The Preprocessor. Chapter 8,Therepdt't'on of the C language.Macroscan be ,.dtnd the power annoa1 sor, WhIch ISusetoex elfa function call. Their use can reduce used to code that takes discussion of the preproces-program executIOn tlme.The ANSIcommittee. In traditional C,the prepro-sor, including ne",: featuresaddedyeiler to another. In ANSIC,the functionality of cessor varies conSIderably from one comp,. the preprocessor has been completely speCIfIed. t xxl'Preface Recursion and List Processing. Chapter S,"Functions," has acareful discuSSionof recursion, which is often a mystifying topic for the beginner.The Useof recursion is illustrated again in Chapter 8,"The Preprocessor," Withthe quicksortalgOrithm and in Chapter 10,"Structures and List ProCessing,"Withbasic list prOceSSingtechniques. A thorough knowledgeof list processing techniques is necessary in advanced program. ming and data structure courses. Operating System Connection.Chapter II, "Input/Ou tpu tand theOpera ting Sys tern," makes the operating system conneCtion.In this chapter, weexplain how to do filepro. cessing and discuss at length thevariousinput/output functionsin thestandard library.Wealso explain how to execute asystem command from Within aC program and how to set file permissions and USeof environment variables.Wegiveexplicit examples shoWing theUseof the proftler,the librarian, and themake facility. Advanced ApPlications. Wediscuss a number of advanced applications in Chapter 12, "Advanced Applications." Wepresent topics such ascreating concurrent processes, overlaying a process, interprocess communication,and Signals,along With Working COde.Also, Wediscuss the dYllamic allocation of vectors and matrices for eng;neers and sdentists. These advanced tOPlescanbeused selectively according to the needs of the audience.They could formthe basis for an excellent second course in programming practlee. lbis book can beused,too,as an aUXiliarytext in adVanced cOlllPuter sdence courses that employ C astheir implementation language. TabIes,Summaries, and exercises. Throughout Ihe book are many tables and liststhat SUCCinctly sununanze key ideas. Thesetables aid and test language comprehension. For example, C is very rich in operators and allowsalmost any useful combination of Opel'. ator mix. It is eSSentialtounderstand order of evaluation and association of each of these operators separately and in combination.These points are llIustrated in tables throughout the text. Asa reference tool,the tables and code ill'eeasily lOoked up. The exerdses test elementary features of the lilllguage and discuss advanced and sys. tem'dependent features.Mony exercisos areorientedto problem solVing,otherstest the reader's SYlltactic or Semantic understanding of C.Someexerdses include a tutorial diSCUSSionthat istangential to the text but may be of special interest to certain readers. lbe exercises offer the instructor all leVelsof question, so asto allow aSSignments sUit- abletothe audience. l'Prefacexxi Acknowledgmentsthechief technical editor for to Debra Dolsberry, whoacted asI er to create PostSCrIptOur spedal thanks goIresponsible for using FrameMa {kSalso goto Robert FIeld, this book She was large Ynof thisbook.Our speetal thanhe chief technical reviewer suitableforthetypesettt ViewCalifornia,whoacted as tdsugestionsextremely ParcPlace Systems,boole' Wefound hisexpertise"gandthe "Dining Phi- d.,.n0I.5"Funcno,d for the firste110f H'01'"picture in Chapter,.g" aredue to Johneh "Twer 0and List Processm, valuable. Teo.Chapter 10, "Structures an.hnks goto him,too. losophers"Riverside. Our speml t'th helpful suggestions: Mur. Pillis, UruverSlty 0kother people whoprOVIded WI hae! Beeson,San Jose State Wealso want toof California,Santa Cruz,State University,Ft.Col-ray Baumgarten, Urn C]"frnia' Randolph Bentson,CoBieHewlett-PackardCo.: University,San Jose:a '.,0of California,Berkeley; JOhn.;w ofuY Budd, University of lins;Jim Bloom, Umve.'" Yilof California, Santa Bru:bara,1Ul ta Cruz; Jim Chrislock, inc.; Skona Bnttam, University of Cabforma,szan effDonnelly, UniversIty Arizona, Tucson; Nl::dJniversity of California, Santa ie': G1ntenbein, University of Minderaft, inc.; AICo.IF'tzAT&TBell Laboratones,'. Lonard Garrett,Temple of IllinOis,Urbana;DIC y) returnx; else returny; This isthe functiondefinition for the function maxi mum O. It specifies explicitly how the function willact when it iscalled,or invoked. A function definition consists of a header and a body. The header isthe code that occurs beforethe first left brace{.The body consists of thedeclarations and statements between the braces{ and}. For this function definition the header isthe line floatmaximum(floatx,floaty) The first keyword float in the header tells the compiler that this function is to return a valueof type float. Theparameter list consists of the comma-separated list of identi-fier declarations within the parenthesese and)that occur in the header to the function definition. Here,the parameter list is given by floatx,floaty The identifiers x and yare formal parameters. Although wehave used the identifiersx and y both here and in the function ma in 0, there is no need to doso.There is no rela-tionship, other than a mnemonic one, between the x and y used in maxi mum 0and the x andy used in ma in O. Parameters in a function definition can bethought of asplace-holders. Whenexpressionsare passed asargumentstoa function,the valuesof the expressionsareassociated with these parameters. The valuesarethen manipulated according tothe code in the body of the function definition. Here,the body of the func-tion definition consists of a single i f-el se statement. Theeffect of this statement is to return the larger of the two valuesx and y that are passed in as arguments. ..returnx; This is aretu rnstatement. The general form of aretu rnstatement is return; orretu rnexpr; 1.7'YFunctions35 A retu rnstatement causes control to be passed back to the calling environment. If an expression followsthe keywordreturn, then the valueof theexpression ispassed back as well. ..floatminimumefloatx,floaty) { } ifex=0;--i) putchar(name[i]); If we assume that Ali ceB.Carole followed by a carriage return was typed in, then i has value15at the beginning of this for loop.(Donot forget to count from 0,not 1.) Afterihas been decremented, thesubscript corresponds to the last character of the name that was typed in. Thus,the effect of thisfo rloop is toprint the name on the screen backwards. IIIprintf("\n%s%d%s\n\n%s\n", "andthelettersinyournamesumto",sum,".", "Haveani ceday! ") ; Weprint the sum of the letters in the name typed in by the user, and then we print a final message. Afterthe sum of the letters in the name is printed, aperiod is printed. Two newlines are used tocreate a blank line before the final message is printed. Notice that thispri ntfO style allows us to easily visualize what is to appear on the screen. Pointers A pointer isan address of anobject in memory.Becausean array name isitself a pointer, the uses of arrays and pointers are intimately related. The following program is designed to illustrate some of these relationships: 1.8TArrays,Strings,andPointers #include #include #defineMAXSTRING100 intmain(void) { } charc='a',1,p,s [MAXSTRINGJ; p= &c; pri ntf("%c%c%c",1,p,' ~ p+1,>"p +2); strcpy(s,"ABC"); pri ntf("%s%c%c%s\n",s,*s+6,t,s+7,s+1); strcpy(s,"shesellsseashellsbytheseashore"); ps+14; for(;*p!='\0';++p){ if("'p=='e') >"p ='E'; if ("'p=='') i'p='\n '; } printf("%s\n",s); return0; The output of this program is abcABCGHBC shesellsseashElls by thE sEashorE Dissectionof theabc Program III#include 43 Thestandard library contains many string-handling functions.(SeeSection 6.11, "String-Handling Functions in the Standard library," on page 272.) The standard header filestring.h contains the function prototypes forthese functions.In this program we will use strcpy() to copy a string. 44 Chapter1VAnOverview of C IIchar c='a',*p,s[MAXSTRING]; The variablecisof typechar. It is initialized with the value'a'. The variablep isof type pointer tochar. The string 5has size MAXSTRING. IIP=&c; Thesymbol & isthe address operator. Thevalueof theexpression &cis the address in memory of the variable c.The address of c is assigned to p.Wenow think of p aspoint-ing toc. IIpr;ntf("%c%c%c", >'='A')&& (c='A'&&c causesthe operating system to redirect the output of thecommand to the filetmp. What was written tothe screen before is now written to the filetmp. Our next program iscalleddbLout.It can be used with redirection of both the input and theoutput.Theprogram readscharacters from thestandard input file,which is normally connectedtothe keyboard,and writeseach character twicetothestandard output file,which is normally connected tothe screen. filedbLout.c #include intmain(void) { } charCj while(scanf("%c",&c)__ pri ntf("%c",c) j } pri ntf("%c",c); return0; 1.10VOperating SystemConsiderations 57 1){ wecompile the program and put theexecutable code in the filedbloutth. dt'.Ih- ,en,usmg reIreclOn,wecan mvo dbLout< infile outfile infile>outfile Used in this context,the < and> can be thought of as arrows.(Seeexercise 26 on page 68, for further dIscussIOn.), Somecommands are not meant tobe used with redirection. For example,theIscom-mandnot read characters from the keyboard. Therefore, it malu>-< tions,such asan i nt that is4bytes on onesystem and 2byteson another,and differencesare critical tothe program,then the use of typedef may make the of thesoftwareeasier. In later chapters,after weintroduce enumeration types structure types, wewill see that the typedef facility gets used routinely. 3.8Thes i zeof Operator C provides the unary operator si zeof to findthe number of bytes needed to store object. It has the same precedence and associativity as allthe other unary operators. expression of the form si zeof(object) 3.8"IfThesi zeof Operator 123 an integer that represents the number of bytes needed to store theobject in . An object can be a type such asi nt or float, or it can be an expression such +b,or it can be an array or structure type. The following program uses this oper-On agiven machine it provides precise information about the storage require-forthe fundamental types. Computethesizeofsomefundamentaltypes.*/ printf("The pri ntf(" pri ntf(" printf(" sizeofsomefundamentaltypesiscomputed.\n\n"); char:%3ubyte\n",sizeof(char)); short:%3uby tes\n" ,sizeof(short)); int:%3ubytes\n",sizeof(int)); pri ntfC" printf(" pri ntf(" printf(" printf("long return0; long:%3uby tes\n" ,sizeof(long)); unsigned:%3uby tes\n" ,sizeof(unsigned)); float:%3uby tes\n" ,s;zeof(float)); double:%3uby tes\n" ,sizeof(double)); double:%3ubytes\n",sizeof(longdouble)); usetheC language isflexiblein itsstorage requirementsforthefundamental , thesituation can vary from one machineto another. However,it is guaranteed sizeof(char)= 1 ='a'&& c=0.0) use the square root function isdefined onlyfornonnegativenumbers,atest is to ensure that the value of x isnonnegative. A call such assq rt (-1.0) can cause timeerror. (Seeexercise20,on page144.) printf("\n%15s%22.15e\n%15s%22.15e\n%15s%22.15e\n\n", "x:=",x, "sqrt(x)=",sqrt(x) , "pow(x,x)=",pow(x,x)); that we are printing doubl e values in the format %22 .15e. This results in 1 place the left of the decimal point and 15 places to the right,16 significant places in all.On machine,onlyn places are valid,wheren is between 15and16.(Theuncertainty about because of the translation from binary to decimal.) You can ask for lots of places to be printed, but you should not believe all that you read. 130 Chapter 3TTheFundamentalData Types TheUseof abs 0andfabs 0 In many languages, the functionabs 0returns the absolute value of its real In this respect, C isdifferent. In C,the function abs 0takesan argument of typein and returns its absolute value as an i nt. Its function prototype is in stdlib.h. For matieal code, the C programmer should use fabs 0, which takes an argument of double and returns its absolute valueasa double. (Seeexercise25,on page 145.) function prototype is in mathh The name fabsstands for floatingabsolute value. UNIX andtheMathematicsLibrary In ANSIC,the mathematics library is conceptually part of the standard library. means that you should not haveto do anything special to get access to functions. However, on older UNIXsystems this is often not the case. Suppose you a program in a file,say pgm.c,that uses the sq rt ()function.The followingLVlllllldJlll should then compile your program: ccpgm.c If,however,the ANSIC system isnot properly connected, you willseesomething the following printed on the screen: Undefinedsymbol:_sqrt This means that the linker looked through the librariesthat were made available to but was unable to finda.0 filethat contained the object code for thesqrtO (SeeSection 11.15,"Libraries,"on page526, forfurtherdiscussion of libraries.) If givethe command ccpgm.c-1m the mathematics library will be attached, which will allowthe loader to findthe sary .0 file.In-1mthe letter 1 stands for"library"and the lettermstands for maties."Asolder versions of UNIXgivewayto newer versions,the necessity of the -1m option disappears. 3.11TConversionsandCasts131 ConversionsandCasts etic expression such asx+yhas both a valueand atype. If both xandy . typei nt, then theexpression x+y also has type int. But if both x and y have short, then x+y isof typei nt, not short. This is because in any expression,a alwaysgets promoted,or converted,toan int. In thissection wewantto give rules forconversions. IntegralPromotions ar or short, either si gnedor unsi gned,or an enumeration typecan be used in expression where an i nt or unsi gnedi nt may be used. (SeeSection 7.5,"Enumer-Types,"on page 345.) If all the valuesof the original type can be represented by nt, then the value is converted to an i nt; otherwise, it is converted to an unsi gned This is called an integral promotion. Here isan example: charc0=IA'; pri ntf("%c\n",c); char variablecoccurs by itself asan argument top ri ntf O. However,because an promotion takes place,the typeof the expression c isi nt, not char. e UsualArithmetic Conversions tic conversions can occur when the operands of a binary operator areevalu-S u p p o s ~ ,forexample,that iisan i nt and fisa float. In the expression i+f, operand 1gets promoted toa float, and the expression i+fas a whole has type at. The rules governing this are called theusual arithmetic conversions;those rules 132Chapter3VTheFundamentalData Types I'heusual arithmetic conversions: If either operand is of typelongdoubl e,the other operand is converted to long Otherwise, if either operand isof type doubl e,the other operand is converted to doubl Othen-vise, if either operand isof type float, the other operand is converted to float, Otherwise,the integral promotions are performed on both operands,and the rules are applied: If either operand isof typeunsi gnedlong,theother operand isconverted unsi gnedlong. Otherwise, if one operand has typelong and the other has typeunsi gned,then of two possibilitiesoccurs: If along can represent allthe values of anunsi gned,then theoperand typeunsi gned is converted tolong. If along cannot represent all the values of an unsi gned,then both of operands are converted tounsi gnedlong. Othervvise, if either operand has typelong, the other operand isconverted tolon Otherwise, if eitheroperand hastypeuns i gned,theother isconverted unsi gned. Otherwise, both operands have type i nt. Thisarithmetic conversion has several alternate names: ..automatic conversion ..implicit conversion IIcoercion III promotion III widening 3.11VConversionsandCasts133 followingtable illustrates the idea of automatic conversion: Declarations charCjshorts;inti; long1;unsignedu;unsignedlongul; floatf;doubled;longdoubleld; ExpressionTypeExpressionType C- s/iintu 'I, 7-iunsigned u'I,2.0- idoublef1< 7- ifloat C+3int71< S, ~ ulunsignedlong C+5.0doubleld+Clongdouble d+5doubleuulunsignedlong 2 #i /1longu1system-dependent In addition toautomatic conversions in mixed expressions, an automatic conversion can occur across an assignment. For example, =i LOILl"the value of i, which is an i nt, to be converted to a dou b1 e and then assigned to d,and doubl eisthe type of the expression as a whole. A promotion or widening such d=iwill usually be well behaved, but a narrowing or demotion such asi=dean information. Here,the fractional part of d will be discarded. If the remaining inte-part does not fitinto an i nt, then what happens issystem-dependent. In addition to implicit conversions, which can occur across assignmentsand in mixed expressions, there are explicit conversions called casts. If iis an i nt, then (double)i will cast, or convert, the value of iso that the expression has type doubl e. The variable iitself remains unchanged. Casts can be applied to expressions. Some examples are 134Chapter3vTheFundamentalData Types (long)(tAl+1.0) f=(float)((int)d+1) d=(double)i/3 (double)(x= 77) but not (double)x=77 /*equivalentto((double)x)= 77,error*/ Thecast operator (type)is a unary operator having the s a m ~precedence and righ left associativity as other unary operators. Thus, the expressIOn (float);+3is equivalent to ((float)i)+3 because the cast operator (type) has higher precedence than +. 3.12 HexadecimalandOctalConstants A number represented by a positional notation in base 16 iscalled a hexadecimal ber. There are 16 hexadecimal digits. Hexadecimaldigitsandtheir correspondingdecimal values Hexadecimaldigit:019ABCDE Decimal value: 0191011121314 F 15 A positive integer written in hexadecimal notation isa string of hexadecimal digits of the form hn I1n-l..112 hI ho where each hi is a hexadecimal digit. It has the value I1nx16n +hn.-:1x16n-1 +... +h2x162 +111x161 +hox16o For example, 3.12vHexadecimalandOctalConstants =AX164 +0x163 +Fx162 +3x161 +Cx160 10x164 +0x163 +15x162 +3x161 +12x160 =:659260 135 hexadecimal numbersand their decimal equivalentsaregiven in the following i Hexadecimalnumber 2A B3 113 Conversiontodecimal 2x16+A=2x16+1042 B x16+311x16+3= 179 1x162 +1x16+3=275 On machines that have8-bit bytes,a byte isconveniently represented astwo hexa-U\'111 Yield tel nt va ue isfalse. 4.2"RelationalOperatorsandExpreSSions149 RelationalOperatorsandExpressions relational operators > = all binary. They each taketwoexpressions asoperands and yieldeither the int or the i nt value1. relationaL expression. '-.. -exprexpr expr=expr ab -1.3>=(2.0*x+3.3) biiO;;U'-.""the value of y.The syntax is given by example is . '-.. -if(c>='a'&& c='a'&& cnext) Examples of comma expressions are given in the followingtable: I Declarations andinitializations inti,j,k=3 ; doublex=3.3; ExpressionEquivalent expressionValue I !i=1,j2,++k+1( (i1),(j=2,((++k)+1)5 k1=1,++ x,y2.0+1(k1=1),(((++x)'i,2.0)+1)9.6 Mostcommas in programs donot represent comma operators. For examp those commas used toseparate expressions in argument listsof functionsor us within initializer lists are not comma operators. If a comma operator is to be used these places, the comma expression in which it occurs must be enclosed in 4.12The doStatement Thedostatement can be considered a variant of the whi 1estatement. Instead of mak- ..ing its test at the top of the loop, it makes it at the bottom. Its syntax is given by dostatementwhil e(expr); An example is 4.12TThedoStatement ='0; == 0; /*sumaseriesofintegerinputsuntil0isinput*/ do{ sum+=i; scanf("%d",&i); wh; 1 e(i>0); a construction of the form statement whi 1e(expr); next statement 173 statement isexecuted and expris evaluated. If the value of expris nonzero (true), control passes back tothe beginning of thedostatement and the process repeats Whenexpr is zero (false),then control passes to next statement. Asan example,suppose that wewant to read in a positive integer and that we want insist that the integer be positive. The followingcode will do the job: do{ printf("Inputapositiveinteger:"); scanf("%d",&n); if(error=(n='0'&& c 00 This algorithm isderived from the Newton-Raphson method in numerical analysis. Write a program that reads in the value of ainteractively and uses this algorithm to compute the square root of a. As you will see,the algorithm is very efficient.(None-theless, it is not the algorithm used by the sq rt 0function in the standard library.) 196Chapter 4"Flow of Control Declare x0and xl to be of type double, and initialize xl to1. Inside aloop do the following: x0=xl; xl=0.5*(xl+a/xl); /*savethecurrentvalueofxl*/ /*computeanewvalueofxl*/ The body of the loop should be executed as long as x0is not equal to xl. Each time through the loop, print out the iteration count and the values of xl (converging to the square root of a)and axl;'xl (acheck on accuracy). 37(Advanced) Modify the program you wrote in the previous exercise,sothatthe square roots of 1,2,...,n are all computed, where n isa value that is entered inter-actively. Print the number, the square root of the number, and the number of itera-tions needed to compute it.(Youcan look in anumerical analysistext to discover why the Newton-Raphson algorithm issoefficient. It issaid to be "quadratically convergent.") 38(Advanced) The constant e,which is the base of the natural logarithms, is given to 41significant figures by e=2.7182818284590452353602874713526624977572 Define (1)1l II+ -n forn= 1,2,... It can be shown mathematically that Investigate how to calculatee toarbitrary precision using this algorithm. You will findthat the algorithm iscomputationally ineffective.(Seeexercise36,on page 195.) 39(Advanced) In addition to the algorithm given in the previous exercise,the value for e is also given by the infinite series 1111 e1 + 11+ 2!+ 3i+ 4!+'" Theabovealgorithm is computationally effective.Use it to compute e to an arbi-trary precision. hapter5 unctions the heartof effective problem solving is problem decomposition. Taking a problem and breaking it into small, manageable pieces iscritical to writing large programs. In C, the function construct is used to implement this "top-down" method of programming. A program consists of one or more files, "\lith each filecontaining zero or more func-tions,one of them being a mai n 0function.Functions are defined as individual objects that cannot benested. Program execution begins with ma in 0, whichcan callother functions, including library functions such as p ri ntfO and sq rt O. Functionsoperate with program variables, and which of these variables is availableat a particular place in a function isdetermined by scope rules. In thischapter we discuss function definition, function declaration,scope rules, storage classes, and recursion. 5.1FunctionDefinition The C code that describes what a function does is called thefunctiondefinition.It must not be confused with the function declaration. A function definition has the following general form: typefunction_name(parameter list){declarationsstatements} Everything before the first brace comprises theheader of the functiondefinition,and everything between the braces comprisesthebody of thefunctiondefinition. The parameter list isa comma-separated list of declarations. An example of a function defi-nition is 198Chapter5TFunctions intfactorial (intn) { } inti,product=1; for(i=2;i0;--n) sum+=n; returnsum; /*sumtheintegersfrom1ton*/ /*storedvalueofnischanged*/ Even though n ispassed to compute_sumOand the value of n in the body of that func-tion ischanged,the value of n in the calling environment remains unchanged. It is the value of n that is being passed, not n itself. The"call-by-value" mechanism is in contrast tothat of "call-by-reference." In Section 6.3,"Call-by-Reference,"on page252,wewillexplain how to accomplish the effect of "call-by-reference." This isawayof passing addresses(references)of variables to a function that then allowsthe body of the function to makechangesto the values of variables in the calling environment. Functioninvocationmeans: 1Each expression in the argument list is evaluated. 2The value of the expression is converted, if necessary,tothe typeof the formal parameter,and that value isassigned to its corresponding formal parameter at the beginning of the body of the function. 3The body of the function is executed. 4If aretu rnstatement is executed, then control is passed back to the calling envi-ronment. 5If theretu rnstatement includes an expression, then the value of the expression is converted, if necessary, tothe type given by the type specifier of the function, and that value is passed back to the calling environment, too. 6If theretu rn statement doesnot include an expression, then no useful value is returned to the calling environment. 7If noreturn statement is present, then control is passed back to the calling envi-ronment when the end of the body of the function is reached.Nouseful value is returned. 8All arguments are passed "call-by-value." 5.8...Developinga LargeProgram209 DevelopingaLargeProgram Typical1y,a large program is ""Titten in a separate directory as acollection of .h and .c files,with each .c filecontaining oneor more function definitions. Each.c filecan be recompiled asneeded,saving time for both the programmer andthe machine. (SeeSec-tion 11.17, "The Useof make,"on page 532for further discussion.) Letussuppose wearedeveloping a large program called pgm.Atthetopof each of our .c filesweput the line #include"pgm.h" When the preprocessor encounters this directive,it looksfirst in the current directory for the filepgm.h. If there is such a file,then it gets included. If not, then the preproces-sor looks in othersystem-dependent placesforthe file.If the filepgm.h cannot be found,then the preprocessor issues an error message and compilation stops. Our header filepgm.h may contain #i ncl udes,#defi nes, templates of enumeration types,templatesof structure and union types,other programming constructs,and finallya list of function prototypesat thebottom. Thus,pgm.h contains program ele-mentsthat areappropriate for our program asa whole.Because the header filepgm.h occurs at the top of each .c file,it acts asthe "glue"that binds our program together. main.e Create a.h filethat is included in all the.c files pgm.h #includes #defines list of fetprototypes fet.eprn.e #include"pgm.h"#include"pgm.h"#include"pgm.h" 210Chapter 5'fFunctions Let us show a very simple example of how this works. Wewill write our program in a separate directory. It will consist of a.h file and three .c files.Typically, the name of the directory and the name of the program are the same. Here is our program: In file pgm.h #include #include #defineN3 voidfctl(intk)j voidfct2(void)j voidwrt_info(char In file main.c #include"pgm.h" i ntmai n (vo; d) C } charanSj inti,n=N; pri ntf("%s" , "Thisprogramdoesnotdoverymuch.\n" "00youwantmoreinformation?H); scanf("%c",&ans); if(ans=='y'I Ians=='Y') wrt_info("pgm"); for(i= 0;iL'-UL.hJoften use homogeneous data. Forexample, if wewant to manipulate some , we might declare grade0,gradel,grade2; the number of grades is large, representing and manipulating thedata by means of identifiers will be cumbersome. Instead, an array, which is a derived type, can be d.Anarray can be thought of asasimple variable withan index,or subscript, Thebrackets[]are used tocontain thearray subscripts.Tousegrade [0] . rade [1]. and grade [2]in a program, we would declare intgrade[3]; 246Chapter 6'"Arrays,Pointers,andStrings h bof elements in the array. The The integer 3 in the declaration represents te numer indexing of array elements alwaysstarts at O.'dtif'wl'th a brack-,,te followed by an 1enler Aone-dimensional array declaratIOn ISayp'hi 'h must be positive eted constant integral The value of The array isthe size of the array, Itth: number ethe array subscripts is 0and scripts can range from 0to sIze- I,rhe lowerour:,, the upper bound issizeLThus, the following relatlonships hold. int a [size] ;l" spacefora[0J,...,a[size lower bound== 0 upper bound== size- 1 size== upper bound+1 IJallocated*/ ,'f an array as a symbolic constant. It is good programming practice todefme the SIzea. #defineN100 fra[0] a[99]isallocated*/ i nta [N] ;/*space0,, ,'d'mforprocessing array elements Given this declaration,the standard programmmg 110.-is with a fo r loop. For example: for(i==N;++i)/*processelementa[i] sum+=a1, ] d'ttively processes each element This iteration startst,he a,an1eraid the error of fallingoff turn. Because the termmatlOn condltlon IS1,p and q are pointing to. Theeffect of "call-by-reference"isaccomplishedby 1Declaring a function parameter to be a pointer 2Using the dereferenced pointer in the function body 3Passing an address as an argument when the function is called The RelationshipBetweenArraysandPointers An array name by itself isan address, or pointer value,and pointers, as well asarrays, can besubscripted. Although pointersand arraysare almost synonymous in terms of howthey are used toaccessmemory,there aredifferences, and these differencesare subtle and important. A pointer variable can take different addresses as values. In con-trast,an array name is an address, or pointer, that isfixed. Supposethataisan array andthatiisan int. It isafundamentalfactthat the expression 254 Chapter 6...Arrays,Pointers,andStrings a[; ] i s equivalent to*(a+i) Theexpression a [i ]hasthe valueof theith elementof thearray (counting from 0), whereas~ ' ( a+i) is the dereferencing of the expression a+i, a pointer expression that pointsielement positions past a. If p isa pointer,then in asimilar fashion the expression p [i ] is equivalent to*(p+i) Thismeans that wecan (and do) use array notation with pointers. Expressionssuch as a+iand p+iareexamples of pointer arithmetic. Theexpression a+ihas as its value the ith offset from the base address of the array a.That is, it points to theith ele-ment of the array (counting from 0).In asimilar manner,p+iistheith offset from the value of p.The actual address produced by such an offset depends on the type that p points to. When an array is declared, the compiler must allocate a sufficient amount of contigu-ous space in memory tocontain all theelements of the array.The base addressof the array isthe initial location in memory where the array isstored; it isthe address of the first element (index 0) of the array.Consider the following declarations: #defineN100 inta[N],i,*p,sum=0; Suppose that thesystem assigns300 as the base address of the array and that memory bytes numbered300,304,308,...,696 are allocated asthe addressesof a[0], a[l], a [2J, ..., a [99], respectively. Weare assuming that each byte is addressable and that 4 bytes are used to store an i nt. This is system-dependent. The statement p=a;i s equivalent top== &a[0]; It causes300 to be assigned top.Pointer arithmetic providesan alternativeto array indexing. The statement p== a+1;isequivalent top= &a[l]; It causes304to be assigned top.Assuming that the elementsof a have been assigned values, wecan use the following code to sum the array: for(p=a;p=N) error_exit_too_rnany_words(); if(strlen(word)>=MAXWORD) error_exit_word_too_long()j If there are too many words, weprint an error message and exit. If there are .too many characters in the word read in by scanfO, weprint an error message and eXit.Bycall-ing error functionstodothis, wereduce the clutter in rnai nO wei]= ca11oc(str1en(word)+1,s;zeof(char)); The functioncallocO is in the standard library,and its function prototype is in stdlib. h.A function call such as ca11oc(n,sizeof( ... )) dynamically allocates space foran array of n elements, with each elementsi zeof( ... )bytes in memory, and returns a pointer to theallocated space.rmm-mum number of bytes needed to store the string word,including the end-of-strIng sen-tinel \0, isstr1 en(word)+ 1.(The+1 is important, and unfortunately it is to forget.)The functioncall oc ()dynamically allocates this space and returnsa pomter to it. The pointer is assigned to w[i ]. 6.13TArraysof Pointers287 Wecould have invoked rna 11 oc 0instead of call oc O. Either of the followingstate-would have worked just as well: wei]= rna110c((strlen(word)+1)i(s;zeof(char)); wei]=rna11oc((strlen(word)+1)); statements are equivalent because si zeof(char) has value 1. The reason for writ-it isto remind readersof thecodethat space foran arrayof chars isbeing sted. With call oc 0, the allocated space is initialized to zero, but with rna 11 oc 0 initialization takes place. Because weare going to overwrite the space, initialization isnot needed. if(w[i]==NULL) error_exit_calloc_fai1ed(); Good programming practice requires that wecheck the return value from call oc 0 rna 11 oc O. If the requested memory is unavailable,NULLis returned.If that is the case, weprint an error message and exit. strcpy(w[i],word); After space has been allocated,the functionstrcpyO isused to copy word into mem-ory starting at the address w[i]. Wecan think of w as an array of words. 17 sort_words(w,n); wrt_words(w,n); o 2 3 w Ii 1s 1\01 Iflolrl\01 !alplplllel\01 l!frl yl.1 \01 /*sortthewords*/ /*wri tesorted1 i stofwordsif / Thefunctionsort_wordsOis used to sort the words in the array w lexicographically. Then wrt_wo rds 0is used to write the sorted list of words on the screen. 288Chapter 6TArrays,Pointers,andStrings Nowwe want to look at the function so rt_wo rds O. It uses a transposition sort is similar in flavorto a bubble sort. In filesort.c #include"sort.h" voidsort_words(char'1'w[J,intn)!*nelementsaretobesorted { } i nti,j; for(i=0;i"p; i nti; p=a; for(i0;i0&& a[iJ==0;--i) /1< putchar(''); 0,9,9,0, 9,6,7,7}; II Afteraleadingdigitgreaterthanzeroisfound, II printalltheremainingdigits,includingzeros. i'l } for(;i>=0;--i) printf("%d",a[iD; putchar('\n'); 8,8}; ...Exercises When we execute this program, here is what appears on the screen: Integera: Integerb: Sum: 88099005798957 776988213 5 77 88875994012534 319 Note that the digitsare stored in array elements going from element 0to element N1, but that the digits are printed in the opposite order. To understand this pro-gram,review how you learned todo addition in grade school. Writea similar pro-gram that computes the product of two integers. Thesi zeof operator can be used tofindthe number of bytes needed tostore a type or an expression. When applied to arrays, it does not yield the size of the array. What gets printed? Explain. #include voidfCinta[]); intmainCvoid) { char char int double s [] i'p a[3] ; d[5] ; "deepintheheartoftexas"; "deepintheheartoftexas"; printfC"%s%d\n%s%d\n%s%d\n%s%d\n" , "sizeof(s)"sizeof(s), "sizeof(p)"sizeof(p), "sizeof(a)"sizeof(a), "sizeof(d)"sizeof(d)); f(a); return0; } voidfCinta[J) { pri ntf("InfO:s1 zeof(a)%d\n",sizeofCa)); } If UNIX is available to you and you are familiar with the diffutility,try the following experiment. Usethe two statements printf("abc\n");andpri ntfC"a%cb%cc\n",'\0', \0') ; to write two versions of an elementary program that writes on the screen. Use redi-rection to put the printout of the respective programs into two files,say tmpl and 320 Chapter 6..,Arrays,Pointers,andStrings tmp2. If you use the UNIX utility cal to print first one fileon the screen and then other, you will not see any difference. Now try the command difftmp 1tmp2 Doyou see what the confusion is? Explain.Hint:Usethe ad command with the option to geta morecomplete view of what is in the files.Bythe way,why did '''le use the %cformat? Why not just print the string "a\0b\0c\n"? 26In traditional C,changing the contents of a string constant wasallowed,although it wasconsidered poor programming practice to doso.In ANSIC,the programmer it;;not supposed to be ableto changeastring constant. However,compilers vary in their ability toenforce this.Consider the followingcode: char"'p="abc"; "'p='X'; printf("%s\n",p); /*illegal?"1:/ /*Xbcgetsprinted?*/ Onour system,one of our compilers does not complain and the program executes, whereas another compiler exhibits a run-time error. What happens on your system? 27Consider the followingcode: char""p="abc","'q="abc"; if (p==q) printf(flThetwostringshavethesameaddress!\n"); else printf(ltAsIexpected,theaddressesaredifferent.\n"); Both p and q have been initialized tothe base address in memory of astring con-stant--namely,"abc". Notethat p==qtests whether twopointer valuesarethe same; it isnot a test forequality of the contents of the strings pointed toby p and q.Arethere twostring constants in memory or onlyone? This is compiler-depen-dent.Moreover,many compilers providean option that determines whether all string constants with the same content get stored separately or as just one string. In traditional C,becausestring constants could be overwritten, string constants with thesamecontent were usually stored separately. (Seeexercise26,on page 320.) In contrast to this, many ANSI C compilers store them in the same place. What happens on your system? ..,Exercises 321 The ANSIC committee has introduced the type qualifier canst as a new keyword in theC language. Here is an example of its use: constchar"l:p; He:e,thetypequalifierconst tellsthecompiler that thecharacter in memory pomted toby p should not be changed. (Read"pisa pointer to aconstant char.") Compilers vary on their ability to enforce this. Try the followingcode: char constchar s[]="abc"; "'p=Sj ""p='A'; printf("%s\n",s); 1'"ill ega l?, ~/ Does your compiler complain? (ItshOUld.) A lot of effort has been expended on the problem of machine translation. How suc-cessful is a naive approach? Gotoa library to findout what the most common, say 100,English wordsare.Consult, forexample,TheAmerican HeritageWord Fre-quency Book by John Carroll et al.(Boston, MA:Houghton Mifflin,1971). Write down the100 words and, with the help of a foreign language dictionary, write down their translation. Writea program that uses twoarrays such as char"l:foreign[100] ,"l:english[100]; to translate foreign text to English. Test your program. (You may be surprised at the results.) Instead of 100 words,try 200. Does your program produce a Significantly better translation? 30A simple encryption scheme isto interchange letters of thealphabet on aone-to-one basis. Thiscan be accomplished with atranslatipn table fortheS2lower- and uppercase letters. Writea program that usessuch aschemetoencode text.Write another program that willdecodetext that has been encoded. This isnot aserious encryption scheme. Doyou know why? If you are interested, learn about amore secure encryption system and then program it. If UNIXis availableto you,read the on-linemanual concerningcrypt to get the flavorof someof theconcerns in the area of encryption. 322Chapter 6TArrays,Pointers,andStrings 31What gets printed? Explain. #include voidtry_rne(int[J[3J); intrnain(void) { } i nta[3J [3J try_rne(a); return0; {{2,5,7},{0,-1,-2},{7,9,3}}; voi dtry_rne(i nt(i'a) [3]) { pri ntf("%d%d%d%d.i nfi ni ty\n" , } a[IJ [0J,-a[IJ [IJ,a[0J [0J,a[2J [2]); Now,changethe declaration of the parameter in the header of the functiondefini-tion of try_rneOto intand leavethe rest of thecodealone.Does yourcompilercomplain?(Itshould.) Explain. 32Choose acharacter and use atwo-dimensional array that matches the size of your screen to graph on the screen the functionssin 0and cos 0from 0 to21t.Because, on most screens,thespace in which acharacter isprinted is not square,there is horizontal/vertical distortion.Experiment with your graphstoseeif youcan remove thisdistortion. 33Writeout adissection forthe followingprogram. An understanding of thestorage mapping function isneededtoexplain it.Acompleteexplanation of thelast pri ntfOstatement is rather technical and should be attempted only by advanced computer sciencestudents. TExercises #include intrnain(void) { } inta[3][5J,i,j, *p=*a;/*aniceinitialization!*/ for(i=0;i" type.Doesthis make your compiler happy? 43(Advanced)The follovvingprogram has an error in it: #include #include intmain(void) { char*pl"abc",>"p2="paci fi csea"; printf("%s%s%s\n",pI,p2,strcat(pl,p2; return0; } On our system, what happens iscompiler-dependent. Withoneof our compilers, the program exhibitsa run-timeerror. With another compiler, weget the following written tothescreen: abcpacificseaacificseaabcpacificsea 328Chapter 6TArrays,Pointers,andStrings This output makes sense and tells us something about the compiler. What program-ming error did we make? What does the output tell us about our compiler? Which is the preferred behavior:acompiler that produces executablecodethat exhibits a run-time error,or a compiler that produces (sometimes) logically incorrect output? 44A function name by itself istreated by the compiler asa pointer. This isa general rule in C.Isthe following code legal? #include voidf(void); voidg(void); voidh(void); intmain(void) { } ("'f) 0; return0; voidf(void) { } pri ntf("Hell 0fromfO. \n") ; ((("'g))) 0; voidg(void) { } printf("HellofromgO.\n"); C'" (>', ("'h))) 0; voidh(void) { pri ntf("Hell 0fromhO. \n") ; } Write your answer before you try tocompile the program. Youranswer should be based on your general knowledgeabout how wellaC compiler can be expected to followa rule,even if the rule isapplied in some strange way. 45A precondition fortherootOsolver towork isthat f(a)and feb)must have opposite signs. Usean assertion at the beginning of root 0to check this condition. TExercises329 46Theancient Egyptianswrote in hieroglyphics.In thissystem of writing,vowel sounds are not represented,only consonants. Iswritten English generally under-standable without vowels?Toexperiment,writeafunctioni 5_ vowe 1 0that returns 1if a letter isa vowel and 0 otherwise. Use your function in a program that readsthestandard input fileand writestothestandard output file,deleting all vowels.Use redirection on a filecontaining some English text to test your program. hapter 7 BitwiseOperatorsand EnumerationTypes . Thereare twoadditional waystorepresent discrete values:as bits and as elements in a finiteset.In this chapter, wefirstdiscuss the bitwise operators. Even though expres-sions involving bitwise operators are explicitly system-dependent, they are very useful. Weillustrate their usefulness in packing and unpacking data. In thesecond half of thechapter, wediscusstheenumeration types.Enumeration typesareuser-defined typesthat allowtheprogrammer to name a finiteset together with itselements, which arecalledenumerators. These typesaredefined and used by the programmer asthe need arises.Weillustrate much of this material by implement-ing a completely worked out interactive game program. 7.1Bitwise OperatorsandExpressions Thehitwiseoperators acton integral expressions represented as strings of binary dig-its. Theseoperators are explicitly system-dependent. Wewill restrict our discussion to machines having8-bit bytes, 4-bytewords,thetwo'scomplement representation of integers,and ASCIIcharacter codes. 332Chapter 7TBitwiseOperatorsandEnumerationTypes Bitwiseoperators Logicaloperators(unary) bitwise complement bitwise and& bitwise exclusive orA bitwise inclusive or Shift operatorsleft shift right shift like other operators,the bitwise operators have rulesof precedence and associativity that determine how expressions involving them are evaluated. OperatorsAssociativity 0[]++(postfix)(postfix)left to right ++(prefix)(prefix)!sizeof(type)+right to left (unary)- (unary)&(address)-{, (dereference) */%left to right +left to right left to right =left to right left to right & left to right A left to right left to right && left to right IIleft to right ? right to left += ,;'(::::::/right to left 'Yo= ==&=A= 1= (comma operator) left to right 7.1TBitwiseOperatorsandExpressions333 operator ~is unary; all the other bitwise operators are binary. They operate on inte-expressions. Wewill discuss each of the bitwise operators in detail. itwise Complement . The operator - is called the one's complement operator, or the bitwise complement oper-. It inverts the bit string representation of its argument; the Osbecome Is, and the become Os.Consider, for example, the declaration inta=70707; The binary representation of a is 00000000000000010001010000110011 Theexpression ~ ais the bitwisecomplement of a,and this expression has the binary representation 11111111111111101110101111001100 The; nt value of the expression -a is -70708. Two'sComplement Thetwo'scomplement representationof anonnegativeintegernisthe bitstring obtained by writing n in base 2.If wetake the bitwise complement of the bit string and add 1 to it, weobtain the two's complement representation of -noThe next table gives some examples. Tosave space, weshow only the two low-order bytes. BinaryTwo'scomplementValue representationBitwisecomplementrepresentationof -nof -n! 7000000000000011111111111111110001111111111111001-7 8000000000000100011111111111101111111111111111000-8 9000000000000100111111111111101101111111111110111-9 -71111111111111001000000000000011000000000000001117 The preceding table is read from left toright.If westart with a positive integern, consider its binary representation, and take its bitwise complement and add 1,then we 334Chapter 7..BitwiseOperatorsandEnumerationTypes obtain the two's complement representation of -noA machine that uses the two's com-plement representation as its binary representation in memory for integral values is called atwo's complement machine. On a two's complement machine, if we start with the binary representation of a nega-tive number -n and take its bitwise complement and add 1, we obtain the two's comple-ment representation, or binary representation, of n.This is illustrated in the last line in the preceding table. The two's complement representations of both 0and -1arespecial. The value 0has all bits off; the value -1 has all bits on. Note that if a binary string is added to its bitwise complement, then the result has all bits on, which is the two'scomplement representa-tion of -1. Negative numbers are characterized by having the high bit on. On atwo'scomplement machine, the hardware that does addition and bitwisecom-plementation can be used to implement subtraction. The operation ab is thesame as a+(-b), and -b is obtained by taking the bitwise complement of b and adding 1. BitwiseBinaryLogicalOperators Thethree operators & (and),A (exclusiveor),andI (inclusive or)are binary operators. They take integral expressions as operands. Thetwo operands, properly widened,are operated on bit position by bit position. The followingtable shows the bitwise opera-tors acting on I-bit fields.The table defines the semantics of the operators. Valuesof: aba&baAbalb 00000 10011 01011 11101 The next table contains examples of the bitwise operators acting on i nt variables. 7.1..BitwiseOperators andExpressions335 Declarationandinitializations inta= 33333,b~-77777; ExpressionRepresentationValue a0000000000000000100000100011010133333 b11111111111111101101000000101111-77777 a& b0000000000000000100000000010010132805 aAb11111111111111100101001000011010-110054 aIb11111111111111101101001000111111-77249 ~ ( aIb)0000000000000001001011011100000077248 0000000000000001001011011100000077248 Left andRight Shift Operators Thetwo operands of ashift operator must be integral expressions. The integral promo-tions are performed on each of the operands. The typeof the expression as a whole is that of its promoted left operand. An expression of the form exprlexpr2 causes the bit representation of exprlto be shifted to the left by the number of places specified by expr2.On the low-order end, Osare shifted in. I Declarationandinitialization charc=IZ '; ExpressionRepresentationAction c00000000000000000000000001011010i unshifted ,c100000000000000000000000010110100left-shifted 1 c400000000000000000000010110100000left-shifted 4 c3100000000000000000000000000000000left-shifted 31 Even though cis stored in 1 byte, in an expression it gets promoted toan i nt. When shift expressionsare evaluated, integral promotions are performed on thetwooper-336Chapter7TBitwiseOperatorsandEnumeration Types andsseparately,and the typeof the result isthat of the promoted left operand. Thus, the valueof an expression such asc1 gets stored in 4 bytes. The rightshift operator isnot symmetric tothe left shift operator. For unsigned integralexpressions,Osareshifted in atthe high end.Forthesignedtypes,some machinesshift in Os,whileothers shift insign bits.(Seeexercise 4,on page357.) sign bit is the high-order bit; it is 0 for nonnegative integers and 1 for negative Inreg-,ers Declarationsandinitializations i i nta=131;I" shift1tothehighbit*1 unsignedb131; ExpressionRepresentationAction a10000000000000000000000000000000unshifted a311110000000000000000000000000000right-shifted 3 b10000000000000000000000000000000unshifted b300010000000000000000000000000000right-shifted3 Notethat on our machine,sign bits areshifted in with an i nt. On another machine, Os. might beshifted in.Toavoidthisdifficulty,programmersoften use unsigned type& when using bitwise operators. If the rightoperand of ashift operator isnegativeor hasavaluethatequalsor exceedsthenumber of bits used to representthe leftoperand,then the behavior is undefined. It isthe programmer's responsibility tokeepthe valueof the rightoperand within proper bounds. Our next table illustrates the rules of precedence and associativity \ith respect to the shift operators. Tosave space, weshow only the two low-order bytes. Declarationandassignments unsigneda1,b=2; ExpressionEquivalentexpressionRepresentation ab1(ab)10000000000000010 a1+23(a(1+2))30000000001000000 a+b121,ab((a+b)(12*a))b0000110000000000 In C++,the twoshift operatorsareoverloaded and used for input/output.ing in C++isa method of giving existing operators and functionsadditional meanings. (SeeSection 13.5, "Overloading," on page 603,forexamplesand explanation.) 7.2vMasks Masks A mask is aconstant or variable that is used toextract de SIr' ed b't ' l'h.. . bl'.."1Srom anoter varI-ae or expreSSIOn.Because the1 nt constant 1 has the bit representation 00000000000000000000000000000001 it can b.eused to the low-order bit of an int expression. The followingcode uses this mask and prmts an alternating sequence of Osand Is: inti,mask= 1; for(i= 0;ilose_cnt) printf(ltCONGRATULATIONSYouwon!\n\n"); elseif(win_cnt==lose_cnt) printf(ltADRAW - Youtied!\n\n"); else printf(ltSORRY- Youlost!\n\n"); voidprn_game_status(intwin_cnt,intlose_cnt,inttie_cnt) { } printf(lt\n%s\n%s%4d\n%s%4d\n%s%4d\n%s%4d\n\nlt, "GAMESTATUS: It, ItWin :"wi n_cnt , "Lose:"1ose_cnt, "Tie:"tie_cnt, "Total:"win_cnt+lose_cnt+tie_cnt); voidprn_help(void) { printf("\n%s\n", "Thefollowingcharacterscanbeusedforinput:\n" Itpforpaper\n" "rforrock\n" IIsforscissors\nltIIgprintthegamestatus\n" "hhelp,printthislist\n" "ireprinttheinstructions\n" "qquitthisgame\n"); } 352 } Chapter7'YBitwiseOperatorsandEnumerationTypes voidprn_instructions(void) { printf("\n%s\n", "PAPER,ROCK,SCISSORS:\n" :: ~ nthisgamepisfor\"paper, \"risfor\"rock, \"and" s1Sfor\"scissors.\"\n" "Boththeplayerandthemachine\n" "willchooseoneofp,r,ors." "Ifthetwochoicesarethesame,\n" " " " H\n" thenthegameisatie.Otherwise:\n" \"papercoverstherock\"(awin \"rockbreaksthescissors\"(awin \"sci ssorscutthepaper\"(awi n forpaper),\n" forrock), \n" forscissors).\n" "There areotherallowableinputs:\n" " " " " If\n" g h i q forgamestatus(thenumberofwinssofar)\n" forhelp,\n"- , forinstructions(reprinttheseinstructions)\n" forquit(toquitthegame).\n"' ::\n"ThiSgameisplayedrepeatedlyuntilqisentered.\n" "Goodluck!\n"); To play the game, both the machine and the player (user) need to make a selection from "paper, rock,scissors." Wewrite these routines in selectionc: In fileselection.c #include"p_r_s.h" ~ _ r _ sselection_by_machine(void) return((p_r_s)(rand()% 3)); } 7.6TAnExample:TheGameof Paper,Rock,Scissors p_r_sselection_by_player(void) { } c; player_choice; printf("Inputp,r,ors:"); while(isspace(c=getchar())) , switch(c){ case'p': player_choicepaper; break; case'r': player_choicerock; break; case's' : player_choicescissors; break; case'g I: player_choicegame; break; case'i I: player_choiceinstructions; break; caseIq' : player_choicequit; break; default: } player_choicehelp; break; returnplayer_choice; /*skipwhitespace*/ 353 Themachine's selection iscomputed by the uses of the expressionrand 0% 3 to pro-ducea randomly distributed integer between 0 and 2.Becausethetype of the function isp_s_r, the value returned will be converted tothis type, if necessary. Weprovided an explicit cast tomake the code more self-documenting. Notethat in selection_by_playerOweuse the macro isspaceOfrom ctype.h to skip whitespace.(SeeSection 8.7,"The Macros in stdio.hand ctype.h,"on page382.) After whitespace isskipped,allother characters input at the terminal are processed, most of them through the defaul tcase of theswi tch statement. Thevaluereturned by selection_by_playerOdetermines whichcase gets exe-cuted in theswi tch statement in rna in O. Thevaluereturned dependson what the player types.If the character 9 isinput,then prn_game_statusOis invoked;if any character other than whitespaceorp,r,s,g,i, or q is input,thenprn_hel pOis invoked. 354Chapter7...BitwiseOperatorsandEnumeration Types Once the player and the machine have made a selection, we need tocompare the two selections in order to determine the outcome of the game.The following function does this: In filecompare.c #include"p_r_s.h" } outcomeresult; if(player_choicemachine_choice) returntie; switch(player_choice){ casepaper: result=(machine_choicerock)?win:lose; break; caserock: result=(machine_choicescissors)?win:lose; break; casesci ssors: result=(machine_choicepaper)?win:lose; break; default: } printf("\nPROGRAMMERERROR:Unexpectedchoice!\n\n"); exit(l); returnresult; The value returned by the calltocompareOin mai nOgets passed tothefunction report_and_tabulateO. This function reports to the user the result of a round of play and increments as appropriate the number of wins, losses,and ties. 7.6...AnExample:The Gameof Paper,Rock,SCissors In filereport.c #include"p_r_s.h" voidreport_and_tabulate(outcomeresult, { } int*win_cnt_ptr,int*lose_cnt_ptr,int*tie_cnt_ptr) switch(result){ casewin: ++i'wi n_cnt_ptr; printf("%27sYouwin.\n",""); break; caselose: ++*lose_cnt_ptr; printf("%27sYoulose.\n",""); break; casetie: ++'''ti e_cnt_ptr; printf("%27sAtie.\n",""); break; default: } pri ntf("\nPROGRAIVIMERERROR:Unexpectedresult! \n\n"); ex;t(l); Weare now ready to compile our function. Wecan do this "'lith the command cc-0PJ_Smain.ccompare.cprn.creportcselection.c Later,after wehave learned about the make utility, wecan facilitateprogram develop-ment by using an appropriate makefile.(SeeSection 11.17, "The Useof make,"on page 532.) 356Chapter 7'fBitwiseOperatorsandEnumerationTypes Summary 1The bitwise operators provide the programmer "vith a means of accessingthe bits in an integral expression. Typically, we think of the operands of these operators as bit strings. 2The use of bitwise expressions allows for data compression across byte boundaries. Thiscapability is useful in saving space, but is more useful in saving time.On a machine with 4-byte words, each instruction cycle processes 32bits in parallel. 3Most machines use the two's complement representation for integers. In this repre-sentation,the high-order bit is thesign bit. It is1 for negative integers andafor nonnegative integers. 4Bitwiseoperations areexplicitly machine-dependent. A leftshift causes as to be shifted in.The situation for a right shift is more complicated. If the integral expres-sion is unsi gned, then as are shifted in. If the expression is one of the signed types, then what getsshifted in is machine-dependent. Some machines shift tn sign bits. This meansthat if thesign bit is0,then Osareshifted in,and if thesign bit is1, then Is are shifted in.Some machines shift in as in allcases. 5Masksare particular values usedtypically with the &operator toextract agiven series of bits. Packing is the act of placing a number of distinct values into various subfields of agiven variable. Unpacking extracts these values. 6The keyword enumallowsthe programmer todefineenumeration types.A variable of such a type can take values from the set of enumerators associated with the type. 7Enumerators aredistinct identifiers chosen fortheir mnemonic Significance. Their use provides atype-checking constraint forthe programmer,as wellasself-docu-mentation for the program. 8Enumerators areconstants of typei nt.they can be used in case labels in a swi tch. A cast can be used to resolve type conflicts. 'fExercises357 Exercises 1Supposethat integers have a16-bit two'scomplement representation. Write the binary representation for-1, -5, -101, -1023. Recall that the two's complement rep-resentation of negative integers is obtained by taking the bit representation of the corresponding positive integer, complementing it,and adding 1. 2Alice, Betty, and Carole all vote on 16 separate referenda. Assume that each individ-ual's vote isstored bitwise in a16-bit integer.Writeafunctiondefinition that begins shortmajority(shorta,shortb,shortc) { This function should take as input the votes of Alice,Betty,and Carole stored in a, b,and c, respectively. It should return the bitwise majority of a,b,and c. 3Write a function definition that begins intcircular_shift(inta,intn) { This function should left-shift aby n positions, where the high-order bits are rein-troduced as the low-order bits. Hereare two examples of acircular shift operation defined for achar instead of an i nt: 10000001 01101011 circular shift 1 yields circular shift 3 yields 00000011 01011011 4Doesyour machine shift in sign bits? Here issome code that will help you deter-mine this. Explain why this code works. int unsigned i u -1; -1; if(i1u1) /*turnallbitson*/ printfC"Zerosareshiftedin.\n"); else printf("Signbitsareshiftedin.\n"); 358Chapter 7TBitwiseOperatorsandEnumeration Types 5Writeafunction that will reverse the bit representation of an i nt. Here are two examples of a reversing operation defined for achar instead of an i nt: 01110101 10101111 reversed yields reversed yields 10101110 11110101 6Writea function that will extract every other bit position from a32-bit expression. The result should be returned as a16-bit expression. Your function should work on machines having eIther 2- or 4-byte words. 7Write a function that takes as its input astring of decimal integers.Each character in the string can be thought of as adecimal digit. The digits should be converted to 4-bit binary strings and packed into an i nt. If an i nt has32 bits,then eight digits can be packed into it. When you test your function,here is what you might see on the screen: Inputastringofdecimaldigits:12345678 12345678=00010010001101000101011001111000 Also,write an inverse function.It should unpack an i nt and return theoriginal string. Hint:Here is one way to begin aconversion function: intconvert(char*s) { char;'p; inta= 0;/*turnallbitsoff*/ for(p= s;*p!='\0';++p){ a=4; swi tch('>"p){ case'1': a1=1; break; case'2': 8Use thebi Lp ri nt 0function to create a table containing n,the binary representa-tion for2n,and the binary representation for2n,forn =0,1,2,...,32. If your machine has 2-byte words, then the output of your program should look like this: 0:0000000000000001 1:0000000000000010 2:0000000000000100 15:1000000000000000 0000000000000000 0000000000000001 0000000000000011 0111111111111111 TExerCises 359 After you havedonethis, write dovVllasimilar table by hand that contains n,lOn, and lOn - 1 forn =0,1,2, ..., 7.Writethe numbers in base 10 in your table. Do you see the similarity between the two tables? Hint:UsefollOwingcode: ; nti,power1; for(i=0;i to access the members of a structure via a pointer. (Thisoperator istyped on the keyboard asa minus sign followed by a greater than sign.) If a pointer variable is assigned the address of a structure, then a member of the structure can beaccessed by a construct of the form pointerJo_structure -> member_name A construct that is equivalent tothis is (*pointer_to_structure). member_name The parentheses are necessary. Along with 0and[J, the operators '.'-"and -> havehighest precedence and associate from left to right. Thus,the precedrng construct WIth-out parentheses would be equivalent to jo_structure. member_name) This is an error because only a structure can be used with the "."operator, not a pointer to a structure. Let us illustrate the use of -> by writing a function that adds complex numbers. First, suppose we have the followingtypedef in a header file: In filecomplex.h struetcomplex{ doublerei doubleim; }; realpart I Ii'i magpart*1 414 Chapter 9TStructuresandUnions typedefstructcomplex complex; Then in another filewewrite #include"complex.hl! voidadd(complex*a,complex*b,complex*c) { } a->re== b->re+c->rei a->im== b->im+c->im; a== b+cif I that a,b,and c are pointers to structures. If wethink of the pointers as represent-mg complex numbers, then weare adding band cand putting the result into a.That is the sense of the comment that followsthe header to the function definition. In the followingtable, wehave illustrated someof the waysthat the two member accessoperatorsbe used.Inthetable,weassumethat the user-definedtype structstudent, which we presented earlier, has already been declared. Declarationsandassignments structstudenttmp,*p= &tmp; tmp.grade== 'A'; tmp.last_name"""Casanova"; tmp.student_id910017; Expression Equivalentexpression Conceptual value tmp.grade p->gradeA tmp . 1 ast_name Casanova ("'p).d ->studenCid910017 (*(p->last_name+1D *(p->last_name+2) (p->last_name)[2Js 9.3VOperator PrecedenceandAssociativity:A FinalLook415 & 9.3Operator PrecedenceandAssociativity: AFinalLook Wenow want to display the entire precedence and associativity table forallthe C oper-ators. The operators" . " and -> have been introduced in this chapter. These operators, together with0and[], have the highest precedence. OperatorsIAssociativity 0[]->++(postfix)--- (postfix)Ileft toright ++(prefix)-- (prefix)Isizeof(type)right to left +(unary)- (unary)&(address)*(dereference) *I%left to right i+left to right left toright =left toright ==!=left to right &left to right Aleft to right 1left to right && left to right left toright I 7:right to left I +== -="'=Irighttoleft %= ==&=A= 1= ,(comma operator)left to right Although the complete table of operators is extensive,somesimple rules apply. The primary operators are function parentheses, subscripting, and the twomember access operators. These four operators are of highest precedence. Unary operators come next, followed by the arithmetic operators. Arithmetic operators follow the usual convention; namely,multiplicative operators havehigher precedence than additiveoperators. Assignments of all kinds are of lowest precedence, with the exception of thestill more lowly comma operator. If a programmer doesnot know the rulesof precedence and 416 Chapter 9TStructuresandUnions associativity in a particular situation, he or she should either look up the rules or use parentheses. If you work at a particular location on a regular basis, you should consider copying this table and pasting it on the wall right next to where you work. 9.4 UsingStructureswithFunctions In C,structures can be passed asargumentsto functionsand can be returned from them. Whena structure is passed as an argument to a function,it is passed by value, meaning that a local copy is made for use in the body of the function.If amember of the structure is anarray,then the array gets copied aswell.If the structure has many members,or members that are large arrays,then passing the structure as an argument can be relatively inefficient. For most applications, an alternate scheme is to write func-tions that take an address of the structure as an argument instead. BUsinessapplications often use structures that have lots of members. Let us imagine that we have such a structure: typedefstruct{ char int structdept structhome_address double }employee_data; name[25]; employee_id; department; 1'a_ptr; salary; Noticethat the department member is itself astructure. Becausethe compiler has to know the size of each member,the declaration forstructdept has to come first.Let us suppose that it was given by structdept{ chardept_name[25]; intdepLno; } ; Notice that the a_pt r member in the type definition of emp 1oyee_data isa pointer to a structure. Because the compiler already knowsthe size of a pointer, this structure need not be defined first. Now,suppose we want to write a function to update employee information. There are two ways wecan proceed. The first way is as follows: 9.4TUsingStructures withFunctions employee_dataupdate(employee_datae) { printf("Inputthedepartmentnumber:It); scanf(lt%d",&n); e.department.dept_no=n; returne; } Notice that weare accessing a member of a structure within a structure, because e.department.dept_nois equivalent to(e.department).dept_no To use the functionupdateO, wecould write in mai nOor in some other function employee_datae; e=update(e); 417 Here,eis being passed by value,causing a local copy of eto be used in the body of the function;when astructure is returned fromupdateO, it is assigned toe,causing a member-by-member copy to be performed. Because the structure is large,the compiler must do a lot of copy work. An alternate way to proceed isto write voidupdate(employee_data1'p) { printf("Inputthedepartmentnumber:It); scanf("%d",&n)j p->department.dept_no=n; In this example, the construct p->department. dept_noisequivalent to(p->department). dept_no This illustrates how a member of a structure withinastructure 'can be accessed viaa pointer. To use this version of the update 0function,wecould write in mai n ()or in some other function employee_datae; update(&e)j Here,theaddressof eis being passed,so no local copy of thestructure isneeded within theupdate 0function.For most applications this isthe more efficient of the twomethods. (Seeexercise5,on page 438, for further discussion.) 418Chapter 9TStructuresandUnions 9.5Initialization of Structures Allexternal and static variables, including structures, that arenot explicitly initialized by the programmer are automatically initialized by the system tozero. In traditional C, only external and static variablescan be initialized. ANSIC allowsautomatic variables, including structures, to be initialized as well. Thesyntax for initializing structures issimilar to that for initializing arrays. A struc-ture variable in a declaration can be initialized by following it with an equal sign and a list of constants contained within braces. If not enough values are used to assign all the membersof thestructure,theremaining membersareassignedthevaluezero by default. Some examples are cardc={l3,'h'};/*thekingofhearts*/ complexa[3][3J={ {{1.0,-0.1},{2.0,0.2},{3.0,0.3}}, {{4.0,-0.4},{5.0,0.5},{6.0,0.6}}, };/*a[2J[Jisassignedzeroes*/ structfruitfrt={"plum",150}; structhome_address{ char char ty_and_state; longzip_code; }address={"8?WestSUeet","Aspen,Colorado",80526}; structhome_addressprevious_address={0}; The last example illustrates a convenient way to initialize all members of a structure to have value zero. It causes pointer members to be initialized with the pointer valueNULL and array members to have their elements initialized to zero. 9.6TAnExample:PlayingPoker419 9.6AnExample:PlayingPoker Letus use theconcepts that wehave presented thus far in thischapter to writeapro-gram toplay poker.The program willcompute the probability that aflush isdealt, meaning that allfivecards in a hand areof the samesuit. In theexercises, wewill dis-cuss ways of extending the program.Caution:Weare going to redesign our card struc-ture. Our program consists of many small functions.Thesimplest scheme istoput them all in one file.Wewill present the functionsone after another asthey occur in the file. Whereappropriate, wewilldiscuss key ideas. Here is what occurs at the top of the file: In filepoker.c #include #include #include #define #define NDEALS NPLAYERS 3000 6 /*numberofdeals*/ /*numberofplayers*/ typedefenum{clubs,diamonds,hearts,spades} structcard{ intpips; cdhssuit; }; typedefstructcardcard; cdhs; Weare envisioning a game with six players. Because weare interested in the probability of a flush occurring, wewant todeal many hands.Noticethat the member sui tis an enumeration type. Aswewillsee,the use of the enumeration type makes the code very readable. Next in the filecomes the function prototypes: cardassign_values(intpips,cdhssuit); voidprn_card_values(card"'c_ptr); voidplay_poker(carddeck[52J); voidshuffle(carddeck[52J); voidswap(card*p,card*q); voiddeal_the_cards(carddeck[52J,cardhand [NPLAYERSJ[5J); intis_flush(cardh[5J); 420 Chapter 9...Structures andUnions Webegin our program development with mai nO. Every time weneed anew function, we write it at the bottom of the fileand put its function prototype in the list just above mainO. intmain(void) { } cdhssuit; i nti,pi ps; carddeck[52]; for(i=0;itop= EMPTY; } voidpush(charc,stack*stk) { stk->top++; stk->s[stk->top]= c; } boolean; 432Chapter 9TStructures andUnions charpop (stack*stk) { } return(stk->s[stk->top--]); chartop (canststack*stk) { } return(stk->s[stk->top]); booleanempty(conststack*stk) { } return((boolean)(stk->top-- EMPTY; booleanfull(conststack*stk) { return((boolean)(stk->top } FULL; Dissectionof thestack Implementation typedefenumboolean{false,true}boolean; Weusethistypedef togivea new name,bool ean,totheenumeration type,enum boo 1 ean. Notethat the new name coincides with the tag name. Programmers often do this.. typedefstructstack{ chars[MAX-LENJ; inttop; }stack; Thiscodedeclaresthestructure typestructstack, and at thesametime uses a typedef to givestructstack the new name stack. Here is an equivalent way to write this: structstack{ chars[MAX-LEN]; inttop; }; typedefstructstackstack; 9.10TTheADT Stack Thestructure has two members, the array member sand the i nt member top. voidreset(stack*stk) { stk->top= EMPTY; } 433 The member top in the stack pOinted to by stk is assigned the valueEMPTY.Thiscon-ceptually resets the stack, making it empty. In the calling environment, if st isastack, wecan write reset(&st); to reset st or initialize it At the beginning of a program, we usually start with an empty stack. voidpush(charc,stack*stk) { stk->top++; stk->s[stk->top] } charpop(stack*stk) { c; return(stk->s[stk->top--]); } Theoperation push isimplemented as a function of twoarguments. First,the member top is incremented. Notethat stk->top++is equivalent to(stk->top)++ Then the value of c is shoved onto the top of the stacIe This function assumes that the stack is not full.The operation pop is implemented in like fashion. It assumes the stack isnot empty. The value of the expression stk->top--isthe valuethat iscurrently stored in the member top. Suppose this value is7.Then stk->s [7J gets returned,and thestored valueof top in memory getsdecremented, making its value 6. 434Chapter 9vStructuresandUnions booleanempty(conststack*stk) { } retur