0% found this document useful (0 votes)
866 views218 pages

The C Answer Book - Solutions To The Exercises in The C Programming Language (Team Nanban) (TPB)

k and r

Uploaded by

Anonymous rmUPvb
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF or read online on Scribd
0% found this document useful (0 votes)
866 views218 pages

The C Answer Book - Solutions To The Exercises in The C Programming Language (Team Nanban) (TPB)

k and r

Uploaded by

Anonymous rmUPvb
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF or read online on Scribd
You are on page 1/ 218
AFHRMA BAB (3 FG) poo SECOND EDITION THE “si Coon ANSWER BOOK Solutions to the Exercises in The C Programming Language,second edition | by Brian W. Kernighan & Dennis M. Ritchie | at Wie Be f) JJ >) Rh fe S (S—hn) __CLOMIS TONDO SCOTT. GINPEL an + PRENTICE HALL an SEEey Not ~ tay The Answer Book Second Edition Solutions to the Exercises in The C Programming Language, Second Edition by Brian W. Kernighan and Dennis M. Ritchie _C Ei (he) ARS EO . ‘lovis-L2Tordo Kot E--Gipipel wna Prentice-Hall International, Inc. / GDREF 1585 / qe tn gf Spur ee The C answer book: solutions tothe exertises in The C programming lan- guage, second edition, by Brian W. Kernighan and Dennis M. Ritchie/ Colvis L. Tondo, Scott E. Gimpel. ~ 2nd ed. €1989 by PTR Prentice Hall, Original edition published by prentice Hall, Inc. , a Simon &. Schuster Com- pany. Prentice Hall 2S r] SAGE 427% oh ROGEL HE PB HK Ay C78 da TT SEK RY 1 AM a PH DA NT A BE EDA ADEA BS AE RSME BHR REDE AAD RRR Al. APBHDWA Prentice Hall MEM HRE KRESS. ACR RL BLS BIC. 01-97-1275 BB 2h B (CLP) RE C RFF RET TFB — Mi) >I IRAE» EX / (HI & (Tondo .C. L. ), (38) & DUAR (Gimpel »S.E. 3% . — EVAR . — AE AR Hh EAL» 1997. 11 KET FA AB ISBN 7-302-02728-5 1.C 1. OW Of 1.CHA- BF RTM IV. TP312-44 ft Bl AS PAL 5 CIP BB EF (97) 5 23936 F BERR: TRAE ACP ah RAL Ce SE EE BE A HB He 100084.) BUS SLE. www. tup. tsinghua. edu. cn EU a REA ET RAS: REDE REAR ARR FF A, 850X1168 1/32 Pak: 6.75 fi WK: 1997 E11 AS 1M 1998 4F 7 A 2 EDR 48 : ISBN 7-302-02728-5/TP + 1414 Fl %. 5001~10000 Oh: 12.00% HH AR BT Df BUNA AE BEI AE YT Be — PB A A BALAN A AT HE GE LT BE HE SP Es Se ES LSS HIREZ A ZC ES LARAMIE. TE PART fe TAB A SB SL FTE FS Fi By ER AAT A AY BEB SP SC EAL SR A FEI). AFL ERB A KPA KN FRE SWEAR. EK eT SUR RAY BY ALE BER Ay RS BER EL SW BER Z Sb SR TE Ee NRE TRB BR ER ST BER BY SEHR APES BER ee FRADE To 7 Ait EBL BLE Ar TB TP A HY BT EFT HR. PURE HH RBEAY 6 ASS SEB A AY RM A HR TR ER SDE SEE BIG. HE MAT AHH. Prentice Hall 205] AUR BA BH ALI OK A PEE BBB HE ZK OF BS SL A FREE POV A ABER TB FLAS ABD ek eT EBA BL SPER RM Te AE Prentice Hall 27] 1997.11 Preface This is an ANSWER BOOK. It provides solutions to all the exercises in The C Programming Language. second edition, by Brian W. Kernighan and Dennis M. Ritchie (Prentice Hall, 1988)* The American National Standards Institute (ANSI) produced the ANSI standard for C and K&R modified the first edition of The C Programming Language. We have rewritten the solutions to conform to both the ANST standard and the second edition of K&R. Careful study of The C Answer Book, second edition. used in conjunction with K&R, will help you understand C and teach you good C programming skills. Use K&R to learn C, work the exercises, then study the solutions pre- sented here. We built our solutions using the language constructions known at the time the exercises appear in K&R. The intent is to follow the pace of KAR. Later, when you learn more about the C language, you will be able to provide possibly better solutions. For example. until the statement A (expression) statement-1 else statement-2 is explained on page 21 of K&R, we do not use it. However, you could improve the solutions to Exercises 1-8, 1-9, and 1-10 (page 20 K&R) by using it. At times we also present unconstrained solutions. We explain the solutions. We presume you have read the material in KQR upto the exercise. We try not to repeat K&R. but describe the highlights of each solution. You cannot learn a programming language by only reading the language constructions. It also requires programming —writing your own code and study- *Hereafter referred to as K&R, ing that of others. We use good features of the language, modularize our code, make extensive use of library routines, and format our programs to help you see the logical flow. We hope this book helps you become proficient in C. We thank the friends that helped us to produce this second edition: Brian Kernighan, Don Kostuch, Bruce Leung, Steve Mackey, Joan Magrabi, Julia Mistrello, Rosemary Morrissey, Andrew Nathanson, Sophie Papanikolaou, Dave Perlin, Carlos Tondo, John Wait, and Eden Yount. Clovis L. Tondo Contents Preface v Chapter 1. A Tutorial Introduction 1 Chapter 2. Types, Operators, and Expressions 43 Chapter 3. Control Flow ES) Chapter 4. Functions and Program Structure Co) Chapter 5. Pointers and Arrays ” Chapter 6. Structures 151 Chapter 7. Input and Output 168 Chapter 8. The UNIX System Interface 188 Index 203 cHapteR1 A Tutorial Introduction Exercise 1-1: (page 8 K&R) Run the “hello, world” program on your system. Experiment with leaving out parts of the program to see what error messages you get include ¢stdio.h> main « printfC*hello, world"); > In this example the newline character (\n) is missing. at the end of the line. Winclude ¢stdio-h> main { printfC*hello, world\ > This leaves the cursor In the second example the semicolon is missing after print (2. Individual C statements are terminated by semicolons (page 10 K&R). The compiler should recognize that the semicolon is missing and print the appropriate message ‘include ¢stdio.h> main 4 printfCthello, world\n‘); > 2 The C Answer Book In the third example the double quote “ after \n is mistyped as a single quote. The single quote, along with the right parenthesis and the semicolon, is taken as part of the string. The compiler should recognize this as an error and com- plain that a double quote is missing, that a right parenthesis is missing before a right brace, the string is too long, or that there is a newline character in a string. A Tutorial Introduction == Chap. 1 3 Exercise 1-2: (page 8 K&R) Experiment to find out what happens when print ’s argument string contains \c, where c is some character not listed above. Finclude ¢stdio.h> main? 4 printfCthello, world\y")5 prantf(hello, world\7" prantf(*hello, world\7"; > ‘The Reference Manual (Appendix A, page 193 K&R) states If the character following the \ is not one of those specified, the behavior is undefined. The result of this experiment is compiler dependent. One possible result might be hello, worldyhello, world is a short beep produced by ASCII 7. It is possible to have \ followed by up to three octal digits (page 37 K&R) to represent a character. \7 is specified to be a short beep in the ASCII character set. 4 The C Answer Book Exercise 1-3: (page 13 K&R) Modify the temperature conversion program to print a heading above the table. finclude ¢atdio.h> /* print Fabrenheit-Celsius table for fahr = 0, 20, . . ., 300; floating-point version +/ main@? t float fahr, celsius; int lower, upper, step; lower + 0; /* lower limit of temperature table #/ upper = 300; /* upper limit ” step + 20; /* step size “ printf(*Fahe Celsius\n™); fahr = lowers while Cfahr ¢* upper) ¢ celsius = (5.0/9.0) © Cfahr-32.09; prantf("%3.0f 26.1f\n", fahr, celsius); fahr + fahr + step; , ‘The addition of printf("Fahr Celsius\n"); before the loop produces a heading above the appropriate columns. We also added two spaces between %3.0f and %6. 1 to align the output with the head- ing. The remainder of the program is the same as on page 12 K&R. ‘A Tutorial Introduction Chap. 1 5 Exercise 1-4: (page 13 K&R) Write a program to print the corresponding Celsius to Fahrenheit table. sinclude 7* print Celsius-Fahrenhert table for celsius * 0, 20, ..., 300; floating-point version +*/ main « float fahr, celsius; int lower, upper, step; lower = 5 /* lower Limit of temperature table */ upper = 300; /* upper Limit ” step = 20; /* step size s printf(*Celsius Fahr\n"); celsius = lower while (celsius <* upper) ¢ fahr = (9.0ecelsius) / 5.0 + 32.05 prantfO"n3.0f 26.14 \n", celsius, fahrd; celsius * celsius + steps » ‘The program produces a table containing temperatures in degrees Celsius (0- 300) and their equivalent Fahrenheit values. Degrees Fabrenheit are calculated using the statement: fahr + (9.0ecelsius? / 5.0 + 32.0 The solution follows the same logic as used in the program that prints the Fahrenheit-Celsius table (page 12 K&R). The integer variables lower, upper, and step refer to the lower limit, upper limit, and step size of the variable celsius, respectively. The variable celsius is initialized to the lower limit, and inside the whi Le loop the equivalent Fahrenheit temperature is calculated ‘The program prints Celsius and Fahrenheit and increments the variable celsius by the step size. The whi le loop repeats until the variable celsius exceeds its upper limit 6 The C Answer Book Exercise 1-5: (page 14 K&R) Modify the temperature conversion program to print the table in reverse order, that is, from 300 degrees to 0. Finclude ¢stdio.h> /* print Fahrenheit-Celsius table in reverse order ” mang) ‘ ant fahi for (fahr + 300; fahr >= 0; fahr = fahr - 20) printfC"%3d t6.1f\n", fahr, (5.0/9. 009 fahr-32)95 The only modification is: for Cfahr * 300; fahr >= 3 fehr + fahr - 20) The first part of the for statement, fahe = 300 initializes the Fahrenheit variable (fahr) to its upper limit. The second part, or the condition that controls the for loop, fahr >= 0 tests whether the Fahrenheit variable exceeds or meets its lower limit. The for loop continues as long as the statement is true. The step expression, fahr + fehe - 20 decrements the Fahrenheit variable by the step size. A Tutorial Introduction Chap. 1 7 Exercise 1-6: (page 17 K&R) Verify that the expression getchar(> !+ €0F is Qor | vinclude ¢staio.n> main « int es while Cc + getchar€> t= EOF) prantfC"ad\n", 5 printfO"%d - at EQF\n", ©); > The expression © + getchar(> t+ EOF is equivalent to c= Cgetchar@) t EOF) (page 17 K&R). The program reads characters from the standard input and uses the expression above. While getcher has a character to read it docs not return the end of file and getchar() != EOF is true. So 1 is assigned to «When the program encounters the end of file, the expression is false. ‘Then 0 is assigned to ¢ and the loop terminates. 8 The C Answer Book Exercise 1-7: (page 17 K&R) Write a program to print the value of EOF. sinelude ¢stdio.h> maine ‘ print€C"EOF is Kain", €OFDs , The symbolic constant EOF is defined in . ‘The EOF outside the double quotes in printf is replaced by whatever text follows adefine EOF in the include file. In our system EOF is —1, but it may vary from system to system. That's why standard symbolic constants like EOF help make your pro- gram portable. A Tutorial Introduction Chap. 1 Exercise 1-8: (page 20 K&R) Write a program to count blanks, tabs, and newlines, Ainclude J+ count blanks, tebs, end newlines main « int c, mb, nt, nls nd = 05 7+ number of blanks at = 05 J+ number of tabs nl = 05 J+ number of newlines while (Co + getchar€>) '*£0F> 4 Wh lee tt) venbs af Cee NED vents if Coss *NntD tents ? printf("%d 2d Xd\n, nb, nt, lds , ‘The integer variables nb, nt, and ni are used to count the number of blanks, tabs, and newlines, respectively, Initially, these three variables are set equal 100. Inside the body of the wh 1e loop. the occurrence of each blank, tab, and newline from input is recorded. All 1f statements are executed each time through the loop. If the character received is anything but a blank. tab, or newline, then no action is taken. If it is one of these three, then the appropriate counter is incremented. The program prints the results when the whi Le loop terminates (get char returns EOF). ” ” ” ” 10 ‘The C Answer Book The 1 f-e1se statement is not presented until page 21 K&R. With that knowledge the solution could be: finclude ¢atdio.h> 7* count blanks, tabs, and newlines main? 4 ant c, mb, nt, ni; nb = 0; J+ number of blanks at = 0; J+ number of tabs nl = 0; J+ number of newlines while (Ce + getchar(>) !=€0F> Af (one tf) renbs elseif (cos \t> vents else if (oo#* ‘\nd tens printf(*td Xd td\n", nb, nt, nds ” ” ” ” A Tutorial Introduction Chap. 1 " Exercise 1-9: (page 20 K&R) Write a program to copy its input to its output, replacing each string of one or more blanks by a single blank include Catdio.h> sdefine NONBLANK ‘a’ /* replace string of blanks with a single blank ” main 4 int ¢, laste: leste = NONBLANK; while (Le = getcharG)) t+ EOF) ¢ ite te putchar(cd; afore 1) af Glaste #00 putcharCe): laste * 5 The integer variable e records the ASCII value of the present character received from input and Leste records the ASCII value of the previous character. The symbolic constant NONBLANK initializes laste to an arbitrary nonblank char- acter. ‘The first 1 £ statement in the body of the whi 1e loop handles the occurrence of nonblanks~it prints them. The second if statement handles blanks, and the third 1 statement tests for a single blank of the first blank of a string of blanks. Finally, laste is updated. and the process repeats. 2 The C Answer Book ‘The 1 f-e1se statement is not presented until page 21 K&R. With that knowledge the solution could be: Fincluce ¢stdio.h> ‘define NONBLANK * /* replace string of blanks with a single blank ” main@> « int c, laste; laste + NONBLAN while (Co = getchar(>) != EOF) ¢ fete ty putchar(eds else if Caste te 11) putchar(e); laste = cs > The logical 08 (11) operator is also not presented until page 21 K&R. With that knowledge the solution could be: #include ‘#define NONBLANK ‘a’ /* replace string of blenks with @ single blank ” main 4 int _c, laste; laste + NONBLANK; while (Ce * getchar()) t= EOF) ¢ fe tet 4 Gt laste te tt) putchar(e)s laste = cy A Tutorial Introduction Chap. 1 3 Exercise 1-10: (page 20 K&R) Write a program to copy its input to its output, replacing each tab by \t, each backspace by \b, and each backslash by \\. This makes tabs and backspaces visible in an unambiguous way #include ¢stdio.h> (+ replace tabs and backspaces with visible characters ” main « int ¢} while (Cc * getchar€)) != EOF) ¢ af Coe NED printfor\\t ys af Comm \bt printf Af Cee TD printfOry yy af Ce fe NBD if Ce te ED Af Ge be ND putcharce): Ns » The character received from input can be a tab, a backspace, a backslash, or anything else. If itis a tab we replace it with \t, a backspace with \b, and a backslash with \\. Anything else is printed as is. A backslash character is represented as *\\" in C. We print two back- slashes by passing the string "\\\\" to printf 4 The C Answer Book The 1 f-else statement is not presented until page 21 K&R. With that knowledge the solution could be: #include 7+ replace tabs and bactspaces with visible characters ” main) « int o5, while (Co = getchar(>) ' EOF) Af (eee NED prantfcnyty; else if Cc s* ‘\bt) PrintfOy\beDs else if Cows \\D printEceyy yi; else putchar(c); A Tutorial Introduction Chap. 1 6 Exercise |: (page 21 K&R) How would you test the word count program? What kinds of input are most likely to uncover bugs if there are any’? To test the word count program first try no input. The output should be: 0.00 (zero newlines. zero words, zero characters). Then try a one-character word. The output should be: 1 1 2 (one newline, one word, two characters—a letter followed by a newline character) ‘Then try a two-character word. The output should be: 1 1 3 (one newline, one word. three characters—two characters followed by a newline character). In addition, try 2 one-character words (the output should be: 1 2 4) and 2 one-character words—one word per line (the output should be 2 2 4) The kinds of input most likely to uncover bugs are those that test boundary conditions. Some boundaries are —no input —no words—just newlines —no words—just blanks, tabs, and newlines —one word per line—no blanks and tabs —word starting at the beginning of the line —word starting after some blanks 16 The C Answer Book Exercise 1-12: page 21 K&R) Write a program that prints its input one word per line. include ¢stdio.h> fdefine IN 4 74 inside @ word ” ‘#define DUT 0 7* outside @ word ” 7+ print input one word per line ” mainc> 4 inte, states state + OUT; while (Co + getchar(>) t* EOF) ¢ Af Core tt cee nt ttc ee NED ¢ if Cstate ++ IND 4 putchare*\n); /* finish the word / state = QUT; > Dd else if (state += OUT) ¢ state = IN; 7+ beginning of word +/ putchared; else ss inside a word of putcharte); , state is an integer boolean that records whether the program is currently inside a word or not. At the beginning of the program, state is initialized to OUT, since no data has been processed. ‘The first if statement Af Cone tbe ee Nat the we MRD determines whether c is a word separator. If itis, then the second 1 f statement, Af Cstete ++ IND determines whether this word separator signifies the end of a word. If so, a newline is printed and stote is updated; otherwise no action is taken. If c is not a word separator, then itis either the first character of a word Of another character within the word. If it is the beginning of a new word, then the program updates state. In either case, the character is printed. A Tutorial Introduction Chap. 1 W7 Exercise 1-13: (page 24 K&R) Write a program to print a histogram of the lengths of words in its input. It is easy to draw the histogram with the bars horizontal: a vertical orientation is more challenging. finclude ¢stdio.h> fdefine MAXHIST 15 7+ max length of histogram —+/ fdefine MAXWORD 11 s+ max length of 2 vord ” sdefine IN 1 J+ inside a word ” fdefine QUT 0 /* outside a word ” /* print horizontal histogram ” main « int c, 4, ne, state: ant lens y+ Length of each bar ” int maxvalue; s+ maximum value for wi(l —«/ int ovflow; y+ number of overflow words +/ int wif MAarWORD) ; 1+ word length counters ” state = OUT; ne = 05 y+ number of chars ina word +/ ovflow = 0; y+ number of words >= MAXWORD#/ for Ci + 05 1 6 MAKWORD; ¢+1) with) = 05 while (Cc * getchar ©) t= EOF) ¢ Af Come at eee Wnt thc ee NED state = OUT if (ne > 0 af (ne « MAXWORDD sewh Enc); else srovf low; nc = 0; D else if (state «= OUT> « state = Is ne = 15 7+ beginning of a new word = */ } else tenes 7+ inside a word "7 y mexvalue = 03 for (1 = 1; 1 € MAXWORD; +91) af GulC1) > maxvalued maxvatue = wifi 18 The C Answer Book for C= ty 4 © MAKWORDS edt | printfOsd - XSd 2", 1, wl lads af Guilal > 0) ¢ af CClen © wif) © MAKHIST / maxvalue) <= 0) lens ty d else len = 05 while Clen > 0) ¢ putchar (/#7)5 --Len; > putchar€*\n‘)5 > af Covflow > 09 . printf("There are td words >* Xd\n", ovflow, MAXWORD); A blank, newline, or tab marks the end of a word. If there isaword(ne > 0) and its length is less than the maximum word length (nc _« MAXWORD), then the program increments the appropriate word length counter (++witne}). If the length of the word is out of range (ne >» MAXHORD), then the program incre- ments the variable ov low that keeps track of the number of words greater than or equal to MAXWORD. ‘When al! words have been read in, the program determines the maximum value (maxvalue) from the atray wi The variable Len scales the value in w1C1 according to MAxHIST and maxvalue, When w1(41 is greater than 0, at least one asterisk is printed +include (stdio.h> fdefine MAXHIST 15 7+ max length of histogram */ #oefine MAXWORD = 11 7* max length of a word ” ‘define IN 1 7+ inside @ word ” fdefine OUT 0 /* outside @ word ” /* print vertical histogram ” mand? « Ante, 1, J) ne, states int maxvelues + maximum value for wif] */ int ovflow; 7+ number of overflow words */ int wI(M@xWORD); 7+ word length counters ” A Tutorial Introduction Chap. 1 3 state = OUT; ne = 05 {+ number of chars in a word wv ovflow + 0; 7+ number of words >= MAXHORD = +/ for (i = 0; 1 € MAXWORD; +419 wits) * 05 while Cle + getchar()) t* EOF) ¢ Af (ose 6 4 tbe ae \nt state = QUT; af Cnc > 09 Af Cre © MAKWORDD sewl ned: else eee tty ¢ trovtlows + else if (state =* OUT) ¢ state = IN; nes 15, 7* beginning of a new word ” > else tenes /* inside a word ” , maxvalue = for (1 © 1; 1 € MAXWORD; +4 if GwlCil > maxvalued maxvelue = wl(i); for (i * MAXHIST; 4 > 0; --1) ¢ for Cj #15 ) © MAXWORD; +44) Af GwlC}1 © MAXHIST / mexvalue >= 1) printfe © ">; else printfc* putchar*\n"); } for Ci = 15 4 € MAXWORD; +01? printfOead "95 putchar(‘\n?; for Gio= 15 i € MAXWORDS +44) printfomtad , wilt); putchar(*\n‘)5, af Cevflow > 09 printfC"There are Xd words >* Xd\n", ovflow, MAXWORD?; > This solution prints a vertical histogram. It is similar to the previous program until maxvelue is determined. ‘Then it is necessary to scale cach element of the array wi and verify whether an asterisk should be printed for each one of the elements. This verification is necessary since all bars are printed simulta- neously (vertical histogram). The last two fr loops print the index and value for each element of wi 20 Exercise 1-14: (page 24 K&R) The C Answer Book Write a program to print a histogram of the frequencies of different characters in its input include include fdefine MAXHIST ‘Adefine MAXCHAR 15 128 /* print horizontal histogram mainQ) « int iat, int, int ea len maxvalue; ec CMAXCHAR] ; for Ci = 0; i eclil = © MAXCHAR; 0; 7 max length of histogram /* max different characters freq. of different characters 7+ Length of each bar 7+ maximum value for ccl) /* character counters ee while (Ce + getchar)) = EOF) Af Co © MAXCHARD recto]; maxvalue * 0; for Ci = 15 2 ¢ MAXCHAR; we if Coclil > maxvalued maxvalue = celils for Ci = 4; 4 € MAXCHAR; af CisprintGi> PrintfCMASd - Xe - xsd: *, else printfonasd - af Geel) > 0) ¢ eer Ay by colisrs - Sd: a, colina; if C€len = cefi) # MAXHIST / maxvalued ¢* 0 len = 15 > else len + 05 while Cien > 0) ¢ putchar€*#*); -=Len; y putchar(*\n* ” ” ” ” ” ” A Tutorial Introduction = Chap. 1 a ‘This program is similar to the horizontal histogram in Exercise 1-13, Now we are counting the frequency of different characters. We use an array character counter of MAXCHAR entries and we ignore characters greater than or equal to MAXCHAR if they exist in the character set being used. The other difference is that we use a macro to determine if a character is printable. The include file is discussed on page 43 K&R. isprint is described on page 249 K&R (Appendix B: Standard Library) 22 The C Answer Book Exercise 1-15: (page 27 K&R) Rewrite the temperature conversion program of Section 1.2 to use a function for conversion #include float celsius(float fahr); J+ peant Fahrenheit-Celsius table for fahr = 0, 20, 300; floating-point version “ maing? 4 float fahr; int lower, upper, ste lower = 05 J+ lower limit of temperature table +/ upper = 300; Ze upper limit “ step > 20; + step size ” fahr = lowers while Cfahr <* upper) « printf("%3.0f 16.1f\n", fahr, celsius(tanrd); fahr = fahr + step; /* celsius: convert fahr inte celsius ” float celsius(float fanr? « return (5.0/9.0) © (fanr-32.0); » We use a function to convert Fahrenheit into Celsius. ‘The name of the function is celsius, it receives a floating-point value, and it returns another floating- point value. The function returns the value of the expression via the return statement. Sometimes the expression is a simple variable, as in the function power (page 26 K&R). Sometimes we use a more involved expression, as in the function celsius, because all the work can be done in the return state- ment. We declared float celsiusCfloet fared; because the function expects a floating-point value and returns another flo: point value after the conversion A Tutorial Introduction Chap. 1 Exercise 1-16: (page 30 K&R) 23 Revise the main routine of the longest-line program so it will correctly print the length of arbitrarily long input lines, and as much as possible of the text. include ¢stdio.h> sdefine MAXLINE 1000 J maximum input line size int getlineCchar Iinef}, int maxlineds void copyCchar tol], char from(1); /* print longest input line mainc) « int lens 7+ curcent line length int ma 7* maximum length seen so far enar Line(MAXLINE]; /* current input line char longest(MAXLINE]; /+ longest iine saved here max * 05 while CClen * getlineCline, MAXLINE)) >» 0) ¢ printf"ad, Xs", len, Lined; if Clen > max? ¢ mex + lens copy(longest, line); » > if Cmax > 09 Js there was a line praintf(™ts", longest); return 05 > 7+ getline: read @ line into s, return length Ant getline€cher s(1, int lim? 4 antic, 4, 45 105 for Ci = 0; Ce = getchar€)) 'EOF th c t= ‘Xn’; 94> AAG © Lam-2) 4 styles 7+ Vine still in boundaries wey ” ” ” ” 7 ” ” ” ” 24 The C Answer Book if Come mtd € styl + ey vas > aly) = N05 return a3 > /* copy: copy ‘from’ into ‘to’; assume to is big enough */ void copy Cehar tol], char from(1) « ant as A205 while CCtoCil = fromtild $= *\04) > The only revision in the main routine is printf("zd, Zs", len, lined; This prints the length of the input fine (1en) and as many characters as it is possible to save in the array line. ‘The function get 1ine has a few modifications. for (1 + 0; Ce * getehar()) t+ EOF sec He "Wnty e017 The test for the limit of characters is not performed in the for loop anymore. This limit is not a condition for termination because get1 ine now returns the Jength of arbitrarily long input lines and saves as much text as possible. The statement af G. © Lim-2> determines if there is room in the array (still within boundaries). The original test in the for loop was 4 limt It was changed because the last index of the array + is Lam-t since s has 1im elements and we already read the input character. So 1 Lime? A Tutorial Introduction Chap. 1 2 leaves room for a possible newline character sClim-2) * ‘\n‘é and an end of string marker atlim-1) = *\0+ The length of the string is returned in copied to the string s. +: ) keeps track of the number of characters 26 ‘The C Answer Book Exercise 1-17: (page 31 K&R) Write a program to print all input lines that are longer than 80 characters. Ainclude fdefine MAXLINE 1000 /* maximum input line size */ ‘define LONGLINE 80 int getiineCchar line(1, int maxlineds /* print lines longer than LONGLINE ” maine? « int lens (+ current line length +/ char linelMAXLINE); fs current input line */ while CClen = getlineCline, MAKLINED? > 0) af Cen > LONGLINED printfCts", Lined; return 0; , ‘The program invokes getiine to read an input line. getline returns the length of the line and as much text as possible. If the length is greater than 80 characters (LCNGL INE), then the program prints the input line. Otherwise, no action is taken, The loop repeats until get 1 ine returns length zero. ‘The function get ine is the same as in Exercise 1-16 A Tutorial Introduction Chap. 1 Exercise 1-18: (page 31 K&R) Write a program to remove trailing blanks and tabs from each line of input, and to delete entirely blank lines. ‘include ¢stdio.h> define MAXLINE 1000 (+ maximum input line size +/ int getlineCchar line}, int maxlined; int removeCchar s(1); J+ remove trailing blanks and tabs, and delete blank lines +/ main « char Line(MAXL INE]; J+ current input line ” while CgetlineCiine, MAXLINE) > 03 1f CremoveCline) > 0) printfOmrs™, lined; return 0; , 7+ remove trailing blanks and tabs from cheracter string 3 */ Anat remove (char sti) « int is 2 05 while (stil '* ‘\nt) /# find newline character ” nay 7+ back off from ‘\n* 7 while Ci >* 0 bb Csi] ee 4 1 EE Stal we “RODD nas if >= 0d ¢ 7* as at a nonblank Line? ” sed stil \nty 74 put newline character back */ ey stil = ‘N05 /* terminate the string ” ? return 15 The remove function removes trailing blanks and tabs from the character string Line and returns its new length. If this length is greater than 0, Line has characters other than blanks and tabs, and the program prints the line. Other- wise, Line is entirely made up of blanks and tabs, and thus ignored. This ensures that entirely blank lines are not printed. 2 The C Answer Book The remove function finds the newline character and backs off one po- sition. The function then steps backward over blanks and tabs until it finds some other character or no more characters are available (1 < 0). Ifa > 0, then there is at least one character. remove puts back the newline and the end of string marker, then returns 1. ‘The function get Line is the sam in Exercise 1-16. A Tutorial Introduction Chap. 1 2 Exercise 1-19: (page 31 K&R) Write a function rever se(s) that reverses the character string 5. Use it to write a program that reverses its input a line at a time. finclude ‘define MAXLINE 1000 7+ maximum input line size */ ant getline€char line(}, int maxiined; void reverse(char s(1); J+ reverse input lines, a line at a time ” mang? « char Line(MAXLINE; 7+ current input line ” while (getline(line, MAXLINE? > 0) ¢ reverseCline); printecrxs", lineds > /* reverse: reverse string 3 “” void reverseCchar sf) « ant ayy char tem i= 05 while Cs(i} '* ‘\0') ss find the end of strings ¢/ ae 7* back off from ‘\0" ” if Galil s* 4\nt> nay 7* leave newline in place v 1705 7* beginning of new string 5 #/ while C) € 19 ¢ temp + s(j35 sty) + sts y+ swap the characters ” sti) = temps may eps , The reverse function first finds the end of string s. It then backs off one position from *\0*, so that the first character will not become an end of string 30 ‘The C Answer Book marker, If a ‘\n! exists, it backs off one more position, since like the *\0", it must remain at the end of the line. | is the index of the first character of the string, and 4 is the index of the last character of the string. While swapping characters, j is incremented (moves toward the end of the string). and 1 is decremented (moves toward the beginning of the string). The process continues while } is less than 1. The main program reads a line of input at a time, reverses it, and prints the reversed line. The function getline is the same as in Exercise 1-16. A Tutorial introduction Chap. 1 a Exercise 1-20: (page 34 K&R) Write a program detab that replaces tabs in the input with the proper number of blanks to space to the next tab stop. Assume a fixed set of tab stops, say every n columns. Should n be a variable or a symbolic parameter? @include adefine TABINC 8 J+ tab increment size ” /* replace tabs with the proper number of blanks ” mainc> { int ©, mb, pos; nb = 05 7+ number of blanks necessary ” pos = 7* position of character in line */ while (Ce * getchar€>> != EDF) ¢ Af Ce ee NED 4 7+ tab character ” nb = TABINC - (pos - 1) % TABINC; while Gnb > 09 ¢ putchar(’ 7); *eposs ==nb5 , d else if (cs ‘\n’ ¢ /* newline character ” putcharceds pos = 15 > else ¢ Je all other characters +/ putcharced;, *sposs > ‘The tab stops are at every TABINC position. In this program TABINC is defined to be8. The variable pos is the position within a line of text where the program currently is. If the character is a tab, the program calculates the number of blanks nb necessary to reach the next tab stop. The statement nb * TABINC - (pos - 1) % TABINC determines this value. If the character is a newline, then it is printed out and pos is reinitialized to the beginning of the line (pos = 1). Anyother character is printed and pos is incremented (++pos). 32 ‘The C Answer Book TABINC is a symbolic constant. Later on, in Chapter 5, you will lean how to pass arguments to the main program and you may want to allow the user to set the number of columns between tab stops. Then you may want to change TABINC into a variable. The program deteb is extended in Exercises 5-11 and 5-12. A Tutorial Introduction Chap. 1 33 Exercise 1-21: (page 34 K&R) Write the program enteb that replaces strings of blanks by the minimum number of tabs and blanks to achieve the same spacing. Use the same tab stops as for detab. When either a tab or a single blank would suffice to reach a tab stop, which should be given preference? include ‘define TABINC 8 7+ teb increment size ¢/ /* replace strings of blanks with tabs and blanks ” main? { int c, nb, nt, poss nb = 05 70 @ of blanks necessary */ nt = 95 J+ # of tabs necessary */ for (pos * 1; Ce = getchar€>) = EOF; ++pos) afc OE if (pos % TABING t= 0) 7+ Anecement # of blanks #/ nb = 05 J+ reset # of blanks #/ tents 7» one more tab ” > velse ¢ for © 5 nt > 0; --nbd putchar(‘\t">; — /* output tabCs> ” if Cem NED 7+ forget the blank(s) —#/ nb #05 else 7+ output blankts> ” for ©; mb > 03 --nb> putchart? "9; putcharce)5 Af Ces \nt> pos = 0; else if Cc == ‘\tt) pos = pos + CTABINC - Cpos-1) % TABINC) - 1; > The integer variables nb and nt are the minimum number of blanks and tabs necessary to replave a string of blanks. The variable pos is the position within a line of text where the program currently is ‘The idea is to find all blanks. A string of blanks is replaced by a tab every time pos reaches a multiple of TABINC. “ The C Answer Book When the program finds a nonblank, then it prints the tabs and blanks accumulated followed by the nonblank character. The program resets nb and nt to zero, and resets pos to the beginning of the line if the current character isa newline. If the nonblank character is a tab, then the program prints only the ac- cumulated tabs followed by the current tab character. When a single blank suffices to reach a tab stop, it is easier to replace it with a tab because we avoid special cases. The program entab is extended in Exercises 5-11 and 5-12. A Tutorial Introduction Chap. 1 Exercise 1-22: (page 34 K&R) ‘Write a program to “fold” long input lines into two or more shorter lines after the last nonbiank character that occurs before the n-th column of input. Make sure your program does something intelligent with very long lines, and if there are no blanks or tabs before the specified column. finclude ‘define MAXCOL 10 7+ maximum column of input rdefine TABINC = 8 7+ tab increment size char line(MAXCOL}; y+ input Line int exptabCint pos); int findbInkCint pos); int newposCint pos); void printiCint pos); 7/* fold long input lines into two or more shorter lines main? t : int ©, poss pos + 05 /* position in the line while CCc + getchar€>) !+ EOF) ¢ Line(pos} = ci J+ store current character af tose Nt [+ expand tab character pos * exptab(pos); else if Cos ‘\nt> { printl(pos); /* print current input line pos * 0; D else if Cespos >= MAXCOL? « pos + findbink(pos); printl (pos); pos * newpos(pos); > 7 printl: print Line until pos column void printiCint pos? « ant a5 ” ” ” ” ” ” ” ” ” Fy ‘The C Answer Book for (1 = 0; 1 € poss e+d putcharClinelil> Af (pos > 09 7* ny chars printed ? ” putchar(/\n?); , /* expteb: expand tab into blents ” int exptabCint pos) € Line(post = * '; J* tab ta at least one blank +/ for (+spos; pos < MAXCOL 4&4 pos % TABINC f= 0; +pos) linetpos} = * Af (pos © MAXCOLD /* room left in current Line */ return pos; else ¢ /* current line is full ” printiCpos); return 0; /* reset current position — «/ > > 7* findbink: find blenk’s position ” Ant findbinkCint pos? { while (pos > 0 48 Jine(pos} te * +> --pos; tf (pos *= 09 7+ no blanks in the line 2? +/ return MAXCOL; else 7* wt least one blank ” return post; /* position efter the blank +/ > “+ -newpos: rearrange line with new position ” Ant newposCint pos) « amt ty js Af (pos €* 0 It pos >* MAxcaL? return 0; 7+ nothing to rearrange ” else 4 40; for Cj = poss } € MAXCOLs ++) 4 Lineal = Linety); wea; ) return 15 7+ new position in line ” A Tutorial Introduction Chap. 1 7 MAXCOL is a symbolic constant. It indicates the n-th column of input. The integer variable pos points to the position within a line of text where the program currently is. ‘The program folds input lines before the n-th column of input, ‘The program expands tab characters, prints the current input when it finds a newline, and folds the input line when pos reaches NAXCOL The function f indb Ink searches for a blank starting at the index pos. It returns the position after a blank or MAXCOL if a blank does not exist. printl prints the characters between position zero and pos-1. newpos rearranges a line, that is, it copies characters, starting at pos, 10 the beginning of the line, then returns the new value of pos. Exercise 1-23: (page 34 K&R) The C Answer Book Write a program to remove all comments from a C program. Don't forget to handle quoted strings and character constants properly. C comments do not nest. #include ¢stdio.h> void rcommentCint o3; void in_comment( void); void echo_quoteCint c); J* remove all comments from a valid C program maine? 4 inte, d while (Ce = getchar(>) != EOF? comment Cc); return 0; y /* rcomment: read each character, remove the comments void rcomment(int? <) 4 int d5 afte 7D Af (Cd © getchar€o) #* f#1> ” ” in_comment(); /*beginning conment+/ else if Cdas 174) ¢ putchar(e); reomment(d) delset putcharCe); 7+ not a comment putchar¢d); > else if Coe VO bh cee mr echo_quote(c); 7* quote begins putcharle?s 7+ not a comment Jeanother slash " ” ” ” A Tutorial introduction Chap. 1 39 /* An_comment: inside of @ valid comment ” void in_comment (void) ‘s prev character +/ {s cure character +/ thd t= 174) (fe search for end +/ d+ getchar Od; 7* echo_quote: echo characters within quotes ” void echo_quoteCint ¢) 4 int ds putchar(c); while (Cd * getcharQ)) t+ 6) (s+ search for end «/ putchartd); if (dae VD putchar(getchar(>); —/* ignore escape seqt/ > putchar(d); The program assumes that the input is a valid C program. rcomment searches for the beginning of a comment (/+) and when it finds it calls 1n_conment This function searches for the end of the comment. The procedure therefore ensures that a comment will be ignored. reomment. also searches for single and double quotes and if it finds them calls echo_quote. The argument to echo_quote indicates whether it is a single or double quote. echo_quote ensures that anything within a quote is echoed and not mistaken for a comment. echo_quote does not consider a quote following a backslash as the terminating quote (see the discussion on escape sequences on page 19 K&R and in Exercise 1-2). Any other character is printed as is. The program terminates when getcher returns an end of file. « ‘The C Answer Book Exercise 1-24: (page 34 K&R) Write a program to check a C program jor rudimentary syntax errors like un- balanced parentheses, brackets, and braces. Don’t forget about quotes, both single and double, escape sequences, and comments. (This program is hard if you do it in full generality.) @include ¢stdic.h> int brace, brack, paren; void in_quoteCint cj; void in_comment(void); void search(int cd; /* rudimentary syntax checker for C programs ” main@? « int es, extern int brace, brach, paren; while (Ce + getchar()) != EOF) 4 Af Gee 79 6 if (eo = getcharer? #= v6") in_comment (5 f+ anside comment — +/ else search(c); yelse if Cone AN th ce fry in_quotete); Is inside quote ” else search€e); Af Cbrace ¢ 0) ¢ fs output errors #/ prantfc"Unb brace = 0; else if Cbrack ¢ 0) ¢ printfC"Unbalanced brackets\n™); brack = 0; d else if Cparen < 09 ¢ printf("Unbalanced parentheses\n"); paren = 0; anced braces\n"); A Tutorial Introduction Chap. 1 a > /* search void 4 > Af (brace > 0) J+ output errors «/ Printf("Undalanced braces\n"); if Corack > 09 printf(*Unbalanced brackets\n"); if (paren > 0) printf("Unbalanced parentheses\n") rch for rudimentary syntax errors ” echCint ©) extern int brace, brack, pareny Af Cee td srbraces else if Co se OD >-brece; else if Cc * ssbrack else if Cc * ~-brack; else if Co ee 104) *oparens- else af Ce ee 00) ~-parens "D no 7 An_conment: inside of @ valid comment ” void in.comment (void? ‘ ante, di © = getchare>; J+ prev character «/ d= getchert>; J+ curr character = #/ while Co fe ‘#7 Id te 474) (Js search for end — #/ erd d= geteharcr; a ‘The C Answer Book 7+ in.quote: inside quote « void in.quoteCint 2) 4 int ds while’ Cd = getcher€)) != 6) 7s search end quote +/ Af doen NED getchar(); 7+ ignore escape seq */ > This solution is not done in full generality. ‘The program checks for three syntax errors: unbalanced parentheses brackets, and braces. Everything else is assumed to be valid. ‘The function search increments the variable brace when the character is a left brace (*«“) and decrements it when the characteris a right brace (‘> *) The variables bract and paren are handled similarly. During the search, it is legal for brace, brack, or paren to be positive orzero. It is an error if brace, brack, or paren ever becomes negative; the program prints an appropriate message. ( (( (brack equals 3) is legal for the moment because 3 balancing right brackets might be found later in the search. 33} (brack equals —3) is illegal because there were no previous left brackets to balance these 3 right brackets; if there were 3 left brackets to balance them, then brack should equal 0, The statements Af (brace ¢ 0) ¢ printfC"Unbalanced braces\n"); brace = 0; d else if Cbreck ¢ 0) ¢ printf("Unbalanced brackets\n"); breck = 0; d else if (paren ¢ 0) ¢ printfC“Unbalenced parentheses \n’ paren = 0; > are necessary because without them >¢ of 13){{{ or }}<{ would be considered balanced. ‘The main routine searches for comments, single and double quotes, and skips the characters within them. The braces, brackets, and parentheses inside comments and quotes need not be balanced. The program makes a final check upon EOF to determine if there are any ‘open braces, brackets, or parentheses. If so, the program prints an appropriate message. CHAPTER2 Types, Operators, and Expressions Exercise 2-1: (page 36 K&R) Write a program to determine the ranges of cher, short, int, and Long variables, both signed and unsigned, by printing appropriate values from standard headers and by direct computation. Harder if you compute them: determine the ranges of the various floating-point types finclude ¢stdio.h> #include 74 determine ranges of types ” main) ‘ /* signed types ” printf('signed char min = + SCHAR_MIND; printf('signed char max = SCHAR MAX); printfC'signed short min = SHRT_MIND ; printf("signed short max = SHRT_MAX); printf('signed int min = INT MIND 5 print#('signed int max = INT MAX); print#("signed long min = + LONG MIND; print#("signed long max = + LONG_MAXD; 7+ unsigned types “ printfCtunsigned cher mex UCHAR_max; printf(ungigned short max USHRT_MAX); printf(unsigned int max UINT MAX) ; printf(unsigned long mex ULONG_max9; “ The C Answer Book ‘The ANSI standard for C specifies that ranges be defined in <1imits..h>. ‘The ranges may vary from machine to machine because the sizes for short, int, and long vary for different hardware. sinclude ¢stdio.h> /* determine ranges of types ” main) < /* signed types " printfC"signed cher min = td\n™, ~(charCCunsigned char? “0 >> 1995 printfC"signed cher max = Xd\n",, (char (Cunsigned chard “0 >> 19); printfC"signed short min * Xd\n", ~Gshort €Cunsigned short) “0 >> 1995 "signed short max = %d\n", shor t)(Cunsigned short? “0 >> 19); signed int min = %d\n", ~CintdCCunsigned int) “9 >> 195 printfCsigned int max + %d\n", CintCCunsigned int? “0 >> 199; printfCsigned long min + Zid\n", ~Clong)(Cunsigned Long) “0 >> 12); "signed long max = X1d\n' Clong)(Cunsigned long) “0 >> 19); 7+ unsigned types ” printfC*unsigned char max = Xu\n", unsigned char) “02; printfC*unsigned short max = Zu\n", (unsigned short) “0); printfC"unsigned int max + tu\n", Gansigned int? “0d; unsigned long max * Xlu\nM, Cungigned long) “09; printf printf printf printf Another possible solution uses bitwise operators (page 48 K&R). For ‘example, the expression (char €Cunsigned char) “0 >> 1) takes a zero and converts each bit to one “0 Types, Operators, and Expressions Chap. 2 then converts the resulting quantity to an unsigned cher Cursigned char) “0 and shifts the unsigned char one position to the right to clear the sign bit Gunsigned char) “0 >> 1 and finally converts the quantity to cher Ccher )CCunsigned chard “0 >> 1) That is the maximum value for a signed character. “ The C Answer Book Exercise 2-2: (page 42 K&R) ‘Write a loop equivatent to the for loop above without using #4 or 11 Original: for Cis0; 16lim-1 46 Ceagetehar()? t= ‘\nt bac t= EOF; +64) Equivalent: enum loop { NO, YES >; enum loop okloop = YES; 10 while Cokloop =* YES? Af Ge Lam-t) /* outside of valid range? +/ ok loop = NO; else if (Ce = getchar(a) += ‘\n‘> okloop = NO: else if Co =* EGF) Js end of file 7 ” ok loop = NO: else ¢ sil =e; vets + Without #6 or 11 we have to break the original for loop into a sequence of 1 statements. We then change the tests. For example, in the original for loop 1 « Limet indicates that 1 still is within boundaries. In the equivalent statement 46 Limt indicates that 1 is out of boundaries and the loop should terminate. ‘ot Loop isanenumeration. Assoon as one of the conditions is met ot Loop is set to NO and the loop terminates, Types, Operators, and Expressions Chap.2 a7 Exercise 2-3: (page 46 K&R) Write the function htoiCs>, which converts a string of hexadecimal digits (in- cluding an optional 0x or 0x) into its equivalent integer value. The allowable digits are 0 through 9, » through f, and A through F. ‘define YES 1 ‘define NO 0 f+ htot: convert hexadecimal string s to integer int htoi€ehar sf) 4 int hexdigit, 1, inhex, m5 a2 05 if GOL) = 1070 4 7+ skip optional Ox or Ox ey af GeQi) ee txt Gt stad ee ed eras > nn 05 J+ integer value to be returned inhex * YES; 7+ assume valid hexadecimal digit for (5 inhex *= YES; +eid ¢ Af (sti) >= 70% ga sCi) e194) hexdigit = sf1) - ‘0° else if Gstil >= fat eb sil ce FD hexdigit * s(1) - ‘a’ + 10; else if Cali) > 7A bb SCA) ee CFD hexdigit © sfi) - ‘Ar + 105 else imhex = NO; /* not @ valid hexadecimal digit Af Cinhex += YES? ne 16 ¢ n+ hexdigits > return ny ‘The statement for € 3 inhex =* YES; #41) controls the function. ‘The integer 1 is the index for the array s.. While 5111 is a valid hexadecimal digit, 1nhex remains YES and the loop continues. The variable hexdigit takes a numerical value of 0 through 15 " o ” “” 43 ‘The C Answer Book ‘The statement Af Cinhex = YES? guarantees that a valid hexadecimal digit was at 31 and its value is in hexdi- git. When the loop terminates, hto1 returns the value of the variable n. “This function is similar to atoi (page 43 K&R) ‘Types, Operators, and Expressions Chap. 2 “9 Exercise 2-4: (page 48 K&R) ‘Write an alternate version of squeeze( 31,32) that deletes each character in ‘1 that matches any character in the string 22. /* squeeze: delete each char in a1 which 1s in a2 ” void squeezecchar si(J, char s2t)> 4 iota, je ts for Cis k= 05 SHCA] fe *\O%s doen ¢ For Cj + 0; s2Cj) f= OF Ga a2lj) f= stCits joer Af Gs2tjl ee N00 74 end of atring - no match #/ siCkeed © 10105 > sttkl = 4\075 ‘The first statement, for Ch = k #0; SICA] te ‘NO; dood initializes 1 and t, the indexes of #1 and the resulting string (also 51), respec- tively. Each character in s1 that matches any character in 92 is deleted. The Joop continues until the end of the string 1. The second for statement checks each character in 32 against the 3111 character. This loop terminates when s2 runs out of characters or there is a match. In the event that there is no match, 31 (11 is copied to the resulting string. If there is a match, the statement AF Cs2tyl e* 14000 fails, and 31(11 is not copied to the resulting string (it is squeezed out). 50 The C Answer Book Exercise 2-5: (page 48 K&R) Write the function any¢st ,s2), which returns the first location in the string ‘21 where any character from the string 32 occurs, or -1 if 31 contains no characters from 32. (The standard library function strpbrk does the same job but returns a pointer to the location.) 7+ any: return first location in st where any cher from s2 occurs+/ int anyCcher 31(1, char s2t1) 1 ant as gs for C1 = 0; sili] $+ *\O%s deed for Cj © 0; s2lj) '* ‘\0%s yoo Af GatCal e© 20y)> 7+ match found? ” return i5 7+ Location first match */ return -15 7+ otherwise, no match — +/ > ‘The statement for Ci = 05 S104) f= *NO7G deed controls the loop. When the loop terminates normally (+1 runs out of characters), eny returns -1 to indicate that no character of 52 was found in 1. ‘The second for statement, for C) © 04 s20j) f= ‘N04; peed is executed for each value of 1. It compares each character of #2 with s1(1). When a character in s2 matches s1 (1) the function returns i—the first location in the string 21 where any character from the string +2 occurs. Types, Operators, and Expressions Chap, 2 st Exercise 2-6: (page 49 K&R) Write a function setbits¢x,p,n.y) that returns x with the n bits that begin at position p set to the rightmost n bits of y, leaving the other bits unchanged. /* setbits: set n bits of x at position p with bits of y #/ unsigned setbitsCunsigned x, int p, int n, unsigned y) ‘ return x @ we O ce md ce Cpetendd I 0 To set n bits of x to the rightmost n bits of y we need to clear the n bits in x, clear all bits in y except the rightmost n bits and then shift them to position p, and OR the quantities together. To clear the n bits in x we AND them with n bits of zeros starting at position p and ones everywhere else. veer shifts all ones n positions to the left, leaving n zeros at the rightmost positions. “C0 «end places all ones at the rightmost n positions, zeros everywhere else. “CO Ce nd Ce (poten? shifts these » 1-bits to position p and “COO 6 nde Cpetendd 52 ‘The C Answer Book sets n bits to zeros starting at position p, leaving ones everywhere else. x8 -OOO Ce nd Ce poten? we AND this value with x to clear the n bits of x at position p. To clear all bits in y except the rightmost n bits we AND them with n bits of ones and zeros everywhere else. “C0 end places all ones at the rightmost positions, zeros everywhere else. y §7C0 cen? selects the rightmost n bits of y. And Cy 8 CO CO nd Ce peter places these n bits starting at position p. x8 -COO Ce md ce Cpetend? Tt &y & C0 Ce dd Ce Cpatend ‘we OR the two values to set the n bits of x starting at position p to the rightmost n bits of y, leaving the other bits unchanged Types, Operators, and Expressions Chap. 2 53 Exercise 2-7: (page 49 K&R) Write a function invert (x,p,n) that returns x with the n bits that begin at position p inverted (i.e., 1 changed into 0 and vice versa), leaving the others unchanged. J+ inverts inverts the n bits of x thet begin et position p */ unsigned invertCunsigned x, int p, int nd ‘ return x (C0 ce nd <« Cpetendds > co « ad shifts all ones n positions to the left, leaving n zeros at the rightmost positions. “0 «end places all ones at the rightmost positions, zeros everywhere else. COD end prin? shifts these n 1-bits to position p. x7 COO Ce nd Ce Cpetend? ‘The bitwise exclusive OR operator (*) produces a 1 when two bits are different, otherwise it produces a0. Since the objective is to invert the n bits starting at position p, it suffices to exclusive OR them with all ones starting at p for n bits (with zeros everywhere else). If the original bit is 0, exclusive OR with 2 1 produces a 1—it is inverted. If the original bit is a 1, exclusive OR with aL produces a 0—it is inverted. ‘The positions outside of the n-bit field are exclusive OR’ed with zeros: 070 (bits are the same) produces a 0—nothing changed; | ~0 (bits are different) produces a 1—nothing changed. Only the n bits are inverted. oe The C Answer Book Exereise 2-8: (page 49 K&R) Write a function ¢ ight rot (x, n? that returns the value of the integer x rorated to the right by n bit positions. /* rightrot: rotate x to the right by n positions ” unsigneé rightrotCunsigned x, int n> « int wordiength(void); ant ebity 7+ rightmost bit ” while (n-- > 0) ¢ rbit = Cx $1) €€ GwvordlengthO) - 195 xr ry de shift x 1 position right */ xe t orbits /* complete one rotetion ” y return x; , The variable rit takes the rightmost bit of x and shifts it to the leftmost position (wordlength() - 1 ‘Next, we shift x one position to the right and OR it one rotation. rightrot rotates x n times. wordlength() is a function that computes the word length on the host machine. rbit to complete /* wordlength: computes word length of the machine “” ant wordiength(void> 4 Amt ay unsigned v + Cunsigned) “Os for CL © ty Cyt v9 19> 05 108? return i;

You might also like