C程序设计语言(第二版)课后答案由刀豆文库小编整理,希望给你工作、学习、生活带来方便,猜你可能喜欢“c程序设计语言答案”。
“The C Programming Language”, 2nd edition,Kernighan and Ritchie 《c程序设计语言》英文的配套答案,所列页码均为英文版的。1.01 1.02 1.03 1.04 1.05 1.06 1.07 1.08 1.09 1.10 1.11 1.12 1.13 1.14 1.15 1.16 1.17 1.18 1.19 1.20 1.21 1.22 1.23 1.24 2.01 2.02 2.03 2.04 2.05 2.06 2.07 2.08 2.09 2.10 3.01 3.02 3.03 3.04 3.05 3.06 4.01 4.02 4.03 4.04 4.05 4.06 4.07 4.08 4.12 4.13 4.14 5.01 5.02 5.03 5.04 5.05 5.06 5.07 5.08 5.09 5.10 5.11 5.13 5.14 6.01 6.03 6.04 6.05 7.01 7.02 7.03 7.06 7.08 7.09 8.01 8.03 8.04 8.06
Answer to Exercise 1-1
Run the “hello, world” program on your system.Experiment with leaving out parts of the program, to see what error meages you get.Murphy's Law dictates that there is no single correct answer to the very first exercise in the book.Oh well.Here's a “hello world” program:
#include
int main(void){
printf(“hello, worldn”);
return 0;}
As you can see, I've added a return statement, because main always returns int, and it's good style to show this explicitly.Answer to Exercise 1-2
Experiment to find out what happens when printf 's argument string contains c, where c is some character not listed above.By 'above', the question is referring to: n(newline)t(tab)b(backspace)“(double quote)(backslash)We have to tread carefully here, because using a non-specified escape sequence invokes undefined behaviour.The following program attempts to demonstrate all the legal escape sequences, not including the ones already shown(except n , which I actually need in the program), and not including hexadecimal and octal escape sequences.#include
int main(void){
printf(”Audible or visual alert.an“);
printf(”Form feed.fn“);
printf(”This escape, r, moves the active position to the initial position of the current line.n“);
printf(”Vertical tab v is tricky, as its behaviour is unspecified under certain conditions.n“);
return 0;}
Answer to Exercise 1-3
Modify the temperature conversion program to print a heading above the table.#include
int main(void){
float fahr, celsius;int lower, upper, step;
lower = 0;
upper = 300;
step = 20;
printf(”F Cnn“);
fahr = lower;
while(fahr
{
celsius =(5.0 / 9.0)*(fahrstep;
}
return 0;}
This version uses a for loop:
#include
int main(void){
float fahr, celsius;
int lower, upper, step;
lower = 0;
upper = 300;step = 20;
printf(”C Fnn“);
for(celsius = upper;celsius >= lower;celsius = celsius20)
printf(”%3d %6.1fn“, fahr,(5.0/9.0)*(fahr-32));
return 0;} Answer to Exercise 1-6
Verify that the expreion getchar()!= EOF is 0 or 1./* This program prompts for input, and then captures a character * from the keyboard.If EOF is signalled(typically through a * control-D or control-Z character, though not necearily), * the program prints 0.Otherwise, it prints 1.*
* If your input stream is buffered(and it probably is), then * you will need to pre the ENTER key before the program will * respond.*/
#include
int main(void){
printf(”Pre a key.ENTER would be nice :-)nn“);
printf(”The expreion getchar()!= EOF evaluates to %dn“, getchar()!= EOF);
return 0;}
Answer to Exercise 1-7
Write a program to print the value of EOF.#include
int main(void){
printf(”The value of EOF is %dnn“, EOF);
return 0;}
Exercise 1-8
Write a program to count blanks, tabs, and newlines.#include int main(void){
int blanks, tabs, newlines;
int c;
int done = 0;
int lastchar = 0;
blanks = 0;
tabs = 0;
newlines = 0;
while(done == 0)
{
c = getchar();
if(c == ' ')
++blanks;
if(c == 't')
++tabs;
if(c == 'n')
++newlines;
if(c == EOF)
{
if(lastchar!= 'n')
{
++newlines;/* this is a bit of a semantic stretch, but it copes * with implementations where a text file might not * end with a newline.Thanks to Jim Stad for pointing * this out.*/
}
done = 1;
}
lastchar = c;
}
printf(”Blanks: %dnTabs: %dnLines: %dn“, blanks, tabs, newlines);
return 0;}
Exercise 1-9 Write a program to copy its input to its output, replacing each string of one or more blanks by a single blank.#include
int main(void){
int c;
int inspace;
inspace = 0;
while((c = getchar())!= EOF)
{
if(c == ' ')
{
if(inspace == 0)
{
inspace = 1;
putchar(c);
}
}
/* We haven't met 'else' yet, so we have to be a little clumsy */
if(c!= ' ')
{
inspace = 0;
putchar(c);
}
}
return 0;}
Chris Sidi writes: ”instead of having an “inspace” boolean, you can keep track of the previous character and see if both the current character and previous character are spaces:“
#include
/* count lines in input */ int main(){
int c, pc;/* c = character, pc = previous character */
/* set pc to a value that wouldn't match any character, in case this program is ever modified to get rid of multiples of other characters */
pc = EOF;
while((c = getchar())!= EOF){
if(c == ' ')
if(pc!= ' ')/* or if(pc!= c)*/
putchar(c);
/* We haven't met 'else' yet, so we have to be a little clumsy */
if(c!= ' ')
putchar(c);
pc = c;
}
return 0;}
Stig writes: ”I am hiding behind the fact that break is mentioned in the introduction“!
#include
int main(void){
int c;
while((c = getchar())!= EOF){
if(c == ' '){
putchar(c);
}
while((c = getchar())== ' ' && c!= EOF)
;}
if(c == EOF)
break;/* the break keyword is mentioned
* in the introduction...* */
putchar(c);
}
return 0;
Exercise 1-10
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.Category 0 Gregory Pietsch pointed out that my solution was actually Category 1.He was quite right.Better still, he was kind enough to submit a Category 0 solution himself.Here it is:
/* Gregory Pietsch */
/*
* Here's my attempt at a Category 0 version of 1-10.*
* Gregory Pietsch */
#include
int main(){
int c, d;
while((c=getchar())!= EOF){
d = 0;
if(c == ''){
putchar('');putchar('');
d = 1;
}
if(c == 't'){
putchar('');
putchar('t');
d = 1;
}
if(c == 'b'){
putchar('');
putchar('b');
d = 1;
}
if(d == 0)
putchar(c);
}
return 0;}
Category 1
This solution, which I wrote myself, is the sadly discredited Cat 0 answer which has found a new lease of life in Category 1.#include
#define ESC_CHAR ''
int main(void){
int c;
while((c = getchar())!= EOF)
{
switch(c)
{ case 'b':
/* The OS on which I tested this(NT)intercepts b characters.*/
putchar(ESC_CHAR);
putchar('b');
break;
case 't':
putchar(ESC_CHAR);
putchar('t');
break;
case ESC_CHAR:
putchar(ESC_CHAR);
putchar(ESC_CHAR);
break;
default:
putchar(c);
break;
}
}
return 0;}
Exercise 1-11
How would you test the word count program? What kinds of input are most likely to uncover bugs if there are any?
It sounds like they are really trying to get the programmers to learn how to do a unit test.I would submit the following:
0.input file contains zero words 1.input file contains 1 enormous word without any newlines 2.input file contains all white space without newlines 3.input file contains 66000 newlines 4.input file contains word/{huge sequence of whitespace of different kinds}/word 5.input file contains 66000 single letter words, 66 to the line 6.input file contains 66000 words without any newlines 7.input file is /usr/dict contents(or equivalent)8.input file is full collection of moby words 9.input file is binary(e.g.its own executable)10.input file is /dev/nul(or equivalent)
66000 is chosen to check for integral overflow on small integer machines.Dann suggests a followup exercise 1-11a: write a program to generate inputs(0,1,2,3,4,5,6)
I gue it was inevitable that I'd receive a solution for this followup exercise!Here is Gregory Pietsch's program to generate Dann's suggested inputs:
#include #include
int main(void){
FILE *f;
unsigned long i;
static char *ws = ” ftv“;
static char *al = ”abcdefghijklmnopqrstuvwxyz“;
static char *i5 = ”a b c d e f g h i j k l m “ ”n o p q r s t u v w x y z “ ”a b c d e f g h i j k l m “ ”n o p q r s t u v w x y z “ ”a b c d e f g h i j k l m “ ”nn“;
/* Generate the following: */
/* 0.input file contains zero words */
f = fopen(”test0“, ”w“);
aert(f!= NULL);
fclose(f);
/* 1.input file contains 1 enormous word without any newlines */
f = fopen(”test1“, ”w“);
aert(f!= NULL);
for(i = 0;i
fputs(al, f);
fclose(f);
/* 2.input file contains all white space without newlines */
f = fopen(”test2“, ”w“);
aert(f!= NULL);
for(i = 0;i
fputs(ws, f);
fclose(f);
/* 3.input file contains 66000 newlines */
f = fopen(”test3“, ”w“);
aert(f!= NULL);
for(i = 0;i
fputc('n', f);
fclose(f);
/* 4.input file contains word/
* {huge sequence of whitespace of different kinds} * /word */
f = fopen(”test4“, ”w“);
aert(f!= NULL);
fputs(”word“, f);
for(i = 0;i
fputs(ws, f);
fputs(”word“, f);
fclose(f);
/* 5.input file contains 66000 single letter words, * 66 to the line */
f = fopen(”test5“, ”w“);
aert(f!= NULL);
for(i = 0;i
fputs(i5, f);
fclose(f);
/* 6.input file contains 66000 words without any newlines */
f = fopen(”test6“, ”w“);
aert(f!= NULL);
for(i = 0;i
fputs(”word “, f);
fclose(f);
return 0;}
Exercise 1-12
Write a program that prints its input one word per line.#include int main(void){
int c;
int inspace;
inspace = 0;
while((c = getchar())!= EOF)
{
if(c == ' ' || c == 't' || c == 'n')
{
if(inspace == 0)
{
inspace = 1;
putchar('n');
}
/* else, don't print anything */
}
else
{
inspace = 0;
putchar(c);
}
}
return 0;}
Exercise 1-13
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./* This program was the subject of a thread in comp.lang.c, because of the way it handled EOF.* The complaint was that, in the event of a text file's last line not ending with a newline, * this program would not count the last word.I objected somewhat to this complaint, on the
* grounds that ”if it hasn't got a newline at the end of each line, it isn't a text file“.*
* These grounds turned out to be incorrect.Whether such a file is a text file turns out to
* be implementation-defined.I'd had a go at checking my facts, and had
* checked the wrong facts!(sigh)*
* It cost me an extra variable.It turned out that the least disturbing way to modify the
* program(I always look for the least disturbing way)was to replace the traditional
* while((c = getchar())!= EOF)with an EOF test actually inside the loop body.This meant
* adding an extra variable, but is undoubtedly worth the cost, because it means the program
* can now handle other people's text files as well as my own.As Ben Pfaff said at the * time, ”Be liberal in what you accept, strict in what you produce“.Sound advice.*
* The new version has, of course, been tested, and does now accept text files not ending in * newlines.*
* I have, of course, regenerated the sample output from this program.Actually, there's no
* ”of course“ about it1];
if(thisval > maxval)
{
maxval = thisval;
}
}
}
else
{
thisval = ++lengtharr[MAXWORDLEN];
if(thisval > maxval)
{
maxval = thisval;
}
}
} if(c == EOF)
{
done = 1;
}
}
else
{
if(inspace == 1 || firstletter == 1)
{
wordlen = 0;
firstletter = 0;
inspace = 0;
}
++wordlen;
}
}
for(thisval = maxval;thisval > 0;thisval--)
{
printf(”%4d | “, thisval);
for(thisidx = 0;thisidx
{
if(lengtharr[thisidx] >= thisval)
{
printf(”* “);
}
else
{
printf(” “);
}
}
printf(”n“);
}
printf(” +“);
for(thisidx = 0;thisidx
{
printf(”---“);
}
printf(”n “);
for(thisidx = 0;thisidx
{
printf(”%2d “, thisidx + 1);
}
printf(”>%dn“, MAXWORDLEN);
return 0;}
Here's the output of the program when given its own source as input:
| * 112 | * 111 | * 110 | * 109 | * 108 | * 107 | * 106 | * 105 | * 104 | * 103 | * 102 | * 101 | * 100 | * 99 | * 98 | * 97 | * 96 | * 95 | * 94 | * * 93 | * * 92 | * * 91 | * * 90 | * * 89 | * * 88 | * * 87 | * * 86 | * * 85 | * * 84 | * * 83 | * * 82 | * * 81 | * * 80 | * * 79 | * * 78 | * * 77 | * * 76 | * * 75 | * * 74 | * * 73 | * * 72 | * * 71 | * * 70 | * * 69 | * * 68 | * * 67 | * * 66 | * * 65 | * * 64 | * * 63 | * * * 62 | * * * 61 | * * * 60 | * * * 59 | * * * 58 | * * * 57 | * * * 56 | * * * 55 | * * * 54 | * * * 53 | * * * 52 | * * * * 51 | * * * * 50 | * * * * 49 | * * * * 48 | * * * * 47 | * * * * 46 | * * * * 45 | * * * * 44 | * * * * 43 | * * * * * 42 | * * * * * 41 | * * * * * 40 | * * * * * 39 | * * * * * 38 | * * * * * 37 | * * * * * 36 | * * * * * 35 | * * * * * 34 | * * * * * 33 | * * * * * 32 | * * * * * 31 | * * * * * 30 | * * * * * * 29 | * * * * * * 28 | * * * * * * * 27 | * * * * * * * 26 | * * * * * * * 25 | * * * * * * * * 24 | * * * * * * * * 23 | * * * * * * * * 22 | * * * * * * * * * 21 | * * * * * * * * * 20 | * * * * * * * * * 19 | * * * * * * * * * 18 | * * * * * * * * * 17 | * * * * * * * * * 16 | * * * * * * * * * 15 | * * * * * * * * * 14 | * * * * * * * * * * 13 | * * * * * * * * * * 12 | * * * * * * * * * * 11 | * * * * * * * * * * 10 | * * * * * * * * * * 9 | * * * * * * * * * * * 8 | * * * * * * * * * * * 7 | * * * * * * * * * * * 6 | * * * * * * * * * * * 5 | * * * * * * * * * * * 4 | * * * * * * * * * * * 3 | * * * * * * * * * * * 2 | * * * * * * * * * * * 1 | * * * * * * * * * * * +--1 2 3 4 5 6 7 8 9 10 >10
Exercise 1-14 Write a program to print a histogram of the frequencies of different characters in its input.Naturally, I've gone for a vertical orientation to match exercise 13.I had some difficulty ensuring that the printing of the X-axis didn't involve cheating.I wanted to display each character if poible, but that would have meant using isprint(), which we haven't yet met.So I decided to display the value of the character instead.(The results below show the output on an ASCII system(100 *(thisidx / 100)))/ 10);
}
}
printf(”n “);
for(thisidx = 0;thisidx
{
if(freqarr[thisidx] > 0)
{
printf(”%d“, thisidx32.0);return c;}
int main(void){
float fahr, celsius;
int lower, upper, step;
lower = 0;
upper = 300;
step = 20;
printf(”F Cnn“);
fahr = lower;
while(fahr
{
celsius = FtoC(fahr);
printf(”%3.0f %6.1fn“, fahr, celsius);
fahr = fahr + step;
}
return 0;}
Answer to Exercise 1-16, page 30
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 poible of the text./* This is the first program exercise where the spec isn't entirely * clear.The spec says, 'Revise the main routine', but the true * length of an input line can only be determined by modifying * getline.So that's what we'll do.getline will now return the * actual length of the line rather than the number of characters * read into the array paed to it.*/
#include #define MAXLINE 1000 /* maximum input line size */
int getline(char line[], int maxline);void copy(char to[], char from[]);
/* print longest input line */ int main(void){
int len;/* current line length */
int max;/* maximum length seen so far */
char line[MAXLINE];/* current input line */
char longest[MAXLINE];/* longest line saved here */
max = 0;
while((len = getline(line, MAXLINE))> 0)
{
printf(”%d: %s“, len, line);
if(len > max)
{
max = len;
copy(longest, line);
}
}
if(max > 0)
{
printf(”Longest is %d characters:n%s“, max, longest);
}
printf(”n“);
return 0;}
/* getline: read a line into s, return length */ int getline(char s[], int lim){
int c, i, j;
for(i = 0, j = 0;(c = getchar())!=EOF && c!= 'n';++i)
{
if(i
{
s[j++] = c;
}
++i;
}
s[j] = ' ';
return i;}
/* copy: copy 'from' into 'to';aume 'to' is big enough */ void copy(char to[], char from[]){
int i;
i = 0;
while((to[i] = from[i])!= ' ')
{
++i;
} }
Chris Sidi, however, was not convinced1]!= 'n')
{
if(getmore == 0)
copy(temp, line);
prevmax += len;
if(max
max = prevmax;
getmore = 1;
}
else
{
if(getmore == 1)
{
if(max
{
max = prevmax + len;
copy(longest, temp);
longest[MAXLINE1 &&((c = getchar())!= EOF && c!= 'n');
++i)
s[i] = c;
if(c == 'n')
{
s[i] = c;
++i;
}
else if(c == EOF && i > 0)
{
/* gotta do something about no newline preceding EOF */
s[i] = 'n';
++i;
}
s[i] = ' ';
return i;}
void copy(char to[], char from[]){
int i;
i = 0;
while((to[i] = from[i])!= ' ')
++i;}
Answer to Exercise 1-17, page 31 Write a program to print all input lines that are longer than 80 characters.#include
#define MINLENGTH 81
int readbuff(char *buffer){
size_t i=0;
int c;
while(i
c = getchar();
if(c == EOF)return-1;
if(c == 'n')return 0;
buffer[i++] = c;
}
return 1;}
int copyline(char *buffer){
size_t i;
int c;
int status = 1;
for(i=0;i
putchar(buffer[i]);
while(status == 1){
c = getchar();
if(c == EOF)
status =-1;
else if(c == 'n')
status = 0;
else
putchar(c);
}
putchar('n');
return status;}
int main(void){
char buffer[MINLENGTH];
int status = 0;
while(status!=-1){
status = readbuff(buffer);if(status == 1)
status = copyline(buffer);
}
return 0;}
Answer to Exercise 1-18, page 31
Write a program to remove all trailing blanks and tabs from each line of input, and to delete entirely blank lines./* K&R2 1-18 p31: Write a program to remove trailing blanks and tabs from each line of input, and to delete entirely blank lines.The program specification is ambiguous: does ”entirely blank lines“ mean lines that contain no characters other than newline, or does it include lines composed of blanks and tabs followed by newline? The latter interpretation is taken here.This implementation does not use any features not introduced in the first chapter of K&R2.As a result, it can't use pointers to
dynamically allocate a buffer to store blanks that it has seen, so it must limit the number of blanks that are allowed to occur consecutively.(This is the value of MAXQUEUE, minus one.)
It is intended that this implementation ”degrades gracefully.“ Even though a particular input might have 1000 or more blanks or tabs in a row, causing a problem for a single pa, multiple paes through the file will correct the problem.The program signals the need for such an additional pa by returning a failure code to the operating system.(EXIT_FAILURE isn't mentioned in the first chapter of K&R, but I'm making an exception here.)*/
#include #include
#define MAXQUEUE 1001
int advance(int pointer){
if(pointer
/* K&R2 1-18 p31: Write a program to remove trailing blanks and tabs from each line of input, and to delete entirely blank lines.The program specification is ambiguous: does ”entirely blank lines“ mean lines that contain no characters other than newline, or does it include lines composed of blanks and tabs followed by newline? The latter interpretation is taken here.This implementation does not use any features not introduced in the first chapter of K&R2.As a result, it can't use pointers to
dynamically allocate a buffer to store blanks that it has seen, so it must limit the number of blanks that are allowed to occur consecutively.(This is the value of MAXQUEUE, minus one.)
It is intended that this implementation ”degrades gracefully.“ Even though a particular input might have 1000 or more trailing blanks or tabs in a row, causing a problem for a single pa, multiple paes through the file will correct the problem.The program signals the need for such an additional pa by returning a failure code to the operating system.(EXIT_FAILURE isn't mentioned in the first chapter of K&R, but I'm making an exception here.)*/
#include #include
#define MAXQUEUE 1001
int advance(int pointer){
if(pointer
{
s[i] = c;
}
if(c == 'n')
{
s[i++] = c;
}
s[i] = ' ';
return i;
}
int main(void){
char line[MAX_LINE];
while(getline(line, sizeof line)> 0)
{
discardnewline(line);
reverse(line);
printf(”%sn", line);
}
return 0;}
Answer to Exercise 1-20, page 34
Thanks to Rick Dearman for pointing out that my solution used fgets()which has not been introduced by page 34.I've fixed the solution to use K&R's getline()function instead.Further thanks to Roman Yablonovsky who, in Oct 2000, pointed out that the solution was buggy, and hinted at a fix.Basically, the problem he spotted was that my solution failed to keep track of the cumulative effect of multiple tabs in a single line.I've adopted his fix(which was in fact also slightly buggy, but I've fixed that too).Write a program detab that replaces tabs in the input with the proper number of blanks to space to the next tab stop.Aume a fixed set of tab stops, say every n columns.Should n be a variable or a symbolic parameter?
#include #include #include
#define MAX_BUFFER 1024 #define SPACE ' ' #define TAB 't'
int CalculateNumberOfSpaces(int Offset, int TabSize){
return TabSize1 &&(c = getchar())!= EOF && c!= 'n';++i)
s[i] = c;
if(c == 'n')
{
s[i] = c;
++i;
}
s[i] = ' ';
return i;}
int main(void){
char Buffer[MAX_BUFFER];
int TabSize = 5;/* A good test value */
int i, j, k, l;
while(getline(Buffer, MAX_BUFFER)> 0)
{