├── Ch19 ├── Exercises │ ├── e2 │ │ └── instructions.txt │ ├── e5 │ │ ├── instructions.txt │ │ └── queue.h │ ├── e1 │ │ ├── queue.h │ │ └── instructions.txt │ ├── e4 │ │ ├── instructions.txt │ │ ├── b │ │ │ ├── stack.h │ │ │ └── stackclient.c │ │ └── a │ │ │ ├── stack.h │ │ │ └── stackclient.c │ ├── e6 │ │ ├── instructions.txt │ │ ├── a │ │ │ ├── stackADT.h │ │ │ └── stackclient.c │ │ ├── c │ │ │ ├── stackADT.h │ │ │ └── stackclient.c │ │ └── b │ │ │ ├── stackADT2.h │ │ │ └── stackclient.c │ ├── e7 │ │ ├── instructions.txt │ │ ├── stackADT2.h │ │ └── stackclient.c │ └── e3 │ │ ├── a │ │ └── queue.h │ │ └── b │ │ └── queue.h ├── ProgrammingProjects │ ├── p7 │ │ ├── instructions.txt │ │ └── queueADT.h │ ├── p6 │ │ ├── instructions.txt │ │ └── queueADT.h │ ├── p1 │ │ ├── instructions.txt │ │ └── stack.h │ ├── p2 │ │ ├── instructions.txt │ │ └── stack.h │ ├── p4 │ │ ├── instructions.txt │ │ ├── stackADT.h │ │ └── stackclient.c │ ├── p3 │ │ ├── stackADT.h │ │ └── instructions.txt │ └── p5 │ │ ├── queueADT.h │ │ └── instructions.txt ├── stack.h ├── stackADT.h ├── stackADT2.h ├── stackclient.c └── stack1.c ├── Ch16 ├── ProgrammingProjects │ ├── p3 │ │ ├── instructions.txt │ │ ├── makefile │ │ ├── read_line.c │ │ └── read_line.h │ ├── p2 │ │ ├── instructions.txt │ │ ├── makefile │ │ ├── read_line.c │ │ └── read_line.h │ └── p4 │ │ ├── makefile │ │ ├── instructions.txt │ │ ├── read_line.c │ │ └── read_line.h ├── makefile ├── Exercises │ ├── e15.txt │ ├── e21.txt │ ├── e19.c │ ├── e17.txt │ ├── e04.c │ ├── e12.txt │ ├── e16.txt │ ├── e01.txt │ ├── e20.c │ ├── e08.c │ ├── e11.txt │ └── e06.c ├── read_line.c └── read_line.h ├── Ch15 ├── ProgrammingProjects │ ├── p5 │ │ ├── instructions.txt │ │ ├── makefile │ │ └── stack.h │ ├── p2 │ │ ├── instructions.txt │ │ ├── makefile │ │ ├── quote.txt │ │ ├── word.h │ │ ├── word.c │ │ └── justify.c │ ├── p3 │ │ ├── makefile │ │ ├── instructions.txt │ │ ├── qsort.c │ │ ├── quicksort.h │ │ └── quicksort.c │ ├── p4 │ │ ├── makefile │ │ ├── instructions.txt │ │ ├── readline.c │ │ └── readline.h │ └── p1 │ │ ├── makefile │ │ ├── output.txt │ │ ├── quote.txt │ │ ├── word.c │ │ ├── word.h │ │ ├── instructions.txt │ │ └── justify.c ├── makefile ├── Exercises │ ├── e2.txt │ ├── e5.txt │ ├── e3.txt │ ├── e6.txt │ └── e1.txt ├── word.c ├── word.h └── justify.c ├── Ch17 ├── Exercises │ ├── e08 │ │ ├── makefile │ │ ├── instructions.txt │ │ └── stack.h │ ├── e17.txt │ ├── e09.txt │ ├── e16.c │ ├── e18.c │ ├── e10.c │ ├── e15.txt │ ├── e05.txt │ ├── e11.c │ ├── e07.txt │ ├── e12.c │ └── e02.c ├── ProgrammingProjects │ ├── p3 │ │ ├── instructions.txt │ │ ├── makefile │ │ ├── read_line.c │ │ └── read_line.h │ ├── p2 │ │ ├── instructions.txt │ │ ├── makefile │ │ ├── read_line.c │ │ └── read_line.h │ ├── p1 │ │ ├── makefile │ │ ├── instructions.txt │ │ ├── read_line.c │ │ └── read_line.h │ └── p4 │ │ ├── makefile │ │ ├── instructions.txt │ │ ├── word.c │ │ ├── word.h │ │ └── justify.c └── inventory2 │ ├── makefile │ ├── read_line.c │ └── read_line.h ├── Ch22 ├── Exercises │ ├── e05.txt │ ├── e09.txt │ ├── e06.txt │ ├── e01.txt │ ├── e08.txt │ ├── e16.txt │ ├── e03.txt │ ├── e15.txt │ ├── e02.txt │ ├── e04.txt │ ├── e13.c │ └── e07.txt ├── canopen.c └── fcopy.c ├── Ch02 ├── pun.c ├── Exercises │ ├── e07.txt │ ├── e06.txt │ ├── e09.txt │ ├── e05.txt │ ├── e08.txt │ ├── e01.c │ ├── e03.c │ └── e02.c ├── ProgrammingProjects │ ├── p4.c │ ├── p1.c │ ├── p3.c │ ├── p6.c │ ├── p5.c │ └── p2.c ├── celsius.c ├── dweight.c └── dweight2.c ├── Ch07 ├── Exercises │ ├── e08.txt │ ├── e11.txt │ ├── e09.txt │ ├── e04.txt │ ├── e07.txt │ ├── e06.txt │ ├── e12.txt │ ├── e01.c │ ├── e10.txt │ ├── e13.txt │ ├── e03.c │ ├── e02.c │ ├── e14.c │ └── e05.c ├── length2.c ├── length.c ├── sum2.c └── ProgrammingProjects │ ├── p03.c │ ├── p06.c │ └── p10.c ├── Ch12 ├── Exercises │ ├── e10.c │ ├── e15.txt │ ├── e03.txt │ ├── e11.c │ ├── e02.txt │ ├── e01.txt │ ├── e05.txt │ ├── e08.c │ ├── e04.c │ ├── e06.c │ ├── e09.c │ ├── e07.c │ └── e17.c ├── reverse3.c └── ProgrammingProjects │ ├── p3.c │ └── p4.c ├── Ch18 └── Exercises │ ├── e14.txt │ ├── e15.txt │ ├── e12.txt │ ├── e13.txt │ ├── e07.txt │ ├── e04.txt │ ├── e02.txt │ ├── e11.txt │ ├── e09.c │ ├── e03.txt │ └── e06.txt ├── Ch11 ├── Exercises │ ├── e1.txt │ ├── e2.txt │ ├── e4.c │ ├── e5.c │ ├── e6.c │ └── e8.c └── maxmin.c ├── Ch20 ├── Exercises │ ├── e03.txt │ ├── e05.txt │ ├── e02.txt │ ├── e01.txt │ ├── e08.txt │ ├── e13.txt │ ├── e04.txt │ ├── e14.txt │ └── e11.txt └── xor.c ├── Ch09 ├── pun2.c ├── Exercises │ ├── e17.c │ ├── e16.c │ ├── e12.c │ ├── e08.txt │ ├── e09.txt │ ├── e18.c │ ├── e07.txt │ ├── e01.c │ ├── e05.c │ ├── e03.c │ ├── e02.c │ └── e19.c ├── countdown.c ├── average.c └── prime.c ├── Ch13 ├── Exercises │ ├── e08.txt │ ├── e14.txt │ ├── e09.txt │ ├── e10.txt │ ├── e07.txt │ ├── e02.txt │ ├── e16.c │ ├── e03.c │ ├── e11.c │ ├── e15.txt │ ├── e05.c │ └── e01.txt ├── ProgrammingProjects │ ├── p04.c │ └── p05.c └── planet.c ├── Ch14 └── Exercises │ ├── e10.txt │ ├── e03.txt │ ├── e12.txt │ ├── e16.c │ ├── e02.c │ ├── e05.txt │ ├── e04.txt │ ├── e13b.txt │ ├── e06.c │ ├── e13a.c │ ├── e11.c │ ├── e15.c │ ├── e08.c │ └── e01.c ├── Ch10 └── Exercises │ ├── e3.txt │ └── e1.txt ├── Ch21 └── Exercises │ ├── e2.txt │ ├── e5.txt │ ├── e3.txt │ └── e7.txt ├── Ch08 ├── Exercises │ ├── e02.txt │ ├── e08.c │ ├── e04.c │ ├── e01.txt │ ├── e09.c │ ├── e03.c │ ├── e05.c │ └── e07.c ├── reverse.c ├── ProgrammingProjects │ └── p04.c ├── reverse2.c └── repdigit.c ├── Ch03 ├── tprintf.c ├── ProgrammingProjects │ ├── p1.c │ ├── p4.c │ ├── p6.c │ └── p3.c ├── addfrac.c └── Exercises │ ├── e5.c │ ├── e1.c │ ├── e6.c │ └── e4.c ├── README.md ├── Ch06 ├── Exercises │ ├── e05.txt │ ├── e09.c │ ├── e14.txt │ ├── e03.c │ ├── e08.c │ ├── e01.c │ ├── e02.c │ ├── e11.c │ ├── e06.c │ ├── e13.c │ ├── e07.c │ ├── e10.c │ └── e04.c ├── square2.c ├── numdigits.c ├── sum.c ├── square.c ├── square3.c └── ProgrammingProjects │ ├── p06.c │ ├── p07.c │ └── p05.c ├── Ch04 ├── Exercises │ ├── e14.txt │ ├── e15.txt │ ├── e04.c │ ├── e06.c │ ├── e03.c │ ├── e05.c │ ├── e02.c │ ├── e13.c │ └── e01.c ├── ProgrammingProjects │ ├── p2.c │ ├── p3.c │ ├── p5.c │ └── p1.c └── upc.c ├── .gitignore └── Ch05 ├── Exercises ├── e07.c ├── e04.c ├── e10.c ├── e05.c ├── e06.c └── e08.c ├── broker.c └── ProgrammingProjects └── p02.c /Ch19/Exercises/e2/instructions.txt: -------------------------------------------------------------------------------- 1 | Modify the stack2.c file to use the PUBLIC and PRIVATE macros. 2 | -------------------------------------------------------------------------------- /Ch16/ProgrammingProjects/p3/instructions.txt: -------------------------------------------------------------------------------- 1 | Modify the inventory.c program of Section 16.3 by making inventory and num_parts 2 | local to the main function. 3 | -------------------------------------------------------------------------------- /Ch19/ProgrammingProjects/p7/instructions.txt: -------------------------------------------------------------------------------- 1 | Modify Programming Project 5 so that the items in a queue are stored in a linked 2 | list (see Exercise 3(b)). 3 | -------------------------------------------------------------------------------- /Ch16/ProgrammingProjects/p2/instructions.txt: -------------------------------------------------------------------------------- 1 | Modify the inventory.c program of Section 16.3 so that the p (print) operation 2 | displays the parts sorted by part number. 3 | -------------------------------------------------------------------------------- /Ch15/ProgrammingProjects/p5/instructions.txt: -------------------------------------------------------------------------------- 1 | Modify Programming Project 6 from Chapter 10 so that it has separate stack.h and 2 | stack.c files, as described in Section 15.2. 3 | -------------------------------------------------------------------------------- /Ch17/Exercises/e08/makefile: -------------------------------------------------------------------------------- 1 | pcalc: pcalc.o stack.o 2 | gcc -o pcalc pcalc.o stack.o 3 | 4 | pcalc.o: stack.h 5 | gcc -c pcalc.c 6 | 7 | stack.o: stack.c stack.h 8 | gcc -c stack.c 9 | -------------------------------------------------------------------------------- /Ch17/ProgrammingProjects/p3/instructions.txt: -------------------------------------------------------------------------------- 1 | Modify the inventory2.c program of Section 17.5 by adding an e (erase) command 2 | that allows the user to remove a part from the database. 3 | -------------------------------------------------------------------------------- /Ch22/Exercises/e05.txt: -------------------------------------------------------------------------------- 1 | Is there any difference between the printf conversion specifications %.4d and 2 | %04d? If so, explain what it is. 3 | 4 | Answer: 5 | No, both are equivalent. 6 | -------------------------------------------------------------------------------- /Ch02/pun.c: -------------------------------------------------------------------------------- 1 | /* Prints a bad pun. */ 2 | 3 | #include 4 | 5 | int main(void) 6 | { 7 | printf("To C, or not to C: that is the question.\n"); 8 | return 0; 9 | } 10 | -------------------------------------------------------------------------------- /Ch02/Exercises/e07.txt: -------------------------------------------------------------------------------- 1 | Which of the following are keywords in C? 2 | 3 | (a) for 4 | (b) If 5 | (c) main 6 | (d) printf 7 | (e) while 8 | 9 | Answer: 10 | (a) and (e) are keywords 11 | -------------------------------------------------------------------------------- /Ch15/ProgrammingProjects/p5/makefile: -------------------------------------------------------------------------------- 1 | pcalc: pcalc.o stack.o 2 | gcc -o pcalc pcalc.o stack.o 3 | 4 | pcalc.o: stack.h 5 | gcc -c pcalc.c 6 | 7 | stack.o: stack.c stack.h 8 | gcc -c stack.c 9 | -------------------------------------------------------------------------------- /Ch17/ProgrammingProjects/p2/instructions.txt: -------------------------------------------------------------------------------- 1 | Modify the inventory.c program of Section 16.3 so that the p (print) command 2 | calls qsort to sort the inventory array before it prints the parts. 3 | -------------------------------------------------------------------------------- /Ch19/ProgrammingProjects/p6/instructions.txt: -------------------------------------------------------------------------------- 1 | Modify Programming Project 5 so that the items in a queue are stored in 2 | a dynamically allocated array whose length is passed to the create function. 3 | -------------------------------------------------------------------------------- /Ch15/ProgrammingProjects/p2/instructions.txt: -------------------------------------------------------------------------------- 1 | Modify the justify program of Section 15.3 by having the read_word function 2 | (instead of main) store the * character at the end of a word that's been 3 | truncated. 4 | -------------------------------------------------------------------------------- /Ch07/Exercises/e08.txt: -------------------------------------------------------------------------------- 1 | Repeat Exercise 7, but give the equivalent hexadecimal escape. 2 | 3 | (a) \b 4 | (b) \n 5 | (c) \r 6 | (d) \t 7 | 8 | Answer: 9 | A - \x08 10 | B - \x0a 11 | C - \x0d 12 | D - \x09 13 | -------------------------------------------------------------------------------- /Ch17/Exercises/e17.txt: -------------------------------------------------------------------------------- 1 | Let a be an array of 100 integers. Write a call of qsort that sorts only the 2 | last 50 elements in a. (You don't need to write the comparison function). 3 | 4 | Answer: 5 | qsort(a, 49, 99); 6 | -------------------------------------------------------------------------------- /Ch12/Exercises/e10.c: -------------------------------------------------------------------------------- 1 | /* Modify the find_middle function of 11.5 so that it uses pointer arithmetic to 2 | * calculate the return value. 3 | */ 4 | int *find_middle(int a[], int n) 5 | { 6 | return a + (n / 2); 7 | } 8 | -------------------------------------------------------------------------------- /Ch15/ProgrammingProjects/p3/makefile: -------------------------------------------------------------------------------- 1 | qsort: qsort.o quicksort.o 2 | gcc -o qsort qsort.o quicksort.o 3 | 4 | qsort.o: quicksort.h 5 | gcc -c qsort.c 6 | 7 | quicksort.o: quicksort.c quicksort.h 8 | gcc -c quicksort.c 9 | -------------------------------------------------------------------------------- /Ch15/ProgrammingProjects/p4/makefile: -------------------------------------------------------------------------------- 1 | remind: remind.o readline.o 2 | gcc -o remind remind.o readline.o 3 | 4 | remind.o: readline.h 5 | gcc -c remind.c 6 | 7 | readline.o: readline.c readline.h 8 | gcc -c readline.c 9 | -------------------------------------------------------------------------------- /Ch16/makefile: -------------------------------------------------------------------------------- 1 | inventory: inventory.o read_line.o 2 | gcc -o inventory inventory.o read_line.o 3 | 4 | inventory.o: inventory.c read_line.h 5 | gcc -c inventory.c 6 | 7 | read_line.o: read_line.c read_line.h 8 | gcc -c read_line.c 9 | -------------------------------------------------------------------------------- /Ch19/ProgrammingProjects/p1/instructions.txt: -------------------------------------------------------------------------------- 1 | Modify Programming Project 1 from Chapter 10 so that it uses the stack ADT 2 | described in Section 19.4. You may use any of the implementations of the ADT 3 | described in that section. 4 | -------------------------------------------------------------------------------- /Ch19/ProgrammingProjects/p2/instructions.txt: -------------------------------------------------------------------------------- 1 | Modify Programming Project 6 from Chapter 10 so that it uses the stack ADT 2 | described in Section 19.4. You may use any of the implementations of the ADT 3 | described in that section. 4 | -------------------------------------------------------------------------------- /Ch07/Exercises/e11.txt: -------------------------------------------------------------------------------- 1 | Suppose that i is a variable of type int, f is a variable of type float, and 2 | d is a variable of type double. What is the type of the expression i * f / d? 3 | 4 | Answer: 5 | The expression will end up as a double. 6 | -------------------------------------------------------------------------------- /Ch18/Exercises/e14.txt: -------------------------------------------------------------------------------- 1 | Which kind of variables cannot be initialized? 2 | 3 | (a) Array variables 4 | (b) Enumeration variables 5 | (c) Structure variables 6 | (d) Union variables 7 | (e) None of the above 8 | 9 | Answer: 10 | E 11 | -------------------------------------------------------------------------------- /Ch02/Exercises/e06.txt: -------------------------------------------------------------------------------- 1 | Why is it not a good idea for an identifier to contain more than one adjacent 2 | underscore (as in current___balance, for example? 3 | 4 | Answer: 5 | Because it becomes difficult to tell how many underscores are being used. 6 | -------------------------------------------------------------------------------- /Ch11/Exercises/e1.txt: -------------------------------------------------------------------------------- 1 | If i is a variable and p points to i, which of the following expressions are 2 | aliases for i? 3 | 4 | (a) *p (c) *&p (e) *i (g) *&i 5 | (b) &p (d) &*p (f) &i (h) &*i 6 | 7 | Answer: 8 | A and G 9 | -------------------------------------------------------------------------------- /Ch19/stack.h: -------------------------------------------------------------------------------- 1 | #ifndef STACK_H 2 | #define STACK_H 3 | 4 | #include /* C99 only */ 5 | 6 | void make_empty(void); 7 | bool is_empty(void); 8 | bool is_full(void); 9 | void (push(int i)); 10 | int pop(void); 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /Ch20/Exercises/e03.txt: -------------------------------------------------------------------------------- 1 | Explain what effect the following macro has on its arguments. You may assume 2 | that the arguments have the same type. 3 | 4 | #define M(x,y) ((x)^=(y),(y)^=(x),(x)^=(y)) 5 | 6 | Answer: 7 | It swaps the values of x and y. 8 | -------------------------------------------------------------------------------- /Ch02/Exercises/e09.txt: -------------------------------------------------------------------------------- 1 | Insert spaces between the tokens in Exercise 8 to make the statement easier to 2 | read. 3 | 4 | answer = (3*q - p*p) / 3; 5 | 6 | (Spaces were left around the asterisks because it makes the 7 | order of operations more clear.) 8 | -------------------------------------------------------------------------------- /Ch17/inventory2/makefile: -------------------------------------------------------------------------------- 1 | inventory2: inventory2.o read_line.o 2 | gcc -o inventory2 inventory2.o read_line.o 3 | 4 | inventory2.o: inventory2.c read_line.h 5 | gcc -c inventory2.c 6 | 7 | read_line.o: read_line.c read_line.h 8 | gcc -c read_line.c 9 | -------------------------------------------------------------------------------- /Ch09/pun2.c: -------------------------------------------------------------------------------- 1 | /* Prints a bad pun */ 2 | 3 | #include 4 | 5 | void print_pun(void) 6 | { 7 | printf("To C, or not to C: that is the question.\n"); 8 | } 9 | 10 | int main(void) 11 | { 12 | print_pun(); 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /Ch13/Exercises/e08.txt: -------------------------------------------------------------------------------- 1 | What will be the value of the string str after the following statements have 2 | executed? 3 | 4 | strcpy(str, "tire-bouchon"); 5 | strcpy(&str[4], "d-or-wi"); 6 | strcat(str, "red?"); 7 | 8 | Answer: 9 | Tired or wired? 10 | -------------------------------------------------------------------------------- /Ch14/Exercises/e10.txt: -------------------------------------------------------------------------------- 1 | Functions can often--but not always--be written as parameterized macros. Discuss 2 | what characteristics of a function would make it suitable as a macro. 3 | 4 | Answer: 5 | Short and simple functions seem best suited to be macros. 6 | -------------------------------------------------------------------------------- /Ch15/makefile: -------------------------------------------------------------------------------- 1 | justify: justify.o word.o line.o 2 | gcc -o justify justify.o word.o line.o 3 | 4 | justify.o: word.h line.h 5 | gcc -c justify.c 6 | 7 | word.o: word.c word.h 8 | gcc -c word.c 9 | 10 | line.o: line.c line.h 11 | gcc -c line.c 12 | -------------------------------------------------------------------------------- /Ch16/ProgrammingProjects/p2/makefile: -------------------------------------------------------------------------------- 1 | inventory: inventory.o read_line.o 2 | gcc -o inventory inventory.o read_line.o 3 | 4 | inventory.o: inventory.c read_line.h 5 | gcc -c inventory.c 6 | 7 | read_line.o: read_line.c read_line.h 8 | gcc -c read_line.c 9 | -------------------------------------------------------------------------------- /Ch16/ProgrammingProjects/p3/makefile: -------------------------------------------------------------------------------- 1 | inventory: inventory.o read_line.o 2 | gcc -o inventory inventory.o read_line.o 3 | 4 | inventory.o: inventory.c read_line.h 5 | gcc -c inventory.c 6 | 7 | read_line.o: read_line.c read_line.h 8 | gcc -c read_line.c 9 | -------------------------------------------------------------------------------- /Ch16/ProgrammingProjects/p4/makefile: -------------------------------------------------------------------------------- 1 | inventory: inventory.o read_line.o 2 | gcc -o inventory inventory.o read_line.o 3 | 4 | inventory.o: inventory.c read_line.h 5 | gcc -c inventory.c 6 | 7 | read_line.o: read_line.c read_line.h 8 | gcc -c read_line.c 9 | -------------------------------------------------------------------------------- /Ch17/ProgrammingProjects/p1/makefile: -------------------------------------------------------------------------------- 1 | inventory: inventory.o read_line.o 2 | gcc -o inventory inventory.o read_line.o 3 | 4 | inventory.o: inventory.c read_line.h 5 | gcc -c inventory.c 6 | 7 | read_line.o: read_line.c read_line.h 8 | gcc -c read_line.c 9 | -------------------------------------------------------------------------------- /Ch17/ProgrammingProjects/p2/makefile: -------------------------------------------------------------------------------- 1 | inventory: inventory.o read_line.o 2 | gcc -o inventory inventory.o read_line.o 3 | 4 | inventory.o: inventory.c read_line.h 5 | gcc -c inventory.c 6 | 7 | read_line.o: read_line.c read_line.h 8 | gcc -c read_line.c 9 | -------------------------------------------------------------------------------- /Ch19/Exercises/e5/instructions.txt: -------------------------------------------------------------------------------- 1 | Modify the queue.h header of Exercise 1 so that it defines a Queue type, where 2 | Queue is a structure containing a fixed-length array (See Exercise 3(a)). Modify 3 | the functions in queue.h to take a Queue * parameter. 4 | -------------------------------------------------------------------------------- /Ch07/Exercises/e09.txt: -------------------------------------------------------------------------------- 1 | Suppose that i and j are variables of type int. What is the type of 2 | the expression i / j + 'a'? 3 | 4 | Answer: 5 | The expression will be an int. 6 | 7 | 'a' is actually an integer value, meaning the expression is made up of 3 ints. 8 | -------------------------------------------------------------------------------- /Ch17/ProgrammingProjects/p3/makefile: -------------------------------------------------------------------------------- 1 | inventory2: inventory2.o read_line.o 2 | gcc -o inventory2 inventory2.o read_line.o 3 | 4 | inventory2.o: inventory2.c read_line.h 5 | gcc -c inventory2.c 6 | 7 | read_line.o: read_line.c read_line.h 8 | gcc -c read_line.c 9 | -------------------------------------------------------------------------------- /Ch17/Exercises/e09.txt: -------------------------------------------------------------------------------- 1 | 2 | (&x)->a is the same as x.a. Justify your answer. 3 | 4 | Answer: 5 | True, because the -> operator is used to access a structure's member through 6 | a pointer to that structure, and &x is the equivalent to a pointer (address 7 | variable) to x. 8 | -------------------------------------------------------------------------------- /Ch02/Exercises/e05.txt: -------------------------------------------------------------------------------- 1 | Which of the following are not legal C identifiers? 2 | 3 | (a) 100_bottles 4 | (b) _100_bottles 5 | (c) one__hundred__bottles 6 | (d) bottles_by_the_hundred 7 | 8 | Answer: 9 | Only (a) is illegal because identifiers can't begin with constants 10 | -------------------------------------------------------------------------------- /Ch15/ProgrammingProjects/p1/makefile: -------------------------------------------------------------------------------- 1 | justify: justify.o word.o line.o 2 | gcc -o justify justify.o word.o line.o 3 | 4 | justify.o: word.h line.h 5 | gcc -c justify.c 6 | 7 | word.o: word.c word.h 8 | gcc -c word.c 9 | 10 | line.o: line.c line.h 11 | gcc -c line.c 12 | -------------------------------------------------------------------------------- /Ch15/ProgrammingProjects/p2/makefile: -------------------------------------------------------------------------------- 1 | justify: justify.o word.o line.o 2 | gcc -o justify justify.o word.o line.o 3 | 4 | justify.o: word.h line.h 5 | gcc -c justify.c 6 | 7 | word.o: word.c word.h 8 | gcc -c word.c 9 | 10 | line.o: line.c line.h 11 | gcc -c line.c 12 | -------------------------------------------------------------------------------- /Ch17/ProgrammingProjects/p4/makefile: -------------------------------------------------------------------------------- 1 | justify: justify.o word.o line.o 2 | gcc -g -o justify justify.o word.o line.o 3 | 4 | justify.o: word.h line.h 5 | gcc -c justify.c 6 | 7 | word.o: word.c word.h 8 | gcc -c word.c 9 | 10 | line.o: line.c line.h 11 | gcc -c line.c 12 | -------------------------------------------------------------------------------- /Ch02/Exercises/e08.txt: -------------------------------------------------------------------------------- 1 | How many tokens are there in the following statement? 2 | 3 | answer=(3*q-p*p)/3; 4 | 5 | Answer: 6 | There are 14 tokens 7 | 8 | answer = ( 3 * q - p * p ) / 3 ; 9 | | | | | | | | | | | | | | | 10 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 11 | -------------------------------------------------------------------------------- /Ch09/Exercises/e17.c: -------------------------------------------------------------------------------- 1 | /* Rewrite the fact function so that it's no longer recursive. */ 2 | 3 | int fact(int n) 4 | { 5 | int factorial = n; 6 | 7 | if (n <= 1) return 1; 8 | for (--n; n > 1; n--) 9 | factorial *= n; 10 | 11 | return factorial; 12 | } 13 | -------------------------------------------------------------------------------- /Ch13/Exercises/e14.txt: -------------------------------------------------------------------------------- 1 | What does the following program print? 2 | 3 | #include 4 | 5 | int main(void) 6 | { 7 | char s[] = "Hsjodi", *p; 8 | 9 | for (p = s; *p; p++) 10 | --*p; 11 | puts(s); 12 | return 0; 13 | } 14 | 15 | Answer: 16 | Grinch 17 | 18 | -------------------------------------------------------------------------------- /Ch14/Exercises/e03.txt: -------------------------------------------------------------------------------- 1 | Let DOUBLE be the following macro: 2 | 3 | #define DOUBLE(x) 2*x 4 | 5 | (a) What is the value of DOUBLE(1+2)? 6 | (b) What is the value 4/DOUBLE(2)? 7 | (c) Fix the definition of DOUBLE. 8 | 9 | Answer: 10 | A - 4 11 | B - 4 12 | C - #define DOUBLE(x) (2*(x)) 13 | -------------------------------------------------------------------------------- /Ch18/Exercises/e15.txt: -------------------------------------------------------------------------------- 1 | Which property of a variable determines whether or not it has a default initial 2 | value? 3 | 4 | (a) Storage duration 5 | (b) Scope 6 | (c) Linkage 7 | (d) Type 8 | 9 | Answer: 10 | A, because static storage duration causes variables to be intitialized to zero. 11 | -------------------------------------------------------------------------------- /Ch19/Exercises/e1/queue.h: -------------------------------------------------------------------------------- 1 | #ifndef QUEUE_H 2 | 3 | #define QUEUE_H 4 | #include 5 | #include 6 | 7 | typedef int Item; 8 | 9 | void insert(Item value); 10 | void remove(); 11 | Item get_first_item(); 12 | Item get_last_item(); 13 | bool is_empty(); 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /Ch19/Exercises/e4/instructions.txt: -------------------------------------------------------------------------------- 1 | (a) Write an implementation of the Stack type, assuming that Stack is 2 | a structure containing a fixed-length array. 3 | 4 | (b) Redo the Stack type, this time using a linked-list representation instead of 5 | an array (Show both stack.h and stack.c) 6 | -------------------------------------------------------------------------------- /Ch12/Exercises/e15.txt: -------------------------------------------------------------------------------- 1 | Write a loop that prints all temperature readings stored in row i of the 2 | temperatures array (see Exercise 14). Use a pointer to visit each element of the 3 | row. 4 | 5 | Answer: 6 | for (p = &temperatures[row][0]; p < &temperatures[row][24]; p++) 7 | printf("%d ", *p); 8 | -------------------------------------------------------------------------------- /Ch14/Exercises/e12.txt: -------------------------------------------------------------------------------- 1 | Suppose that the macro M has been defined as follows: 2 | 3 | #define M 10 4 | 5 | Which of the following tests will fail? 6 | 7 | (a) #if M 8 | (b) #ifdef M 9 | (c) #ifndef M 10 | (d) #if defined(M) 11 | (e) #if !defined(M) 12 | 13 | Answer: 14 | Tests C and E will fail. 15 | -------------------------------------------------------------------------------- /Ch15/ProgrammingProjects/p4/instructions.txt: -------------------------------------------------------------------------------- 1 | Modify the remind.c program of Section 13.5 so that the read_line function is in 2 | a separate file named readline.c. Create a header file named readline.h that 3 | contains a prototype for the function and have both remind.c and readline.c 4 | include this file. 5 | -------------------------------------------------------------------------------- /Ch22/Exercises/e09.txt: -------------------------------------------------------------------------------- 1 | Which one of the following calls s not a valid way of reading one character from 2 | the standard input stream? 3 | 4 | (a) getch() 5 | (b) getchar() 6 | (c) getc(stdin) 7 | (d) fgetc(stdin) 8 | 9 | Answer: 10 | A, because getch isn't a function in the C standard library. 11 | -------------------------------------------------------------------------------- /Ch19/ProgrammingProjects/p4/instructions.txt: -------------------------------------------------------------------------------- 1 | Modify the stackADT.h and stackADT3.c files of Section 19.4 so that a stack 2 | stores values of type void *, as described in Section 19.5; the Item type will 3 | no longer be used. Modify stackclient.c so that it stores pointers to strings in 4 | the s1 and s2 stacks. 5 | -------------------------------------------------------------------------------- /Ch15/ProgrammingProjects/p4/readline.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "readline.h" 3 | 4 | int read_line(char str[], int n) 5 | { 6 | int ch, i = 0; 7 | 8 | while ((ch = getchar()) != '\n') 9 | if (i < n) 10 | str[i++] = ch; 11 | str[i] = '\0'; 12 | return i; 13 | } 14 | -------------------------------------------------------------------------------- /Ch09/countdown.c: -------------------------------------------------------------------------------- 1 | /* Prints a countdown */ 2 | 3 | #include 4 | 5 | void print_count(int n) 6 | { 7 | printf("T minus %d and counting\n", n); 8 | } 9 | 10 | int main(void) 11 | { 12 | int i; 13 | 14 | for (i = 10; i > 0; --i) 15 | print_count(i); 16 | 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /Ch11/Exercises/e2.txt: -------------------------------------------------------------------------------- 1 | If i is an int variable and p and q are pointers to int, which of the following 2 | assignments are legal? 3 | 4 | (a) p = i; (d) p = &q; (g) p = *q; 5 | (b) *p = &i; (e) p = *&q; (h) *p = q; 6 | (c) &p = q; (f) p = q; (i) *p = *q; 7 | 8 | Answer: 9 | E, F, and I 10 | -------------------------------------------------------------------------------- /Ch15/ProgrammingProjects/p3/instructions.txt: -------------------------------------------------------------------------------- 1 | Modify the qsort.c program of Section 9.6 so that the quicksort and split 2 | functions are in a separate file named quicksort.c. Create a header file named 3 | quicksort.h that contains prototypes for the two functions and have both 4 | qsort.c and quicksort.c include the file. 5 | -------------------------------------------------------------------------------- /Ch16/Exercises/e15.txt: -------------------------------------------------------------------------------- 1 | (a) Declare a tag for an enumeration whose values represent the seven days of 2 | the week. 3 | 4 | (b) Use typedef to define a name for the enumeration of part (a). 5 | 6 | Answer: 7 | A - enum { MON, TUE, WED, THU, FRI, SAT, SUN }; 8 | B - typedef enum { MON, TUE, WED, THU, FRI, SAT, SUN } weekday; 9 | -------------------------------------------------------------------------------- /Ch17/ProgrammingProjects/p1/instructions.txt: -------------------------------------------------------------------------------- 1 | Modify the inventory.c program of Section 16.3 so that the inventory array is 2 | allocated dynamically and later reallocated when it fills up. Use malloc 3 | initially to allocate parts, use realloc to double its size. Repeat the doubling 4 | step each time the array becomes full. 5 | -------------------------------------------------------------------------------- /Ch10/Exercises/e3.txt: -------------------------------------------------------------------------------- 1 | Suppose that a program has only one function (main). How many different 2 | variables named i could this program contain? 3 | 4 | Answer: 5 | It could have as many i's as there are blocks in main that declare it. 6 | So potentially infinite i's, or at least as many as the stack allows for. 7 | Not 100% sure. 8 | -------------------------------------------------------------------------------- /Ch13/Exercises/e09.txt: -------------------------------------------------------------------------------- 1 | What will be the value of the string s1 after the following statements have 2 | executed? 3 | 4 | strcpy(s1, "computer"); 5 | strcpy(s2, "science"); 6 | if (strcmp(s1, s2) < 0) 7 | strcat(s1, s2); 8 | else 9 | strcat(s2, s1); 10 | s1[strlen(s1)-6] = '\0'; 11 | 12 | Answer: 13 | computers 14 | -------------------------------------------------------------------------------- /Ch14/Exercises/e16.c: -------------------------------------------------------------------------------- 1 | /* (C99) Assume the following macro definitions are in effect: 2 | * 3 | * #define IDENT(x) PRAGMA(ident #x) 4 | * #define PRAGMA(x) _Pragma(#x) 5 | * 6 | * What will the following line look like after macro expansion? 7 | * 8 | * IDENT(foo) 9 | */ 10 | /* Answer: */ 11 | #pragma ident "foo" 12 | -------------------------------------------------------------------------------- /Ch07/length2.c: -------------------------------------------------------------------------------- 1 | /* Determines the length of a message */ 2 | 3 | #include 4 | 5 | int main(void) 6 | { 7 | int len = 0; 8 | 9 | printf("Enter a message: "); 10 | while (getchar() != '\n') 11 | len++; 12 | printf("Your message was %d characters long.\n", len); 13 | 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /Ch16/ProgrammingProjects/p4/instructions.txt: -------------------------------------------------------------------------------- 1 | Modify the inventory.c program of Section 16.3 by adding a price member to the 2 | structure. The insert function should ask the user for the price of the new 3 | item. The search and print functions should display the price. Add a new command 4 | that allows the user to change the price of a part. 5 | -------------------------------------------------------------------------------- /Ch21/Exercises/e2.txt: -------------------------------------------------------------------------------- 1 | Having located the header files on your system (see Exercise 1), find a standard 2 | header in which a macro hides a function. 3 | 4 | Answer: 5 | alloca.h uses the following macro to hide the function alloca: 6 | 7 | #ifdef __GNUC__ 8 | # define alloca(size) __builtin_alloca (size) 9 | #endif /* GCC. */ 10 | -------------------------------------------------------------------------------- /Ch19/Exercises/e6/instructions.txt: -------------------------------------------------------------------------------- 1 | (a) Add a peek function to stackADT.c. This function will have a parameter of 2 | type Stack. When called, it returns the top item on the stack but doesn't 3 | modify the stack. 4 | 5 | (b) Repeat part (a), modifying stackADT2.c this time. 6 | 7 | (c) Repeat part (a), modifying stackADT3.c this time. 8 | -------------------------------------------------------------------------------- /Ch07/Exercises/e04.txt: -------------------------------------------------------------------------------- 1 | If c is a variable of type char, which one of the following statements is 2 | illegal? 3 | 4 | (a) i += c; /* i has type int */ 5 | (b) c = 2 * c - 1; 6 | (c) putchar(c); 7 | (d) printf(c); 8 | 9 | Answer: 10 | D is illegal because characters are interpreted as constants. Printf requires 11 | a string, not a constant. 12 | -------------------------------------------------------------------------------- /Ch08/Exercises/e02.txt: -------------------------------------------------------------------------------- 1 | The Q&A section shows how to use a letter as an array subscript. Describe how 2 | to use a digit (in character form) as a subscript. 3 | 4 | Answer: 5 | Using a digit as an array subscript is very similar to using a letter. Instead 6 | of array[letter - 'a'] for a letter, it becomes array[digit - '0'] for digit 7 | characters. 8 | -------------------------------------------------------------------------------- /Ch03/tprintf.c: -------------------------------------------------------------------------------- 1 | /* Prints int and float values in various formats */ 2 | 3 | #include 4 | 5 | int main(void) 6 | { 7 | int i; 8 | float x; 9 | 10 | i = 40; 11 | x = 839.21f; 12 | 13 | printf("|%d|%5d|%-5d|%.3d|\n", i, i, i, i); 14 | printf("|%10.3f|%10.3e|%-10g|\n", x, x, x); 15 | 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /Ch09/Exercises/e16.c: -------------------------------------------------------------------------------- 1 | /* Condense the fact function in the same way we condensed power. */ 2 | 3 | /* Original */ 4 | int fact(int n) 5 | { 6 | if (n <= 1) 7 | return 1; 8 | else 9 | return n * fact(n - 1); 10 | } 11 | 12 | /* Answer: */ 13 | int fact(int n) 14 | { 15 | return (n <= 1) ? 1 : n * fact(n - 1); 16 | } 17 | -------------------------------------------------------------------------------- /Ch20/Exercises/e05.txt: -------------------------------------------------------------------------------- 1 | Write macros named GET_RED, GET_GREEN, and GET_BLUE that, when given a color as 2 | an argument (see Exercise 4), return its 8-bit red, green, and blue 3 | intensitities. 4 | 5 | Answer: 6 | #define GET_RED(color) ((color) & 0xff) 7 | #define GET_GREEN(color) ((color) >> 8 & 0xff) 8 | #define GET_BLUE(color) ((color) >> 16 & 0xff) 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This repo has my solutions to the various exercises and programming projects 2 | found throughout the book [C Programming: A Modern Approach, 2nd 3 | Edition](http://www.amazon.com/Programming-Modern-Approach-2nd-Edition/dp/0393979504) 4 | by K. N. King. If you come across any errors or things I could've done better, 5 | please tell me about it. 6 | -------------------------------------------------------------------------------- /Ch17/Exercises/e16.c: -------------------------------------------------------------------------------- 1 | /* Write the following function. The call sum(g, i, j) should return 2 | * g(i) + ... + g(j). 3 | * 4 | * int sum(int (*f)(int), int start, int end); 5 | */ 6 | int sum(int (*f)(int), int start, int end) 7 | { 8 | int sum = 0; 9 | for (; start <= end; ++start) 10 | sum += f(start); 11 | return sum; 12 | } 13 | -------------------------------------------------------------------------------- /Ch07/Exercises/e07.txt: -------------------------------------------------------------------------------- 1 | For each of the following character escapes, give the equivalent octal escape. 2 | (Assume that the character set is ASCII.) You may wish to consult Appendix E, 3 | which lists the numerical codes for ASCII characters. 4 | 5 | (a) \b 6 | (b) \n 7 | (c) \r 8 | (d) \t 9 | 10 | Answer: 11 | A - \10 12 | B - \12 13 | C - \15 14 | D - \11 15 | -------------------------------------------------------------------------------- /Ch19/Exercises/e5/queue.h: -------------------------------------------------------------------------------- 1 | #ifndef QUEUE_H 2 | 3 | #define QUEUE_H 4 | #include 5 | #include 6 | 7 | typedef int Item; 8 | typedef struct queue_type *Queue; 9 | 10 | void insert(Queue q, Item value); 11 | void remove(Queue q); 12 | Item get_first_item(Queue q); 13 | Item get_last_item(Queue q); 14 | bool is_empty(Queue q); 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /Ch15/ProgrammingProjects/p1/output.txt: -------------------------------------------------------------------------------- 1 | C is quirky, flawed, and an enormous success. Although accidents of history surely helped, it evidently satisfied a need for a system implementation language effifient enough to displace assembly language, yet sufficiently abstract and fluent to describe algorithms and interactions in a wide variety of environments. -- Dennis M. Ritchie 2 | -------------------------------------------------------------------------------- /Ch15/ProgrammingProjects/p1/quote.txt: -------------------------------------------------------------------------------- 1 | C is quirky, flawed, and an enormous success. Although accidents of history surely helped, it evidently satisfied a need for a system implementation language effifient enough to displace assembly language, yet sufficiently abstract and fluent to describe algorithms and interactions in a wide variety of environments. -- Dennis M. Ritchie 2 | -------------------------------------------------------------------------------- /Ch19/Exercises/e7/instructions.txt: -------------------------------------------------------------------------------- 1 | Modify stackADT2.c so that a stack automatically doubles in size when it becomes 2 | full. Have the push function dynamically allocate a new array that's twice as 3 | large as the old one and then copy the stack contents from the old array to the 4 | new one. Be sure to have push deallocate the old array once the data has been 5 | copied. 6 | -------------------------------------------------------------------------------- /Ch06/Exercises/e05.txt: -------------------------------------------------------------------------------- 1 | Whick one of the following statements is not equivalent to the other two 2 | (assuming that the loop bodies are the same?) 3 | 4 | (a) while (i < 10) {...} 5 | (b) for (; i < 10;) {...} 6 | (c) do {...} while (i < 10); 7 | 8 | Answer: 9 | C, because unlike A and B, it executes whatever statements are under it 10 | before doing the first check. 11 | -------------------------------------------------------------------------------- /Ch07/Exercises/e06.txt: -------------------------------------------------------------------------------- 1 | For each of the following items of date, specify which one of the 2 | types char, short, int, or long is the smallest one guaranteed to be 3 | large enough to store the item. 4 | 5 | (a) Days in a month 6 | (b) Days in a year 7 | (c) Minutes in a day 8 | (d) Seconds in a day 9 | 10 | Answer: 11 | A - char 12 | B - short 13 | C - short 14 | D - int 15 | -------------------------------------------------------------------------------- /Ch12/Exercises/e03.txt: -------------------------------------------------------------------------------- 1 | What will be the contents of the a array after the following statements are 2 | executed? 3 | 4 | #define N 10 5 | 6 | int a[N] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; 7 | int *p = &a[0], *q = a[N-1], temp; 8 | 9 | while (p < q) { 10 | temp = *p; 11 | *p++ = *q; 12 | *q-- = temp; 13 | } 14 | 15 | Answer: 16 | 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 17 | -------------------------------------------------------------------------------- /Ch04/Exercises/e14.txt: -------------------------------------------------------------------------------- 1 | Supply parentheses to show how a C compiler would interpret each of the 2 | following expressions. 3 | 4 | (a) a * b - c * d + e 5 | (b) a / b % c / d 6 | (c) - a - b + c - + d 7 | (d) a * - b / c - d 8 | 9 | Answer: 10 | (a) (((a * b) - (c * d)) + e) 11 | (b) (((a / b) % c) / d) 12 | (c) ((((- a) - b) + c) - (+ d)) 13 | (d) (((a * (- b)) / c) - d) 14 | -------------------------------------------------------------------------------- /Ch04/Exercises/e15.txt: -------------------------------------------------------------------------------- 1 | Give the values of i and j after each of the following expression statements 2 | has been executed. 3 | (Assume that i has the value 1 initially and j has the value 2.) 4 | 5 | (a) i += j; 6 | (b) i--; 7 | (c) i * j / i; 8 | (d) i % ++j; 9 | 10 | Answer: 11 | (a) i is 3, j is 2 12 | (b) i is 0, j is 2 13 | (c) i is 1, j is 2 14 | (d) i is 1, j is 3 15 | -------------------------------------------------------------------------------- /Ch07/Exercises/e12.txt: -------------------------------------------------------------------------------- 1 | Suppose that i is a variable of type int, f is a variable of type float, and 2 | d is a variable of type double. Explain what conversion takes place during the 3 | execution of the following statement: 4 | 5 | d = i + f; 6 | 7 | Answer: 8 | In the statement, i is converted to a float, then the result of i + f is 9 | converted to a double in the end. 10 | -------------------------------------------------------------------------------- /Ch12/Exercises/e11.c: -------------------------------------------------------------------------------- 1 | /* Modify the find_largest function of Section 12.3 so that it uses pointer 2 | * arithmetic--not subscripting--to visit array elements. 3 | */ 4 | int find_largest(int a[], int n) 5 | { 6 | int *p, max; 7 | 8 | max = a[0]; 9 | for (p = a + 1; p < a + n; p++) 10 | if (*p > max) 11 | max = *p; 12 | return max; 13 | } 14 | -------------------------------------------------------------------------------- /Ch08/Exercises/e08.c: -------------------------------------------------------------------------------- 1 | /* Write a declaration for a two-dimensional array named temperature_readings that 2 | * stores one month of hourly temperature readings. (For simplicity, assume that 3 | * a month has 30 days.) The rows of the array should represent days of the month; 4 | * the columns should represent hours of the day. 5 | */ 6 | 7 | /* Answer: */ 8 | int temperature_readings[30][24]; 9 | -------------------------------------------------------------------------------- /Ch17/ProgrammingProjects/p4/instructions.txt: -------------------------------------------------------------------------------- 1 | Modify the justify program of Section 15.3 by rewriting the line.c file so that 2 | it stores the current line in a linked list. Each node in the list will store 3 | a single word. The line array will be replaced by a variable that points to the 4 | node containing the first word. This variable will store a null pointer whenever 5 | the line is empty. 6 | -------------------------------------------------------------------------------- /Ch19/ProgrammingProjects/p4/stackADT.h: -------------------------------------------------------------------------------- 1 | #ifndef STACKADT_H 2 | #define STACKADT_H 3 | 4 | #include /* C99 only */ 5 | 6 | typedef struct stack_type *Stack; 7 | 8 | Stack create(void); 9 | void destroy(Stack s); 10 | void make_empty(Stack s); 11 | bool is_empty(Stack s); 12 | bool is_full(Stack s); 13 | void (push(Stack s, void *i)); 14 | void *pop(Stack s); 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /Ch12/Exercises/e02.txt: -------------------------------------------------------------------------------- 1 | Suppose that high, low, and middle are all pointer variables of the same type, 2 | and that low and high point to elements of an array. Why is the following 3 | statement illegal and how could it be fixed? 4 | 5 | middle = (low + high) / 2; 6 | 7 | Answer: 8 | It's illegal because pointers can only be subtracted from eachother. 9 | 10 | middle = low + (high - low) / 2; 11 | -------------------------------------------------------------------------------- /Ch15/ProgrammingProjects/p2/quote.txt: -------------------------------------------------------------------------------- 1 | C is quirky, flawed, and an enormous success. Although accidents of history surely helped, HERESABIGWORDITNEVERENDSUNTILNOW it evidently satisfied a need for a system implementation language effifient enough to displace assembly language, yet sufficiently abstract and fluent to describe algorithms and interactions in a wide variety of environments. -- Dennis M. Ritchie 2 | -------------------------------------------------------------------------------- /Ch19/stackADT.h: -------------------------------------------------------------------------------- 1 | #ifndef STACKADT_H 2 | #define STACKADT_H 3 | 4 | #include /* C99 only */ 5 | 6 | typedef int Item; 7 | 8 | typedef struct stack_type *Stack; 9 | 10 | Stack create(void); 11 | void destroy(Stack s); 12 | void make_empty(Stack s); 13 | bool is_empty(Stack s); 14 | bool is_full(Stack s); 15 | void (push(Stack s, Item i)); 16 | Item pop(Stack s); 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /Ch07/Exercises/e01.c: -------------------------------------------------------------------------------- 1 | /* Give the value of each of the following integer constants. 2 | * (a) 077 3 | * (b) 0x77 4 | * (c) 0XABC 5 | */ 6 | #include 7 | 8 | int main(void) 9 | { 10 | printf("\nA: %d\n", 077); 11 | printf("B: %d\n", 0x77); 12 | printf("C: %d\n\n", 0XABC); 13 | return 0; 14 | } 15 | 16 | /* Answer: 17 | * A - 63 18 | * B - 119 19 | * C - 2748 20 | */ 21 | -------------------------------------------------------------------------------- /Ch13/Exercises/e10.txt: -------------------------------------------------------------------------------- 1 | The following function supposedly creates an identical copy of a string. 2 | What's wrong with the function? 3 | 4 | char *duplicate(const char *p) 5 | { 6 | char *q; 7 | 8 | strcpy(q, p); 9 | return q; 10 | } 11 | 12 | Answer: 13 | It's wrong because q was never set to point anywhere, and it's a local 14 | variable, meaning it's gone after the function is over. 15 | 16 | -------------------------------------------------------------------------------- /Ch18/Exercises/e12.txt: -------------------------------------------------------------------------------- 1 | (a) Write a complete description of the type of the function f, assuming that 2 | it's declared as follows: 3 | 4 | int (*f(float (*)(long), char *))(double); 5 | 6 | (b) Give an example of how f would be called. 7 | 8 | Answer: 9 | A - The f function returns a function pointer to a function with a double argument that returns an int 10 | 11 | B - f(function_name, char_ptr); 12 | -------------------------------------------------------------------------------- /Ch19/stackADT2.h: -------------------------------------------------------------------------------- 1 | #ifndef STACKADT_H 2 | #define STACKADT_H 3 | 4 | #include /* C99 only */ 5 | 6 | typedef int Item; 7 | 8 | typedef struct stack_type *Stack; 9 | 10 | Stack create(int size); 11 | void destroy(Stack s); 12 | void make_empty(Stack s); 13 | bool is_empty(Stack s); 14 | bool is_full(Stack s); 15 | void (push(Stack s, Item i)); 16 | Item pop(Stack s); 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /Ch11/Exercises/e4.c: -------------------------------------------------------------------------------- 1 | /* Write the following function: 2 | * 3 | * void swap(int *p, int *q); 4 | * 5 | * When passed the addresses of two variables, swap should exchange the values 6 | * of the variables: 7 | * 8 | * swap(&i, &j); // exchanges the values of i and j 9 | */ 10 | void swap(int *p, int *q) 11 | { 12 | int temp; 13 | temp = *p; 14 | *p = *q; 15 | *q = temp; 16 | } 17 | -------------------------------------------------------------------------------- /Ch13/Exercises/e07.txt: -------------------------------------------------------------------------------- 1 | Suppose that str is an array of characters. Which one of the following 2 | statements is not equivalent to the other three? 3 | 4 | (a) *str = 0; 5 | (b) str[0] = '\0'; 6 | (c) strcpy(str, ""); 7 | (d) strcat(str, ""); 8 | 9 | Answer: 10 | D is not equivalent, because it leaves the string the same, while the other 11 | three erase the string by setting it's first character to null. 12 | -------------------------------------------------------------------------------- /Ch16/read_line.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "read_line.h" 4 | 5 | int read_line(char str[], int n) 6 | { 7 | int ch, i = 0; 8 | 9 | while (isspace(ch = getchar())) 10 | ; 11 | while (ch != '\n' && ch != EOF) { 12 | if (i < n) 13 | str[i++] = ch; 14 | ch = getchar(); 15 | } 16 | str[i] = '\0'; 17 | return i; 18 | } 19 | -------------------------------------------------------------------------------- /Ch20/Exercises/e02.txt: -------------------------------------------------------------------------------- 1 | Describe a simple way to "toggle" a bit (change it from 0 to 1 or from 1 or 0). 2 | Illustrate the technique by writing a statement that toggles bit 4 of the 3 | variable i. 4 | 5 | Answer: 6 | You can use the tertiary operator to check the current state of the bit in i, 7 | and then set or clear the bit depending on that. 8 | 9 | Statement: (i & 8) ? i &= ~8 : i |= 8; 10 | -------------------------------------------------------------------------------- /Ch06/square2.c: -------------------------------------------------------------------------------- 1 | /* Prints a table of squares using a for statement */ 2 | 3 | #include 4 | 5 | int main(void) 6 | { 7 | int i, n; 8 | 9 | printf("This program prints a table of squares.\n"); 10 | printf("Enter the number of entries in a table: "); 11 | scanf("%d", &n); 12 | 13 | for (i = 1; i <= n; i++) 14 | printf("%10d%10d\n", i, i * i); 15 | 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /Ch07/length.c: -------------------------------------------------------------------------------- 1 | /* Determines the length of a message */ 2 | 3 | #include 4 | 5 | int main(void) 6 | { 7 | char ch; 8 | int len = 0; 9 | 10 | printf("Enter a message: "); 11 | ch = getchar(); 12 | while (ch != '\n') 13 | { 14 | len++; 15 | ch = getchar(); 16 | } 17 | printf("Your message was %d characters long.\n", len); 18 | 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /Ch14/Exercises/e02.c: -------------------------------------------------------------------------------- 1 | /* Write a macro NELEMS(a) that computes the number of elements in 2 | * a one-dimensional array a. Hint: See the discussion of the sizeof operator in 3 | * Section 8.1. 4 | */ 5 | #include 6 | 7 | #define NELEMS(a) (sizeof(a) / sizeof(a[0])) 8 | 9 | int main(void) 10 | { 11 | int array[] = { 3, 4 }; 12 | printf("\n%ld\n\n", NELEMS(array)); 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /Ch16/Exercises/e21.txt: -------------------------------------------------------------------------------- 1 | What are the integer values of the enumeration constants in each of the 2 | following declarations? 3 | 4 | (a) enum {NUL, SOH, STX, ETX}; 5 | (b) enum {VT = 11, FF, CR}; 6 | (c) enum {SO = 14, SI, DLE, CAN = 24, EM}; 7 | (d) enum {ENQ = 45, ACK, BEL, LF = 37, ETB, ESC}; 8 | 9 | Answer: 10 | A - 0, 1, 2, 3 11 | B - 11, 12, 13 12 | C - 14, 15, 16, 24, 25 13 | D - 45, 46, 47, 37, 38, 39 14 | -------------------------------------------------------------------------------- /Ch19/Exercises/e7/stackADT2.h: -------------------------------------------------------------------------------- 1 | #ifndef STACKADT_H 2 | #define STACKADT_H 3 | 4 | #include /* C99 only */ 5 | 6 | typedef int Item; 7 | 8 | typedef struct stack_type *Stack; 9 | 10 | Stack create(int size); 11 | void destroy(Stack s); 12 | void make_empty(Stack s); 13 | bool is_empty(Stack s); 14 | bool is_full(Stack s); 15 | void (push(Stack s, Item i)); 16 | Item pop(Stack s); 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /Ch22/Exercises/e06.txt: -------------------------------------------------------------------------------- 1 | Write a call of printf that prints 2 | 3 | 1 widget 4 | 5 | if the widget variable (of type int) has the value 1, and 6 | 7 | n widgets 8 | 9 | otherwise, where n is the value of widget. You are not allowed to use the if 10 | statement or any other statement; the answer must be a single call of printf. 11 | 12 | Answer: 13 | printf("%d widget%s", widget, ((widget == 1) ? "" : "s")); 14 | -------------------------------------------------------------------------------- /Ch17/inventory2/read_line.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "read_line.h" 4 | 5 | int read_line(char str[], int n) 6 | { 7 | int ch, i = 0; 8 | 9 | while (isspace(ch = getchar())) 10 | ; 11 | while (ch != '\n' && ch != EOF) { 12 | if (i < n) 13 | str[i++] = ch; 14 | ch = getchar(); 15 | } 16 | str[i] = '\0'; 17 | return i; 18 | } 19 | -------------------------------------------------------------------------------- /Ch18/Exercises/e13.txt: -------------------------------------------------------------------------------- 1 | Which of the following declarations are legal? (Assume that PI is a macro that 2 | represents 3.14159.) 3 | 4 | (a) char c = 65; 5 | (b) static int i = 5, j = i * i; 6 | (c) double d = 2 * PI; 7 | (d) double angles[] = {0, PI / 2, PI, 3 * PI / 2); 8 | 9 | Answer: 10 | A - legal 11 | B - illegal, static variables require constant expressions for initialization 12 | C - legal 13 | D - legal 14 | -------------------------------------------------------------------------------- /Ch22/Exercises/e01.txt: -------------------------------------------------------------------------------- 1 | Indicate whether each of the following files is more likely to contain text data 2 | or binary data: 3 | 4 | (a) A file of object code being produced by a C compiler 5 | (b) A program listing produced by a C compiler 6 | (c) An email message sent from one computer to another 7 | (d) A file containing a graphics image 8 | 9 | Answer: 10 | A - binary 11 | B - text 12 | C - text 13 | D - binary 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Object files 2 | *.o 3 | *.ko 4 | *.obj 5 | *.elf 6 | 7 | # Precompiled Headers 8 | *.gch 9 | *.pch 10 | 11 | # Libraries 12 | *.lib 13 | *.a 14 | *.la 15 | *.lo 16 | 17 | # Shared objects (inc. Windows DLLs) 18 | *.dll 19 | *.so 20 | *.so.* 21 | *.dylib 22 | 23 | # Executables 24 | *.exe 25 | *.out 26 | *.app 27 | *.i*86 28 | *.x86_64 29 | *.hex 30 | 31 | # ctags 32 | tags 33 | tags.lock 34 | tags.temp 35 | -------------------------------------------------------------------------------- /Ch09/Exercises/e12.c: -------------------------------------------------------------------------------- 1 | /* Write the following function: 2 | * 3 | * double inner_product(double a[], double b[], int n); 4 | * 5 | * The function should return a[0] * b[0] + a[1] * b[1] + ... + a[n-1] * b[n-1]. 6 | */ 7 | double inner_product(double a[], double b[], int n) 8 | { 9 | int i; 10 | double result; 11 | for (i = 0; i < n; i++) 12 | result += a[i] * b[i]; 13 | return result; 14 | } 15 | -------------------------------------------------------------------------------- /Ch19/Exercises/e4/b/stack.h: -------------------------------------------------------------------------------- 1 | #ifndef STACK_H 2 | #define STACK_H 3 | 4 | #include 5 | #include 6 | 7 | typedef int Item; 8 | typedef struct stack_type *Stack; 9 | 10 | static void terminate(const char* message); 11 | Stack create(void); 12 | void destroy(Stack s); 13 | void make_empty(Stack s); 14 | bool is_empty(Stack s); 15 | void push(Stack s, Item i); 16 | Item pop(Stack s); 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /Ch22/Exercises/e08.txt: -------------------------------------------------------------------------------- 1 | In the previous chapters, we've used the scanf format string " %c" when we 2 | wanted to skip white-space characters and read a nonblank character. Some 3 | programmers use "%1s" instead. Are the two techniques equivalent? If not, what 4 | are the differences? 5 | 6 | Answer: 7 | They're nearly identical, but %s will add a null character at the end, since 8 | it's a string and strings are null terminated. 9 | -------------------------------------------------------------------------------- /Ch06/numdigits.c: -------------------------------------------------------------------------------- 1 | /* Calculates the number of digits in an integer */ 2 | 3 | #include 4 | 5 | int main(void) 6 | { 7 | int digits = 0, n; 8 | 9 | printf("Enter a nonnegative integer: "); 10 | scanf("%d", &n); 11 | 12 | do 13 | { 14 | n /= 10; 15 | digits++; 16 | } while (n > 0); 17 | 18 | printf("The number has %d digit(s).\n", digits); 19 | 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /Ch16/ProgrammingProjects/p2/read_line.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "read_line.h" 4 | 5 | int read_line(char str[], int n) 6 | { 7 | int ch, i = 0; 8 | 9 | while (isspace(ch = getchar())) 10 | ; 11 | while (ch != '\n' && ch != EOF) { 12 | if (i < n) 13 | str[i++] = ch; 14 | ch = getchar(); 15 | } 16 | str[i] = '\0'; 17 | return i; 18 | } 19 | -------------------------------------------------------------------------------- /Ch16/ProgrammingProjects/p3/read_line.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "read_line.h" 4 | 5 | int read_line(char str[], int n) 6 | { 7 | int ch, i = 0; 8 | 9 | while (isspace(ch = getchar())) 10 | ; 11 | while (ch != '\n' && ch != EOF) { 12 | if (i < n) 13 | str[i++] = ch; 14 | ch = getchar(); 15 | } 16 | str[i] = '\0'; 17 | return i; 18 | } 19 | -------------------------------------------------------------------------------- /Ch16/ProgrammingProjects/p4/read_line.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "read_line.h" 4 | 5 | int read_line(char str[], int n) 6 | { 7 | int ch, i = 0; 8 | 9 | while (isspace(ch = getchar())) 10 | ; 11 | while (ch != '\n' && ch != EOF) { 12 | if (i < n) 13 | str[i++] = ch; 14 | ch = getchar(); 15 | } 16 | str[i] = '\0'; 17 | return i; 18 | } 19 | -------------------------------------------------------------------------------- /Ch17/Exercises/e18.c: -------------------------------------------------------------------------------- 1 | /* Modify the compare_parts function so that parts are sorted with their numbers 2 | * in descending order. 3 | */ 4 | #define NAME_LEN 25 5 | 6 | struct part { 7 | int number; 8 | char name[NAME_LEN+1]; 9 | int on_hand; 10 | }; 11 | 12 | /* Answer: */ 13 | int compare_parts(const void *p, const void *q) 14 | { 15 | return ((struct part *)q)->number - ((struct part *)p)->number; 16 | } 17 | -------------------------------------------------------------------------------- /Ch17/ProgrammingProjects/p1/read_line.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "read_line.h" 4 | 5 | int read_line(char str[], int n) 6 | { 7 | int ch, i = 0; 8 | 9 | while (isspace(ch = getchar())) 10 | ; 11 | while (ch != '\n' && ch != EOF) { 12 | if (i < n) 13 | str[i++] = ch; 14 | ch = getchar(); 15 | } 16 | str[i] = '\0'; 17 | return i; 18 | } 19 | -------------------------------------------------------------------------------- /Ch17/ProgrammingProjects/p2/read_line.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "read_line.h" 4 | 5 | int read_line(char str[], int n) 6 | { 7 | int ch, i = 0; 8 | 9 | while (isspace(ch = getchar())) 10 | ; 11 | while (ch != '\n' && ch != EOF) { 12 | if (i < n) 13 | str[i++] = ch; 14 | ch = getchar(); 15 | } 16 | str[i] = '\0'; 17 | return i; 18 | } 19 | -------------------------------------------------------------------------------- /Ch17/ProgrammingProjects/p3/read_line.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "read_line.h" 4 | 5 | int read_line(char str[], int n) 6 | { 7 | int ch, i = 0; 8 | 9 | while (isspace(ch = getchar())) 10 | ; 11 | while (ch != '\n' && ch != EOF) { 12 | if (i < n) 13 | str[i++] = ch; 14 | ch = getchar(); 15 | } 16 | str[i] = '\0'; 17 | return i; 18 | } 19 | -------------------------------------------------------------------------------- /Ch05/Exercises/e07.c: -------------------------------------------------------------------------------- 1 | /* What does the following statement print if i has the value 17? 2 | * What does it print if i has the value -17? 3 | */ 4 | #include 5 | 6 | int main(void) 7 | { 8 | int i = 17; 9 | printf("\n%d\n", i >= 0 ? i : -i); 10 | 11 | i = -17; 12 | printf("%d\n\n", i >= 0 ? i : -i); 13 | 14 | return 0; 15 | } 16 | 17 | /* Answer: 18 | * In both instances it prints 17. 19 | */ 20 | -------------------------------------------------------------------------------- /Ch08/reverse.c: -------------------------------------------------------------------------------- 1 | /* Reverses a series of numbers */ 2 | 3 | #include 4 | 5 | #define N 10 6 | 7 | int main(void) 8 | { 9 | int a[N], i; 10 | 11 | printf("Enter %d numbers ", N); 12 | for (i = 0; i < N; i++) 13 | scanf("%d", &a[i]); 14 | 15 | printf("In reverse order:"); 16 | for (i = N - 1; i >= 0; i--) 17 | printf(" %d", a[i]); 18 | printf("\n"); 19 | 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /Ch19/ProgrammingProjects/p2/stack.h: -------------------------------------------------------------------------------- 1 | #ifndef STACK_H 2 | #define STACK_H 3 | 4 | #include 5 | #include 6 | 7 | typedef struct stack_type *Stack; 8 | 9 | static void terminate(const char *message); 10 | Stack create(void); 11 | void destroy(Stack s); 12 | void make_empty(Stack s); 13 | bool is_empty(Stack s); 14 | bool is_full(Stack s); 15 | void push(Stack s, int i); 16 | int pop(Stack s); 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /Ch07/Exercises/e10.txt: -------------------------------------------------------------------------------- 1 | Suppose that i is a variable of type int, j is a variable of type long, and 2 | k is a variable of type unsigned int. What is the type of the expression 3 | i + (int) j * k? 4 | 5 | Answer: 6 | j is first explicitly converted from a long to an int. 7 | Then the expression becomes (int) + (int) * (unsigned int). Which is much more 8 | simple. 9 | 10 | The expression should evaluate to unsigned int in the end. 11 | -------------------------------------------------------------------------------- /Ch18/Exercises/e07.txt: -------------------------------------------------------------------------------- 1 | Suppose we declare x to be a const object. Which of the following statements 2 | about x is false? 3 | 4 | (a) If x is of type int, it can be used as the value of a case label in a switch 5 | statement. 6 | (b) The compiler will check that no assignment is made to x. 7 | (c) x is subject to the same scope rules as variables. 8 | (d) x can be of any type. 9 | 10 | Answer: 11 | False answers: a 12 | -------------------------------------------------------------------------------- /Ch19/Exercises/e6/a/stackADT.h: -------------------------------------------------------------------------------- 1 | #ifndef STACKADT_H 2 | #define STACKADT_H 3 | 4 | #include /* C99 only */ 5 | 6 | typedef int Item; 7 | 8 | typedef struct stack_type *Stack; 9 | 10 | Stack create(void); 11 | void destroy(Stack s); 12 | void make_empty(Stack s); 13 | bool is_empty(Stack s); 14 | bool is_full(Stack s); 15 | void (push(Stack s, Item i)); 16 | Item pop(Stack s); 17 | Item peek(Stack s); 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /Ch19/Exercises/e6/c/stackADT.h: -------------------------------------------------------------------------------- 1 | #ifndef STACKADT_H 2 | #define STACKADT_H 3 | 4 | #include /* C99 only */ 5 | 6 | typedef int Item; 7 | 8 | typedef struct stack_type *Stack; 9 | 10 | Stack create(void); 11 | void destroy(Stack s); 12 | void make_empty(Stack s); 13 | bool is_empty(Stack s); 14 | bool is_full(Stack s); 15 | void (push(Stack s, Item i)); 16 | Item pop(Stack s); 17 | Item peek(Stack s); 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /Ch19/ProgrammingProjects/p1/stack.h: -------------------------------------------------------------------------------- 1 | #ifndef STACK_H 2 | #define STACK_H 3 | 4 | #include 5 | #include 6 | 7 | typedef struct stack_type *Stack; 8 | 9 | static void terminate(const char *message); 10 | Stack create(void); 11 | void destroy(Stack s); 12 | void make_empty(Stack s); 13 | bool is_empty(Stack s); 14 | bool is_full(Stack s); 15 | void push(Stack s, char i); 16 | char pop(Stack s); 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /Ch18/Exercises/e04.txt: -------------------------------------------------------------------------------- 1 | Let f be the following function. What will be the value of f(10) if f has 2 | never been called before? What will be the value of f(10) if f has been 3 | called five times previously? 4 | 5 | int f(int i) 6 | { 7 | static int j = 0; 8 | return i * j++; 9 | } 10 | 11 | Answer: 12 | Value of f(10) if f has never been called before: 0 13 | value of f(10) if f has been called five times previously: 50 14 | -------------------------------------------------------------------------------- /Ch19/Exercises/e6/b/stackADT2.h: -------------------------------------------------------------------------------- 1 | #ifndef STACKADT_H 2 | #define STACKADT_H 3 | 4 | #include /* C99 only */ 5 | 6 | typedef int Item; 7 | 8 | typedef struct stack_type *Stack; 9 | 10 | Stack create(int size); 11 | void destroy(Stack s); 12 | void make_empty(Stack s); 13 | bool is_empty(Stack s); 14 | bool is_full(Stack s); 15 | void (push(Stack s, Item i)); 16 | Item pop(Stack s); 17 | Item peek(Stack s); 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /Ch19/ProgrammingProjects/p3/stackADT.h: -------------------------------------------------------------------------------- 1 | #ifndef STACKADT_H 2 | #define STACKADT_H 3 | 4 | #include /* C99 only */ 5 | 6 | typedef int Item; 7 | 8 | typedef struct stack_type *Stack; 9 | 10 | Stack create(void); 11 | void destroy(Stack s); 12 | void make_empty(Stack s); 13 | bool is_empty(Stack s); 14 | bool is_full(Stack s); 15 | void (push(Stack s, Item i)); 16 | Item pop(Stack s); 17 | int length(Stack s); 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /Ch06/sum.c: -------------------------------------------------------------------------------- 1 | /* Sums a series of numbers */ 2 | 3 | #include 4 | 5 | int main(void) 6 | { 7 | int n, sum = 0; 8 | 9 | printf("This program sums a series of integers.\n"); 10 | printf("Enter integers (0 to terminate): "); 11 | 12 | scanf("%d", &n); 13 | while (n != 0) 14 | { 15 | sum += n; 16 | scanf("%d", &n); 17 | } 18 | printf("The sum is %d\n", sum); 19 | 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /Ch02/ProgrammingProjects/p4.c: -------------------------------------------------------------------------------- 1 | /* Write a program that asks the user to enter a dollars-and-cents amount, then 2 | * displays the amount with 5% tax added 3 | */ 4 | #include 5 | 6 | int main(void) 7 | { 8 | float money; 9 | 10 | printf("\nEnter an amount: "); 11 | scanf("%f", &money); 12 | 13 | money = money + (money * 0.05f); 14 | 15 | printf("With tax added: $%.2f\n\n", money); 16 | 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /Ch12/Exercises/e01.txt: -------------------------------------------------------------------------------- 1 | Suppose that the following declarations are in effect: 2 | 3 | int a[] = {5, 15, 34, 54, 14, 2, 52, 72}; 4 | int *p = &a[1], *q = &a[5]; 5 | 6 | (a) What is the value of *(p+3)? 7 | (b) What is the value of *(q-3)? 8 | (c) What is the value of q - p? 9 | (d) Is the condition p < q true or false? 10 | (e) Is the condition *p < *q true or false? 11 | 12 | Answer: 13 | A - 14 14 | B - 34 15 | C - 4 16 | D - true 17 | E - false 18 | -------------------------------------------------------------------------------- /Ch19/Exercises/e4/a/stack.h: -------------------------------------------------------------------------------- 1 | #ifndef STACK_H 2 | #define STACK_H 3 | 4 | #include 5 | #include 6 | 7 | typedef int Item; 8 | typedef struct stack_type *Stack; 9 | 10 | static void terminate(const char* message); 11 | Stack create(void); 12 | void destroy(Stack s); 13 | void make_empty(Stack s); 14 | bool is_empty(Stack s); 15 | bool is_full(Stack s); 16 | void push(Stack s, Item i); 17 | Item pop(Stack s); 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /Ch20/Exercises/e01.txt: -------------------------------------------------------------------------------- 1 | Show the output produced by each of the following program fragments. Assume that 2 | i, j, and k are unsigned short variables. 3 | 4 | (a) i = 8; j = 9; 5 | printf("%d", i >> 1 + j >> 1); 6 | (b) i = 1; 7 | printf("%d", i & ~i); 8 | (c) i = 2; j = 1; k = 0; 9 | printf("%d", ~i & j ^ k); 10 | (d) i = 7; j = 8; k = 9; 11 | printf("%d", i ^ j & k); 12 | 13 | Answer: 14 | A - 0 15 | B - 0 16 | C - 1 17 | D - 16 18 | -------------------------------------------------------------------------------- /Ch03/ProgrammingProjects/p1.c: -------------------------------------------------------------------------------- 1 | /* Write a program that accepts a date from the user in the form 2 | * mm/dd/yyyy and then displays the form yyyymmdd 3 | */ 4 | #include 5 | 6 | int main(void) 7 | { 8 | int month, day, year; 9 | 10 | printf("\nEnter a date (mm/dd/yyyy): "); 11 | scanf("%d/%d/%d", &month, &day, &year); 12 | 13 | printf("You entered the date %d%.2d%.2d\n\n", year, month, day); 14 | 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /Ch12/reverse3.c: -------------------------------------------------------------------------------- 1 | /* Reverses a series of numbers (pointer version) */ 2 | 3 | #include 4 | 5 | #define N 10 6 | 7 | int main(void) 8 | { 9 | int a[N], *p; 10 | 11 | printf("Enter %d numbers ", N); 12 | for (p = a; p < a + N; p++) 13 | scanf("%d", p); 14 | 15 | printf("In reverse order:"); 16 | for (p = a + N - 1; p >= a; p--) 17 | printf(" %d", *p); 18 | printf("\n"); 19 | 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /Ch14/Exercises/e05.txt: -------------------------------------------------------------------------------- 1 | Let TOUPPER be the following macro: 2 | 3 | #define TOUPPER(c) ('a'<=(c)&&(c)<='z'?(c)-'a'+'A':(c)) 4 | 5 | Let s be a string and let i be an int variable. Show the output produced by 6 | each of the following program fragments. 7 | 8 | (a) strcpy(s, "abcd"); 9 | i = 0; 10 | putchar(TOUPPER(s[++i])); 11 | (b) strcpy(s, "0123"); 12 | i = 0; 13 | putchar(TOUPPER(s[++i])); 14 | 15 | Answer: 16 | A - D 17 | B - 2 18 | -------------------------------------------------------------------------------- /Ch06/Exercises/e09.c: -------------------------------------------------------------------------------- 1 | /* Translate the for statement of Exercise 8 into an equivalent while statement. 2 | * You will need one statement in addition to the while loop itself. 3 | */ 4 | #include 5 | 6 | int main(void) 7 | { 8 | int i; 9 | 10 | printf("\n"); 11 | 12 | i = 10; 13 | while (i >= 1) 14 | { 15 | printf("%d ", i++); 16 | i /= 2; 17 | } 18 | 19 | printf("\n\n"); 20 | 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /Ch06/square.c: -------------------------------------------------------------------------------- 1 | /* Prints a table of squares using a while statement */ 2 | 3 | #include 4 | 5 | int main(void) 6 | { 7 | int i, n; 8 | 9 | printf("This program prints a table of squares.\n"); 10 | printf("Enter the number of entries in a table: "); 11 | scanf("%d", &n); 12 | 13 | i = 1; 14 | while (i <= n) 15 | { 16 | printf("%10d%10d\n", i, i * i); 17 | i++; 18 | } 19 | 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /Ch07/Exercises/e13.txt: -------------------------------------------------------------------------------- 1 | Assume a program contains the following declarations: 2 | 3 | char c = '\1'; 4 | short s = 2; 5 | int i = -3; 6 | long m = 5; 7 | float f = 6.5f; 8 | double d = 7.5; 9 | 10 | Give the value and the type of each expression listed below: 11 | (a) c * i (c) f / c (e) f - d 12 | (b) s + m (d) d / s (f) (int) f 13 | 14 | 15 | Answer: 16 | 17 | A: int 18 | B: long 19 | C: float 20 | D: double 21 | E: double 22 | F: int 23 | -------------------------------------------------------------------------------- /Ch20/xor.c: -------------------------------------------------------------------------------- 1 | /* Performs XOR encryption */ 2 | 3 | #include 4 | #include 5 | 6 | #define KEY '&' 7 | 8 | int main(void) 9 | { 10 | int orig_char, new_char; 11 | 12 | while ((orig_char = getchar()) != EOF) { 13 | new_char = orig_char ^ KEY; 14 | if (isprint(orig_char) && isprint(new_char)) 15 | putchar(new_char); 16 | else 17 | putchar(orig_char); 18 | } 19 | 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /Ch06/Exercises/e14.txt: -------------------------------------------------------------------------------- 1 | Find the error in the following program fragment and fix it. 2 | 3 | if (n % 2 == 0); 4 | printf("n is even\n"); 5 | 6 | Answer: 7 | The error was the first semicolon after the if condition. It considers that an 8 | empty statement, so the printf statement below always executes no matter what, 9 | even though it appears correct because of the indentation. 10 | 11 | Corrected version: 12 | 13 | if (n % 2 == 0) 14 | printf("n is even\n"); 15 | -------------------------------------------------------------------------------- /Ch08/Exercises/e04.c: -------------------------------------------------------------------------------- 1 | /* (C99) Repeat Exercise 3, but this time use a designated initializer. Make 2 | * the initializer as short as possible. 3 | */ 4 | #include /* C99 only */ 5 | #include 6 | 7 | int main(void) 8 | { 9 | bool weekend[] = { [0] = true, [6] = true }; 10 | int i; 11 | 12 | for (i = 0; i < 7; i++) 13 | printf("\nDay %d: Weekend %d", i + 1, weekend[i]); 14 | printf("\n\n"); 15 | 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /Ch19/ProgrammingProjects/p5/queueADT.h: -------------------------------------------------------------------------------- 1 | #ifndef QUEUE_H 2 | #define QUEUE_H 3 | 4 | #include 5 | #include 6 | 7 | typedef int Item; 8 | typedef struct queue_type *Queue; 9 | 10 | static void terminate(const char* message); 11 | Queue create(); 12 | void destroy(Queue q); 13 | void push(Queue q, Item value); 14 | Item pop(Queue q); 15 | Item get_first_item(Queue q); 16 | Item get_last_item(Queue q); 17 | bool is_empty(Queue q); 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /Ch19/ProgrammingProjects/p6/queueADT.h: -------------------------------------------------------------------------------- 1 | #ifndef QUEUE_H 2 | #define QUEUE_H 3 | 4 | #include 5 | #include 6 | 7 | typedef int Item; 8 | typedef struct queue_type *Queue; 9 | 10 | static void terminate(const char* message); 11 | Queue create(); 12 | void destroy(Queue q); 13 | void push(Queue q, Item value); 14 | Item pop(Queue q); 15 | Item get_first_item(Queue q); 16 | Item get_last_item(Queue q); 17 | bool is_empty(Queue q); 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /Ch19/ProgrammingProjects/p7/queueADT.h: -------------------------------------------------------------------------------- 1 | #ifndef QUEUE_H 2 | #define QUEUE_H 3 | 4 | #include 5 | #include 6 | 7 | typedef int Item; 8 | typedef struct queue_type *Queue; 9 | 10 | static void terminate(const char* message); 11 | Queue create(); 12 | void destroy(Queue q); 13 | void push(Queue q, Item value); 14 | Item pop(Queue q); 15 | Item get_first_item(Queue q); 16 | Item get_last_item(Queue q); 17 | bool is_empty(Queue q); 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /Ch07/sum2.c: -------------------------------------------------------------------------------- 1 | /* Sums a series of numbers (using long variables) */ 2 | 3 | #include 4 | 5 | int main(void) 6 | { 7 | long n, sum = 0; 8 | 9 | printf("This program sums a series of integers.\n"); 10 | printf("Enter integers (0 to terminate): "); 11 | 12 | scanf("%ld", &n); 13 | while (n != 0) 14 | { 15 | sum += n; 16 | scanf("%ld", &n); 17 | } 18 | printf("The sum is: %ld\n", sum); 19 | 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /Ch03/ProgrammingProjects/p4.c: -------------------------------------------------------------------------------- 1 | /* Write a program that prompts the user to enter a telephone number 2 | * in the form (xxx) xxx-xxxx and then displays the number 3 | * in the form xxx.xxx.xxx 4 | */ 5 | #include 6 | 7 | int main(void) 8 | { 9 | int n1, n2, n3; 10 | 11 | printf("\nEnter phone number (xxx) xxx-xxxx: "); 12 | scanf("(%d) %d-%d", &n1, &n2, &n3); 13 | 14 | printf("You entered %d.%d.%d\n\n", n1, n2, n3); 15 | 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /Ch07/Exercises/e03.c: -------------------------------------------------------------------------------- 1 | /* Which of the following are not legal types in C? 2 | * (a) short unsigned int 3 | * (b) short float 4 | * (c) long double 5 | * (d) unsigned long 6 | */ 7 | #include 8 | 9 | int main(void) 10 | { 11 | short unsigned int a; 12 | /* short float b; */ 13 | long double c; 14 | unsigned long d; 15 | 16 | return 0; 17 | } 18 | 19 | /* Answer: 20 | * A - legal 21 | * B - illegal 22 | * C - legal 23 | * D - legal 24 | */ 25 | -------------------------------------------------------------------------------- /Ch02/ProgrammingProjects/p1.c: -------------------------------------------------------------------------------- 1 | /* Write a program that uses printf to display 2 | * the following picture on the screen: 3 | * * 4 | * * 5 | * * 6 | * * * 7 | * * * 8 | * * 9 | */ 10 | #include 11 | 12 | int main(void) 13 | { 14 | printf("\n *\n"); 15 | printf(" * \n"); 16 | printf(" * \n"); 17 | printf("* * \n"); 18 | printf(" * * \n"); 19 | printf(" * \n\n"); 20 | 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /Ch02/celsius.c: -------------------------------------------------------------------------------- 1 | /* Converts a Fahrenheit temperature to Celsius */ 2 | 3 | #include 4 | 5 | #define FREEZING_PT 32.0f 6 | #define SCALE_FACTOR (5.0f / 9.0f) 7 | 8 | int main(void) 9 | { 10 | float fahrenheit, celsius; 11 | 12 | printf("Enter Fahrenheit temperature: "); 13 | scanf("%f", &fahrenheit); 14 | 15 | celsius = (fahrenheit - FREEZING_PT) * SCALE_FACTOR; 16 | 17 | printf("Celsius equivalent: %.1f\n", celsius); 18 | 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /Ch06/Exercises/e03.c: -------------------------------------------------------------------------------- 1 | /* What output does the following for statement produce? 2 | * 3 | * for (i = 5, j = i - 1; i > 0, j > 0; --i, j = i - j) 4 | * printf("%d ", i); 5 | */ 6 | #include 7 | 8 | int main(void) 9 | { 10 | int i, j; 11 | 12 | printf("\n"); 13 | 14 | for (i = 5, j = i - 1; i > 0, j > 0; --i, j = i - j) 15 | printf("%d ", i); 16 | 17 | printf("\n\n"); 18 | 19 | return 0; 20 | } 21 | 22 | /* Answer: 23 | * 5 24 | */ 25 | -------------------------------------------------------------------------------- /Ch06/Exercises/e08.c: -------------------------------------------------------------------------------- 1 | /* What output does the following for statement produce? 2 | * for (i = 10; i >= 1; i /= 2) 3 | * printf("%d ", i++); 4 | */ 5 | #include 6 | 7 | int main(void) 8 | { 9 | int i; 10 | 11 | printf("\n"); 12 | 13 | for (i = 10; i >= 1; i /= 2) 14 | printf("%d ", i++); 15 | 16 | printf("\n\n"); 17 | 18 | return 0; 19 | } 20 | 21 | /* Answer: 22 | * 10 5 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ... etc. endless 1s 23 | */ 24 | -------------------------------------------------------------------------------- /Ch20/Exercises/e08.txt: -------------------------------------------------------------------------------- 1 | Let f be the following function: 2 | 3 | unsigned int f(unsigned int i, int m, int n) 4 | { 5 | return (i >> (m + 1 - n)) && ~(~0 << n); 6 | } 7 | 8 | (a) What is the value of ~(~0 << n)? 9 | (b) What does this function do? 10 | 11 | 12 | Answer: 13 | A - The value is 2 ^ n. 14 | B - It returns a bit-field within i of length n starting at position m. 15 | Positions are assumed to be numbered starting from the rightmost bit, which 16 | is position 0. 17 | -------------------------------------------------------------------------------- /Ch08/Exercises/e01.txt: -------------------------------------------------------------------------------- 1 | We discussed using the expression sizeof(a) / sizeof(a[0]) to calculate the 2 | number of elements in an array. The expression of sizeof(a) / sizeof(t), where 3 | t is the type of a's elements, would also work, but it's considered an inferior 4 | technique. Why? 5 | 6 | Answer: 7 | Because the latter expression is less flexible. Now if someone decides to 8 | change the datatype of the array, they'll have to change t to that datatype in 9 | every subsequent expression. 10 | -------------------------------------------------------------------------------- /Ch15/Exercises/e2.txt: -------------------------------------------------------------------------------- 1 | Which of the following should not be put in a header file? Why not? 2 | 3 | (a) Function prototypes 4 | (b) Function definitions 5 | (c) Macro definitions 6 | (d) Type definitions 7 | 8 | Answer: 9 | B. Function definitions shouldn't be in header files because when the function 10 | is modified, any source files that included the function's header file would 11 | need to be recompiled. Normally that would only be the case if the function's 12 | prototype was modified. 13 | -------------------------------------------------------------------------------- /Ch17/Exercises/e10.c: -------------------------------------------------------------------------------- 1 | /* Modify the print_part function of Section 16.2 so that its parameter is 2 | * a pointer to a part structure. Use the -> operator in your answer. 3 | */ 4 | #include 5 | 6 | struct part { 7 | int number; 8 | char *name; 9 | int on_hand; 10 | }; 11 | 12 | void print_part(struct part *p) 13 | { 14 | printf("Part number: %d\n", p->number); 15 | printf("Part name: %s\n", p->name); 16 | printf("Quantity on hand: %d\n", p->on_hand); 17 | } 18 | -------------------------------------------------------------------------------- /Ch17/Exercises/e15.txt: -------------------------------------------------------------------------------- 1 | Show the output of the following program and explain what it does. 2 | 3 | #include 4 | 5 | int f1(int (*f)(int)); 6 | int f2(int i); 7 | 8 | int main(void) 9 | { 10 | printf("Answer: %d\n", f1(f2)); 11 | return 0; 12 | } 13 | 14 | int f1(int (*f)(int)) 15 | { 16 | int n = 0; 17 | 18 | while ((*f)(n)) n++; 19 | return n; 20 | } 21 | 22 | int f2(int i) 23 | { 24 | return i * i + i - 12; 25 | } 26 | 27 | Answer: 28 | Output: 29 | 3 30 | -------------------------------------------------------------------------------- /Ch09/Exercises/e08.txt: -------------------------------------------------------------------------------- 1 | Which of the following would be valid prototypes for a function that returns 2 | nothing and has one double parameter? 3 | 4 | (a) void f(double x); 5 | (b) void f(double); 6 | (c) void f(x); 7 | (d) f(double x); 8 | 9 | Answer: 10 | A - Valid 11 | B - Valid 12 | C - Invalid, x is missing a datatype for its parameter 13 | D - Depends, f is missing a datatype for its return value. 14 | Valid in C89, but it would default to an int return value. 15 | Invalid/Illegal in C99. 16 | -------------------------------------------------------------------------------- /Ch12/Exercises/e05.txt: -------------------------------------------------------------------------------- 1 | Suppose that a is a one-dimensional array and p is a pointer variable. Assuming that the assignment p = a has just been performed, which of the following expressions are illegal because of mismatched types? Of the remaining expressions, which are true (have a nonzero value)? 2 | 3 | (a) p == a[0] 4 | (b) p == &a[0] 5 | (c) *p == a[0] 6 | (d) p[0] == a[0] 7 | 8 | Answer: 9 | A - Illegal 10 | B - Legal: evaluates true 11 | C - Legal: evaluates true 12 | D - Legal: evaluates true 13 | -------------------------------------------------------------------------------- /Ch04/ProgrammingProjects/p2.c: -------------------------------------------------------------------------------- 1 | /* Extend the program in Programming Project 1 to handle three-digit numbers. */ 2 | 3 | #include 4 | 5 | int main(void) 6 | { 7 | int number, digit1, digit2, digit3; 8 | 9 | printf("\nEnter a three-digit number: "); 10 | scanf("%d", &number); 11 | 12 | digit1 = number / 100; 13 | digit2 = (number / 10) % 10; 14 | digit3 = number % 10; 15 | 16 | printf("The reversal is: %d%d%d\n\n", digit3, digit2, digit1); 17 | 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /Ch12/Exercises/e08.c: -------------------------------------------------------------------------------- 1 | /* Rewrite the following function to use pointer arithmetic instead of array 2 | * subscripting. (In other words, eliminate the variable i and all uses of the 3 | * [] operator.) Make as few changes as possible. 4 | * 5 | * void store_zeros(int a[], int n) 6 | * { 7 | * int i; 8 | * 9 | * for (i = 0; i < n; i++) 10 | * a[i] = 0; 11 | * } 12 | */ 13 | void store_zeros(int a[], int n) 14 | { 15 | int* p; 16 | 17 | for (p = a; p < a + n; p++) 18 | *p = 0; 19 | } 20 | -------------------------------------------------------------------------------- /Ch20/Exercises/e13.txt: -------------------------------------------------------------------------------- 1 | If n is an unsigned int variable, what effect does the following statement have 2 | on the bits in n? 3 | 4 | n &= n - 1; 5 | 6 | Hint: Consider the effect on n if this statement is executed more than once. 7 | 8 | Answer: 9 | It removes the least significant 1 bit of n. 10 | If n is 1010, it will become 1000 because: 11 | 12 | 1010 13 | 1001 14 | &= 15 | 1000 16 | 17 | If this is executed more than once, it can be used to do something based on how 18 | many 1s are in a bit field. 19 | -------------------------------------------------------------------------------- /Ch05/Exercises/e04.c: -------------------------------------------------------------------------------- 1 | /* Write a single expression whose value is either -1, 0, or +1, 2 | * depending on whether i is less than, equal to, or greater than j, 3 | * respectively. 4 | */ 5 | #include 6 | 7 | int main(void) 8 | { 9 | int i, j; 10 | 11 | printf("\nValues for i and j (e.g. 22 6): "); 12 | scanf("%d %d", &i, &j); 13 | 14 | printf("Expression: %d\n\n", !(i == j) * (i < j ? -1 : 1)); 15 | 16 | return 0; 17 | } 18 | 19 | /* Answer: 20 | * !(i == j) * (i < j ? -1 : 1) 21 | */ 22 | -------------------------------------------------------------------------------- /Ch02/ProgrammingProjects/p3.c: -------------------------------------------------------------------------------- 1 | /* Modify the program of Programming Project 2 so that 2 | * it prompts the user for the radius of the sphere. 3 | */ 4 | #include 5 | 6 | #define NUM_PIE 3.141592653f 7 | 8 | int main(void) 9 | { 10 | int radius; 11 | 12 | printf("\nEnter the radius of a sphere: "); 13 | scanf("%d", &radius); 14 | 15 | printf("The volume of a %d-meter sphere is: %.2f\n\n", 16 | radius, (4.0f/3.0f) * NUM_PIE * (radius * radius * radius)); 17 | 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /Ch15/word.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "word.h" 3 | 4 | int read_char(void) 5 | { 6 | int ch = getchar(); 7 | 8 | if (ch == '\n' || ch == '\t') 9 | return ' '; 10 | return ch; 11 | } 12 | 13 | void read_word(char *word, int len) 14 | { 15 | int ch, pos = 0; 16 | 17 | while((ch = read_char()) == ' ') 18 | ; 19 | while(ch != ' ' && ch != EOF) { 20 | if (pos < len) 21 | word[pos++] = ch; 22 | ch = read_char(); 23 | } 24 | word[pos] = '\0'; 25 | } 26 | -------------------------------------------------------------------------------- /Ch16/Exercises/e19.c: -------------------------------------------------------------------------------- 1 | /* Declare a structure with the following members whose tag is pinball_machine: 2 | * 3 | * name - a string of up to 40 characters 4 | * year - an integer (representing the year of manufacture) 5 | * type - an enumeration with the values EM (electromechanical) 6 | * and SS (solid state) 7 | * players - an integer (representing the maximum number of players) 8 | */ 9 | struct pinball_machine { 10 | char name[41]; 11 | int year; 12 | enum { EM, SS } type; 13 | int players; 14 | }; 15 | -------------------------------------------------------------------------------- /Ch03/addfrac.c: -------------------------------------------------------------------------------- 1 | /* Adds two fractions */ 2 | 3 | #include 4 | 5 | int main(void) 6 | { 7 | int num1, denom1, num2, denom2, result_num, result_denom; 8 | 9 | printf("Enter first fraction: "); 10 | scanf("%d/%d", &num1, &denom1); 11 | 12 | printf("Enter second fraction: "); 13 | scanf("%d/%d", &num2, &denom2); 14 | 15 | result_num = num1 * denom2 + num2 * denom1; 16 | result_denom = denom1 * denom2; 17 | printf("The sum is %d/%d\n", result_num, result_denom); 18 | 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /Ch06/Exercises/e01.c: -------------------------------------------------------------------------------- 1 | /* What output does the following program fragment produce? 2 | * 3 | * i = 1; 4 | * while (i <= 128) { 5 | * printf("%d ", i); 6 | * i *= 2; 7 | * } 8 | */ 9 | #include 10 | 11 | int main(void) 12 | { 13 | int i; 14 | 15 | printf("\n"); 16 | 17 | i = 1; 18 | while (i <= 128) 19 | { 20 | printf("%d ", i); 21 | i *= 2; 22 | } 23 | 24 | printf("\n\n"); 25 | 26 | return 0; 27 | } 28 | 29 | /* Answer: 30 | * 1 2 4 8 16 32 64 128 31 | */ 32 | -------------------------------------------------------------------------------- /Ch06/square3.c: -------------------------------------------------------------------------------- 1 | /* Prints a table of squares using an odd method */ 2 | 3 | #include 4 | 5 | int main(void) 6 | { 7 | int i, n, odd, square; 8 | 9 | printf("This program prints a table of squares.\n"); 10 | printf("Enter the number of entries in a table: "); 11 | scanf("%d", &n); 12 | 13 | i = 1; 14 | odd = 3; 15 | for (square = 1; i <= n; odd += 2) 16 | { 17 | printf("%10d%10d\n", i, i * i); 18 | ++i; 19 | square += odd; 20 | } 21 | 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /Ch07/ProgrammingProjects/p03.c: -------------------------------------------------------------------------------- 1 | /* Modify the sum2.c program of Section 7.1 to sum a series of double 2 | * values. 3 | */ 4 | #include 5 | 6 | int main(void) 7 | { 8 | double n, sum = 0; 9 | 10 | printf("\nThis program sums a series of doubles.\n"); 11 | printf("Enter doubles (0 to terminate): "); 12 | 13 | scanf("%lf", &n); 14 | while (n != 0) 15 | { 16 | sum += n; 17 | scanf("%lf", &n); 18 | } 19 | printf("The sum is: %.3lf\n\n", sum); 20 | 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /Ch22/Exercises/e16.txt: -------------------------------------------------------------------------------- 1 | Assume that str is a string that contains a "sales rank" immediately preceded by 2 | the # symbol (other characters may precede the # and/or follow the sales rank). 3 | A sales rank is a series of decimal digits (possibly containing commas, such as 4 | the following examples: 5 | 6 | 989 7 | 24,675 8 | 1,162,620 9 | 10 | Write a call of sscanf that extracts the sales rank (but not the # symbol) and 11 | stores it in a string variable named sales_rank. 12 | 13 | Answer: 14 | sscanf(str, "#%s", sales_rank); 15 | -------------------------------------------------------------------------------- /Ch06/Exercises/e02.c: -------------------------------------------------------------------------------- 1 | /* What output does the following program fragment produce? 2 | * 3 | * i = 9384; 4 | * do { 5 | * printf("%d ", i); 6 | * i /= 10; 7 | * } while (i > 0); 8 | */ 9 | #include 10 | 11 | int main(void) 12 | { 13 | int i; 14 | 15 | printf("\n"); 16 | 17 | i = 9384; 18 | do 19 | { 20 | printf("%d ", i); 21 | i /= 10; 22 | } while (i > 0); 23 | 24 | printf("\n\n"); 25 | 26 | return 0; 27 | } 28 | 29 | /* Answer: 30 | * 9384 938 93 9 31 | */ 32 | -------------------------------------------------------------------------------- /Ch08/Exercises/e09.c: -------------------------------------------------------------------------------- 1 | /* Using the array of Exercise 8, write a program fragment that computes the 2 | * average temperature for a month (averaged over all the days of the month and 3 | * all hours of the day). 4 | */ 5 | 6 | /* Answer: */ 7 | int temperature_readings[30][24]; /* From exercise 8 */ 8 | int day, hour, average_temperature = 0; 9 | 10 | for (day = 0; day < 30; day++) 11 | for (hour = 0; hour < 24; hour++) 12 | average_temperature += temperature_readings[day][hour]; 13 | 14 | average_temperature /= (30 * 24); 15 | -------------------------------------------------------------------------------- /Ch15/Exercises/e5.txt: -------------------------------------------------------------------------------- 1 | Suppose that a program consists of three source files--main.c, f1.c, and 2 | f2.c--plus two header files, f1.h and f2.h. All three source files include f1.h, 3 | but only f1.c and f2.c include f2.h. Write a makefile for this program, assuming 4 | that the compiler is gcc and that the executable file is to be named demo. 5 | 6 | main: main.o f1.o 7 | gcc -o demo main.o f1.o 8 | 9 | main.o: main.c f1.c 10 | gcc -c main.c 11 | 12 | f1.o: f1.h f2.h 13 | gcc -c f1.c 14 | 15 | f2.o: f1.h f2.h 16 | gcc -c f2.c 17 | -------------------------------------------------------------------------------- /Ch02/Exercises/e01.c: -------------------------------------------------------------------------------- 1 | /* Create and run Kernigham and Ritchie's famous "hello, world" program: 2 | * Do you get a warning message from the compiler? 3 | * If so, what's needed to make it go away? 4 | */ 5 | #include 6 | 7 | int main(void) 8 | { 9 | printf("hello, world\n"); 10 | } 11 | 12 | /* Answer: 13 | * Error with -std=c89: In main, control reaches the end of a non-void function 14 | * No error in c99, even with all the error flags 15 | * 16 | * Fixed by returning a value at the end of main: 17 | * return 0; 18 | */ 19 | -------------------------------------------------------------------------------- /Ch13/Exercises/e02.txt: -------------------------------------------------------------------------------- 1 | Suppose that p has been declared as follows: 2 | 3 | char *p = "abc"; 4 | 5 | Which of the following function calls are legal? Show the output produced by 6 | each legal call, and explain why the others are illegal. 7 | 8 | (a) putchar(p); 9 | (b) putchar(*p); 10 | (c) puts(p); 11 | (d) puts(*p); 12 | 13 | Answer: 14 | A - Illegal, putchar takes a character, but was given a pointer 15 | B - Legal 16 | Output: a 17 | C - Legal 18 | Output: abc 19 | 20 | D - Illegal, puts takes a string, but was given a character 21 | -------------------------------------------------------------------------------- /Ch02/dweight.c: -------------------------------------------------------------------------------- 1 | /* Computes the dimensional weight of a 12" x 10" x 8" box */ 2 | 3 | #include 4 | 5 | int main(void) 6 | { 7 | int height, length, width, volume, weight; 8 | 9 | height = 8; 10 | length = 12; 11 | width = 10; 12 | volume = height * length * width; 13 | weight = (volume + 165) / 166; 14 | 15 | printf("Dimensions: %dx%dx%d\n", length, width, height); 16 | printf("Volume (cubic inches): %d\n", volume); 17 | printf("Dimensional weight (pounds): %d\n", weight); 18 | 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /Ch15/ProgrammingProjects/p1/word.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "word.h" 3 | 4 | int read_char(void) 5 | { 6 | int ch = getchar(); 7 | 8 | if (ch == '\n' || ch == '\t') 9 | return ' '; 10 | return ch; 11 | } 12 | 13 | void read_word(char *word, int len) 14 | { 15 | int ch, pos = 0; 16 | 17 | while((ch = read_char()) == ' ') 18 | ; 19 | while(ch != ' ' && ch != EOF) { 20 | if (pos < len) 21 | word[pos++] = ch; 22 | ch = read_char(); 23 | } 24 | word[pos] = '\0'; 25 | } 26 | -------------------------------------------------------------------------------- /Ch17/ProgrammingProjects/p4/word.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "word.h" 3 | 4 | int read_char(void) 5 | { 6 | int ch = getchar(); 7 | 8 | if (ch == '\n' || ch == '\t') 9 | return ' '; 10 | return ch; 11 | } 12 | 13 | void read_word(char *word, int len) 14 | { 15 | int ch, pos = 0; 16 | 17 | while((ch = read_char()) == ' ') 18 | ; 19 | while(ch != ' ' && ch != EOF) { 20 | if (pos < len) 21 | word[pos++] = ch; 22 | ch = read_char(); 23 | } 24 | word[pos] = '\0'; 25 | } 26 | -------------------------------------------------------------------------------- /Ch04/ProgrammingProjects/p3.c: -------------------------------------------------------------------------------- 1 | /* Rewrite the program in Programming Project 2 so that it prints the reversal 2 | * of a three-digit number without using arithmetic to split the number into 3 | * digits. Hint: see upc.c program of Section 4.1 4 | */ 5 | #include 6 | 7 | int main(void) 8 | { 9 | int digit1, digit2, digit3; 10 | 11 | printf("\nEnter a three-digit number: "); 12 | scanf("%1d%1d%1d", &digit1, &digit2, &digit3); 13 | 14 | printf("The reversal is: %d%d%d\n", digit3, digit2, digit1); 15 | 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /Ch09/average.c: -------------------------------------------------------------------------------- 1 | /* Computes the pairwise averages of three numbers */ 2 | 3 | #include 4 | 5 | double average(double a, double b) 6 | { 7 | return (a + b) / 2; 8 | } 9 | 10 | int main(void) 11 | { 12 | double x, y, z; 13 | 14 | printf("Enter three numbers: "); 15 | scanf("%lf%lf%lf", &x, &y, &z); 16 | printf("Average of %g and %g: %g\n", x, y, average(x, y)); 17 | printf("Average of %g and %g: %g\n", y, z, average(y, z)); 18 | printf("Average of %g and %g: %g\n", x, z, average(x, z)); 19 | 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /Ch08/Exercises/e03.c: -------------------------------------------------------------------------------- 1 | /* Write a declaration of an array named weekend containing seven bool values. 2 | * Include an initializer that makes the first and last values true; all other 3 | * values should be false. 4 | */ 5 | #include /* C99 only */ 6 | #include 7 | 8 | int main(void) 9 | { 10 | bool weekend[] = { true, false, false, false, false, false, true }; 11 | int i; 12 | 13 | for (i = 0; i < 7; i++) 14 | printf("\nDay %d: Weekend %d", i + 1, weekend[i]); 15 | printf("\n\n"); 16 | 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /Ch19/ProgrammingProjects/p3/instructions.txt: -------------------------------------------------------------------------------- 1 | Modify the stackADT3.c file of Section 19.4 by adding an int member named len to 2 | the stack_type structure. This member will keep track of how many items are 3 | currently stored in a stack. Add a new function named length that has a Stack 4 | parameter and returns the value of the len member. (Some of the existing 5 | functions in stackADT3.c will need to be modified as well.) Modify stackclient.c 6 | so that it calls the length function (and displays the value that it returns) 7 | after each operation that modifies a stack. 8 | -------------------------------------------------------------------------------- /Ch22/canopen.c: -------------------------------------------------------------------------------- 1 | /* Checks whether a file can be opened for reading */ 2 | 3 | #include 4 | #include 5 | 6 | int main(int argc, char *argv[]) 7 | { 8 | FILE *fp; 9 | 10 | if (argc != 2) { 11 | printf("usage: canopen filename\n"); 12 | exit(EXIT_FAILURE); 13 | } 14 | 15 | if ((fp = fopen(argv[1], "r")) == NULL) { 16 | printf("%s can't be opened\n", argv[1]); 17 | exit(EXIT_FAILURE); 18 | } 19 | 20 | printf("%s can't be opened\n", argv[1]); 21 | fclose(fp); 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /Ch08/Exercises/e05.c: -------------------------------------------------------------------------------- 1 | /* The Fibonacci numbers are 0, 1, 1, 2, 3, 5, 8, 13, ..., where each number is 2 | * the sum of the two preceding numbers. Write a program fragment that declares 3 | * an array named fib_numbers of length 40 and fills the array with the first 4 | * 40 Fibonacci numbers, Hint: Fill in the first two numbers individually, then 5 | * use a loop to compute the remaining numbers. 6 | */ 7 | 8 | /* Answer: */ 9 | int fib_numbers[40] = { 0, 1 }, i; 10 | 11 | for (i = 2; i < 40; i++) 12 | fib_numbers[i] = fib_numbers[i-2] + fib_numbers[i-1]; 13 | -------------------------------------------------------------------------------- /Ch15/Exercises/e3.txt: -------------------------------------------------------------------------------- 1 | We saw that writing #include instead of #include "file" may not work if 2 | file is one that we've written. Would there be any problem with writing #include 3 | "file" instead of #include if file is a system header? 4 | 5 | Answer: 6 | There would only be a problem if you had (for some strange reason) created your 7 | own file with the same name as the system header aforementioned, because when 8 | using quotes, the compiler searches the current directory for that file first, 9 | and then goes to wherever the system headers are. 10 | -------------------------------------------------------------------------------- /Ch15/word.h: -------------------------------------------------------------------------------- 1 | #ifndef WORD_H 2 | #define WORD_H 3 | 4 | /*********************************************************** 5 | * read_word: Reads the next word from the input and * 6 | * stores it in word. Makes word empty if no * 7 | * word could be read because of end-of-file. * 8 | * Truncates the word if its length exceeds * 9 | * len. * 10 | **********************************************************/ 11 | void read_word(char *word, int len); 12 | 13 | #endif 14 | 15 | -------------------------------------------------------------------------------- /Ch22/Exercises/e03.txt: -------------------------------------------------------------------------------- 1 | Find the error in the following program fragment and show how to fix it. 2 | 3 | FILE *fp; 4 | 5 | if (fp = fopen(filename, "r")) { 6 | read characters until end-of-file 7 | } 8 | fclose(fp); 9 | 10 | Answer: 11 | The error is that fclose attempts to close a NULL pointer when fopen fails. 12 | 13 | Corrected version: 14 | FILE *fp; 15 | 16 | if (fp = fopen(filename, "r")) { 17 | read characters until end-of-file 18 | } 19 | else { 20 | printf("Error opening file: %s\n", filename); 21 | exit(EXIT_FAILURE); 22 | } 23 | fclose(fp); 24 | -------------------------------------------------------------------------------- /Ch04/Exercises/e04.c: -------------------------------------------------------------------------------- 1 | /* What is the value of each of the following expressions in C99? 2 | * (Give all possible values if an expression may have more than one value.) 3 | * (a) 8 / 5 4 | * (b) -8 / 5 5 | * (c) 8 / -5 6 | * (d) -8 / -5 7 | */ 8 | #include 9 | 10 | int main(void) 11 | { 12 | printf("\n(a) %d\n", 8 / 5); 13 | printf("(b) %d\n", -8 / 5); 14 | printf("(c) %d\n", 8 / -5); 15 | printf("(d) %d\n\n", -8 / -5); 16 | 17 | return 0; 18 | } 19 | 20 | /* Answer: 21 | * (a) 1 22 | * (b) -1 23 | * (c) -1 24 | * (d) 1 25 | */ 26 | -------------------------------------------------------------------------------- /Ch04/Exercises/e06.c: -------------------------------------------------------------------------------- 1 | /* What is the value of each of the following expressions in C99? 2 | * (Give all possible values if an expression may have more than one value.) 3 | * (a) 8 % 5 4 | * (b) -8 % 5 5 | * (c) 8 % -5 6 | * (d) -8 % -5 7 | */ 8 | #include 9 | 10 | int main(void) 11 | { 12 | printf("\n(a) %d\n", 8 % 5); 13 | printf("(b) %d\n", -8 % 5); 14 | printf("(c) %d\n", 8 % -5); 15 | printf("(d) %d\n\n", -8 % -5); 16 | 17 | return 0; 18 | } 19 | 20 | /* Answer: 21 | * (a) 3 22 | * (b) -3 23 | * (c) 3 24 | * (d) -3 25 | */ 26 | -------------------------------------------------------------------------------- /Ch12/Exercises/e04.c: -------------------------------------------------------------------------------- 1 | /* Rewrite the make_empty, is_empty, and is_full functions of Section 10.2 to 2 | * use the pointer variable top_ptr instead of the integer variable top. 3 | */ 4 | #include 5 | #define STACK_SIZE 100 6 | 7 | /* external variables */ 8 | int contents[STACK_SIZE]; 9 | int* top_ptr; 10 | 11 | void make_empty(void) 12 | { 13 | top_ptr = &contents[0]; 14 | } 15 | 16 | bool is_empty(void) 17 | { 18 | return top_ptr == &contents[0]; 19 | } 20 | 21 | bool is_full(void) 22 | { 23 | return top_ptr == &contents[STACK_SIZE]; 24 | } 25 | -------------------------------------------------------------------------------- /Ch16/read_line.h: -------------------------------------------------------------------------------- 1 | #ifndef READLINE_H 2 | #define READLINE_H 3 | 4 | 5 | /********************************************************** 6 | * read_line: Skips leading white-space characters, then * 7 | * reads the remainder of the input line and * 8 | * stores it in str. Truncates the line if its * 9 | * length exceeds n. Returns the number of * 10 | * characters stored. * 11 | *********************************************************/ 12 | int read_line(char str[], int n); 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /Ch06/Exercises/e11.c: -------------------------------------------------------------------------------- 1 | /* What output does the following program fragment produce? 2 | * 3 | * sum = 0; 4 | * for (i = 0; i < 10; i++) { 5 | * if (i % 2) 6 | * continue; 7 | * sum += 1; 8 | * } 9 | * printf("%d\n", sum); 10 | */ 11 | #include 12 | 13 | int main(void) 14 | { 15 | int sum, i; 16 | 17 | sum = 0; 18 | for (i = 0; i < 10; i++) 19 | { 20 | if (i % 2) 21 | continue; 22 | sum += 1; 23 | } 24 | printf("\n%d\n\n", sum); 25 | 26 | return 0; 27 | } 28 | 29 | /* Answer: 30 | * 5 31 | */ 32 | -------------------------------------------------------------------------------- /Ch16/Exercises/e17.txt: -------------------------------------------------------------------------------- 1 | Suppose that b and i are declared as follows: 2 | 3 | enum {FALSE, TRUE} b; 4 | int i; 5 | 6 | Which of the following statements are legal? Which ones are "safe" (always yield 7 | a meaningful result)? 8 | 9 | (a) b = FALSE; 10 | (b) b = i; 11 | (c) b++; 12 | (d) i = b; 13 | (e) i = 2 * b + 1; 14 | 15 | Answer: 16 | A - Legal 17 | 18 | B - Illegal because i is uninitialized, and has an unknown value 19 | 20 | C - Illegal because b is uninitialized 21 | 22 | D - Illegal because b is uninitialized 23 | 24 | E - Illegal because b is uninitialized 25 | -------------------------------------------------------------------------------- /Ch17/Exercises/e08/instructions.txt: -------------------------------------------------------------------------------- 1 | Section 15.2 describes a file, stack.c, that provides functions for storing 2 | integers in a stack. In that section, the stack was implemented as an array. 3 | Modify stack.c so that a stack is now stored as a linked list. Replace the 4 | contents and top variables by a single variable that points to the first node in 5 | the list (the "top" of the stack). Write the functions in stack.c so that they 6 | use this pointer. Remove the is_full function, instead having push return either 7 | true (if memory was available to create a node) or false (if not). 8 | -------------------------------------------------------------------------------- /Ch17/inventory2/read_line.h: -------------------------------------------------------------------------------- 1 | #ifndef READLINE_H 2 | #define READLINE_H 3 | 4 | 5 | /********************************************************** 6 | * read_line: Skips leading white-space characters, then * 7 | * reads the remainder of the input line and * 8 | * stores it in str. Truncates the line if its * 9 | * length exceeds n. Returns the number of * 10 | * characters stored. * 11 | *********************************************************/ 12 | int read_line(char str[], int n); 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /Ch03/Exercises/e5.c: -------------------------------------------------------------------------------- 1 | /* Suppose we call scanf as follows: scanf("%f%d%f", &x, &i, &y); 2 | * 3 | * If the user enters 12.3 45.6 789 4 | * 5 | * what will be the values of x, i, and y after the call? (Assume that x and 6 | * y are float variables and i is a int variable) 7 | */ 8 | #include 9 | 10 | int main(void) 11 | { 12 | float x, y; 13 | int i; 14 | 15 | scanf("%f%d%f", &x, &i, &y); 16 | printf("\nx: %f, i: %d, y: %f\n\n", x, i, y); 17 | 18 | return 0; 19 | } 20 | 21 | /* Answer: 22 | * x: 12.300000 23 | * i: 45 24 | * y: 0.600000 25 | */ 26 | -------------------------------------------------------------------------------- /Ch04/Exercises/e03.c: -------------------------------------------------------------------------------- 1 | /* What is the value of each of the following expressions in C89? 2 | * (Give all possible values if an expression may have more than one value.) 3 | * (a) 8 / 5 4 | * (b) -8 / 5 5 | * (c) 8 / -5 6 | * (d) -8 / -5 7 | */ 8 | #include 9 | 10 | int main(void) 11 | { 12 | printf("\n(a) %d\n", 8 / 5); 13 | printf("(b) %d\n", -8 / 5); 14 | printf("(c) %d\n", 8 / -5); 15 | printf("(d) %d\n\n", -8 / -5); 16 | 17 | return 0; 18 | } 19 | 20 | /* Answer: 21 | * (a) 1 22 | * (b) -1 or -2 23 | * (c) -1 or -2 24 | * (d) 1 or 2 25 | */ 26 | -------------------------------------------------------------------------------- /Ch04/Exercises/e05.c: -------------------------------------------------------------------------------- 1 | /* What is the value of each of the following expressions in C89? 2 | * (Give all possible values if an expression may have more than one value.) 3 | * (a) 8 % 5 4 | * (b) -8 % 5 5 | * (c) 8 % -5 6 | * (d) -8 % -5 7 | */ 8 | #include 9 | 10 | int main(void) 11 | { 12 | printf("\n(a) %d\n", 8 % 5); 13 | printf("(b) %d\n", -8 % 5); 14 | printf("(c) %d\n", 8 % -5); 15 | printf("(d) %d\n\n", -8 % -5); 16 | 17 | return 0; 18 | } 19 | 20 | /* Answer: 21 | * (a) 3 22 | * (b) -3 or 2 23 | * (c) 3 or -2 24 | * (d) -3 or 2 25 | */ 26 | -------------------------------------------------------------------------------- /Ch11/Exercises/e5.c: -------------------------------------------------------------------------------- 1 | /* Write the following function: 2 | * 3 | * void split_time(long total_sec, int *hr, int *min, int *sec); 4 | * 5 | * total_sec is a time represented as a number of seconds since midnight. hr, 6 | * min, and sec are pointers to variables in which the function will store the 7 | * equivalent time in hours (0-23), minutes (0-59), and seconds (0-59), 8 | * respectively. 9 | */ 10 | void split_time(long total_sec, int *hr, int *min, int *sec) 11 | { 12 | *sec = total_sec % 60; 13 | *min = total_sec / 60 % 60; 14 | *hr = total_sec / 60 / 60; 15 | } 16 | -------------------------------------------------------------------------------- /Ch17/Exercises/e05.txt: -------------------------------------------------------------------------------- 1 | Suppose that f and p are declared as follows: 2 | 3 | struct { 4 | union { 5 | char a, b; 6 | int c; 7 | } d; 8 | int e[5]; 9 | } f, *p = &f; 10 | 11 | Which of the following statements are legal? 12 | 13 | (a) p->b = ' '; 14 | (b) p->e[3] = 10; 15 | (c) (*p).d.a = '*'; 16 | (d) p->d->c = 20; 17 | 18 | Answer: 19 | A - Illegal because the variable b is inside the union d, not directly in f. 20 | Should be: p->d.b = ' '; 21 | 22 | B - Legal 23 | 24 | C - Legal 25 | 26 | D - Illegal because d isn't a pointer. 27 | Should be: p->d.c = 20; 28 | -------------------------------------------------------------------------------- /Ch15/Exercises/e6.txt: -------------------------------------------------------------------------------- 1 | The following questions refer to the program described in Exercise 5. 2 | 3 | (a) Which files need to be compiled when the program is built for the first 4 | time? 5 | (b) If f1.c is changed after the program has been built, which files need to be recompiled? 6 | (c) If f1.h is changed after the program has been built, which files need to be recompiled? 7 | (d) If f2.h is changed after the program has been built, which files need to be recompiled? 8 | 9 | Answer: 10 | A - main.c, f1.c, f2.c 11 | 12 | B - f1.c 13 | 14 | C - main.c, f1.c, f2.c 15 | 16 | D - f1.c, f2.c 17 | -------------------------------------------------------------------------------- /Ch15/ProgrammingProjects/p1/word.h: -------------------------------------------------------------------------------- 1 | #ifndef WORD_H 2 | #define WORD_H 3 | 4 | /*********************************************************** 5 | * read_word: Reads the next word from the input and * 6 | * stores it in word. Makes word empty if no * 7 | * word could be read because of end-of-file. * 8 | * Truncates the word if its length exceeds * 9 | * len. * 10 | **********************************************************/ 11 | void read_word(char *word, int len); 12 | 13 | #endif 14 | 15 | -------------------------------------------------------------------------------- /Ch15/ProgrammingProjects/p2/word.h: -------------------------------------------------------------------------------- 1 | #ifndef WORD_H 2 | #define WORD_H 3 | 4 | /*********************************************************** 5 | * read_word: Reads the next word from the input and * 6 | * stores it in word. Makes word empty if no * 7 | * word could be read because of end-of-file. * 8 | * Truncates the word if its length exceeds * 9 | * len. * 10 | **********************************************************/ 11 | void read_word(char *word, int len); 12 | 13 | #endif 14 | 15 | -------------------------------------------------------------------------------- /Ch15/ProgrammingProjects/p4/readline.h: -------------------------------------------------------------------------------- 1 | #ifndef READLINE_H 2 | #define READLINE_H 3 | 4 | /*********************************************************** 5 | * read_line: Reads characters from stdin into a string * 6 | * str of maximum length n. * 7 | * * 8 | * Returns how many characters were entered, * 9 | * even if there were more than n. * 10 | **********************************************************/ 11 | int read_line(char str[], int n); 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /Ch16/Exercises/e04.c: -------------------------------------------------------------------------------- 1 | /* Repeat exercise 3, but this time using a type named Complex */ 2 | 3 | /* Answer: 4 | * A: */ 5 | typedef struct { 6 | double real, imaginary; 7 | } Complex; 8 | 9 | /* B: */ 10 | Complex c1, c2, c3; 11 | 12 | /* C: */ 13 | Complex 14 | make_complex(double mem1, double mem2) 15 | { 16 | return (Complex) { mem1, mem2 }; 17 | } 18 | 19 | /* D: */ 20 | Complex 21 | add_complex(Complex com1, Complex com2) 22 | { 23 | Complex sum; 24 | sum.real = com1.real + com2.real; 25 | sum.imaginary = com1.imaginary + com2.imaginary; 26 | return sum; 27 | } 28 | -------------------------------------------------------------------------------- /Ch16/ProgrammingProjects/p2/read_line.h: -------------------------------------------------------------------------------- 1 | #ifndef READLINE_H 2 | #define READLINE_H 3 | 4 | 5 | /********************************************************** 6 | * read_line: Skips leading white-space characters, then * 7 | * reads the remainder of the input line and * 8 | * stores it in str. Truncates the line if its * 9 | * length exceeds n. Returns the number of * 10 | * characters stored. * 11 | *********************************************************/ 12 | int read_line(char str[], int n); 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /Ch16/ProgrammingProjects/p3/read_line.h: -------------------------------------------------------------------------------- 1 | #ifndef READLINE_H 2 | #define READLINE_H 3 | 4 | 5 | /********************************************************** 6 | * read_line: Skips leading white-space characters, then * 7 | * reads the remainder of the input line and * 8 | * stores it in str. Truncates the line if its * 9 | * length exceeds n. Returns the number of * 10 | * characters stored. * 11 | *********************************************************/ 12 | int read_line(char str[], int n); 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /Ch16/ProgrammingProjects/p4/read_line.h: -------------------------------------------------------------------------------- 1 | #ifndef READLINE_H 2 | #define READLINE_H 3 | 4 | 5 | /********************************************************** 6 | * read_line: Skips leading white-space characters, then * 7 | * reads the remainder of the input line and * 8 | * stores it in str. Truncates the line if its * 9 | * length exceeds n. Returns the number of * 10 | * characters stored. * 11 | *********************************************************/ 12 | int read_line(char str[], int n); 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /Ch17/ProgrammingProjects/p1/read_line.h: -------------------------------------------------------------------------------- 1 | #ifndef READLINE_H 2 | #define READLINE_H 3 | 4 | 5 | /********************************************************** 6 | * read_line: Skips leading white-space characters, then * 7 | * reads the remainder of the input line and * 8 | * stores it in str. Truncates the line if its * 9 | * length exceeds n. Returns the number of * 10 | * characters stored. * 11 | *********************************************************/ 12 | int read_line(char str[], int n); 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /Ch17/ProgrammingProjects/p2/read_line.h: -------------------------------------------------------------------------------- 1 | #ifndef READLINE_H 2 | #define READLINE_H 3 | 4 | 5 | /********************************************************** 6 | * read_line: Skips leading white-space characters, then * 7 | * reads the remainder of the input line and * 8 | * stores it in str. Truncates the line if its * 9 | * length exceeds n. Returns the number of * 10 | * characters stored. * 11 | *********************************************************/ 12 | int read_line(char str[], int n); 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /Ch17/ProgrammingProjects/p3/read_line.h: -------------------------------------------------------------------------------- 1 | #ifndef READLINE_H 2 | #define READLINE_H 3 | 4 | 5 | /********************************************************** 6 | * read_line: Skips leading white-space characters, then * 7 | * reads the remainder of the input line and * 8 | * stores it in str. Truncates the line if its * 9 | * length exceeds n. Returns the number of * 10 | * characters stored. * 11 | *********************************************************/ 12 | int read_line(char str[], int n); 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /Ch17/ProgrammingProjects/p4/word.h: -------------------------------------------------------------------------------- 1 | #ifndef WORD_H 2 | #define WORD_H 3 | 4 | /*********************************************************** 5 | * read_word: Reads the next word from the input and * 6 | * stores it in word. Makes word empty if no * 7 | * word could be read because of end-of-file. * 8 | * Truncates the word if its length exceeds * 9 | * len. * 10 | **********************************************************/ 11 | void read_word(char *word, int len); 12 | 13 | #endif 14 | 15 | -------------------------------------------------------------------------------- /Ch05/Exercises/e10.c: -------------------------------------------------------------------------------- 1 | /* What output does the following program fragment produce? (Assume that i is 2 | * an integer variable.) 3 | * 4 | * i = 1; 5 | * switch (i % 3) { 6 | * case 0: printf("zero"); 7 | * case 1: printf("one"); 8 | * case 2: printf("two"); 9 | * } 10 | */ 11 | #include 12 | 13 | int main(void) 14 | { 15 | int i = 1; 16 | 17 | switch (i % 3) 18 | { 19 | case 0: printf("zero"); 20 | case 1: printf("one"); 21 | case 2: printf("two"); 22 | } 23 | 24 | return 0; 25 | } 26 | 27 | /* Answer: 28 | * onetwo 29 | */ 30 | -------------------------------------------------------------------------------- /Ch07/ProgrammingProjects/p06.c: -------------------------------------------------------------------------------- 1 | /* Write a program that prints the values of sizeof(int), sizeof(short), 2 | * sizeof(long), sizeof(float), sizeof(double) and sizeof(long double). 3 | */ 4 | #include 5 | 6 | int main(void) 7 | { 8 | printf("\nSize of:\n"); 9 | printf("int - %ld\n", sizeof(int)); 10 | printf("short - %ld\n", sizeof(short)); 11 | printf("long - %ld\n", sizeof(long)); 12 | printf("float - %ld\n", sizeof(float)); 13 | printf("double - %ldn", sizeof(double)); 14 | printf("long double - %ld\n\n", sizeof(long double)); 15 | 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /Ch14/Exercises/e04.txt: -------------------------------------------------------------------------------- 1 | For each of the folloing macros, give an example that illustrates a problem with 2 | the macro and show how to fix it. 3 | 4 | (a) #define AVG(x,y) (x+y)/2 5 | (b) #define AREA(x,y) (x)*(y) 6 | 7 | Answer: 8 | A - Problem: 9 | The replacement list is missing many parenthesis, meaning the expression 10 | may be evaluated incorrectly. For example, AVG(4,2*2) would become 11 | (4+2*2)/2. 12 | Solution: 13 | #define AVG(x,y) (((x)+(y))/2) 14 | 15 | B - Problem: 16 | Same as A 17 | Solution: 18 | #define AREA(x,y) ((x)*(y)) 19 | -------------------------------------------------------------------------------- /Ch16/Exercises/e12.txt: -------------------------------------------------------------------------------- 1 | Suppose that u is the following union: 2 | 3 | union { 4 | double a; 5 | struct { 6 | char b[4]; 7 | double c; 8 | int d; 9 | } e; 10 | char f[4]; 11 | } u; 12 | 13 | If char values occupy one byte, int values occupy four bytes, and double values 14 | occupy eight bytes, how much space will a C compiler allocate for u? 15 | (Assume that the compiler leaves no "holes" between members.) 16 | 17 | Answer: 18 | The union's largest element is struct e, 19 | which is 4 bytes (b[4]) + 8 bytes (c) + 4 bytes (d) = 16 bytes (e). 20 | 21 | The union u is 16 bytes. 22 | -------------------------------------------------------------------------------- /Ch08/ProgrammingProjects/p04.c: -------------------------------------------------------------------------------- 1 | /* Modify the reverse.c program of Section 8.1 to use the expression (int) 2 | * (sizeof(a) / sizeof(a[0])) (or a macro with this value) for array length. 3 | */ 4 | #include 5 | 6 | #define N ((int)(sizeof(a) / sizeof(a[0]))) 7 | 8 | int main(void) 9 | { 10 | int a[10], i; 11 | 12 | printf("\nEnter %d numbers ", N); 13 | for (i = 0; i < N; i++) 14 | scanf("%d", &a[i]); 15 | 16 | printf("In reverse order:"); 17 | for (i = N - 1; i >= 0; i--) 18 | printf(" %d", a[i]); 19 | printf("\n\n"); 20 | 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /Ch13/Exercises/e16.c: -------------------------------------------------------------------------------- 1 | /* Use the techniques of Section 13.6 to condense the count_spaces function of 2 | * Section 13.4. In particular, replace the for statement by a while loop. 3 | */ 4 | /* original */ 5 | int count_spacesA(const char s[]) 6 | { 7 | int count = 0, i; 8 | 9 | for (i = 0; s[i] != '\0'; i++) 10 | if (s[i] == ' ') 11 | count++; 12 | return count; 13 | } 14 | 15 | /* condensed */ 16 | int count_spacesB(const char s[]) 17 | { 18 | int count = 0; 19 | 20 | while (*s++) 21 | if (*s == ' ') 22 | count++; 23 | return count; 24 | } 25 | -------------------------------------------------------------------------------- /Ch22/Exercises/e15.txt: -------------------------------------------------------------------------------- 1 | Write calls of fseek that perform the following file-positioning operations on 2 | a binary file whose data is arranged in 64-byte "records." Use fp as the file 3 | pointer in each case. 4 | 5 | (a) Move to the beginning of record n. (Assume that the first record in the file 6 | is record 0.) 7 | (b) Move to the beginning of the last record in the file. 8 | (c) Move forward one record. 9 | (d) Move backward two records. 10 | 11 | Answer: 12 | A - fseek(fp, 64*n, SEEK_SET); 13 | B - fseek(fp, -64, SEEK_END); 14 | C - fseek(fp, 64, SEEK_CUR); 15 | D - fseek(fp, -128, SEEK_CUR); 16 | -------------------------------------------------------------------------------- /Ch18/Exercises/e02.txt: -------------------------------------------------------------------------------- 1 | Answer each of the following questions with auto, extern, register, and/or 2 | static. 3 | 4 | (a) Which storage class is used primarily to indicate that a variable or 5 | function can be shared by several files? 6 | 7 | (b) Suppose that a variable x is to be shared by several functions in one 8 | file, but hidden from functions in other files. Which storage class 9 | should x be declared to have? 10 | 11 | (c) Which storage classes can affect storage duration of a variable? 12 | 13 | Answer: 14 | A - extern 15 | B - internal 16 | C - auto, extern, static 17 | -------------------------------------------------------------------------------- /Ch19/Exercises/e1/instructions.txt: -------------------------------------------------------------------------------- 1 | A queue is similar to a stack, except that items are added at one end but 2 | removed from the other in a FIFO (first-in, first-out) fashion. Operations on 3 | a queue might include: 4 | 5 | Inserting an item at the end of a queue 6 | Removing an item from the beginning of a queue 7 | Returning the first item in the queue (without changing the queue) 8 | Returning the last item in the queue (without changing the queue) 9 | Testing whether the queue is empty 10 | 11 | Write an interface for a queue module in the form of a header file named 12 | queue.h. 13 | -------------------------------------------------------------------------------- /Ch12/Exercises/e06.c: -------------------------------------------------------------------------------- 1 | /* Rewrite the following function to use pointer arithmetic instead of array 2 | * subscripting. (In other words, eliminate the variable i and all uses of the 3 | * [] operator.) Make as few changes as possible. 4 | * 5 | * int sum_array(const int a[], int n) 6 | * { 7 | * int i, sum; 8 | * 9 | * sum = 0; 10 | * for (i = 0; i < n; i++) 11 | * sum += a[i]; 12 | * return sum; 13 | * } 14 | */ 15 | int sum_array (const int a[], int n) 16 | { 17 | int *p, sum; 18 | 19 | sum = 0; 20 | for (p = a; p < a + n; p++) 21 | sum += *p; 22 | return sum; 23 | } 24 | -------------------------------------------------------------------------------- /Ch15/ProgrammingProjects/p2/word.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "word.h" 3 | 4 | int read_char(void) 5 | { 6 | int ch = getchar(); 7 | 8 | if (ch == '\n' || ch == '\t') 9 | return ' '; 10 | return ch; 11 | } 12 | 13 | void read_word(char *word, int len) 14 | { 15 | int ch, pos = 0; 16 | 17 | while((ch = read_char()) == ' ') 18 | ; 19 | while(ch != ' ' && ch != EOF) { 20 | if (pos < len) 21 | word[pos++] = ch; 22 | ch = read_char(); 23 | } 24 | if ((pos - 1) == (len - 1)) 25 | word[len-1] = '*'; 26 | word[pos] = '\0'; 27 | } 28 | -------------------------------------------------------------------------------- /Ch06/Exercises/e06.c: -------------------------------------------------------------------------------- 1 | /* Translate the program fragment of Exercise 1 into a single for statement */ 2 | 3 | #include 4 | 5 | int main(void) 6 | { 7 | int i; 8 | 9 | printf("\n"); 10 | 11 | /* original while loop */ 12 | i = 1; 13 | while (i <= 128) 14 | { 15 | printf("%d ", i); 16 | i *= 2; 17 | } 18 | 19 | printf("\n\n"); 20 | 21 | /* new for loop */ 22 | for (i = 1; i <= 128; i *= 2) printf("%d ", i); 23 | 24 | printf("\n\n"); 25 | 26 | return 0; 27 | } 28 | 29 | /* Answer: 30 | * for (i = 1; i <= 128; i *= 2) printf("%d ", i); 31 | */ 32 | -------------------------------------------------------------------------------- /Ch06/Exercises/e13.c: -------------------------------------------------------------------------------- 1 | /* Rewrite the following loop so that its body is empty. : 2 | * for (n = 0; m > 0; n++) 3 | * m /= 2; 4 | */ 5 | #include 6 | 7 | int main(void) 8 | { 9 | int n, m; 10 | 11 | printf("\n"); 12 | 13 | m = 100; 14 | for (n = 0; m > 0; n++) 15 | { 16 | printf("%d ", m); 17 | m /= 2; 18 | } 19 | 20 | printf("\n"); 21 | 22 | m = 100; 23 | for (n = 0; m > 0; m /= 2, n++) 24 | printf("%d ", m); 25 | 26 | printf("\n\n"); 27 | 28 | return 0; 29 | } 30 | 31 | /* Answer: 32 | * for (n = 0; m > 0; m /= 2, n++) 33 | */ 34 | -------------------------------------------------------------------------------- /Ch07/Exercises/e02.c: -------------------------------------------------------------------------------- 1 | /* Which of the following are not legal constants in C? Classify each legal 2 | * constant as either integer or floating-point. 3 | */ 4 | #include 5 | 6 | int main(void) 7 | { 8 | printf("\nA: %f\n", 010E2); 9 | printf("B: %f\n", 32.1E+5); 10 | /* printf("C: %d\n", 0790); */ 11 | /* printf("D: %f\n", 100_000); */ 12 | printf("E: %f\n\n", 3.978e-2); 13 | 14 | return 0; 15 | } 16 | 17 | /* Answer: 18 | * A: legal float 19 | * B: legal float 20 | * C: illegal, octal doesn't use 9 21 | * D: illegal, no underscores in constants 22 | * E: legal float 23 | */ 24 | -------------------------------------------------------------------------------- /Ch13/Exercises/e03.c: -------------------------------------------------------------------------------- 1 | /* Suppose that we call scanf as follows: 2 | * 3 | * scanf("%d%s%d", &i, s, &j); 4 | * 5 | * If the user enter 12abc32 56def78, what will be the values of i, s, and 6 | * j after the call? (Assume that i and j are int variables and s is an array of 7 | * characters.) 8 | */ 9 | #include 10 | 11 | int main(void) 12 | { 13 | int i, j; 14 | char s[50]; 15 | scanf("%d%s%d", &i, s, &j); 16 | 17 | printf("\ni: %d\ns: %s\nj: %d\n\n", i, s, j); 18 | 19 | return 0; 20 | } 21 | 22 | /* Answer: 23 | * i will be 12 24 | * s will be abc32 25 | * j will be 56 26 | */ 27 | -------------------------------------------------------------------------------- /Ch03/ProgrammingProjects/p6.c: -------------------------------------------------------------------------------- 1 | /* Modify the addfrac.c program of Section 3.2 so that the user enters 2 | * both fractions at the same time, separated by a plus sign. 3 | */ 4 | #include 5 | 6 | int main(void) 7 | { 8 | int num1, denom1, num2, denom2, result_num, result_denom; 9 | 10 | printf("\nEnter two fractions separated by a plus sign: "); 11 | scanf("%d/%d + %d/%d", &num1, &denom1, &num2, &denom2); 12 | 13 | result_num = num1 * denom2 + num2 * denom1; 14 | result_denom = denom1 * denom2; 15 | printf("The sum is %d/%d\n\n", result_num, result_denom); 16 | 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /Ch15/ProgrammingProjects/p1/instructions.txt: -------------------------------------------------------------------------------- 1 | The justify program of Section 15.3 justifies the lines by inserting extra 2 | spaces beteen words. The way the write_line function currently works, the words 3 | closer to the end of a line tend to have slightly wider gaps between them than 4 | the words at the beginning. (For example, the words closer to the end might have 5 | three spaces between them, while the words closer to the beginning might be 6 | separated by only two spaces.) Improve the program by having write_line 7 | alternate between putting larger gaps at the end of the line and putting them at 8 | the beginning of the line. 9 | -------------------------------------------------------------------------------- /Ch16/Exercises/e16.txt: -------------------------------------------------------------------------------- 1 | Which of the following statements about enumeration are true? 2 | 3 | (a) An enumeration constant may represent any integer specified by the 4 | programmer. 5 | 6 | (b) Enumeration constants have exactly the same properties as constants created 7 | using #define. 8 | 9 | (c) Enumeration constants have the values 0, 1, 2, ... by default. 10 | 11 | (d) All constants in an enumeration must have different values. 12 | 13 | (e) Enumeration constants may be used as integers in expressions. 14 | 15 | Answer: 16 | A - true 17 | B - false, enumerations have scope 18 | C - true 19 | D - false 20 | E - true 21 | -------------------------------------------------------------------------------- /Ch20/Exercises/e04.txt: -------------------------------------------------------------------------------- 1 | In computer graphics, colors are often stored as three numbers, representing 2 | red, green, and blue intensities. Suppose that each number requires eight bits, 3 | and we'd like to store all three values in a single long integer. Write a macro 4 | named MK_COLOR with three parameters (the red, green, and blue intensities). 5 | MK_COLOR should return a long in which the last three bytes contain red, green, 6 | and blue intensities, with the red value as the last byte and the green value as 7 | the next-to-last byte. 8 | 9 | Answer: 10 | #define MK_COLOR(r,b,g) ((long) ((b) << 16) | ((g) << 8) | (r)) 11 | -------------------------------------------------------------------------------- /Ch20/Exercises/e14.txt: -------------------------------------------------------------------------------- 1 | When stored according to the IEEE floating-point standard, a float value 2 | consists of a 1-bit sign (the leftmost-or most significant-bit), an 8-bit 3 | exponent, and a 23-bit fraction, in that order. Design a structure type that 4 | occupies 32 bits, with bit-field members corresponding to the sign, exponent, 5 | and fraction. Declare the bit-fields to have type unsigned int. 6 | 7 | Check the manual for your compiler to determine the order of the bit-fields. 8 | 9 | Answer: 10 | struct float_bf { 11 | unsigned int sign: 1; 12 | unsigned int exp: 8; 13 | unsigned int frac: 23; 14 | }; 15 | -------------------------------------------------------------------------------- /Ch22/Exercises/e02.txt: -------------------------------------------------------------------------------- 1 | Indicate which mode string is most likely to be passed to fopen in each of the 2 | following situations: 3 | 4 | (a) A database management system opens a file containing records to be updated. 5 | (b) A mail program opens a file of saved messages so that it can add additional 6 | messages to the end. 7 | (c) A graphics program opens a file containing a picture to be displayed on 8 | screen. 9 | (d) An operating system command interpreter opens a "shell script" 10 | (or "batch file") containing commands to be executed. 11 | 12 | Answer: 13 | A - "rb+" 14 | B - "a" 15 | C - "rb" 16 | D - "r" 17 | -------------------------------------------------------------------------------- /Ch03/ProgrammingProjects/p3.c: -------------------------------------------------------------------------------- 1 | /* Write a program that breaks down an ISBN entered by the user. */ 2 | 3 | #include 4 | 5 | int main(void) 6 | { 7 | int prefix, identifier, publisher, itemNum, check; 8 | 9 | printf("\nEnter ISBN: "); 10 | scanf("%d-%d-%d-%d-%d", 11 | &prefix, &identifier, &publisher, &itemNum, &check); 12 | 13 | printf("GS1 prefix: %d\n", prefix); 14 | printf("Group identifier: %d\n", identifier); 15 | printf("Publisher code: %d\n", publisher); 16 | printf("Item number: %d\n", itemNum); 17 | printf("Check digit: %d\n\n", check); 18 | 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /Ch06/Exercises/e07.c: -------------------------------------------------------------------------------- 1 | /* Translate the program fragment of Exercise 2 into a single for statement */ 2 | 3 | #include 4 | 5 | int main(void) 6 | { 7 | int i; 8 | 9 | printf("\n"); 10 | 11 | /* original while loop */ 12 | i = 9384; 13 | do 14 | { 15 | printf("%d ", i); 16 | i /= 10; 17 | } while (i > 0); 18 | 19 | printf("\n\n"); 20 | 21 | /* new for loop */ 22 | for (i = 9384; i > 0; i /= 10) printf("%d ", i); 23 | 24 | printf("\n\n"); 25 | 26 | return 0; 27 | } 28 | 29 | /* Answer: 30 | * for (i = 9384; i > 0; i /= 10) printf("%d ", i); 31 | */ 32 | -------------------------------------------------------------------------------- /Ch13/Exercises/e11.c: -------------------------------------------------------------------------------- 1 | /* The Q&A section at the end of this chapter shows how the strcmp function 2 | * might be written using array subscripting. Modify the function to use pointer 3 | * arithmetic instead. 4 | */ 5 | /* array subscripting */ 6 | int A_strcmp(char *s, char *t) 7 | { 8 | int i; 9 | 10 | for (i = 0; s[i] == t[i]; i++) 11 | if (s[i] == '\0') 12 | return 0; 13 | return s[i] - t[i]; 14 | } 15 | 16 | /* pointer arithmetic */ 17 | int B_strcmp(char *s, char *t) 18 | { 19 | while (*s++ == *t++) 20 | if (!*s) 21 | return 0; 22 | return *(--s) - *(--t); 23 | } 24 | -------------------------------------------------------------------------------- /Ch03/Exercises/e1.c: -------------------------------------------------------------------------------- 1 | /* What output do the following calls of printf produce? 2 | * (a) printf("%6d,%4d\n", 86, 1040); 3 | * (b) printf("%12.5e\n", 30.253); 4 | * (c) printf("%.4f\n", 83.162); 5 | * (d) printf("%-6.2g\n", .0000009979); 6 | */ 7 | #include 8 | 9 | int main(void) 10 | { 11 | printf("\n%6d,%4d\n", 86, 1040); 12 | printf("%12.5e\n", 30.253); 13 | printf("%.4f\n", 83.162); 14 | printf("%-6.2g\n\n", .0000009979); 15 | 16 | return 0; 17 | } 18 | 19 | /* Answer: 20 | * Output: 21 | * (a) " 86,1040" 22 | * (b) " 3.02530e+001" 23 | * (c) "83.1620" 24 | * (d) "1e-006" 25 | */ 26 | -------------------------------------------------------------------------------- /Ch06/Exercises/e10.c: -------------------------------------------------------------------------------- 1 | /* Show how to replace a continue statement by an equivalent goto statement. */ 2 | 3 | #include 4 | 5 | int main(void) 6 | { 7 | int i; 8 | 9 | printf("\n"); 10 | 11 | for (i = 0; i <= 10; i++) 12 | if (i == 8) 13 | continue; 14 | else 15 | printf("%d ", i); 16 | 17 | printf("\n"); 18 | 19 | for (i = 0; i <= 10; i++) 20 | { 21 | if (i == 8) 22 | goto end_of_loop; 23 | else 24 | printf("%d ", i); 25 | 26 | end_of_loop:; 27 | } 28 | 29 | printf("\n\n"); 30 | 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /Ch06/ProgrammingProjects/p06.c: -------------------------------------------------------------------------------- 1 | /* Write a program that prompts the user to enter a number n, then prints all 2 | * even squares between 1 and n. For example, if the user enters 100, the 3 | * program should print the following: 4 | * 4 5 | * 16 6 | * 36 7 | * 64 8 | * 100 9 | */ 10 | #include 11 | 12 | int main(void) 13 | { 14 | int n, i = 1; 15 | 16 | printf("\nEnter a number: "); 17 | scanf("%d", &n); 18 | 19 | while (i * i <= n) 20 | { 21 | if ((i * i) % 2 == 0) 22 | printf("%d\n", i * i); 23 | i++; 24 | } 25 | 26 | printf("\n"); 27 | 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /Ch08/reverse2.c: -------------------------------------------------------------------------------- 1 | /* Reverses a series of numbers using a variable-length 2 | * array - C99 only */ 3 | 4 | #include 5 | 6 | #define N 10 7 | 8 | int main(void) 9 | { 10 | int i, n; 11 | 12 | printf("How many numbers do you want to reverse? "); 13 | scanf("%d", &n); 14 | 15 | int a[n]; /* C99 only - length of array depends on n */ 16 | 17 | printf("Enter %d numbers ", N); 18 | for (i = 0; i < n; i++) 19 | scanf("%d", &a[i]); 20 | 21 | printf("In reverse order:"); 22 | for (i = N - 1; i >= 0; i--) 23 | printf(" %d", a[i]); 24 | printf("\n"); 25 | 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /Ch09/prime.c: -------------------------------------------------------------------------------- 1 | /* Tests whether a number is prime */ 2 | 3 | #include /* C99 only */ 4 | #include 5 | 6 | bool is_prime(int n) 7 | { 8 | int divisor; 9 | 10 | if (n <= 1) 11 | return false; 12 | for (divisor = 2; divisor * divisor <= n; divisor++) 13 | if (n % divisor == 0) 14 | return false; 15 | return true; 16 | } 17 | 18 | int main(void) 19 | { 20 | int n; 21 | 22 | printf("Enter a number: "); 23 | scanf("%d", &n); 24 | if (is_prime(n)) 25 | printf("Prime\n"); 26 | else 27 | printf("Not prime\n"); 28 | 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /Ch16/Exercises/e01.txt: -------------------------------------------------------------------------------- 1 | In the following declarations, the x and y structures have members named x and y: 2 | 3 | struct { int x, y; } x; 4 | struct { int x, y; } y; 5 | 6 | Are these declarations legal on an individual basis? 7 | Could both declarations appear as shown in a program? Justify your answer. 8 | 9 | Answer: 10 | Yes, both declarations are legal individually; and yes, they could appear as 11 | shown in a program. This is because variables in structs have their own separate 12 | namespace, so even though x and y are seemingly declared multiple times, they're 13 | fine because they aren't conflicting within their own namespaces. 14 | -------------------------------------------------------------------------------- /Ch02/Exercises/e03.c: -------------------------------------------------------------------------------- 1 | /* Condense the dweight.c program by (1) replacing assignments to height, 2 | * length, and width with initializers and (2) removing the weight variable, 3 | * instead calculating (volume+165) / 166 with the last printf. 4 | */ 5 | #include 6 | 7 | int main(void) 8 | { 9 | int height = 8, length = 12, width = 10, volume; 10 | 11 | volume = height * length * width; 12 | 13 | printf("\nDimensions: %dx%dx%d\n", length, width, height); 14 | printf("Volume (cubic inches): %d\n", volume); 15 | printf("Dimensional weight (pounds): %d\n\n", (volume + 165) / 166); 16 | 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /Ch02/ProgrammingProjects/p6.c: -------------------------------------------------------------------------------- 1 | /* Modify the program of Programming Project 5 so that the polynomial is 2 | * evaluated using the following formula: 3 | * ((((3x + 2)x - 5)x - 1)x + 7)x - 6 4 | */ 5 | #include 6 | 7 | int main(void) 8 | { 9 | int x; 10 | 11 | printf("\nThe following polynomial will be calculated:\n"); 12 | printf("(3x + 2)x - 5)x - 1)x + 7)x - 6)\n\n"); 13 | 14 | printf("Enter a number x: "); 15 | scanf("%d", &x); 16 | printf("\n"); 17 | 18 | x = (((((((((3 * x) + 2) * x) - 5) * x) - 1) * x) + 7) * x) - 7; 19 | 20 | printf("Answer is: %d\n\n", x); 21 | 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /Ch15/ProgrammingProjects/p3/qsort.c: -------------------------------------------------------------------------------- 1 | /* Sorts an array of integer using Quicksort */ 2 | 3 | #include 4 | #include "quicksort.h" 5 | 6 | #define N 10 7 | 8 | void quicksort(int a[], int low, int high); 9 | int split(int a[], int low, int high); 10 | 11 | int main(void) 12 | { 13 | int a[N], i; 14 | 15 | printf("\nEnter %d numbers to be sorted: ", N); 16 | for (i = 0; i < N; i++) 17 | scanf("%d", &a[i]); 18 | 19 | quicksort(a, 0, N - 1); 20 | 21 | printf("In sorted order: "); 22 | for (i = 0; i < N; i++) 23 | printf("%d ", a[i]); 24 | printf("\n\n"); 25 | 26 | return 0; 27 | } 28 | 29 | -------------------------------------------------------------------------------- /Ch21/Exercises/e5.txt: -------------------------------------------------------------------------------- 1 | The islower function, which belongs to , tests whether a character is 2 | a lower-case letter. Why would the following macro version of islower not be 3 | legal according to the C standard? (You may assume that the character set is 4 | ASCII.) 5 | 6 | #define islower(c) ((c) >= 'a' && (c) <= 'z') 7 | 8 | Answer: 9 | The macro is illegal because it evaluates its argument more than once. This is 10 | a problem because an argument may be modified after evaluation. For example, if 11 | islower(var--) was called, var would be incorrectly compared with 'z', because 12 | the comparison with 'a' would change var's value. 13 | -------------------------------------------------------------------------------- /Ch08/repdigit.c: -------------------------------------------------------------------------------- 1 | /* Checks numbers for repeated digits */ 2 | 3 | #include /* C99 only */ 4 | #include 5 | 6 | int main(void) 7 | { 8 | bool digit_seen[10] = {false}; 9 | int digit; 10 | long n; 11 | 12 | printf("Enter a number: "); 13 | scanf("%ld", &n); 14 | 15 | while (n > 0) 16 | { 17 | digit = n % 10; 18 | if (digit_seen[digit]) 19 | break; 20 | digit_seen[digit] = true; 21 | n /= 10; 22 | } 23 | 24 | if (n > 0) 25 | printf("Repeated digit\n"); 26 | else 27 | printf("No repeated digit\n"); 28 | 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /Ch12/Exercises/e09.c: -------------------------------------------------------------------------------- 1 | /* Write the following function: 2 | * 3 | * double inner_product(const double *a, const double *b, 4 | * int n); 5 | * 6 | * a and b both point to arrays of length n. The function should return a[0] 7 | * * b[0] + a[1] * b[1] + ... + a[n-1] * b[n-1]. Use pointer arithmetic--not 8 | * subscripting--to visit array elements. 9 | */ 10 | double inner_product(const double *a, const double *b, int n) 11 | { 12 | double *pa, *pb, product; 13 | 14 | product = 0; 15 | for (pa = a, pb = b; pa < a + n - 1;) 16 | product = (*pa + *pb) * (*pa++ + *pb++); 17 | 18 | return product; 19 | } 20 | -------------------------------------------------------------------------------- /Ch22/Exercises/e04.txt: -------------------------------------------------------------------------------- 1 | Show how each of the following numbers will look if displayed by printf with 2 | %#012.5g as the conversion specification: 3 | 4 | (a) 83.7361 5 | (b) 29748.6607 6 | (c) 1054932234.0 7 | (d) 0.0000235218 8 | 9 | Answer: 10 | The conversion specification... specifcations: 11 | # - trailing zeros aren't removed 12 | 0 - numbers are padded with leading zeros 13 | 12 - minimum field width 14 | 5 - number of significant digits 15 | g - displays number as either exponential or 16 | fixed decimal depending on its size 17 | 18 | Output: 19 | A - 00000083.736 20 | B - 00000029748. 21 | C - 01.0549e+009 22 | D - 02.3522e-005 23 | -------------------------------------------------------------------------------- /Ch09/Exercises/e09.txt: -------------------------------------------------------------------------------- 1 | What will be the output of the following program? 2 | 3 | #include 4 | 5 | void swap(int a, int b); 6 | 7 | int main(void) 8 | { 9 | int i = 1, j = 2; 10 | 11 | swap(i, j); 12 | printf("i = %d, j = %d\n", i, j); 13 | return 0; 14 | } 15 | 16 | void swap(int a, int b) 17 | { 18 | int temp = a; 19 | a = b; 20 | b = temp; 21 | } 22 | 23 | Answer: 24 | i = 1, j = 2 25 | 26 | This is because arguments are passed to functions by value. So swap is just 27 | swapping its temporary variables using the values it recieved, and then the 28 | temporary variables are gone after the function is over. 29 | -------------------------------------------------------------------------------- /Ch12/Exercises/e07.c: -------------------------------------------------------------------------------- 1 | /* Write the following function: 2 | * 3 | * bool search(const int a[], int n, int key); 4 | * 5 | * a is an array to be searched, n is the number of elements in the array, and 6 | * key is the search key. search should return true if key matches some element 7 | * of a, and false if it doesn't. Use pointer arithmetic--not subscripting--to 8 | * visit array elements. 9 | */ 10 | #include /* C99 only */ 11 | 12 | bool search(const int a[], int n, int key) 13 | { 14 | int *p; 15 | 16 | for (p = a; p < a + n; p++) 17 | if (*p == key) 18 | return true; 19 | 20 | return false; 21 | } 22 | -------------------------------------------------------------------------------- /Ch09/Exercises/e18.c: -------------------------------------------------------------------------------- 1 | /* Write a recursive version of the gcd function (see Exercise 3). Here's the 2 | * strategy to use for computing gcd(m, n): If n is 0, return m. Otherwise, call 3 | * gcd recursively, passing n as the first argument and m % n as the second. 4 | */ 5 | #include 6 | 7 | int gcd(int m, int n) 8 | { 9 | if (n == 0) 10 | return m; 11 | else 12 | return gcd(n, m % n); 13 | } 14 | 15 | int main(void) 16 | { 17 | int m, n; 18 | 19 | printf("\nEnter two integers: "); 20 | scanf("%d %d", &m, &n); 21 | 22 | printf("Greatest common divisor: %d\n\n", gcd(m, n)); 23 | 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /Ch13/ProgrammingProjects/p04.c: -------------------------------------------------------------------------------- 1 | /* Write a program named reverse.c that echoes its command-line arguments in 2 | * reverse order. Run the program by typing 3 | * 4 | * reverse void and null 5 | * 6 | * should produce the following output: 7 | * 8 | * null and void 9 | */ 10 | #include 11 | 12 | int main(int argc, char *argv[]) 13 | { 14 | int i; 15 | if (argc == 1) 16 | { 17 | printf("\nUsage: %s words as arguments like this\n\n", argv[0]); 18 | return 0; 19 | } 20 | putchar('\n'); 21 | for (i = argc-1; i > 0; i--) 22 | printf("%s ", argv[i]); 23 | printf("\n\n"); 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /Ch21/Exercises/e3.txt: -------------------------------------------------------------------------------- 1 | When a macro hides a function, which must come first in the header file: the 2 | macro definition or the function prototype? Justify your answer. 3 | 4 | Answer: 5 | The function prototype must always come first, because otherwise the function 6 | name in the prototype will be expanded as a valid macro by the preprocessor. 7 | 8 | For example, say these were hypothetically defined in a header in the following 9 | order: 10 | 11 | #define add_nums(x,y) ((x) + (y)) 12 | int add_nums(int x, int y); 13 | 14 | After preproccessing, the prototype would become 15 | 16 | int ((x) + (y))(int x, int y) 17 | 18 | which is obviously erroneous 19 | -------------------------------------------------------------------------------- /Ch02/dweight2.c: -------------------------------------------------------------------------------- 1 | /* Computes the dimensional weight of a 2 | box from input provided by the user */ 3 | 4 | #include 5 | 6 | int main(void) 7 | { 8 | int height, length, width, volume, weight; 9 | 10 | printf("Enter height of box: "); 11 | scanf("%d", &height); 12 | printf("Enter length of box: "); 13 | scanf("%d", &length); 14 | printf("Enter width of box: "); 15 | scanf("%d", &width); 16 | volume = height * length * width; 17 | weight = (volume + 165) / 166; 18 | 19 | printf("Volume (cubic inches): %d\n", volume); 20 | printf("Dimensional weight (pounds): %d\n", weight); 21 | 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /Ch02/ProgrammingProjects/p5.c: -------------------------------------------------------------------------------- 1 | /* Write a program that asks the user to enter a value for x and then displays 2 | * the value of the following polynomial: (3x^5 + 2x^4 - 5x^3 - x^2 + 7x - 6) 3 | */ 4 | #include 5 | 6 | int main(void) 7 | { 8 | int x; 9 | 10 | printf("\nThe following polynomial will be calculated:\n"); 11 | printf("(3x^5 + 2x^4 - 5x^3 - x^2 + 7x - 6)\n\n"); 12 | 13 | printf("Enter a number x: "); 14 | scanf("%d", &x); 15 | printf("\n"); 16 | 17 | x = (3 * (x*x*x*x*x)) + (2 * (x*x*x*x)) 18 | - (5 * (x*x*x)) - (x*x) + (7 * x) - 6; 19 | 20 | printf("Answer: %d\n\n", x); 21 | 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /Ch07/Exercises/e14.c: -------------------------------------------------------------------------------- 1 | /* Does the following statement always compute the fractional part of 2 | * f correctly (assuming that f and frac_part are float variables)? 3 | * 4 | * fract_part = f - (int) f; 5 | * 6 | * If not, what's the problem? 7 | */ 8 | #include 9 | 10 | int main(void) 11 | { 12 | float f, fract_part; 13 | 14 | printf("\nEnter a fractional number (e.g. 1.55): "); 15 | scanf("%f", &f); 16 | 17 | fract_part = f - (int) f; 18 | printf("Fractional part: %f\n\n", fract_part); 19 | 20 | return 0; 21 | } 22 | 23 | /* Answer: 24 | * No, it will fail if the value of f exceeds the largest 25 | * value of an int. 26 | */ 27 | -------------------------------------------------------------------------------- /Ch15/ProgrammingProjects/p2/justify.c: -------------------------------------------------------------------------------- 1 | /* Formats a file of text */ 2 | 3 | #include 4 | #include "line.h" 5 | #include "word.h" 6 | 7 | #define MAX_WORD_LEN 20 8 | 9 | int main(void) 10 | { 11 | char word[MAX_WORD_LEN+2]; 12 | int word_len; 13 | 14 | clear_line(); 15 | for (;;) { 16 | read_word(word, MAX_WORD_LEN+1); 17 | word_len = strlen(word); 18 | if (word_len == 0) { 19 | flush_line(); 20 | return 0; 21 | } 22 | if (word_len + 1 > space_remaining()) { 23 | write_line(); 24 | clear_line(); 25 | } 26 | add_word(word); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Ch18/Exercises/e11.txt: -------------------------------------------------------------------------------- 1 | In Section 18.4, we saw that the following declarations are illegal: 2 | 3 | int f(int)[]; /* functions can't return arrays */ 4 | int g(int)(int); /* functions can't return functions */ 5 | int a[10](int); /* array elements can't be functions */ 6 | 7 | We can, however, achieve similar effects by using pointers: a function can 8 | return a pointer to the first element in an array, a function can return 9 | a pointer to a function, and the elements of an array can be pointers to 10 | functions. Revise each of these declarations accordingly. 11 | 12 | Answer: 13 | int *f(int); 14 | int (*g(int))(int); 15 | int (*a[10])(int); 16 | -------------------------------------------------------------------------------- /Ch09/Exercises/e07.txt: -------------------------------------------------------------------------------- 1 | Suppose that the function f has the following definition: 2 | 3 | int f(int a, int b) { ... } 4 | 5 | Which of the following statements are legal? (Assume that i has type int and x has type double.) 6 | 7 | (a) i = f(83, 12); 8 | (b) x = f(83, 12); 9 | (c) i = f(3.15, 9.28); 10 | (d) x = f(3.15, 9.28); 11 | (e) f(83, 12); 12 | 13 | Answer: 14 | A - Legal, standard behavior 15 | B - Legal, but the return value is converted into a double 16 | C - Legal, but the arguments are truncated as ints and lose their decimal value 17 | D - Legal, but the arguments are truncated as ints and lose their decimal value 18 | F - Legal, but the return value is unused 19 | -------------------------------------------------------------------------------- /Ch17/Exercises/e08/stack.h: -------------------------------------------------------------------------------- 1 | #ifndef STACK_H 2 | #define STACK_H 3 | 4 | /* is_empty: Returns whether or not the stack is empty. */ 5 | bool is_empty(void); 6 | 7 | /* push: Calls stack_overflow if the stack is too full, 8 | * otherwise it adds the value i to the top of the stack */ 9 | bool push(int i); 10 | 11 | /* pop: Calls stack_underflow if the stack is empty, 12 | * otherwise it removes and returns the top value of the stack. */ 13 | int pop(void); 14 | 15 | /* stack_overflow: Prints an error and exits the program */ 16 | void stack_overflow(); 17 | 18 | /* stack_underflow: Prints an error and exits the program */ 19 | void stack_underflow(); 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /Ch19/Exercises/e3/a/queue.h: -------------------------------------------------------------------------------- 1 | #ifndef QUEUE_H 2 | #define QUEUE_H 3 | 4 | #include 5 | #include 6 | 7 | typedef int Item; 8 | 9 | /* Sends an error message and terminates the program */ 10 | static void terminate(const char* message); 11 | 12 | /* Inserts i to the top of the queue */ 13 | void que_insert(Item i); 14 | 15 | /* Removes item from the queue and returns it */ 16 | Item que_remove(); 17 | 18 | /* Returns the top item of the queue */ 19 | Item que_get_top_item(); 20 | 21 | /* Returns the bottom item of the queue */ 22 | Item que_get_bottom_item(); 23 | 24 | /* Returns whether or not the queue is empty */ 25 | bool que_is_empty(); 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /Ch19/Exercises/e3/b/queue.h: -------------------------------------------------------------------------------- 1 | #ifndef QUEUE_H 2 | #define QUEUE_H 3 | 4 | #include 5 | #include 6 | 7 | typedef int Item; 8 | 9 | /* Sends an error message and terminates the program */ 10 | static void terminate(const char* message); 11 | 12 | /* Inserts i to the top of the queue */ 13 | void que_insert(Item i); 14 | 15 | /* Removes item from the queue and returns it */ 16 | Item que_remove(); 17 | 18 | /* Returns the top item of the queue */ 19 | Item que_get_top_item(); 20 | 21 | /* Returns the bottom item of the queue */ 22 | Item que_get_bottom_item(); 23 | 24 | /* Returns whether or not the queue is empty */ 25 | bool que_is_empty(); 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /Ch06/ProgrammingProjects/p07.c: -------------------------------------------------------------------------------- 1 | /* Rearrange the square3.c program so that the for loop initializes i, 2 | * tests i, and increments i. Don't rewrite the program; in particular, 3 | * don't use any multiplications 4 | */ 5 | #include 6 | 7 | int main(void) 8 | { 9 | int i, n, odd, square; 10 | 11 | printf("\nThis program prints a table of squares.\n"); 12 | printf("Enter the number of entries in a table: "); 13 | scanf("%d", &n); 14 | 15 | odd = 3; 16 | for (square = 1, i = 1; i <= n; odd += 2, i++) 17 | { 18 | printf("%10d%10d\n", i, i * i); 19 | square += odd; 20 | } 21 | 22 | printf("\n"); 23 | 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /Ch12/ProgrammingProjects/p3.c: -------------------------------------------------------------------------------- 1 | /* Simplify Programming Project 1(b) by taking advantage of the fact that an 2 | * array name can be used as a pointer. 3 | */ 4 | #include 5 | 6 | #define BUF 100 7 | 8 | int main(void) 9 | { 10 | char *p, msg[BUF], input; 11 | 12 | printf("\nEnter a message: "); 13 | for (p = msg; p < msg + BUF; p++) 14 | { 15 | if ((input = getchar()) == '\n') break; 16 | *p = input; 17 | } 18 | 19 | /* print the message in reverse, starting from the last character */ 20 | printf("Reversal is: "); 21 | for (p = p-1; p >= msg; p--) 22 | putchar(*p); 23 | printf("\n\n"); 24 | 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /Ch16/Exercises/e20.c: -------------------------------------------------------------------------------- 1 | /* Suppose that the direction variable is declared in the following way: 2 | * 3 | * enum {NORTH, SOUTH, EAST, WEST} direction; 4 | * 5 | * Let x and y be int variables. Write a switch statement that tests the 6 | * direction, incrementing x if direction is EAST, decrementing x if direction 7 | * is WEST, incrementing y if direction is SOUTH, decrementing y if direction is 8 | * NORTH. 9 | */ 10 | switch (direction) 11 | { 12 | case NORTH: 13 | --y; 14 | break; 15 | case EAST: 16 | ++x; 17 | break; 18 | case SOUTH: 19 | ++y; 20 | break; 21 | case WEST: 22 | --x; 23 | break; 24 | }; 25 | -------------------------------------------------------------------------------- /Ch17/Exercises/e11.c: -------------------------------------------------------------------------------- 1 | /* Write the following function: 2 | * 3 | * int count occurences(struct node *list, int n); 4 | * 5 | * The list parameter points to a linked list; the function should return 6 | * the number of times that n appears in this list. Assume that the node 7 | * structure is the one defined in Section 17.5. 8 | */ 9 | #include 10 | 11 | struct node { 12 | int value; 13 | struct node *next; 14 | }; 15 | 16 | int count_occurences(struct node *list, int n) 17 | { 18 | int times_seen = 0; 19 | 20 | for (; list != NULL; list = list->next) 21 | if (list->value == n) 22 | times_seen++; 23 | 24 | return times_seen; 25 | } 26 | -------------------------------------------------------------------------------- /Ch18/Exercises/e09.c: -------------------------------------------------------------------------------- 1 | /* Use a series of type definitions to symplify each of the following 2 | * declarations in Exercise 8. 3 | */ 4 | char (*x[10])(int); 5 | typedef char Fcn(int); 6 | typedef Fcn *Fcn_ptr; 7 | typedef Fcn Fcn_ptr_array[10]; 8 | Fcn_ptr_array x; 9 | 10 | int (*x(int))[5]; 11 | typedef int array_of_ints[5]; 12 | typedef array_of_ints *Fcn(int); 13 | Fcn x; 14 | 15 | float *(*x(void))(int); 16 | typedef float Out_fcn(int); 17 | typedef Out_fcn *In_fcn(int); 18 | Out_fcn x; 19 | 20 | void (*x(int, void (*y)(int)))(int); 21 | typedef void Out_fcn(int); 22 | typedef void *Fcn_ptr_arg(int); 23 | typedef Out_fcn *In_fcn(int, Fcn_ptr_arg); 24 | Out_fcn x; 25 | -------------------------------------------------------------------------------- /Ch09/Exercises/e01.c: -------------------------------------------------------------------------------- 1 | /* The following function, which computes the area of a triangle, contains two 2 | * errors. Locate the errors and show how to fix them. (Hint: There are no 3 | * errors in the formula.) 4 | * 5 | * double triangle_area(double base, height) 6 | * double product; 7 | * { 8 | * product = base * height; 9 | * return product / 2; 10 | * } 11 | */ 12 | double triangle_area(double base, double height) 13 | { 14 | double product; 15 | product = base * height; 16 | return product / 2; 17 | } 18 | 19 | /* Answer: 20 | * Error 1 - The height parameter was missing its datatype. 21 | * Error 2 - The variable product was defined outside of the function's block. 22 | */ 23 | -------------------------------------------------------------------------------- /Ch16/Exercises/e08.c: -------------------------------------------------------------------------------- 1 | /* Let color be the following structure: 2 | * 3 | * struct color { 4 | * int red; 5 | * int green; 6 | * int blue; 7 | * } 8 | * 9 | * (a) Write a declaration for a const variable named MAGENTA of type struct 10 | * color whose members have the values 255, 0, and 255, respectively. 11 | * 12 | * (b) (C99) Repeat part (a), but use a designated initializer that doesn't 13 | * specify the value of green, allowing it to default to 0. 14 | */ 15 | struct color { int red, green, blue; }; 16 | 17 | /* Answer: 18 | * A: */ 19 | const struct color MAGENTA = { 255, 0, 255 }; 20 | 21 | /* B: */ 22 | const struct color MAGENTA = { .red = 255, .blue = 255 }; 23 | -------------------------------------------------------------------------------- /Ch19/ProgrammingProjects/p5/instructions.txt: -------------------------------------------------------------------------------- 1 | Starting from the queue.h header of Exercise 1, create a file name queueADT.h 2 | that defines the following Queue type: 3 | 4 | typedef struct queue_type *Queue; 5 | 6 | queue_type is an incomplete structure type. Create a file named queueADT.c that 7 | contains the full definition of queue_type as well as definitions for all the 8 | functions in queue.h. Use a fixed-length array to store the items in a queue 9 | (see Exercise 3(a)). Create a file named queueclient.c (similar to the 10 | stackclient.c file of Section 19.4) that creates two queues and performs 11 | operations on them. Be sure to provide create and destroy functions for your 12 | ADT. 13 | -------------------------------------------------------------------------------- /Ch03/Exercises/e6.c: -------------------------------------------------------------------------------- 1 | /* Show how to modify the addfrac.c program of Section 3.2 so that 2 | * the user is allowed to enter fractions that contain spaces before 3 | * and after each / character. 4 | */ 5 | #include 6 | 7 | int main(void) 8 | { 9 | int num1, denom1, num2, denom2, result_num, result_denom; 10 | 11 | printf("\nEnter first fraction: "); 12 | scanf("%d / %d", &num1, &denom1); 13 | 14 | printf("Enter second fraction: "); 15 | scanf("%d / %d", &num2, &denom2); 16 | 17 | result_num = num1 * denom2 + num2 * denom1; 18 | 19 | result_denom = denom1 * denom2; 20 | printf("The sum is %d/%d\n\n", result_num, result_denom); 21 | 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /Ch05/Exercises/e05.c: -------------------------------------------------------------------------------- 1 | /* Is the following if statement legal? 2 | * if (n >= 1 <= 10) 3 | * printf("n is between 1 and 10\n"); 4 | * If so, what does it do when n is equal to 0? 5 | */ 6 | #include 7 | 8 | int main(void) 9 | { 10 | int n = 0; 11 | 12 | if (n >= 1 <= 10) 13 | printf("\nn is between 1 and 10\n\n"); 14 | 15 | return 0; 16 | } 17 | 18 | /* Answer: 19 | * It is a legal statement. 20 | * 21 | * Here's what happens when n equals 0: 22 | * 23 | * First, in the if's expression, (n >= 1) is evaluated to 0. 24 | * Then, (0 <= 10) is then evaluated as 1, meaning the final value is 1. 25 | * Since the value isn't 0, it runs the printf statement. 26 | */ 27 | -------------------------------------------------------------------------------- /Ch09/Exercises/e05.c: -------------------------------------------------------------------------------- 1 | /* Write a function num_digits(n) that returns the number of digits in n 2 | * (a positive integer). Hint: To determine the number of digits in a number n, 3 | * divide it by 10 repeatedly. When n reaches 0, the number of divisions 4 | * indicates how many digits n originally had. 5 | */ 6 | #include 7 | 8 | int num_digits(int n) 9 | { 10 | int digits; 11 | for (digits = 0; n != 0; digits++) 12 | n /= 10; 13 | return digits; 14 | } 15 | 16 | int main(void) 17 | { 18 | int num; 19 | 20 | printf("\nEnter a number: "); 21 | scanf("%d", &num); 22 | printf("Digits in %d: %d\n\n", num, num_digits(num)); 23 | 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /Ch15/Exercises/e1.txt: -------------------------------------------------------------------------------- 1 | Section 15.1 listed several advantages of dividing a prgram into multiple source files. 2 | 3 | (a) Describe several other advantages. 4 | (b) Describe some disadvantages. 5 | 6 | Answer: 7 | A. Advantages: 8 | - Grouping related functions and variables to better clarify the structure of 9 | the program. 10 | - Separate source files compile separately, which saves time. 11 | - Functions are more easily reused in other programs when grouped in separate 12 | source files. 13 | B. Disadvantages: 14 | - More files means more complexity, which means its easier to overlook 15 | details and make mistakes. 16 | - Harder to maintain and update. 17 | 18 | -------------------------------------------------------------------------------- /Ch16/Exercises/e11.txt: -------------------------------------------------------------------------------- 1 | Suppose that s is the following structure: 2 | 3 | struct { 4 | double a; 5 | union { 6 | char b[4]; 7 | double c; 8 | int d; 9 | } e; 10 | char f[4]; 11 | } s; 12 | 13 | If char values occupy one byte, int values occupy four bytes, and double values 14 | occupy eight bytes, how much space will a C compiler allocate for s? 15 | (Assume that the compiler leaves no "holes" between members.) 16 | 17 | Answer: 18 | The double variable a takes up 8 bytes, the union e takes up 8 bytes because its 19 | largest member is a double, and the character array f takes up 4 bytes, one byte 20 | per character in the array. 21 | 22 | struct s is 8 + 8 + 4 = 20 bytes in size 23 | -------------------------------------------------------------------------------- /Ch20/Exercises/e11.txt: -------------------------------------------------------------------------------- 1 | Each of the following macros defines the position of a single bit within an 2 | integer: 3 | #define SHIFT_BIT 1 4 | #define CTRL_BIT 2 5 | #define ALT_BIT 4 6 | 7 | The following statement is supposed to test whether any of the three bits have 8 | been set, but it never displays the specified message. Explain why the statement 9 | doesn't work and show how to fix it. Assume that key_code is an int variable. 10 | 11 | if (key_code & (SHIFT_BIT | CTRL_BIT | ALT_BIT) == 0) 12 | 13 | Answer: 14 | The statement always evaluates to 0 because == has higher precedence than &. 15 | First, (SHIFT_BIT | CTRL_BIT | ALT_BIT) == 0) is evaluated to 0 16 | Then, key_code & 0 is evaluated to 0. 17 | -------------------------------------------------------------------------------- /Ch03/Exercises/e4.c: -------------------------------------------------------------------------------- 1 | /* Suppose we call scanf as follows: 2 | * scanf("%d%f%d", &i, &x, &j); 3 | * 4 | * If the user enters 5 | * 10.3 5 6 6 | * 7 | * what will be the values of i, x, and j after the call? 8 | * (Assume that i and j are int variables and x is a float variable) 9 | */ 10 | #include 11 | 12 | int main(void) 13 | { 14 | int i, j; 15 | float x; 16 | 17 | scanf("%d%f%d", &i, &x, &j); 18 | printf("\ni: %d, x: %f, j: %d\n\n", i, x, j); 19 | 20 | return 0; 21 | } 22 | 23 | /* Answer: (note: I did figure the answer out on my own first, 24 | * but I had to be 100% sure by writing it out and running it) 25 | * i = 10 26 | * x = 0.300000 27 | * j = 5 28 | */ 29 | -------------------------------------------------------------------------------- /Ch09/Exercises/e03.c: -------------------------------------------------------------------------------- 1 | /* Write a function gcd(m, n) that calculates the greatest common divisor of the 2 | * integers m and n. (Programming Project 2 in Chapter 6 descripes Euclid's 3 | * algorithm for computing the GCD.) 4 | */ 5 | #include 6 | 7 | int gcd(int m, int n) 8 | { 9 | int remainder; 10 | 11 | do 12 | { 13 | remainder = m % n; 14 | m = n; 15 | n = remainder; 16 | } while (n != 0); 17 | 18 | return m; 19 | } 20 | 21 | int main(void) 22 | { 23 | int m, n; 24 | 25 | printf("\nEnter two integers: "); 26 | scanf("%d %d", &m, &n); 27 | 28 | printf("Greatest common divisor: %d\n\n", gcd(m, n)); 29 | 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /Ch05/Exercises/e06.c: -------------------------------------------------------------------------------- 1 | /* Is the following if statement legal? 2 | 3 | * if (n == 1-10) 4 | * printf("n is between 1 and 10\n"); 5 | 6 | * If so, what does it do when n is equal to 5? 7 | */ 8 | #include 9 | 10 | int main(void) 11 | { 12 | int n = 5; 13 | 14 | if (n == 1-10) 15 | printf("\nn is between 1 and 10\n\n"); 16 | 17 | return 0; 18 | } 19 | 20 | /* Answer: 21 | * It is a legal statement. 22 | * 23 | * Here's what happens when n equals 5: 24 | * 25 | * First, in the if's expression, 1-10 is evaluated to -9. 26 | * Then, (n == -9) is then evaluated as 0, meaning the final value is 0. 27 | * Since the value is 0, it skips the printf statement and exits. 28 | */ 29 | -------------------------------------------------------------------------------- /Ch12/Exercises/e17.c: -------------------------------------------------------------------------------- 1 | /* Rewrite the following function to use pointer arithmetic instead of array 2 | * subscripting. (In other words, eliminate variables i and k and all uses of 3 | * the [] operator.) Use a single loop instead of nested loops. 4 | * 5 | * int sum_two_dimensional_array(const int a[][LEN], int n) 6 | * { 7 | * int i, j, sum = 0; 8 | * 9 | * for (i = 0; i < n; i++) 10 | * for (j = 0; j < LEN; j++) 11 | * sum += a[i][j]; 12 | * 13 | * return sum; 14 | * } 15 | */ 16 | int sum_two_dimensional_array(const int a[][LEN], int n) 17 | { 18 | int *p, sum = 0; 19 | 20 | for (p = &a[0][0]; p < &a[0][0] + n * LEN; p++) 21 | sum += *p; 22 | 23 | return sum; 24 | } 25 | -------------------------------------------------------------------------------- /Ch14/Exercises/e13b.txt: -------------------------------------------------------------------------------- 1 | (a) Show what the following program will look like after preprocessing. You 2 | may ignore any lines added to the program as a result of including the 3 | header. 4 | 5 | #include 6 | 7 | #define N 100 8 | 9 | int main(void) 10 | { 11 | f(); 12 | #ifdef N 13 | #undef N 14 | #endif 15 | return 0; 16 | } 17 | 18 | void f(void) 19 | { 20 | #if defined(N) 21 | printf("N is %d\n", N); 22 | #else 23 | printf("N is undefined\n"); 24 | #endif 25 | } 26 | 27 | (b) What will be the output of this program? 28 | 29 | Answer: 30 | The output will be "N is undefined" because the preprocessor directives are 31 | evaluated from top to bottom before the program is ran. 32 | -------------------------------------------------------------------------------- /Ch15/ProgrammingProjects/p3/quicksort.h: -------------------------------------------------------------------------------- 1 | #ifndef QUICKSORT_H 2 | #define QUICKSORT_H 3 | 4 | /*********************************************************** 5 | * quicksort: Sorts an array of integers from lowest to * 6 | * highest. * 7 | **********************************************************/ 8 | void quicksort(int a[], int low, int high); 9 | 10 | /*********************************************************** 11 | * split: Returns the median value between positions low * 12 | * and high in array a. * 13 | **********************************************************/ 14 | int split(int a[], int low, int high); 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /Ch07/ProgrammingProjects/p10.c: -------------------------------------------------------------------------------- 1 | /* Write a program that counts the number of vowels (a, e, i, o, and u) in a sentence: 2 | * 3 | * Enter a sentence: And that's the way it is. 4 | * Your sentence contains 6 vowels. 5 | */ 6 | #include 7 | #include 8 | 9 | int main(void) 10 | { 11 | char input; 12 | int vowels = 0; 13 | 14 | printf("\nEnter a sentence: "); 15 | 16 | while ((input = getchar()) != '\n') 17 | { 18 | switch (toupper(input)) 19 | { 20 | case 'A': case 'E': case 'I': case 'O': case 'U': 21 | vowels++; 22 | } 23 | } 24 | 25 | printf("Your sentence contains %d vowels.\n\n", vowels); 26 | 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /Ch06/Exercises/e04.c: -------------------------------------------------------------------------------- 1 | /* Whick one of the following statements is not equivalent to the other two 2 | * (assuming that the loop bodies are the same?) 3 | * (a) for (i = 0; i < 10; i++) ... 4 | * (b) for (i = 0; i < 10; ++i) ... 5 | * (c) for (i = 0; i++ < 10; ) ... 6 | */ 7 | #include 8 | 9 | int main(void) 10 | { 11 | int i; 12 | 13 | printf("\nA: "); 14 | for (i = 0; i < 10; i++) 15 | printf("\ni = %d", i); 16 | 17 | printf("\nB: "); 18 | for (i = 0; i < 10; ++i) 19 | printf("\ni = %d", i); 20 | 21 | printf("\nC: "); 22 | for (i = 0; i++ < 10; ) 23 | printf("\ni = %d", i); 24 | 25 | printf("\n\n"); 26 | 27 | return 0; 28 | } 29 | 30 | /* Answer: C */ 31 | -------------------------------------------------------------------------------- /Ch06/ProgrammingProjects/p05.c: -------------------------------------------------------------------------------- 1 | /* Programming Project 1 in Chapter 4 asked you to write a program that 2 | * displays a two-digit number with its digits reversed. Generalize the program 3 | * so that the number can have one, two, three, or more digits. Hint: Use a do 4 | * loop that repeatedly divides the number by 10, stopping when it reaches 0. 5 | */ 6 | #include 7 | 8 | int main(void) 9 | { 10 | int number; 11 | 12 | printf("\nEnter a number: "); 13 | scanf("%d", &number); 14 | 15 | printf("The reversal is: "); 16 | do 17 | { 18 | printf("%d", number % 10); 19 | number = number/10; 20 | } while (number != 0); 21 | 22 | printf("\n\n"); 23 | 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /Ch15/justify.c: -------------------------------------------------------------------------------- 1 | /* Formats a file of text */ 2 | 3 | #include 4 | #include "line.h" 5 | #include "word.h" 6 | 7 | #define MAX_WORD_LEN 20 8 | 9 | int main(void) 10 | { 11 | char word[MAX_WORD_LEN+2]; 12 | int word_len; 13 | 14 | clear_line(); 15 | for (;;) { 16 | read_word(word, MAX_WORD_LEN+1); 17 | word_len = strlen(word); 18 | if (word_len == 0) { 19 | flush_line(); 20 | return 0; 21 | } 22 | if (word_len > MAX_WORD_LEN) 23 | word[MAX_WORD_LEN] = '*'; 24 | if (word_len + 1 > space_remaining()) { 25 | write_line(); 26 | clear_line(); 27 | } 28 | add_word(word); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Ch17/Exercises/e07.txt: -------------------------------------------------------------------------------- 1 | The following loop is supposed to delete all nodes from a linked list and 2 | release memory that they occupy. Unfortunately the loop is incorrect. Explain 3 | what's wrong with it and show how to fix the bug. 4 | 5 | for (p = first; p != NULL; p = p->next) 6 | free(p); 7 | 8 | Answer: 9 | The loop is incorrect because the node p's memory is freed before it attempts to 10 | go to the next node. p becomes a dangling pointer. The way to fix it is to use 11 | a temporary variable that remembers where p was, so it can be freed after moving 12 | on to the next node: 13 | 14 | struct node *temp; 15 | p = first; 16 | while (p != NULL) 17 | { 18 | temp = p; 19 | p = p->next; 20 | free(temp); 21 | } 22 | 23 | -------------------------------------------------------------------------------- /Ch17/Exercises/e12.c: -------------------------------------------------------------------------------- 1 | /* Write the following function: 2 | * 3 | * struct node *find_last(struct node *list, int n); 4 | * 5 | * The list parameter points to a linked list. The function should return 6 | * a pointer to the last node that contains n; it should return NULL if 7 | * n doesn't appear in the list. Assume that the node structure is the one 8 | * defined in 17.5. 9 | */ 10 | #include 11 | 12 | struct node { 13 | int value; 14 | struct node *next; 15 | }; 16 | 17 | struct node *find_last(struct node *list, int n) 18 | { 19 | struct node *found = NULL; 20 | 21 | for (; list != NULL; list = list->next) 22 | if (list->value == n) 23 | found = list; 24 | 25 | return found; 26 | } 27 | -------------------------------------------------------------------------------- /Ch19/stackclient.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "stack.h" 3 | 4 | int main(void) 5 | { 6 | Stack s1, s2; 7 | int n; 8 | 9 | s1 = create(); 10 | s2 = create(); 11 | 12 | push(s1, 1); 13 | push(s1, 2); 14 | 15 | n = pop(s1); 16 | printf("Popped %d from s1\n", n); 17 | push(s2, n); 18 | n = pop(s1); 19 | printf("Popped %d from s1\n", n); 20 | push(s2, n); 21 | destroy(s1); 22 | 23 | while (!is_empty(s2)) 24 | printf("Popped %d from s2\n", pop(s2)); 25 | 26 | push(s2, 3); 27 | make_empty(s2); 28 | if (is_empty(s2)) 29 | printf("s2 is empty\n"); 30 | else 31 | printf("s2 is not empty\n"); 32 | 33 | destroy(s2); 34 | 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /Ch05/Exercises/e08.c: -------------------------------------------------------------------------------- 1 | /* The follownig if statement is unnecessarily complicated. 2 | * Simplify it as much as possible. 3 | * (Hint: The entire statement can be replaced by a single assignment). 4 | * 5 | * if (age >= 13) 6 | * if (age <= 19) 7 | * teenager = true; 8 | * else 9 | * teenager = false; 10 | * else if (age < 13) 11 | * teenager = false; 12 | */ 13 | #include 14 | 15 | int main(void) 16 | { 17 | int age; 18 | 19 | printf("\nInput age: "); 20 | scanf("%d", &age); 21 | 22 | printf(age >= 13 && age <= 19 ? "Is" : "Isn't"); 23 | printf(" a teenager.\n\n"); 24 | 25 | return 0; 26 | } 27 | 28 | /* Answer: 29 | * age >= 13 && age <= 19 ? teenager = true : teenager = false; 30 | */ 31 | -------------------------------------------------------------------------------- /Ch09/Exercises/e02.c: -------------------------------------------------------------------------------- 1 | /* Write a function check(x, y, n) that returns 1 if both x and y fall between 2 | * 0 and n - 1, inclusive. The function should return 0 otherwise. Assume that 3 | * x, y, and n are all of type int. 4 | */ 5 | #include 6 | 7 | int check(int x, int y, int n) 8 | { 9 | if ((x >= 0 && x < n) && (y >= 0 && y < n)) 10 | return 1; 11 | return 0; 12 | } 13 | 14 | int main(void) 15 | { 16 | int x, y, n; 17 | 18 | printf("\nEnter x, y, and n: "); 19 | scanf("%d%d%d", &x, &y, &n); 20 | 21 | if (check(x, y, n)) 22 | printf("%d and %d are between 0 and %d\n\n", x, y, n); 23 | else 24 | printf("%d and %d are not between 0 and %d\n\n", x, y, n); 25 | 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /Ch15/ProgrammingProjects/p1/justify.c: -------------------------------------------------------------------------------- 1 | /* Formats a file of text */ 2 | 3 | #include 4 | #include "line.h" 5 | #include "word.h" 6 | 7 | #define MAX_WORD_LEN 20 8 | 9 | int main(void) 10 | { 11 | char word[MAX_WORD_LEN+2]; 12 | int word_len; 13 | 14 | clear_line(); 15 | for (;;) { 16 | read_word(word, MAX_WORD_LEN+1); 17 | word_len = strlen(word); 18 | if (word_len == 0) { 19 | flush_line(); 20 | return 0; 21 | } 22 | if (word_len > MAX_WORD_LEN) 23 | word[MAX_WORD_LEN] = '*'; 24 | if (word_len + 1 > space_remaining()) { 25 | write_line(); 26 | clear_line(); 27 | } 28 | add_word(word); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Ch17/ProgrammingProjects/p4/justify.c: -------------------------------------------------------------------------------- 1 | /* Formats a file of text */ 2 | 3 | #include 4 | #include "line.h" 5 | #include "word.h" 6 | 7 | #define MAX_WORD_LEN 20 8 | 9 | int main(void) 10 | { 11 | char word[MAX_WORD_LEN+2]; 12 | int word_len; 13 | 14 | clear_line(); 15 | for (;;) { 16 | read_word(word, MAX_WORD_LEN+1); 17 | word_len = strlen(word); 18 | if (word_len == 0) { 19 | flush_line(); 20 | return 0; 21 | } 22 | if (word_len > MAX_WORD_LEN) 23 | word[MAX_WORD_LEN] = '*'; 24 | if (word_len + 1 > space_remaining()) { 25 | write_line(); 26 | clear_line(); 27 | } 28 | add_word(word); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Ch07/Exercises/e05.c: -------------------------------------------------------------------------------- 1 | /* Which one of the following is not a legal way to write the number 65? 2 | * (Assume the character set is ASCII.) 3 | * (a) 'A' 4 | * (b) 0b1000001 5 | * (c) 0101 6 | * (d) 0x41 7 | */ 8 | #include 9 | 10 | int main(void) 11 | { 12 | int a = 'A'; 13 | int b = 0b1000001; 14 | int c = 0101; 15 | int d = 0x41; 16 | 17 | printf("\nA: %d\n", a); 18 | printf("B: %d\n", b); 19 | printf("C: %d\n", c); 20 | printf("D: %d\n\n", d); 21 | 22 | return 0; 23 | } 24 | 25 | /* Answer: 26 | * B is illegal because binary constants aren't standard C. 27 | * However, GCC does support them as an extension, so this will successfully 28 | * compile and work fine _only_ when compiled with GCC. 29 | */ 30 | -------------------------------------------------------------------------------- /Ch19/Exercises/e4/a/stackclient.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "stack.h" 3 | 4 | int main(void) 5 | { 6 | Stack s1, s2; 7 | int n; 8 | 9 | s1 = create(); 10 | s2 = create(); 11 | 12 | push(s1, 1); 13 | push(s1, 2); 14 | 15 | n = pop(s1); 16 | printf("Popped %d from s1\n", n); 17 | push(s2, n); 18 | n = pop(s1); 19 | printf("Popped %d from s1\n", n); 20 | push(s2, n); 21 | destroy(s1); 22 | 23 | while (!is_empty(s2)) 24 | printf("Popped %d from s2\n", pop(s2)); 25 | 26 | push(s2, 3); 27 | make_empty(s2); 28 | if (is_empty(s2)) 29 | printf("s2 is empty\n"); 30 | else 31 | printf("s2 is not empty\n"); 32 | 33 | destroy(s2); 34 | 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /Ch19/Exercises/e4/b/stackclient.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "stack.h" 3 | 4 | int main(void) 5 | { 6 | Stack s1, s2; 7 | int n; 8 | 9 | s1 = create(); 10 | s2 = create(); 11 | 12 | push(s1, 1); 13 | push(s1, 2); 14 | 15 | n = pop(s1); 16 | printf("Popped %d from s1\n", n); 17 | push(s2, n); 18 | n = pop(s1); 19 | printf("Popped %d from s1\n", n); 20 | push(s2, n); 21 | destroy(s1); 22 | 23 | while (!is_empty(s2)) 24 | printf("Popped %d from s2\n", pop(s2)); 25 | 26 | push(s2, 3); 27 | make_empty(s2); 28 | if (is_empty(s2)) 29 | printf("s2 is empty\n"); 30 | else 31 | printf("s2 is not empty\n"); 32 | 33 | destroy(s2); 34 | 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /Ch10/Exercises/e1.txt: -------------------------------------------------------------------------------- 1 | The following program outline shows only function definitions and variable 2 | declarations. 3 | 4 | int a; 5 | 6 | void f(int b) 7 | { 8 | int c; 9 | } 10 | 11 | void g(void) 12 | { 13 | int d; 14 | { 15 | int e; 16 | } 17 | } 18 | 19 | int main(void) 20 | { 21 | int f; 22 | } 23 | 24 | For each of the following scopes, list all variables and parameter names 25 | visible in that scope: 26 | (a) The f function 27 | (b) The g function 28 | (c) The block in which e is declared 29 | (d) The main function 30 | 31 | Answer: 32 | A - global a 33 | parameter b 34 | local c 35 | 36 | B - global a 37 | local d 38 | 39 | C - global a 40 | local d 41 | local e 42 | 43 | D - global a 44 | local f 45 | -------------------------------------------------------------------------------- /Ch14/Exercises/e06.c: -------------------------------------------------------------------------------- 1 | /* (a) Write a macro DISP(f,x) that expands into a call of printf that displays 2 | * the value of the function f when called with argument x. For example, 3 | * 4 | * DISP(sqrt, 3.0); 5 | * 6 | * should expand into 7 | * 8 | * printf("sqrt(%g) = %g\n", 3.0, sqrt(3.0)); 9 | * 10 | * (b) Write a macro DISP2(f,x,y) that's similar to DISP but works for functions 11 | * with two arguments. 12 | */ 13 | #include 14 | #include 15 | 16 | #define DISP(f,x) printf("f(%g) = %g\n", x, f(x)) 17 | #define DISP2(f,x,y) printf("f(%g, %g) = %g\n", x, y, f(x, y)) 18 | 19 | int main(void) 20 | { 21 | putchar('\n'); 22 | 23 | DISP(sqrt, 25.0); 24 | DISP2(fmod, 11.0, 5.0); 25 | 26 | putchar('\n'); 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /Ch15/ProgrammingProjects/p5/stack.h: -------------------------------------------------------------------------------- 1 | #ifndef STACK_H 2 | #define STACK_H 3 | 4 | /* is_empty: Returns whether or not the stack is empty. */ 5 | bool is_empty(void); 6 | 7 | /* is_full: Returns whether or not the stack is full. */ 8 | bool is_full(void); 9 | 10 | /* push: Calls stack_overflow if the stack is too full, 11 | * otherwise it adds the value i to the top of the stack */ 12 | void push(int i); 13 | 14 | /* pop: Calls stack_underflow if the stack is empty, 15 | * otherwise it removes and returns the top value of the stack. */ 16 | int pop(void); 17 | 18 | /* stack_overflow: Prints an error and exits the program */ 19 | void stack_overflow(); 20 | 21 | /* stack_underflow: Prints an error and exits the program */ 22 | void stack_underflow(); 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /Ch16/Exercises/e06.c: -------------------------------------------------------------------------------- 1 | /* Write the following function, assuming that the time structure contains three 2 | * members: hours, minutes, and seconds (all of type int) 3 | * 4 | * struct time split_time(long total_seconds); 5 | * 6 | * total_seconds is a time represented as the number of seconds since midnight. 7 | * The function returns a structure containing the equivalent time in hours 8 | * (0-23), minutes (0-59) and seconds (0-59). 9 | */ 10 | struct time { int hours, minutes, seconds; }; 11 | 12 | struct time split_time(long total_seconds) 13 | { 14 | struct time conversion; 15 | conversion.seconds = total_seconds % 60; 16 | conversion.minutes = total_seconds / 60; 17 | conversion.hours = total_seconds / 60 / 60; 18 | return conversion; 19 | } 20 | -------------------------------------------------------------------------------- /Ch04/upc.c: -------------------------------------------------------------------------------- 1 | /* Computes a Universal Product Code check digit */ 2 | 3 | #include 4 | 5 | int main(void) 6 | { 7 | int d, i1, i2, i3, i4, i5, j1, j2, j3, j4, j5, 8 | first_sum, second_sum, total; 9 | 10 | printf("Enter the first (single) digit: "); 11 | scanf("%1d", &d); 12 | printf("Enter the first group of five digits: "); 13 | scanf("%1d%1d%1d%1d%1d", &i1, &i2, &i3, &i4, &i5); 14 | printf("Enter the second group of five digits: "); 15 | scanf("%1d%1d%1d%1d%1d", &j1, &j2, &j3, &j4, &j5); 16 | 17 | first_sum = d + i2 + i4 + j1 + j3 + j5; 18 | second_sum = i1 + i3 + i5 + j2 + j4; 19 | total = 3 * first_sum + second_sum; 20 | 21 | printf("Check digit: %d\n", 9 - ((total - 1) % 10)); 22 | 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /Ch13/planet.c: -------------------------------------------------------------------------------- 1 | /* Checks planet names */ 2 | 3 | #include 4 | #include 5 | 6 | #define NUM_PLANETS 9 7 | 8 | int main(int argc, char *argv[]) 9 | { 10 | char *planets[] = {"Mercury", "Venus", "Earth", 11 | "Mars", "Jupiter", "Saturn", 12 | "Uranus", "Neptune", "Pluto"}; 13 | int i, j; 14 | 15 | for (i = 1; i < argc; i++) 16 | { 17 | for (j = 0; j < NUM_PLANETS; j++) 18 | if (strcmp(argv[i], planets[j]) == 0) 19 | { 20 | printf("%s is planet %d\n", argv[i], j + 1); 21 | break; 22 | } 23 | if (j == NUM_PLANETS) 24 | printf("%s is not a planet\n", argv[i]); 25 | } 26 | 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /Ch21/Exercises/e7.txt: -------------------------------------------------------------------------------- 1 | In which standard header would you expect to find each of the following? 2 | 3 | (a) A function that determines the current day of the week 4 | (b) A function that tests whether a character is a digit 5 | (c) A macro that gives the largest unsigned int value 6 | (d) A function that rounds a floating-point number to the next higher integer 7 | (e) A macro that specifies the number of bits in a character 8 | (f) A macro that specifies the number of significant digits in a double value 9 | (g) A function that searches a string for a particular character 10 | (h) A function that opens a file for reading 11 | 12 | Answer: 13 | A - time.h 14 | B - ctype.h 15 | C - limits.h 16 | D - math.h 17 | E - limits.h 18 | F - float.h 19 | G - string.h 20 | H - stdio.h 21 | -------------------------------------------------------------------------------- /Ch14/Exercises/e13a.c: -------------------------------------------------------------------------------- 1 | /* (a) Show what the following program will look like after preprocessing. You 2 | * may ignore any lines added to the program as a result of including the 3 | * header. 4 | * 5 | * #include 6 | * 7 | * #define N 100 8 | * 9 | * int main(void) 10 | * { 11 | * f(); 12 | * #ifdef N 13 | * #undef N 14 | * #endif 15 | * return 0; 16 | * } 17 | * 18 | * void f(void) 19 | * { 20 | * #if defined(N) 21 | * printf("N is %d\n", N); 22 | * #else 23 | * printf("N is undefined\n"); 24 | * #endif 25 | * } 26 | * 27 | * (b) What will be the output of this program? 28 | */ 29 | int main(void) 30 | { 31 | f(); 32 | return 0; 33 | } 34 | 35 | void f(void) 36 | { 37 | printf("N is undefined\n"); 38 | } 39 | -------------------------------------------------------------------------------- /Ch18/Exercises/e03.txt: -------------------------------------------------------------------------------- 1 | List the storage duration (static or automatic), scope (block or file), and 2 | linkage (internal, external, none) of each variable and parameter in the 3 | following file: 4 | 5 | extern float a; 6 | 7 | void f(register double b) 8 | { 9 | static int c; 10 | auto char d; 11 | } 12 | 13 | Answer: 14 | 15 | a: storage duration: static 16 | scope: file 17 | linkage: undefined until definition 18 | 19 | b: storage duration: automatic 20 | scope: block 21 | linkage: none 22 | 23 | c: storage duration: static 24 | scope: block 25 | linkage: none 26 | 27 | d: storage duration: automatic 28 | scope: block 29 | linkage: none 30 | -------------------------------------------------------------------------------- /Ch19/Exercises/e7/stackclient.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "stackADT2.h" 3 | 4 | int main(void) 5 | { 6 | Stack s1, s2; 7 | int n; 8 | 9 | s1 = create(1); 10 | s2 = create(1); 11 | 12 | push(s1, 1); 13 | push(s1, 2); 14 | push(s1, 3); 15 | 16 | n = pop(s1); 17 | printf("Popped %d from s1\n", n); 18 | push(s2, n); 19 | n = pop(s1); 20 | printf("Popped %d from s1\n", n); 21 | push(s2, n); 22 | destroy(s1); 23 | 24 | while (!is_empty(s2)) 25 | printf("Popped %d from s2\n", pop(s2)); 26 | 27 | push(s2, 3); 28 | make_empty(s2); 29 | if (is_empty(s2)) 30 | printf("s2 is empty\n"); 31 | else 32 | printf("s2 is not empty\n"); 33 | 34 | destroy(s2); 35 | 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /Ch14/Exercises/e11.c: -------------------------------------------------------------------------------- 1 | /* (C99) C programmers often use the fprintf function to write error messages: 2 | * 3 | * fprintf(stderr, "Range error: index = %d\n", index); 4 | * 5 | * stderr is C's "standard error" stream; the remaining arguments are the same 6 | * as those for prntf, starting with the format string. Write a macro named 7 | * ERROR that generates the call of printf shown above when given a format 8 | * string and the items to be displayed: 9 | * 10 | * ERROR("Range error: index = %d\n", index); 11 | */ 12 | #include 13 | 14 | #define ERROR(s, ...) fprintf(stderr, s, __VA_ARGS__) 15 | 16 | int main(void) 17 | { 18 | int index = 10; 19 | putchar('\n'); 20 | ERROR("Range error: index = %d\n", index); 21 | putchar('\n'); 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /Ch04/Exercises/e02.c: -------------------------------------------------------------------------------- 1 | /* If i and j are positive integers, does (-i)/j 2 | * always have the same value as -(i/j)? Justify your answer. 3 | */ 4 | #include 5 | 6 | int main(void) 7 | { 8 | int i = 12; 9 | int j = 5; 10 | 11 | printf("\ni is %d and j is %d\n", i, j); 12 | printf("(-i)/j = %d\n", (-i)/j); 13 | printf("-(i/j) = %d\n\n", -(i/j)); 14 | 15 | return 0; 16 | } 17 | 18 | /* Answer: 19 | * When compiled in C89, the the first expression could be evaluated 20 | * differently and have two different answers, depending on implementation. 21 | * When compiled in C99, they should always have the same result no matter what. 22 | * 23 | * This happens because C89 will round either up or down when doing division 24 | * with any negative operands. 25 | */ 26 | -------------------------------------------------------------------------------- /Ch22/Exercises/e13.c: -------------------------------------------------------------------------------- 1 | /* Write the following function: 2 | * 3 | * int lien_length(const char *filename, int n); 4 | * 5 | * The functions should return the length of n in the text file whose name is 6 | * filename (assuming that the first line in the file is 1). If the line doesn't 7 | * exist, the function should return 0; 8 | * 9 | */ 10 | 11 | /* Answer: */ 12 | int line_length(const char *filename, int n) 13 | { 14 | FILE *fp; 15 | char ch; 16 | int len = 0; 17 | 18 | if ((fp = fopen(filename, "r")) == NULL) 19 | return 0; 20 | for (; n > 1; --n) 21 | while ((ch = fgetc(fp)) != '\n') 22 | if (ch == EOF) 23 | return 0; 24 | while ((ch = fgetc(fp)) != '\n' && ch != EOF) 25 | len++; 26 | return len; 27 | } 28 | -------------------------------------------------------------------------------- /Ch02/Exercises/e02.c: -------------------------------------------------------------------------------- 1 | /* Consider the following program: 2 | * (a) Identify the directives and statements in this program 3 | * (b) What output does the program produce? 4 | */ 5 | #include 6 | 7 | int main(void) 8 | { 9 | printf("\nParkinson's Law:\nWork expands as to "); 10 | printf("fill the time\n"); 11 | printf("available for its completion.\n\n"); 12 | return 0; 13 | } 14 | 15 | /* Answer: 16 | * (a) Directives: 17 | * #include 18 | * Statements: 19 | * printf("Parkinson's Law:\nWork expands as to "); 20 | * printf("fill the time\n"); 21 | * printf("available for its completion.\n"); 22 | * return 0; 23 | * 24 | * (b) Output: 25 | * Parkinson's Law: 26 | * Work expands as to fill the time 27 | * available for its completion. 28 | */ 29 | -------------------------------------------------------------------------------- /Ch04/ProgrammingProjects/p5.c: -------------------------------------------------------------------------------- 1 | /* Rewrite the upc.c program of Section 4.1 so that the user enters 11 digits 2 | * at one time, instead of entering one digit, then five digits, and then 3 | * another five digits. 4 | */ 5 | #include 6 | 7 | int main(void) 8 | { 9 | int d, i1, i2, i3, i4, i5, j1, j2, j3, j4, j5, 10 | first_sum, second_sum, total; 11 | 12 | printf("\nEnter the first 11 digits of a UPC: "); 13 | scanf("%1d%1d%1d%1d%1d%1d%1d%1d%1d%1d%1d", 14 | &d, &i1, &i2, &i3, &i4, &i5, 15 | &j1, &j2, &j3, &j4, &j5); 16 | 17 | first_sum = d + i2 + i4 + j1 + j3 + j5; 18 | second_sum = i1 + i3 + i5 + j2 + j4; 19 | total = 3 * first_sum + second_sum; 20 | 21 | printf("Check digit: %d\n\n", 9 - ((total - 1) % 10)); 22 | 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /Ch14/Exercises/e15.c: -------------------------------------------------------------------------------- 1 | /* Suppose that a program needs to display messages in either English, French, 2 | * or Spanish. Using conditional compilation, write a program fragment that 3 | * displays one of the following three messages, depending on whether or not the 4 | * specified macro is defined: 5 | * 6 | * Insert Disk 1 (if ENGLISH is defined) 7 | * Inserez Le Diskque 1 (if FRENCH is defined) 8 | * Inserte El Disco 1 (if SPANISH is defined) 9 | */ 10 | #include 11 | #define FRENCH 12 | 13 | int main(void) 14 | { 15 | printf("\n" 16 | #if defined(ENGLISH) 17 | "Insert Disk 1" 18 | #elif defined(FRENCH) 19 | "Inserez Le Diskque 1" 20 | #elif defined(SPANISH) 21 | "Inserte El Disco 1" 22 | #endif 23 | "\n\n"); 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /Ch15/ProgrammingProjects/p3/quicksort.c: -------------------------------------------------------------------------------- 1 | #include "quicksort.h" 2 | 3 | void quicksort(int a[], int low, int high) 4 | { 5 | int middle; 6 | 7 | if (low >= high) return; 8 | middle = split(a, low, high); 9 | quicksort(a, low, middle - 1); 10 | quicksort(a, middle + 1, high); 11 | } 12 | 13 | int split(int a[], int low, int high) 14 | { 15 | int part_element = a[low]; 16 | 17 | for (;;) 18 | { 19 | while (low < high && part_element <= a[high]) 20 | high--; 21 | if (low >= high) break; 22 | a[low++] = a[high]; 23 | 24 | while (low < high && a[low] <= part_element) 25 | low++; 26 | if (low >= high) break; 27 | a[high--] = a[low]; 28 | } 29 | 30 | a[high] = part_element; 31 | return high; 32 | } 33 | -------------------------------------------------------------------------------- /Ch11/maxmin.c: -------------------------------------------------------------------------------- 1 | /* Finds the largest and smallest elements in an array */ 2 | 3 | #include 4 | 5 | #define N 10 6 | 7 | void max_min(int a[], int n, int *max, int *min); 8 | 9 | int main(void) 10 | { 11 | int b[N], i, big, small; 12 | 13 | printf("Enter %d numbers: ", N); 14 | for (i = 0; i < N; i++) 15 | scanf("%d", &b[i]); 16 | 17 | max_min(b, N, &big, &small); 18 | 19 | printf("Largest: %d\n", big); 20 | printf("Smallest: %d\n", small); 21 | 22 | return 0; 23 | } 24 | 25 | void max_min(int a[], int n, int *max, int *min) 26 | { 27 | int i; 28 | 29 | *max = *min = a[0]; 30 | for (i = 0; i < n; i++) 31 | { 32 | if (a[i] > *max) 33 | *max = a[i]; 34 | else if (a[i] < *min) 35 | *min = a[i]; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Ch19/stack1.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "stack.h" 4 | 5 | #define STACK_SIZE 100 6 | 7 | static int contents[STACK_SIZE]; 8 | static int top = 0; 9 | 10 | static void terminate(const char *message) 11 | { 12 | printf("%s\n", message); 13 | exit(EXIT_FAILURE); 14 | } 15 | 16 | void make_empty(void) 17 | { 18 | top = 0; 19 | } 20 | 21 | bool is_empty(void) 22 | { 23 | return top == 0; 24 | } 25 | 26 | bool is_full(void) 27 | { 28 | return top == STACK_SIZE; 29 | } 30 | 31 | void push(int i) 32 | { 33 | if (is_full()) 34 | terminate("Error in push: stack is full."); 35 | contents[top++] = i; 36 | } 37 | 38 | int pop(void) 39 | { 40 | if (is_empty()) 41 | terminate("Error in pop: stack is empty."); 42 | return contents[--top]; 43 | } 44 | -------------------------------------------------------------------------------- /Ch04/Exercises/e13.c: -------------------------------------------------------------------------------- 1 | /* Only one of the expressions ++i and i++ is exactly the same as (i += 1); 2 | * which is it? Justify your answer. 3 | */ 4 | #include 5 | 6 | int main(void) 7 | { 8 | int i = 1; 9 | printf("\nduring ++i: %d\n", ++i); 10 | printf("after ++i: %d\n\n", i); 11 | 12 | i = 1; 13 | printf("during (i += 1): %d\n", (i += 1)); 14 | printf("after (i += 1): %d\n\n", i); 15 | 16 | i = 1; 17 | printf("during i++: %d\n", i++); 18 | printf("after i++: %d\n\n", i); 19 | 20 | return 0; 21 | } 22 | /* Answer: 23 | * ++i is exactly the same as (i += 1) because they both immediately modify i 24 | * and evaluate as the modified value. 25 | * 26 | * But i++ is different because it evaluates as i before it's modified 27 | * and then modifies i afterward. 28 | */ 29 | -------------------------------------------------------------------------------- /Ch04/ProgrammingProjects/p1.c: -------------------------------------------------------------------------------- 1 | /* Write a program that asks the user to enter a two-digit number, then prints 2 | * the number with its digits reversed. A session with the program should have 3 | * the following: 4 | * 5 | * Enter a two-digit number: 28 6 | * The reversal is: 82 7 | * 8 | * Read the number using %d, then break it into two digits. Hint: If n is an 9 | * integer, then n % 10 is the last digit in n and n / 10 is n with the last 10 | * digit removed. 11 | */ 12 | #include 13 | 14 | int main(void) 15 | { 16 | int number, digit1, digit2; 17 | 18 | printf("\nEnter a two-digit number: "); 19 | scanf("%d", &number); 20 | 21 | digit1 = number / 10; 22 | digit2 = number % 10; 23 | 24 | printf("The reversal is: %d%d\n\n", digit2, digit1); 25 | 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /Ch19/Exercises/e6/a/stackclient.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "stackADT.h" 3 | 4 | int main(void) 5 | { 6 | Stack s1, s2; 7 | int n; 8 | 9 | s1 = create(); 10 | s2 = create(); 11 | 12 | push(s1, 1); 13 | push(s1, 2); 14 | 15 | printf("Peeked at %d from s1\n", peek(s1)); 16 | 17 | n = pop(s1); 18 | printf("Popped %d from s1\n", n); 19 | push(s2, n); 20 | n = pop(s1); 21 | printf("Popped %d from s1\n", n); 22 | push(s2, n); 23 | destroy(s1); 24 | 25 | while (!is_empty(s2)) 26 | printf("Popped %d from s2\n", pop(s2)); 27 | 28 | push(s2, 3); 29 | make_empty(s2); 30 | if (is_empty(s2)) 31 | printf("s2 is empty\n"); 32 | else 33 | printf("s2 is not empty\n"); 34 | 35 | destroy(s2); 36 | 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /Ch19/Exercises/e6/c/stackclient.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "stackADT.h" 3 | 4 | int main(void) 5 | { 6 | Stack s1, s2; 7 | int n; 8 | 9 | s1 = create(); 10 | s2 = create(); 11 | 12 | push(s1, 1); 13 | push(s1, 2); 14 | 15 | printf("Peeked at %d from s1\n", peek(s1)); 16 | 17 | n = pop(s1); 18 | printf("Popped %d from s1\n", n); 19 | push(s2, n); 20 | n = pop(s1); 21 | printf("Popped %d from s1\n", n); 22 | push(s2, n); 23 | destroy(s1); 24 | 25 | while (!is_empty(s2)) 26 | printf("Popped %d from s2\n", pop(s2)); 27 | 28 | push(s2, 3); 29 | make_empty(s2); 30 | if (is_empty(s2)) 31 | printf("s2 is empty\n"); 32 | else 33 | printf("s2 is not empty\n"); 34 | 35 | destroy(s2); 36 | 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /Ch11/Exercises/e6.c: -------------------------------------------------------------------------------- 1 | /* Write the following function: 2 | * 3 | * void find_two_largest(int a[], int n, int *largest, 4 | * int *second_largest); 5 | * 6 | * When passed an array a of length n, the function will search a for its 7 | * largest and second largest elements, storing them in the variables pointed to 8 | * by largest and second_largest, respectively. 9 | */ 10 | void find_two_largest(int a[], int n, int *largest, int *second_largest) 11 | { 12 | int i; 13 | 14 | *largest = a[0]; 15 | for (i = 1; i < n; i++) 16 | if (a[i] > *largest) 17 | *largest = a[i]; 18 | 19 | *second_largest = a[0]; 20 | for (i = 1; i < n; i++) 21 | if (a[i] > *second_largest) 22 | if (a[i] != *largest) 23 | *second_largest = a[i]; 24 | } 25 | -------------------------------------------------------------------------------- /Ch13/ProgrammingProjects/p05.c: -------------------------------------------------------------------------------- 1 | /* Write a program named sum.c that adds up its command-line arguments, which 2 | * are assumed to be integers. Running the program by typing 3 | * 4 | * sum 8 24 62 5 | * 6 | * should produce the following output: 7 | * 8 | * Total: 94 9 | * 10 | * Hint: Use the atoi function to convert each command-line argument from string 11 | * form to integer form. 12 | */ 13 | #include 14 | #include 15 | 16 | int main(int argc, char *argv[]) 17 | { 18 | int i, sum = 0; 19 | 20 | if (argc == 1) 21 | { 22 | printf("\nUsage: Enter integers as command-line arguments.\n\n"); 23 | return 0; 24 | } 25 | 26 | for (i = 1; i < argc; i++) 27 | sum += atoi(argv[i]); 28 | printf("\nTotal: %d\n\n", sum); 29 | 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /Ch19/Exercises/e6/b/stackclient.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "stackADT2.h" 3 | 4 | int main(void) 5 | { 6 | Stack s1, s2; 7 | int n; 8 | 9 | s1 = create(100); 10 | s2 = create(100); 11 | 12 | push(s1, 1); 13 | push(s1, 2); 14 | 15 | printf("Peeked at %d from s1\n", peek(s1)); 16 | 17 | n = pop(s1); 18 | printf("Popped %d from s1\n", n); 19 | push(s2, n); 20 | n = pop(s1); 21 | printf("Popped %d from s1\n", n); 22 | push(s2, n); 23 | destroy(s1); 24 | 25 | while (!is_empty(s2)) 26 | printf("Popped %d from s2\n", pop(s2)); 27 | 28 | push(s2, 3); 29 | make_empty(s2); 30 | if (is_empty(s2)) 31 | printf("s2 is empty\n"); 32 | else 33 | printf("s2 is not empty\n"); 34 | 35 | destroy(s2); 36 | 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /Ch08/Exercises/e07.c: -------------------------------------------------------------------------------- 1 | /* Using the shortcuts descirbed in Section 8.2, shrink the intitializer for 2 | * the segments array (Exercise 6) as much as you can. 3 | */ 4 | 5 | /* Answer: */ 6 | const int segments[10][7] = {{1, 1, 1, 1, 1, 1}, /* 0 */ 7 | {0, 1, 1}, /* 1 */ 8 | {1, 1, 0, 1, 1, 0, 1}, /* 2 */ 9 | {1, 1, 1, 1, 0, 0, 1}, /* 3 */ 10 | {0, 1, 1, 0, 0, 1, 1}, /* 4 */ 11 | {1, 0, 1, 1, 0, 1, 1}, /* 5 */ 12 | {1, 0, 1, 1, 1, 1, 1}, /* 6 */ 13 | {1, 1, 1}, /* 7 */ 14 | {1, 1, 1, 1, 1, 1, 1}, /* 8 */ 15 | {1, 1, 1, 1, 0, 1, 1}}; /* 9 */ 16 | -------------------------------------------------------------------------------- /Ch14/Exercises/e08.c: -------------------------------------------------------------------------------- 1 | /* Suppose we want a macro that expands into a string containing the current 2 | * line number and file name. In other words, we'd like to write 3 | * 4 | * const char *str = LINE_FILE; 5 | * 6 | * and have it expand into 7 | * 8 | * const char *str = "Line 10 of file foo.c"; 9 | * 10 | * where foo.c is the file containing the program and 10 is the line on which 11 | * the invocation of LINE_FILE appears. Warning: This exercise is for experts 12 | * only. Be sure to read the Q&A section carefully before attempting. 13 | */ 14 | #include 15 | 16 | #define xstr(s) str(s) 17 | #define str(s) #s 18 | #define LINE_FILE "Line " xstr(__LINE__) " of file " __FILE__ 19 | 20 | int main(void) 21 | { 22 | const char *str = LINE_FILE; 23 | 24 | printf("\n%s\n\n", str); 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /Ch22/fcopy.c: -------------------------------------------------------------------------------- 1 | /* Copies a file */ 2 | 3 | #include 4 | #include 5 | 6 | int main(int argc, char *argv[]) 7 | { 8 | FILE *source_fp, *dest_fp; 9 | int ch; 10 | 11 | if (argc != 3) { 12 | fprintf(stderr, "usage: fcopy source dest\n"); 13 | exit(EXIT_FAILURE); 14 | } 15 | 16 | if ((source_fp = fopen(argv[1], "rb")) == NULL) { 17 | fprintf(stderr, "Can't open %s\n", argv[1]); 18 | exit(EXIT_FAILURE); 19 | } 20 | 21 | if ((dest_fp = fopen(argv[2], "wb")) == NULL) { 22 | fprintf(stderr, "Can't open %s\n", argv[2]); 23 | fclose(source_fp); 24 | exit(EXIT_FAILURE); 25 | } 26 | 27 | while ((ch = getc(source_fp)) != EOF) 28 | putc(ch, dest_fp); 29 | 30 | fclose(source_fp); 31 | fclose(dest_fp); 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /Ch02/ProgrammingProjects/p2.c: -------------------------------------------------------------------------------- 1 | /* Write a program that computes the volume of a sphere with a 10-meter radius, 2 | * using the formula v = 4/3(pi)r^3. 3 | * 4 | * Write the fraction 4/3 as 4.0f/3.0f. (Try writing it as 4/3. What happens?) 5 | * Hint: C doesn't have an exponentiation operator, so you'll need to 6 | * multiply r by itself twice to compute (r to the power of 3). 7 | */ 8 | #include 9 | 10 | #define RAD 10 11 | #define NUM_PIE 3.141592653f 12 | 13 | int main(void) 14 | { 15 | printf("\nThe volume of a %d-meter sphere is: %.2f\n\n", 16 | RAD, (4.0f/3.0f) * NUM_PIE * (RAD * RAD * RAD)); 17 | 18 | return 0; 19 | } 20 | 21 | /* Additional Answer: 22 | * When (4.0f/3.0f) is (4/3), the answer is evaluated as an int 1 23 | * instead of a float 1.3333.. Making the answer much less accurate. 24 | */ 25 | -------------------------------------------------------------------------------- /Ch19/ProgrammingProjects/p4/stackclient.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "stackADT.h" 3 | 4 | int main(void) 5 | { 6 | Stack s1, s2; 7 | int n; 8 | 9 | s1 = create(); 10 | s2 = create(); 11 | 12 | n = 1; 13 | push(s1, &n); 14 | n = 2; 15 | push(s1, &n); 16 | 17 | n = *(int *)pop(s1); 18 | printf("Popped %d from s1\n", n); 19 | push(s2, &n); 20 | n = *(int *)pop(s1); 21 | printf("Popped %d from s1\n", n); 22 | push(s2, &n); 23 | destroy(s1); 24 | 25 | while (!is_empty(s2)) 26 | printf("Popped %d from s2\n", *(int *)pop(s2)); 27 | 28 | n = 3; 29 | push(s2, &n); 30 | make_empty(s2); 31 | if (is_empty(s2)) 32 | printf("s2 is empty\n"); 33 | else 34 | printf("s2 is not empty\n"); 35 | 36 | destroy(s2); 37 | 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /Ch09/Exercises/e19.c: -------------------------------------------------------------------------------- 1 | /* Consider the following "mystery" function: 2 | * 3 | * void pb(int n) 4 | * { 5 | * if (n != 0) { 6 | * pb(n / 2); 7 | * putchar('0' + n % 2); 8 | * } 9 | * } 10 | * 11 | * Trace the execution of the function by hand. Then write a program that calls 12 | * the function, passing it a number entered by the user. What does the function 13 | * do? 14 | */ 15 | #include 16 | 17 | void pb(int n); 18 | 19 | int main(void) 20 | { 21 | int num; 22 | 23 | printf("\nEnter a number: "); 24 | scanf("%d", &num); 25 | 26 | pb(num); 27 | printf("\n\n"); 28 | } 29 | 30 | void pb(int n) 31 | { 32 | if (n != 0) 33 | { 34 | pb(n / 2); 35 | putchar('0' + n % 2); 36 | } 37 | } 38 | 39 | /* Answer: 40 | * It prints the binary conversion of the integer n. 41 | */ 42 | -------------------------------------------------------------------------------- /Ch12/ProgrammingProjects/p4.c: -------------------------------------------------------------------------------- 1 | /* Simplify Programming Project 2(b) by taking advantage of the fact that an 2 | * array name can be used as a pointer. 3 | */ 4 | #include 5 | #include 6 | 7 | #define BUF 50 8 | 9 | int main(void) 10 | { 11 | char *pa, *pb; 12 | char input, msg[BUF] = {0}; 13 | 14 | printf("\nEnter a message: "); 15 | pa = msg; 16 | while ((input = tolower(getchar())) != '\n') 17 | if (isalpha(input)) 18 | *pa++ = input; 19 | 20 | pb = pa-1; 21 | pa = msg; 22 | while (pa < msg + BUF) 23 | { 24 | if (*pa == 0) break; 25 | if (*pa != *pb) 26 | { 27 | printf("Not a palindrome\n\n"); 28 | return 0; 29 | } 30 | pa++, pb--; 31 | } 32 | printf("Palindrome\n\n"); 33 | 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /Ch13/Exercises/e15.txt: -------------------------------------------------------------------------------- 1 | Let f be the following function: 2 | 3 | int f(char *s, char *t) 4 | { 5 | char *p1, *p2; 6 | 7 | for (p1 = s; *p1; p1++) { 8 | for (p2 = t; *p2; p2++) 9 | if (*p1 == *p2) break; 10 | if (*p2 == '\0') break; 11 | } 12 | return p1 - s; 13 | } 14 | 15 | (a) What is the value of f("abcd", "babc")? 16 | (b) What is the value of f("abcd", "bcd")? 17 | (c) In general, what value does f return when passed two strings s and t? 18 | 19 | Answer: 20 | A - 3 21 | B - 0 22 | C - It returns the index position of the first character in string s that 23 | doesn't appear in string t, and if both strings contain the same characters, 24 | it returns the length of s. For example, in question (b), it returns 0, 25 | which is the position of 'a' in the string "abcd", because 'a' doesn't 26 | appear in "bcd". 27 | -------------------------------------------------------------------------------- /Ch18/Exercises/e06.txt: -------------------------------------------------------------------------------- 1 | The following function is supposed to print an error message. Each message is 2 | preceded by an integer, indicating the number of times the function has been 3 | called. Unfortunately, the function always displays 1 as the number of the 4 | error message. Locate the error and show how to fix it without making any 5 | changes outside the function. 6 | 7 | void print_error(const char *message) 8 | { 9 | int n = 1; 10 | printf("Error %d: %s\n", n++, message); 11 | } 12 | 13 | Answer: 14 | The problem is that n isn't declared as static, so it defaults to an automatic 15 | storage class and its value will always get reset after the function is 16 | returned. 17 | 18 | Fixed: 19 | void print_error(const char *message) 20 | { 21 | static int n = 1; 22 | printf("Error %d: %s\n", n++, message); 23 | } 24 | -------------------------------------------------------------------------------- /Ch13/Exercises/e05.c: -------------------------------------------------------------------------------- 1 | /* (a) Write a function named capitalize that capitalizes all letters in its 2 | * argument. The argument will be a null-terminate string containing arbitrary 3 | * characters, not just letters. Use array subscripting to access the characters 4 | * in the string. Hint: Use the toupper function to convert each character to 5 | * upper-case. 6 | * 7 | * (b) Rewrite the capitalize function, this time only using pointer arithmetic 8 | * to access the characters in the string. 9 | */ 10 | #include 11 | 12 | /* array subscripting */ 13 | void capitalizeA(char* text) 14 | { 15 | int i = 0; 16 | for (;text[i] != '\0'; i++) 17 | text[i] = toupper(text[i]); 18 | } 19 | 20 | /* pointer arithmetic */ 21 | void capitalizeB(char* text) 22 | { 23 | while (*text != '\0') 24 | *text++ = toupper(*text); 25 | } 26 | -------------------------------------------------------------------------------- /Ch22/Exercises/e07.txt: -------------------------------------------------------------------------------- 1 | Suppose that we call scanf as follows: 2 | 3 | n = scanf("%d%f%d", &i, &x, &j); 4 | 5 | (i, j, and n are int variables and x is a float variable.) Assuming that the 6 | input stream contains the characters shown, give the values of i, j, n, and 7 | x after the call. In addition, indicate which characters were consumed by the 8 | call. 9 | 10 | (a) 10 20 30 11 | (b) 1.0 2.0 3.0 12 | (c) 0.1 0.2 0.3 13 | (d) .1 .2 .3 14 | 15 | Answer: 16 | A - 10 20 30 17 | i = 10 18 | x = 20 19 | j = 30 20 | n = 3 21 | consumed chars: 10 20 30 22 | 23 | B - 1.0 2.0 3.0 24 | i = 1 25 | x = 0 26 | j = 2 27 | n = 3 28 | consumed chars: 1.0 2 29 | 30 | C - 0.1 0.2 0.3 31 | i = 0 32 | x = .1 33 | j = 0 34 | n = 3 35 | consumed chars: 0.1 0 36 | 37 | D - .1 .2 .3 38 | i = undefined 39 | x = undefined 40 | j = undefined 41 | n = 0 42 | consumed chars: none 43 | -------------------------------------------------------------------------------- /Ch13/Exercises/e01.txt: -------------------------------------------------------------------------------- 1 | The following function calls supposedly write a single new-line character, 2 | but some are incorrect. Identify which calls don't work and explain why. 3 | 4 | (a) printf("%c\n", '\n'); (g) putchar('\n'); 5 | (b) printf("%c\n", "\n"); (h) putchar("\n"); 6 | (c) printf("%s\n", '\n'); (i) puts('\n'); 7 | (d) printf("%s\n", "\n"); (j) puts("\n"); 8 | (e) printf('\n'); (k) puts(""); 9 | (f) printf("\n"); 10 | 11 | Answer: 12 | A - Prints two new lines instead of one 13 | B - %c expects a character, but gets a string 14 | C - %s expects a string, but gets a character 15 | D - Prints two new lines instead of one 16 | E - Printf needs a string, but gets a character 17 | H - putchar expects a character, but gets a string 18 | I - puts expects a string, but gets a character 19 | J - Prints two new line characters 20 | 21 | -------------------------------------------------------------------------------- /Ch14/Exercises/e01.c: -------------------------------------------------------------------------------- 1 | /* Write parameterized macros that compute the following values. 2 | * 3 | * (a) The cube of x. 4 | * (b) The remainder when n is divided by 4. 5 | * (c) 1 if the product of x and y is less than 100, 0 otherwise. 6 | * 7 | * Do your macros always work? If not describe what arguments would make them 8 | * fail. 9 | */ 10 | #include 11 | 12 | #define A_CUBE(x) ((x)*(x)) 13 | #define B_REMAINDER(n) ((n)/4) 14 | #define C_LESSTHAN(x, y) (((x)*(y)) ? 1 : 0) 15 | 16 | int main(void) 17 | { 18 | int Ex, Why, En; 19 | 20 | printf("\nEnter x, y, and n: "); 21 | scanf("%d %d %d", &Ex, &Why, &En); 22 | 23 | printf("\n%d cubed: %d", Ex, A_CUBE(Ex)); 24 | printf("\nRemainder of %d/4: %d", En, B_REMAINDER(En)); 25 | printf("\n%d * %d < 100?: %d\n\n", Ex, Why, C_LESSTHAN(Ex, Why)); 26 | 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /Ch17/Exercises/e02.c: -------------------------------------------------------------------------------- 1 | /* Write a function named duplicate that uses dynamic setorage allocation to 2 | * create a copy of a string. For example, the call 3 | * 4 | * p = duplicate(str); 5 | * 6 | * would allocate space for a string of the same length as str, copy the 7 | * contents of str into the new string, and return a pointer to it. Have 8 | * duplicate return a null pointer if the memory allocation fails. 9 | */ 10 | #include 11 | #include 12 | #include 13 | 14 | char *duplicate(char* str); 15 | 16 | int main(void) 17 | { 18 | char *str1 = "Here's a string"; 19 | char *str2 = duplicate(str1); 20 | 21 | printf("\nDuplicate: %s\n\n", str2); 22 | return 0; 23 | } 24 | 25 | char *duplicate(char* str) 26 | { 27 | char *copy = malloc(sizeof(str) + 1); 28 | strcpy(copy, str); 29 | return copy; 30 | } 31 | -------------------------------------------------------------------------------- /Ch05/broker.c: -------------------------------------------------------------------------------- 1 | /* Calculates a broker's commission */ 2 | 3 | #include 4 | 5 | int main(void) 6 | { 7 | float commission, value; 8 | 9 | printf("Enter value of trade: "); 10 | scanf("%f", &value); 11 | 12 | if (value < 2500.00f) 13 | commission = 30.00f + .017f * value; 14 | else if (value < 6250.00f) 15 | commission = 56.00f + .0066f * value; 16 | else if (value < 20000.00f) 17 | commission = 76.00f + .0034f * value; 18 | else if (value < 50000.00f) 19 | commission = 100.00f + .0022f * value; 20 | else if (value < 500000.00f) 21 | commission = 155.00f + .0011f * value; 22 | else 23 | commission = 255.0f + .0009f * value; 24 | 25 | if (commission < 39.00f) 26 | commission = 39.00f; 27 | 28 | printf("Commission: $%.2f\n", commission); 29 | 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /Ch05/ProgrammingProjects/p02.c: -------------------------------------------------------------------------------- 1 | /* Write a program that asks the user for a 24-hour time, then displays the 2 | * time in 12-hor form: 3 | * 4 | * Enter a 24-hour time: 22:11 5 | * Equivalent 12-hour time: 9:11 PM 6 | * 7 | * Be careful to not display 12:00 as 0:00. 8 | */ 9 | #include 10 | 11 | int main(void) 12 | { 13 | int hours24, hours12, minutes; 14 | 15 | printf("\nEnter a 24-hour time: "); 16 | scanf("%d:%d", &hours24, &minutes); 17 | 18 | if (hours24 > 12 && hours24 <= 24) 19 | hours12 = hours24 - 12; 20 | else 21 | hours12 = hours24; 22 | 23 | printf("Equivalent 12-hour time: %d:%.2d ", hours12, minutes); 24 | 25 | if (hours24 == 24) 26 | printf("AM"); 27 | else if (hours24 >= 12) 28 | printf("PM"); 29 | else 30 | printf("AM"); 31 | 32 | printf("\n\n"); 33 | 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /Ch11/Exercises/e8.c: -------------------------------------------------------------------------------- 1 | /* Write the following function: 2 | * 3 | * int *find_largest(int a[], int n); 4 | * 5 | * When passed an array of length n, the function will return a pointer to the 6 | * array's largest element. 7 | */ 8 | #include 9 | 10 | #define NUMS 5 11 | 12 | int *find_largest(int a[], int n); 13 | 14 | int main(void) 15 | { 16 | int i; 17 | int A[NUMS], *Largest; 18 | 19 | printf("\nEnter %d numbers: ", NUMS); 20 | for (i = 0; i < NUMS; i++) 21 | scanf(" %d", &A[i]); 22 | 23 | Largest = find_largest(A, NUMS); 24 | 25 | printf("Largest: %d\n\n", *Largest); 26 | 27 | return 0; 28 | } 29 | 30 | int *find_largest(int a[], int n) 31 | { 32 | int i, *largest; 33 | 34 | largest = &a[0]; 35 | for (i = 1; i < n; i++) 36 | if (a[i] > *largest) 37 | largest = &a[i]; 38 | 39 | return largest; 40 | } 41 | -------------------------------------------------------------------------------- /Ch04/Exercises/e01.c: -------------------------------------------------------------------------------- 1 | /* Show the output produced by each of the following program fragments. 2 | * Assume that i, j, and k are int variables. 3 | * (a) i = 5; j = 3; 4 | * printf("%d %d", i / j, i % j); 5 | * (b) i = 2; j = 3; 6 | * printf("%d", (i + 10) % j); 7 | * (c) i = 7; j = 8; k = 9; 8 | * printf("%d", (i + 10) % k / j); 9 | * (d) i = 1; j = 2; k = 3; 10 | * printf("%d", (i + 5) % (j + 2) / k); 11 | */ 12 | #include 13 | 14 | int main(void) 15 | { 16 | int i = 5, j = 3, k; 17 | printf("\na: %d %d\n", i / j, i % j); 18 | 19 | i = 2, j = 3; 20 | printf("b: %d\n", (i + 10) % j); 21 | 22 | i = 7, j = 8, k = 9; 23 | printf("c: %d\n", (i + 10) % k / j); 24 | 25 | i = 1, j = 2, k = 3; 26 | printf("d: %d\n\n", (i + 5) % (j + 2) / k); 27 | 28 | return 0; 29 | } 30 | 31 | /* Answer: 32 | * (a) 1, 2 33 | * (b) 0 34 | * (c) 1 35 | * (d) 0 36 | */ 37 | --------------------------------------------------------------------------------