├── .gitignore ├── README.md ├── ch03 ├── README.md ├── exercise1.c ├── exercise2.c ├── exercise3.c ├── exercise4.c ├── exercise5.c ├── exercise6.c ├── exercise7.c └── exercise8.c ├── ch04 ├── README.md ├── exercise1.c ├── exercise2.c ├── exercise3.c ├── exercise4.c ├── exercise5.c ├── exercise6.c ├── exercise7.c └── exercise8.c ├── ch05 ├── README.md ├── exercise1.c ├── exercise2.c ├── exercise3.c ├── exercise4.c ├── exercise5.c ├── exercise6.c ├── exercise7.c ├── exercise8.c └── exercise9.c ├── ch06 ├── README.md ├── exercise01.c ├── exercise02.c ├── exercise03.c ├── exercise04.c ├── exercise05.c ├── exercise06.c ├── exercise07.c ├── exercise08.c ├── exercise09.c ├── exercise10.c ├── exercise11.c ├── exercise12.c ├── exercise13.c ├── exercise14.c ├── exercise15.c ├── exercise16.c ├── exercise17.c └── exercise18.c ├── ch07 ├── README.md ├── exercise01.c ├── exercise02.c ├── exercise03.c ├── exercise04.c ├── exercise05.c ├── exercise06.c ├── exercise07.c ├── exercise08.c ├── exercise09.c ├── exercise10.c └── exercise11.c ├── ch08 ├── README.md ├── exercise01.c ├── exercise02.c ├── exercise03.c ├── exercise04.c ├── exercise05.c ├── exercise06.c ├── exercise07.c └── exercise08.c ├── ch09 ├── exercise01.c ├── exercise02.c ├── exercise03.c ├── exercise04.c ├── exercise05.c ├── exercise06.c ├── exercise07.c ├── exercise08.c ├── exercise09.c ├── exercise10.c └── exercise11.c ├── ch10 ├── exercise01.c ├── exercise02.c ├── exercise03.c ├── exercise04.c ├── exercise05.c ├── exercise06.c ├── exercise07.c ├── exercise08.c ├── exercise09.c ├── exercise10.c ├── exercise11.c ├── exercise12.c ├── exercise13.c └── exercise14.c ├── ch11 ├── exercise01.c ├── exercise02.c ├── exercise03.c ├── exercise04.c ├── exercise05.c ├── exercise06.c ├── exercise07.c ├── exercise08.c ├── exercise09.c ├── exercise10.c ├── exercise11.c ├── exercise12.c ├── exercise13.c ├── exercise14.c ├── exercise15.c └── exercise16.c ├── ch12 ├── exercise01.c ├── exercise02-b.c ├── exercise02.c ├── exercise02.h ├── exercise03-b.c ├── exercise03.c ├── exercise03.h ├── exercise04.c ├── exercise05.c ├── exercise06.c ├── exercise07-b.c ├── exercise07.c ├── exercise07.h ├── exercise08.c └── exercise09.c ├── ch13 ├── data.txt ├── exercise01.c ├── exercise02.c ├── exercise03.c ├── exercise04.c ├── exercise05.c ├── exercise06.c ├── exercise07-mod.c ├── exercise07.c ├── exercise08.c ├── exercise09.c ├── exercise10.c ├── exercise11.c ├── exercise12.c ├── exercise13.c └── exercise14.c ├── ch14 ├── exercise01.c ├── exercise02.c ├── exercise03.c ├── exercise04.c ├── exercise05.c ├── exercise06.c ├── exercise07.c ├── exercise08.c ├── exercise09.c ├── exercise10.c ├── exercise11.c └── roster.txt ├── ch15 ├── exercise01.c ├── exercise02.c ├── exercise03.c ├── exercise04.c ├── exercise05.c ├── exercise06.c └── exercise07.c ├── ch16 ├── coordinates.c ├── coordinates.h ├── exercise01.h ├── exercise02.c ├── exercise03.c ├── exercise04.c ├── exercise05.c ├── exercise06.c └── exercise07.c └── ch17 ├── binary_search.c ├── binary_search.h ├── exercise01.c ├── exercise02.c ├── exercise03.c ├── exercise04.c ├── exercise05.c ├── exercise06.c ├── exercise07.c ├── exercise08.c ├── film.c ├── film.h ├── list.c ├── list.h ├── list2.c ├── list2.h ├── pettree.c ├── pettree.h ├── queue.c ├── queue.h ├── stack.c ├── stack.h ├── tree.c └── tree.h /.gitignore: -------------------------------------------------------------------------------- 1 | *.out 2 | *.o 3 | *.so 4 | *.gch -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | C Primer Plus 2 | ============= 3 | 4 | Solutions to exercises from the book [C Primer Plus](http://www.amazon.com/Primer-Plus-6th-Developers-Library/dp/0321928423/ref=sr_1_1?ie=UTF8&qid=1444160774&sr=8-1&keywords=c+primer+plus) by Stephen Prata. 5 | 6 | #### Sections 7 | 8 | - [Chapter 3: Data and C](ch03/) 9 | - [Chapter 4: Character Strings and Formatted Input/Output](ch04/) 10 | - [Chapter 5: Operators, Expressions and Statements](ch05/) 11 | - [Chapter 6: C Control Statements: Looping](ch06/) 12 | - [Chapter 7: C Control Statements: Branching and Jumps](ch07/) 13 | - [Chapter 8: Character Input/Output and Input Validation](ch08/) 14 | - [Chapter 9: Functions](ch09/) 15 | - [Chapter 10: Arrays and Pointers](ch10/) 16 | - [Chapter 11: Character Strings and String Functions](ch11/) 17 | - [Chapter 12: Storage Classes, Linkage and Memory Management](ch12/) 18 | - [Chapter 13: File Input/Output](ch13/) 19 | - [Chapter 14: Structures and Other Data Forms](ch14/) 20 | - [Chapter 15: Bit Fiddling](ch15/) 21 | - [Chapter 16: The C Preprocessor and C Library](ch16/) 22 | - [Chapter 17: Advanced Data Representation](ch17/) -------------------------------------------------------------------------------- /ch03/README.md: -------------------------------------------------------------------------------- 1 | Chapter 3: Data and C 2 | ====================== 3 | 4 | Introduction to basic C data types. -------------------------------------------------------------------------------- /ch03/exercise1.c: -------------------------------------------------------------------------------- 1 | /* Exercise 1 2 | 3 | Find out what your system does with integer overflow, floating-point overflow, 4 | and floating point underflow by using the experimental approach; that is, 5 | write programs that have these problems. 6 | 7 | */ 8 | #include 9 | #include 10 | #include 11 | 12 | int main(void) 13 | { 14 | int int_overflow; 15 | int MAX_INTEGER = INT_MAX; 16 | float flt_overflow, flt_underflow; 17 | float MIN_FLOAT = FLT_MIN; 18 | float MAX_FLOAT = FLT_MAX; 19 | 20 | // artificially create over/underflow 21 | int_overflow = INT_MAX + 1; 22 | flt_overflow = FLT_MAX * 2.; 23 | flt_underflow = FLT_MIN / 2.; 24 | 25 | // print results 26 | printf("Max integer: %d \tMax integer + 1: %d\n", INT_MAX, int_overflow); 27 | printf("Max float: %f \tMax float * 2: %f\n", FLT_MAX, flt_overflow); 28 | printf("Min float: %f \tMin float / 2: %f\n", FLT_MIN, flt_underflow); 29 | 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /ch03/exercise2.c: -------------------------------------------------------------------------------- 1 | /* C Primer Plus 2 | 3 | Chapter 3 Exercise 2: 4 | 5 | Write a program that asks you to enter an ASCII code value, such as 66, and 6 | then prints the character having that ASCII code. */ 7 | 8 | 9 | #include 10 | int main(void) 11 | { 12 | int ascii_code; 13 | printf("Enter an ASCII code: "); 14 | scanf("%d", &ascii_code); 15 | printf("Character for ASCII code %d: %c\n", ascii_code, ascii_code); 16 | 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /ch03/exercise3.c: -------------------------------------------------------------------------------- 1 | /* C Primer Plus 2 | 3 | Chapter 3 Exercise 3: 4 | 5 | Write a program that sounds an alert and then prints the following text: Startled by the sudden sound, Sally shouted, 6 | "By the Great Pumpkin, what was that!" */ 7 | 8 | #include 9 | int main(void) 10 | 11 | { 12 | printf("\a"); // sound alert 13 | printf("Startled by the sudden sound, Sally shouted, \"By the Great Pumpkin, what was that!\"\n"); 14 | 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /ch03/exercise4.c: -------------------------------------------------------------------------------- 1 | /* C Primer Plus 2 | 3 | Chapter 3 Exercise 4: 4 | 5 | Write a program that reads in a floating-point number and prints it first in decimal-point notation, 6 | then in exponential notation, and then, if your system supports it, p notation. Have the output use 7 | the following format (the actual number of digits displayed for the exponent depends on the system): 8 | 9 | Enter a floating-point value: 64.25 10 | fixed-point notation: 64.250000 11 | exponential notation: 6.425000e+01 12 | p notation: 0x1.01p+6 */ 13 | 14 | #include 15 | int main(void) 16 | { 17 | float flt_input; 18 | 19 | printf("Enter a floating-point value: "); 20 | scanf("%f", &flt_input); 21 | printf("Fixed-point notation: %f\n", flt_input); 22 | printf("Exponential notation: %e\n", flt_input); 23 | printf("P notation: %a\n", flt_input); 24 | 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /ch03/exercise5.c: -------------------------------------------------------------------------------- 1 | /* C Primer Plus 2 | 3 | Chapter 3 Exercise 5 4 | 5 | There are approximately 3.156 × 10^7 seconds in a year. Write a program that requests 6 | your age in years and then displays the equivalent number of seconds. */ 7 | 8 | #include 9 | 10 | int main(void) 11 | { 12 | unsigned int SECONDS_PER_YEAR = 31560000; 13 | unsigned int age; 14 | 15 | printf("What is your age (in years)?: "); 16 | scanf("%u", &age); 17 | printf("You are %u seconds old!\n", SECONDS_PER_YEAR * age); 18 | 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /ch03/exercise6.c: -------------------------------------------------------------------------------- 1 | /* C Primer Plus 2 | 3 | Chapter 3 Exercise 6: 4 | 5 | The mass of a single molecule of water is about 3.0×10^-23 grams. A quart of 6 | water is about 950 grams. Write a program that requests an amount of water, 7 | in quarts, and displays the number of water molecules in that amount. */ 8 | 9 | #include 10 | 11 | int main(void) 12 | { 13 | float H20_MASS = 3.0e-23; 14 | float GRAMS_H20_PER_QUART = 950.; 15 | float quarts; 16 | 17 | printf("Enter an amount of water (in quarts): "); 18 | scanf("%f", &quarts); 19 | printf("There are %f molecules in %f quarts of water.\n", quarts * GRAMS_H20_PER_QUART / H20_MASS, quarts); 20 | 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /ch03/exercise7.c: -------------------------------------------------------------------------------- 1 | /* C Primer Plus 2 | 3 | Chapter3 Exercise 7: 4 | 5 | There are 2.54 centimeters to the inch. Write a program that asks you to enter 6 | your height in inches and then displays your height in centimeters. Or, if you 7 | prefer, ask for the height in centimeters and convert that to inches. */ 8 | 9 | #include 10 | 11 | int main(void) 12 | { 13 | float CM_PER_INCH = 2.54; 14 | float height; 15 | 16 | printf("Enter your height (in inches): "); 17 | scanf("%f", &height); 18 | printf("You are %f centimeters tall.\n", height * CM_PER_INCH); 19 | 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /ch03/exercise8.c: -------------------------------------------------------------------------------- 1 | /* C Primer Plus 2 | 3 | Chapter 3 Exercise 8: 4 | 5 | In the U.S. system of volume measurements, a pint is 2 cups, a cup is 8 ounces, 6 | an ounce is 2 tablespoons, and a tablespoon is 3 teaspoons. Write a program 7 | that requests a volume in cups and that displays the equivalent volumes in 8 | pints, ounces, tablespoons, and teaspoons. Why does a floating-point type make 9 | more sense for this application than an integer type? */ 10 | 11 | #include 12 | 13 | int main(void) 14 | { 15 | 16 | /* If the number of cups is not an even whole number, then the number of 17 | pints will not be a whole number. */ 18 | float PINTS_PER_CUP = .5; 19 | float OUNCES_PER_CUP = 8; 20 | float TBS_PER_CUP = 2 * OUNCES_PER_CUP; // tablespoons/ounce * ounces/cup 21 | float TSP_PER_CUP = 3 * TBS_PER_CUP; // teaspoons/tablespoon * tablespoons/ounce * ounces/cup 22 | float cups; 23 | 24 | printf("Enter an amount in cups:"); 25 | scanf("%f", &cups); 26 | printf("%f cups is equivalent to:\n", cups); 27 | printf("%f pints\n", cups * PINTS_PER_CUP); 28 | printf("%f ounces\n", cups * OUNCES_PER_CUP); 29 | printf("%f tablespoons\n", cups * TBS_PER_CUP); 30 | printf("%f teaspoons\n", cups * TSP_PER_CUP); 31 | 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /ch04/README.md: -------------------------------------------------------------------------------- 1 | Chapter 4: Character Strings and Formatted Output 2 | ============ 3 | -------------------------------------------------------------------------------- /ch04/exercise1.c: -------------------------------------------------------------------------------- 1 | /* C Primer Plus 2 | 3 | Chapter 4 Exercise 1: 4 | 5 | Write a program that asks for your first name, your last name, and then prints the names 6 | in the format last, first. */ 7 | 8 | #include 9 | 10 | int main(void) 11 | { 12 | char first_name[20]; 13 | char last_name[20]; 14 | 15 | printf("Enter your first and last name (e.g.: John Doe): "); 16 | scanf("%s %s", first_name, last_name); 17 | printf("%s, %s\n", last_name, first_name); 18 | 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /ch04/exercise2.c: -------------------------------------------------------------------------------- 1 | /* C Primer Plus 2 | 3 | Chapter 4 Exercise 2: 4 | 5 | Write a program that requests your first name and does the following with it: 6 | a. Prints it enclosed in double quotation marks 7 | b. Prints it in a field 20 characters wide, with the whole field in quotes and the name at the right end of the field 8 | c. Prints it at the left end of a field 20 characters wide, with the whole field enclosed in quotes 9 | d. Prints it in a field three characters wider than the name */ 10 | 11 | #include 12 | #include 13 | 14 | int main(void) 15 | { 16 | char name[20]; 17 | int name_length; 18 | 19 | printf("Enter your first name: "); 20 | scanf("%s", name); 21 | name_length = strlen(name); 22 | printf("\"%s\"\n", name); // a. enclosed in double quotes 23 | printf("\"%20s\"\n", name); // b. double quotes, 20 char wide, right-justified 24 | printf("\"%-20s\"\n", name); // c. double quotes, 20 char wide, left-justified 25 | printf("\"%*s\"\n", name_length + 3, name); // d. double quotes, 3 char wider than name 26 | 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /ch04/exercise3.c: -------------------------------------------------------------------------------- 1 | /* C Primer Plus 2 | 3 | Chapter 4 Exercise 3: 4 | 5 | Write a program that reads in a floating-point number and prints it first in 6 | decimal-point notation and then in exponential notation. Have the output use 7 | the following formats (the number of digits shown in the exponent may be 8 | different for your system): 9 | 10 | a. The input is 21.3 or 2.1e+001. 11 | b. The input is +21.290 or 2.129E+001. */ 12 | 13 | #include 14 | 15 | int main(void) 16 | { 17 | float num; 18 | 19 | printf("Enter a number: "); 20 | scanf("%f", &num); 21 | printf("The input is %.1f or %.1e\n", num, num); 22 | printf("The input is %+.3f or %.3E\n", num, num); 23 | 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /ch04/exercise4.c: -------------------------------------------------------------------------------- 1 | /* C Primer Plus 2 | 3 | Chapter 4 Exercise 4: 4 | 5 | Write a program that requests your height in inches and your name, and then 6 | displays the information in the following form: 7 | 8 | Dabney, you are 6.208 feet tall 9 | 10 | Use type float, and use / for division. If you prefer, request the height in 11 | centimeters and display it in meters. */ 12 | 13 | #include 14 | 15 | int main(void) 16 | { 17 | const float INCHES_PER_FEET = 12; 18 | float height; 19 | char name[40]; 20 | 21 | printf("What is your name?: "); 22 | scanf("%s", name); 23 | printf("What is your height in inches?: "); 24 | scanf("%f", &height); 25 | printf("%s, you are %.3f feet tall.\n", name, height / INCHES_PER_FEET); 26 | 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /ch04/exercise5.c: -------------------------------------------------------------------------------- 1 | /* C Primer Plus 2 | 3 | Chapter 4 Exercise 5: 4 | 5 | Write a program that requests the download speed in megabits per second (Mbs) 6 | and the size of a file in megabytes (MB). The program should calculate the 7 | download time for the file. Note that in this context one byte is eight bits. 8 | Use type float, and use / for division. The program should report all three 9 | values (download speed, file size, and download time) showing two digits to the 10 | right of the decimal point, as in the following: 11 | 12 | > At 18.12 megabits per second, a file of 2.20 megabytes downloads in 0.97 seconds. */ 13 | 14 | #include 15 | 16 | int main(void) 17 | { 18 | const float BITS_PER_BYTE = 8; 19 | float download_speed_Mps; 20 | float file_size_MB; 21 | 22 | printf("Enter the download speed (in megabits/second): "); 23 | scanf("%f", &download_speed_Mps); 24 | printf("Enter the file size (in megabytes): "); 25 | scanf("%f", &file_size_MB); 26 | printf("At %.2f megabits per second, a file of %.2f megabytes" 27 | " downloads in %.2f seconds.\n", download_speed_Mps, file_size_MB, 28 | file_size_MB * BITS_PER_BYTE / download_speed_Mps); 29 | 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /ch04/exercise6.c: -------------------------------------------------------------------------------- 1 | /* C Primer Plus 2 | 3 | Chapter 4 Exercise 6: 4 | 5 | Write a program that requests the user’s first name and then the user’s last 6 | name. Have it print the entered names on one line and the number of letters in 7 | each name on the following line. Align each letter count with the end of the 8 | corresponding name, as in the following: 9 | 10 | Melissa Honeybee 11 | 7 8 12 | 13 | Next, have it print the same information, but with the counts aligned with the 14 | beginning of each name. 15 | 16 | Melissa Honeybee 17 | 7 8 18 | 19 | */ 20 | 21 | #include 22 | #include 23 | 24 | int main(void) 25 | { 26 | char first_name[20]; 27 | char last_name[20]; 28 | 29 | printf("Enter your first and last name: "); 30 | scanf("%s %s", first_name, last_name); 31 | printf("\n"); 32 | printf("%s %s\n", first_name, last_name); 33 | printf("%*lu %*lu\n", // right justified 34 | (int) strlen(first_name), strlen(first_name), 35 | (int) strlen(last_name), strlen(last_name)); 36 | printf("\n"); 37 | printf("%s %s\n", first_name, last_name); 38 | printf("%-*lu %-*lu\n", // left justified 39 | (int) strlen(first_name), strlen(first_name), 40 | (int) strlen(last_name), strlen(last_name)); 41 | printf("\n"); 42 | 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /ch04/exercise7.c: -------------------------------------------------------------------------------- 1 | /* C Primer Plus 2 | 3 | Chapter 4 Exercise 7: 4 | 5 | Write a program that sets a type double variable to 1.0/3.0 and a type float 6 | variable to 1.0/3.0. Display each result three times—once showing four digits 7 | to the right of the decimal, once showing 12 digits to the right of the decimal, 8 | and once showing 16 digits to the right of the decimal. Also have the program 9 | include float.h and display the values of FLT_DIG and DBL_DIG. Are the displayed 10 | values of 1.0/3.0 consistent with these values? */ 11 | 12 | #include 13 | #include 14 | 15 | int main(void) 16 | { 17 | double db_one_third = 1.0 / 3.0; 18 | float ft_one_third = 1.0 / 3.0; 19 | 20 | printf("Float Double \n"); 21 | printf("-------------------- --------------------\n"); 22 | printf("%-20.4f %-20.4f\n", ft_one_third, db_one_third); // show 4 digits 23 | printf("%-20.12f %-20.12f\n", ft_one_third, db_one_third); // show 12 digits 24 | printf("%-20.16f %-20.16f\n", ft_one_third, db_one_third); 25 | printf("\n"); 26 | printf("FLT_DIG: %d\n", FLT_DIG); 27 | printf("DBL_DIG: %d\n", DBL_DIG); 28 | 29 | /* results: both float and double are accurate to at least the amount of sig 30 | figs specified by FLT_DIG and DBL_DIG */ 31 | 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /ch04/exercise8.c: -------------------------------------------------------------------------------- 1 | /* C Primer Plus 2 | 3 | Chapter 4 Exercise 8: 4 | 5 | Write a program that asks the user to enter the number of miles traveled and 6 | the number of gallons of gasoline consumed. It should then calculate and 7 | display the miles-per-gallon value, showing one place to the right of the 8 | decimal. Next, using the fact that one gallon is about 3.785 liters and one 9 | mile is about 1.609 kilometers, it should convert the mile- per-gallon value 10 | to a liters-per-100-km value, the usual European way of expressing fuel 11 | consumption, and display the result, showing one place to the right of the 12 | decimal. Note that the U. S. scheme measures the distance traveled per amount 13 | of fuel (higher is better), whereas the European scheme measures the amount of 14 | fuel per distance (lower is better). Use symbolic constants (using const or 15 | #define) for the two conversion factors. */ 16 | 17 | #include 18 | 19 | int main(void) 20 | { 21 | const float KM_PER_MILE = 1.609; 22 | const float LT_PER_GALLON = 3.785; 23 | float miles_travelled, gallons_gas_consumed; 24 | float miles_per_gallon, liters_per_100km; 25 | 26 | printf("Enter your distance travelled in miles: "); 27 | scanf("%f", &miles_travelled); 28 | printf("Enter the amount of gas consumed in gallons: "); 29 | scanf("%f", &gallons_gas_consumed); 30 | 31 | // calculate miles per gallon and liters per km 32 | miles_per_gallon = miles_travelled / gallons_gas_consumed; 33 | liters_per_100km = 100. / miles_per_gallon * LT_PER_GALLON / KM_PER_MILE; 34 | 35 | printf("Miles per gallon: %.1f\n", miles_per_gallon); 36 | printf("Liters per 100 kilometers: %.1f\n", liters_per_100km); 37 | 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /ch05/README.md: -------------------------------------------------------------------------------- 1 | Chapter 5: Operators, Expressions and Statements 2 | ================================================ -------------------------------------------------------------------------------- /ch05/exercise1.c: -------------------------------------------------------------------------------- 1 | /* C Primer Plus 2 | 3 | Chapter 5 Exercise 1: 4 | 5 | Write a program that converts time in minutes to time in hours and minutes. Use 6 | #define or const to create a symbolic constant for 60. Use a while loop to 7 | allow the user to enter values repeatedly and terminate the loop if a value for 8 | the time of 0 or less is entered. */ 9 | 10 | #include 11 | 12 | const int MINUTES_PER_HOUR = 60; 13 | 14 | int main(void) 15 | { 16 | int minutes; 17 | 18 | printf("Enter an amount of time in minutes: "); // get first input 19 | scanf("%d", &minutes); 20 | 21 | while (minutes > 0) 22 | { 23 | printf("%d minute(s) is %d hour(s) and %d minute(s).\n", 24 | minutes, 25 | minutes / MINUTES_PER_HOUR, // hours 26 | minutes % MINUTES_PER_HOUR); // minutes 27 | 28 | printf("Enter an amount of time in minutes: "); // get new input 29 | scanf("%d", &minutes); 30 | } 31 | 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /ch05/exercise2.c: -------------------------------------------------------------------------------- 1 | /* C Primer Plus 2 | 3 | Chapter 5 Exercise 2: 4 | 5 | Write a program that asks for an integer and then prints all the integers from 6 | (and including) that value up to (and including) a value larger by 10. (That 7 | is, if the input is 5, the output runs from 5 to 15.) Be sure to separate each 8 | output value by a space or tab or newline. */ 9 | 10 | #include 11 | 12 | int main(void) 13 | { 14 | int input; 15 | int i = 0; 16 | 17 | printf("Enter an integer: "); 18 | scanf("%d", &input); 19 | while (i <= 10) 20 | { 21 | printf("%d\n", input + i); 22 | i++; 23 | } 24 | 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /ch05/exercise3.c: -------------------------------------------------------------------------------- 1 | /* C Primer Plus 2 | 3 | Chapter 5 Exercise 3: 4 | 5 | Write a program that asks the user to enter the number of days and then converts 6 | that value to weeks and days. For example, it would convert 18 days to 2 weeks, 7 | 4 days. Display results in the following format: 8 | 9 | 18 days are 2 weeks, 4 days. 10 | 11 | Use a while loop to allow the user to repeatedly enter day values; terminate the 12 | loop when the user enters a nonpositive value, such as 0 or -20. */ 13 | 14 | #include 15 | 16 | const int DAYS_PER_WEEK = 7; 17 | 18 | int main(void) 19 | { 20 | int days; 21 | 22 | printf("Enter a number of days (or enter 0 to quit): "); 23 | scanf("%d", &days); 24 | while (days > 0) 25 | { 26 | printf("%d days are %d weeks, %d days.\n", days, days / DAYS_PER_WEEK, 27 | days % DAYS_PER_WEEK); 28 | 29 | printf("Enter a number of days (or enter 0 to quit): "); 30 | scanf("%d", &days); 31 | } 32 | 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /ch05/exercise4.c: -------------------------------------------------------------------------------- 1 | /* C Primer Plus 2 | 3 | Chapter 5 Exercise 4: 4 | 5 | Write a program that asks the user to enter a height in centimeters and then 6 | displays the height in centimeters and in feet and inches. Fractional 7 | centimeters and inches should be allowed, and the program should allow the 8 | user to continue entering heights until a nonpositive value is entered. A 9 | sample run should look like this: 10 | 11 | Enter a height in centimeters: 182 12 | 182.0 cm = 5 feet, 11.7 inches 13 | Enter a height in centimeters (<=0 to quit): 168.7 14 | 168.0 cm = 5 feet, 6.4 inches 15 | Enter a height in centimeters (<=0 to quit): 0 16 | bye 17 | */ 18 | 19 | #include 20 | 21 | const float CM_PER_IN = 2.54; 22 | const int IN_PER_FT = 12; 23 | 24 | int main(void) 25 | { 26 | float height_cm, height_in, inches; 27 | int feet; 28 | 29 | printf("Enter a height in centimeters: "); 30 | scanf("%f", &height_cm); 31 | 32 | while (height_cm > 0) 33 | { 34 | height_in = height_cm / CM_PER_IN; // convert height to inches 35 | feet = (int) height_in / IN_PER_FT; // get number of feet in height 36 | inches = height_in - feet * IN_PER_FT; // get remaining inches 37 | 38 | printf("%.1f cm = %d feet, %.1f inches\n", 39 | height_cm, feet, inches); 40 | 41 | printf("Enter a height in centimeters (<= 0 to quit): "); 42 | scanf("%f", &height_cm); 43 | } 44 | 45 | printf("bye\n"); 46 | return 0; 47 | } 48 | -------------------------------------------------------------------------------- /ch05/exercise5.c: -------------------------------------------------------------------------------- 1 | /* C Primer Plus 2 | 3 | Chapter 5 Exercise 5: 4 | 5 | Change the program addemup.c (Listing 5.13), which found the sum of the first 20 6 | integers. (If you prefer, you can think of addemup.c as a program that calculates 7 | how much money you get in 20 days if you receive $1 the first day, $2 the second 8 | day, $3 the third day, and so on.) Modify the program so that you can tell it 9 | interactively how far the calculation should proceed. That is, replace the 20 with 10 | a variable that is read in. */ 11 | 12 | #include 13 | 14 | int main(void) 15 | { 16 | int count, sum, max_count; 17 | sum = 0; 18 | count = 1; 19 | 20 | printf("How many integers would you like to sum? "); 21 | scanf("%d", &max_count); 22 | while (count <= max_count) 23 | { 24 | sum = sum + count; 25 | count++; 26 | } 27 | printf("sum = %d\n", sum); 28 | 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /ch05/exercise6.c: -------------------------------------------------------------------------------- 1 | /* C Primer Plus 2 | 3 | Chapter 5 Exercise 6: 4 | 5 | Now modify the program of Programming Exercise 5 so that it computes the sum of 6 | the squares of the integers. (If you prefer, how much money you receive if you 7 | get $1 the first day, $4 the second day, $9 the third day, and so on. This looks 8 | like a much better deal!) C doesn’t have a squaring function, but you can use the 9 | fact that the square of n is n * n. */ 10 | 11 | #include 12 | 13 | int main(void) 14 | { 15 | int sum, count, max_count; 16 | sum = 0; 17 | count = 1; 18 | 19 | printf("How many squares would you like to sum? "); 20 | scanf("%d", &max_count); 21 | while (count <= max_count) 22 | { 23 | sum = sum + count * count; 24 | count++; 25 | } 26 | printf("The sum of the first %d squares is: %d\n", max_count, sum); 27 | 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /ch05/exercise7.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | 3 | // Chapter 5 Exercise 7: 4 | 5 | // Write a program that requests a type double number and prints the value of the 6 | // number cubed. Use a function of your own design to cube the value and print it. 7 | // The main() program should pass the entered value to this function. 8 | 9 | #include 10 | 11 | double cubed(double n); // prototype declaration for cubed 12 | 13 | int main(void) 14 | { 15 | double input; 16 | printf("Enter a number to cube: "); 17 | scanf("%lf", &input); 18 | 19 | printf("%.3f cubed is %.3f\n", input, cubed(input)); 20 | 21 | return 0; 22 | } 23 | 24 | double cubed(double n) 25 | { 26 | return n * n * n; 27 | } 28 | -------------------------------------------------------------------------------- /ch05/exercise8.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | 3 | // Chapter 5 Exercise 8: 4 | 5 | // Write a program that displays the results of applying the modulus operation. The 6 | // user should first enter an integer to be used as the second operand, which will 7 | // then remain unchanged. Then the user enters the numbers for which the modulus 8 | // will be computed, terminating the process by entering 0 or less. A sample run 9 | // should look like this: 10 | 11 | // > This program computes moduli. 12 | // > Enter an integer to serve as the second operand: 256 13 | // > Now enter the first operand: 438 14 | // > 438 % 256 is 182 15 | // > Enter next number for first operand (<= 0 to quit): 1234567 16 | // > 1234567 % 256 is 135 17 | // > Enter next number for first operand (<= 0 to quit): 0 18 | // > Done 19 | 20 | #include 21 | 22 | int main(void) 23 | { 24 | int first, second; 25 | printf("This program computes moduli.\n"); 26 | printf("Enter an integer to serve as the second operand: "); 27 | scanf("%d", &second); 28 | printf("Now enter the first operand: "); 29 | scanf("%d", &first); 30 | while (first > 0) 31 | { 32 | printf("%d %% %d is %d\n", first, second, first % second); //print results 33 | 34 | printf("Enter next number for first operand (<= 0 to quit): "); 35 | scanf("%d", &first); // get new input 36 | } 37 | 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /ch05/exercise9.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | 3 | // Chapter 5 Exercise 9: 4 | 5 | // Write a program that requests the user to enter a Fahrenheit temperature. The 6 | // program should read the temperature as a type double number and pass it as an 7 | // argument to a user-supplied function called Temperatures(). This function should 8 | // calculate the Celsius equivalent and the Kelvin equivalent and display all three 9 | // temperatures with a precision of two places to the right of the decimal. It 10 | // should identify each value with the temperature scale it represents. Here is the 11 | // formula for converting Fahrenheit to Celsius: 12 | // Celsius = 5.0 / 9.0 * (Fahrenheit - 32.0) 13 | // The Kelvin scale, commonly used in science, is a scale in which 0 represents 14 | // absolute zero, the lower limit to possible temperatures. Here is the formula for 15 | // converting Celsius to Kelvin: 16 | // Kelvin = Celsius + 273.16 17 | // The Temperatures() function should use const to create symbolic representations 18 | // of the three constants that appear in the conversions. The main() function 19 | // should use a loop to allow the user to enter temperatures repeatedly, stopping 20 | // when a q or other nonnumeric value is entered. Use the fact that scanf() returns 21 | // the number of items read, so it will return 1 if it reads a number, but it won’t 22 | // return 1 if the user enters q. The == operator tests for equality, so you can 23 | // use it to compare the return value of scanf() with 1. 24 | 25 | #include 26 | 27 | void Temperatures(double fahr); // prototype declaration of Temperatures 28 | 29 | int main(void) 30 | { 31 | double fahr; 32 | printf("This program converts fahrenheit to celsius and kelvin.\n"); 33 | printf("Enter a temperature in degrees fahrenheit (q to quit): "); 34 | while (scanf("%lf", &fahr) == 1) // continue executing loop if user enters valid number 35 | { 36 | Temperatures(fahr); // convert fahr to celsius and kelvin 37 | 38 | // prompt for new input 39 | printf("Enter a temperature in degrees fahrenheit (q to quit): "); 40 | } 41 | 42 | printf("bye\n"); 43 | } 44 | 45 | void Temperatures(double fahr) 46 | { 47 | const double FAHR_TO_CEL_SCALE = 5.0 / 9.0; 48 | const double FAHR_TO_CEL_OFFSET = -32.0; 49 | const double CEL_TO_KEL_OFFSET = 273.16; 50 | 51 | double celsius = (fahr + FAHR_TO_CEL_OFFSET) * FAHR_TO_CEL_SCALE; 52 | double kelvin = celsius + CEL_TO_KEL_OFFSET; 53 | 54 | printf("%.2f degrees fahrenheit is %.2f degrees celsius or %.2f degrees kelvin.\n", 55 | fahr, celsius, kelvin); 56 | } 57 | -------------------------------------------------------------------------------- /ch06/README.md: -------------------------------------------------------------------------------- 1 | C Control Statements: Looping 2 | ============================= -------------------------------------------------------------------------------- /ch06/exercise01.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | 3 | // Chapter 6 Exercise 1: 4 | 5 | // Write a program that creates an array with 26 elements and stores the 26 lowercase 6 | // letters in it. Also have it show the array contents. 7 | 8 | #include 9 | #define ALPHABET_LENGTH 26 10 | 11 | int main(void) 12 | { 13 | char alphabet_lowercase[ALPHABET_LENGTH]; 14 | char letter; 15 | int i; 16 | 17 | // initialize array 18 | for (letter = 'a'; letter - 'a' < ALPHABET_LENGTH; letter++) 19 | { 20 | alphabet_lowercase[letter - 'a'] = letter; // store letter in array 21 | } 22 | 23 | printf("The lowercase letters of the alphabet are:\n"); 24 | // print each item in array 25 | for (i = 0; i < ALPHABET_LENGTH; i++) 26 | { 27 | printf("%c ", alphabet_lowercase[i]); 28 | } 29 | printf("\n"); 30 | 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /ch06/exercise02.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | 3 | // Chapter 6 Exercise 2: 4 | 5 | // Use nested loops to produce the following pattern: 6 | // $ 7 | // $$ 8 | // $$$ 9 | // $$$$ 10 | // $$$$$ 11 | 12 | #include 13 | 14 | int main(void) 15 | { 16 | for (int i = 1; i < 6; i++) 17 | { 18 | for (int j = 1; j <= i; j++) 19 | { 20 | printf("$"); 21 | } 22 | printf("\n"); 23 | } 24 | 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /ch06/exercise03.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | 3 | // Chapter 6 Exercise 3: 4 | 5 | // Use nested loops to produce the following pattern: 6 | // F 7 | // FE 8 | // FED 9 | // FEDC 10 | // FEDCB 11 | // FEDCBA 12 | 13 | #include 14 | 15 | int main(void) 16 | { 17 | for (int i = 1; i < 7; i++) 18 | { 19 | for (char c = 'F'; 'F' - c < i; c--) 20 | { 21 | printf("%c", c); 22 | } 23 | printf("\n"); 24 | } 25 | 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /ch06/exercise04.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | 3 | // Chapter 6 Exercise 4: 4 | 5 | // Use nested loops to produce the following pattern: 6 | // A 7 | // BC 8 | // DEF 9 | // GHIJ 10 | // KLMNO 11 | // PQRSTU 12 | 13 | #include 14 | 15 | int main(void) 16 | { 17 | char c = 'A'; 18 | 19 | for (int i = 1; i < 7; i++) 20 | { 21 | for(int j = 1; j <= i; j++) 22 | { 23 | printf("%c", c++); // print and THEN increment c 24 | } 25 | printf("\n"); 26 | } 27 | 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /ch06/exercise05.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 6 Exercise 5: 3 | 4 | // Have a program request the user to enter an uppercase letter. Use nested loops 5 | // to produce a pyramid pattern like this: 6 | // A 7 | // ABA 8 | // ABCBA 9 | // ABCDCBA 10 | // ABCDEDCBA 11 | // The pattern should extend to the character entered. For example, the preceding 12 | // pattern would result from an input value of E. 13 | 14 | #include 15 | 16 | void print_spaces(unsigned int n); 17 | 18 | int main(void) 19 | { 20 | char uppercase_letter; 21 | char c1, c2; 22 | 23 | do // get uppercase letter from user 24 | { 25 | printf("Enter an uppercase letter: "); 26 | scanf(" %c", &uppercase_letter); 27 | } while (uppercase_letter < 'A' || 'Z' < uppercase_letter); 28 | 29 | for(c1 = 'A'; c1 <= uppercase_letter; c1++) 30 | { 31 | // print opening spaces 32 | print_spaces(uppercase_letter - c1); 33 | 34 | // print letters 35 | // ascending 36 | for (c2 = 'A'; c2 < c1; c2++) 37 | { 38 | printf("%c", c2); 39 | 40 | } 41 | // descending 42 | for (; 'A' <= c2; c2--) 43 | { 44 | printf("%c", c2); 45 | } 46 | 47 | // print closing spaces 48 | print_spaces(uppercase_letter - c1); 49 | printf("\n"); 50 | } 51 | 52 | return 0; 53 | } 54 | 55 | void print_spaces(unsigned int n) 56 | { 57 | for (int i = 0; i < n; i++) 58 | { 59 | printf(" "); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /ch06/exercise06.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 6 Exercise 6: 3 | // Write a program that prints a table with each line giving an integer, its 4 | // square, and its cube. Ask the user to input the lower and upper limits for the 5 | // table. Use a for loop. 6 | 7 | #include 8 | 9 | int main(void) 10 | { 11 | long upper = -1, lower=0; 12 | int reads; 13 | 14 | printf("This program prints a table of integers with their " 15 | "squares and cubes.\n"); 16 | do 17 | { 18 | printf("Enter lower and upper integer limits (in that order): "); 19 | reads = scanf("%ld%ld", &lower, &upper); 20 | if (reads != 2) 21 | { 22 | while (getchar() != '\n') ; // if read fails, clear input buffer 23 | } 24 | } while (lower > upper); // if lower is greater than upper, get new input 25 | 26 | printf("\n"); 27 | // table header 28 | printf(" Integer | Square | Cube \n"); 29 | printf("---------------|---------------|---------------\n"); 30 | for (long int i = lower; i <= upper; i++) 31 | { 32 | printf(" %-14ld| %-14ld| %-14ld\n", i, i * i, i * i * i); 33 | } 34 | printf("\n"); 35 | 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /ch06/exercise07.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 6 Exercise 7: 3 | // Write a program that reads a single word into a character array and then prints 4 | // the word backward. Hint: Use strlen() (Chapter 4) to compute the index of the 5 | // last character in the array. 6 | 7 | #include 8 | #include 9 | 10 | int main(void) 11 | { 12 | char word[30]; 13 | 14 | printf("Enter a string: "); 15 | scanf("%s", word); 16 | for (int i = strlen(word) - 1; i >= 0; i--) 17 | { 18 | printf("%c", word[i]); 19 | } 20 | printf("\n"); 21 | 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /ch06/exercise08.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 6 Exercise 8: 3 | 4 | // Write a program that requests two floating-point numbers and prints the value of 5 | // their difference divided by their product. Have the program loop through pairs 6 | // of input values until the user enters nonnumeric input. 7 | 8 | #include 9 | 10 | int main(void) 11 | { 12 | float num1, num2; 13 | int reads; 14 | 15 | printf("Enter two floating-point numbers: "); 16 | while (scanf(" %f %f", &num1, &num2) == 2) 17 | { 18 | printf("(%.3f - %.3f)/(%.3f * %.3f) = %.3f\n", num1, num2, num1, num2, 19 | (num1 - num2)/(num1 * num2)); 20 | printf("Enter two floating-point numbers (enter non-numeric to quit): "); 21 | } 22 | 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /ch06/exercise09.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 6 Exercise 9: 3 | 4 | // Modify exercise 8 so that it uses a function to return the value of the 5 | // calculation. 6 | 7 | #include 8 | 9 | float calculate(float n1, float n2); 10 | 11 | int main(void) 12 | { 13 | float num1, num2; 14 | int reads; 15 | 16 | printf("Enter two floating-point numbers: "); 17 | while (scanf(" %f %f", &num1, &num2) == 2) 18 | { 19 | printf("(%.3f - %.3f)/(%.3f * %.3f) = %.3f\n", num1, num2, num1, num2, 20 | calculate(num1, num2)); 21 | printf("Enter two floating-point numbers (enter non-numeric to quit): "); 22 | } 23 | 24 | return 0; 25 | } 26 | 27 | float calculate(float n1, float n2) 28 | { 29 | return (n1 - n2) / (n1 * n2); 30 | } 31 | -------------------------------------------------------------------------------- /ch06/exercise10.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 6 Exercise 10: 3 | 4 | // Write a program that requests lower and upper integer limits, calculates the 5 | // sum of all the integer squares from the square of the lower limit to the 6 | // square of the upper limit, and displays the answer. The program should then 7 | // continue to prompt for limits and display answers until the user enters an 8 | // upper limit that is equal to or less than the lower limit. A sample run should 9 | // look something like this: 10 | 11 | // Enter lower and upper integer limits: 5 9 12 | // The sums of the squares from 25 to 81 is 255 13 | // Enter next set of limits: 3 25 14 | // The sums of the squares from 9 to 625 is 5520 15 | // Enter next set of limits: 5 5 16 | // Done 17 | 18 | #include 19 | 20 | int sum_of_squares(int lower, int upper); 21 | 22 | int main(void) 23 | { 24 | int upper, lower, reads; 25 | 26 | printf("Enter lower and upper integer limits: "); 27 | while(reads = scanf("%d%d", &lower, &upper), reads == 2 && lower < upper) 28 | { 29 | printf("The sums of the squares from %d to %d is %d\n", 30 | lower * lower, upper * upper, sum_of_squares(lower, upper)); 31 | printf("Enter next set of limits: "); 32 | } 33 | printf("Done\n"); 34 | 35 | return 0; 36 | } 37 | 38 | int sum_of_squares(int lower, int upper) // calculate sum of squares from lower to upper 39 | { 40 | int sum = 0; 41 | 42 | for (int i = lower; i <= upper; i++) 43 | { 44 | sum += i * i; 45 | } 46 | 47 | return sum; 48 | } 49 | -------------------------------------------------------------------------------- /ch06/exercise11.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 6 Exercise 11: 3 | 4 | // Write a program that reads eight integers into an array and then prints them in 5 | // reverse order. 6 | 7 | #include 8 | 9 | int main(void) 10 | { 11 | int int_array[8]; 12 | int i; // array index 13 | 14 | printf("Enter 8 integers:\n"); 15 | for (i = 0; i < 8; i++) // read ints into array 16 | { 17 | scanf("%d", &int_array[i]); 18 | } 19 | for (i--; i >= 0; i--) // decrement i to 7 to initialize loop 20 | { 21 | printf("%d", int_array[i]); 22 | } 23 | printf("\n"); 24 | 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /ch06/exercise12.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 6 Exercise 12: 3 | 4 | // Consider these two infinite series: 5 | // 1.0 + 1.0/2.0 + 1.0/3.0 + 1.0/4.0 + ... 6 | // 1.0 - 1.0/2.0 + 1.0/3.0 - 1.0/4.0 + ... 7 | // Write a program that evaluates running totals of these two series up to some 8 | // limit of number of terms. Hint: –1 times itself an odd number of times is –1, 9 | // and –1 times itself an even number of times is 1. Have the user enter the limit 10 | // interactively; let a zero or negative value terminate input. Look at the running 11 | // totals after 100 terms, 1000 terms, 10,000 terms. Does either series appear to 12 | // be converging to some value? 13 | 14 | #include 15 | 16 | int main(void) 17 | { 18 | long int limit; 19 | float sign = 1.0f; 20 | float series1 = 0, series2 = 0; 21 | 22 | printf("Enter a number of terms to sum: "); 23 | scanf("%ld", &limit); 24 | 25 | for (long int i = 1; i <= limit; i++) 26 | { 27 | series1 += 1.0f/i; 28 | series2 += (1.0f/i) * sign; 29 | sign = -sign; // toggle sign 30 | } 31 | 32 | printf("The %ldth partial sum for series 1 is: %.5f\n", limit, series1); 33 | printf("The %ldth partial sum for series 2 is: %.5f\n", limit, series2); 34 | 35 | // Answer: Series 1 has no limit. Series 2 appears to be bounded above 36 | 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /ch06/exercise13.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 6 Exercise 13: 3 | 4 | // Write a program that creates an eight-element array of ints and sets the 5 | // elements to the first eight powers of 2 and then prints the values. Use a for 6 | // loop to set the values, and, for variety, use a do while loop to display the 7 | // values. 8 | 9 | #include 10 | 11 | int main(void) 12 | { 13 | int powers_of_2[8]; 14 | int power = 1; 15 | int i; 16 | 17 | for (int i = 0; i < 8; i++) 18 | { 19 | power *= 2; 20 | powers_of_2[i] = power; 21 | } 22 | printf("Powers of 2:\n"); 23 | i = 0; 24 | do { 25 | printf("%d ", powers_of_2[i]); 26 | i++; 27 | } while (i < 8); 28 | printf("\n"); 29 | 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /ch06/exercise14.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 6 Exercise 14: 3 | 4 | // Write a program that creates two eight-element arrays of doubles and uses a 5 | // loop to let the user enter values for the eight elements of the first array. 6 | // Have the program set the elements of the second array to the cumulative totals 7 | // of the elements of the first array. For example, the fourth element of the 8 | // second array should equal the sum of the first four elements of the first 9 | // array, and the fifth element of the second array should equal the sum of the 10 | // first five elements of the first array. (It’s possible to do this with nested 11 | // loops, but by using the fact that the fifth element of the second array equals 12 | // the fourth element of the second array plus the fifth element of the first 13 | // array, you can avoid nesting and just use a single loop for this task.) 14 | // Finally, use loops to display the contents of the two arrays, with the first 15 | // array displayed on one line and with each element of the second array displayed 16 | // below the corresponding element of the first array. 17 | 18 | #include 19 | 20 | int main(void) 21 | { 22 | int int_array[8], cumulative_sum[8]; 23 | int sum = 0; 24 | 25 | printf("Enter 8 integers:\n"); 26 | for (int i = 0; i < 8; i++) 27 | { 28 | scanf("%d", &int_array[i]); 29 | sum += int_array[i]; 30 | cumulative_sum[i] = sum; 31 | } 32 | printf("\n"); 33 | // display loops 34 | printf(" Integers:"); 35 | for (int i = 0; i < 8; i++) 36 | { 37 | printf("%6d ", int_array[i]); 38 | } 39 | printf("\n"); 40 | printf("Cumulative sum:"); 41 | for (int i = 0; i < 8; i++) 42 | { 43 | printf("%6d ", cumulative_sum[i]); 44 | } 45 | printf("\n"); 46 | 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /ch06/exercise15.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 6 Exercise 15: 3 | 4 | // Write a program that reads in a line of input and then prints the line in 5 | // reverse order. You can store the input in an array of char; assume that the 6 | // line is no longer than 255 characters. Recall that you can use scanf() with 7 | // the %c specifier to read a character at a time from input and that the newline 8 | // character (\n) is generated when you press the Enter key. 9 | 10 | #include 11 | 12 | int main(void) 13 | { 14 | char line[255]; 15 | int i = 0; // array index 16 | printf("Enter a line to reverse:\n"); 17 | while (scanf("%c", &line[i]), line[i] != '\n') 18 | i++; 19 | 20 | for (; 0 <= i; i--) // previous loop leaves i in right position 21 | printf("%c", line[i]); 22 | 23 | printf("\n"); 24 | 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /ch06/exercise16.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 6 Exercise 16: 3 | 4 | // Daphne invests $100 at 10% simple interest. (That is, every year, the 5 | // investment earns an interest equal to 10% of the original investment.) Deirdre 6 | // invests $100 at 5% interest compounded annually. (That is, interest is 5% of 7 | // the current balance, including previous addition of interest.) Write a program 8 | // that finds how many years it takes for the value of Deirdre’s investment to 9 | // exceed the value of Daphne’s investment. Also show the two values at that time. 10 | 11 | #include 12 | 13 | int main(void) 14 | { 15 | const float DEIRDE_PRINCIPLE = 100.0f; 16 | const float DAPHNE_PRINCIPLE = 100.0f; 17 | const float DEIRDE_INTEREST = 0.05f; 18 | const float DAPHNE_INTEREST = 0.10f; 19 | 20 | // initialize years and balances 21 | int years = 0; 22 | float daphne_balance = DAPHNE_PRINCIPLE; 23 | float deirdre_balance = DEIRDE_PRINCIPLE; 24 | 25 | while (deirdre_balance <= daphne_balance) 26 | { 27 | // eq. for compound interest 28 | deirdre_balance *= 1.0f + DEIRDE_INTEREST; 29 | // eq. for simple interest 30 | daphne_balance += DAPHNE_PRINCIPLE * DAPHNE_INTEREST; 31 | years++; 32 | } 33 | printf("After %d years, Daphne's investment is worth $%.2f and " 34 | "Deirdre’s investment is worth $%.2f.\n", years, 35 | daphne_balance, deirdre_balance); 36 | 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /ch06/exercise17.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 6 Exercise 17: 3 | 4 | // Chuckie Lucky won a million dollars (after taxes), which he places in an 5 | // account that earns 8% a year. On the last day of each year, Chuckie 6 | // withdraws $100,000. Write a program that finds out how many years it takes 7 | // for Chuckie to empty his account. 8 | 9 | #include 10 | 11 | int main(void) 12 | { 13 | const float WINNINGS = 1000000.0f; 14 | const float INTEREST = 0.08f; 15 | const float SPENDING = 100000.0f; 16 | 17 | int years = 0; 18 | float balance = WINNINGS; 19 | 20 | // the problem is not quite clear, but I'm assuming 21 | // Chuckie makes his first withdrawal before collecting 22 | // any interest 23 | while (balance > 0) 24 | { 25 | balance -= SPENDING; 26 | balance *= 1.0f + INTEREST; 27 | years++; 28 | } 29 | 30 | printf("After %d years, Chuckie is in the red with a balance of" 31 | " %.2f USD.\n", years, balance); 32 | 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /ch06/exercise18.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 6 Exercise 18: 3 | 4 | // Professor Rabnud joined a social media group. Initially he had five friends. 5 | // He noticed that his friend count grew in the following fashion. The first 6 | // week one friend dropped out and the remaining number of friends doubled. The 7 | // second week two friends dropped out and the remaining number of friends 8 | // doubled. In general, in the Nth week, N friends dropped out and the 9 | // remaining number doubled. Write a program that computes and displays the 10 | // number of friends each week. The program should continue until the count 11 | // exceeds Dunbar’s number. Dunbar’s number is a rough estimate of the maximum 12 | // size of a cohesive social group in which each member knows every other 13 | // member and how they relate to one another. Its approximate value is 150. 14 | 15 | #include 16 | 17 | int main(void) 18 | { 19 | const int DUNBARS_NUMBER = 150; 20 | 21 | int friends = 5, week = 0; 22 | 23 | printf("Week | Friends\n"); 24 | printf("-----+--------\n"); 25 | while (friends < DUNBARS_NUMBER) 26 | { 27 | printf("%4d | %7d\n", week, friends); 28 | week++; 29 | friends -= week; 30 | friends *= 2; 31 | } 32 | 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /ch07/README.md: -------------------------------------------------------------------------------- 1 | C Control Statements: Branching and Jumps 2 | ======================== 3 | -------------------------------------------------------------------------------- /ch07/exercise01.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 7 Exercise 1: 3 | 4 | // Write a program that reads input until encountering the # character and then 5 | // reports the number of spaces read, the number of newline characters read, 6 | // and the number of all other characters read. 7 | 8 | #include 9 | #define STOP '#' 10 | 11 | int main(void) 12 | { 13 | char ch; 14 | unsigned int spaces = 0, newlines = 0, other= 0; 15 | printf("Enter input (%c to stop):\n", STOP); 16 | while((ch = getchar()) != STOP) 17 | { 18 | if (ch == ' ') 19 | spaces++; 20 | else if (ch == '\n') 21 | newlines++; 22 | else 23 | other++; 24 | } 25 | printf("\n"); 26 | printf("Character Count:\n"); 27 | printf("----------------\n"); 28 | printf("Spaces: %u\n" 29 | "Newlines: %u\n" 30 | "Other: %u\n", spaces, newlines, other); 31 | 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /ch07/exercise02.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 7 Exercise 2: 3 | 4 | // Write a program that reads input until encountering #. Have the program 5 | // print each input character and its ASCII decimal code. Print eight 6 | // character-code pairs per line. Suggestion: Use a character count and the 7 | // modulus operator (%) to print a newline character for every eight cycles of 8 | // the loop. 9 | 10 | #include 11 | #define STOP '#' 12 | 13 | #define SPACE ' ' 14 | #define TAB '\t' 15 | #define NEWLINE '\n' 16 | #define BACKSPACE '\b' 17 | 18 | int main(void) 19 | { 20 | unsigned int count = 0; 21 | char ch; 22 | printf("ASCII Character Codes\n"); 23 | printf("Enter input (%c to stop):\n", STOP); 24 | while ((ch = getchar()) != STOP) 25 | { 26 | switch (ch) 27 | { 28 | case SPACE : 29 | printf("' ': %3d ", ch); 30 | break; 31 | case TAB : 32 | printf("'\\t': %3d ", ch); 33 | break; 34 | case NEWLINE : 35 | printf("'\\n': %3d ", ch); 36 | break; 37 | case BACKSPACE : 38 | printf("'\\b': %3d ", ch); 39 | break; 40 | default: 41 | printf(" %c : %3d ", ch, ch); 42 | } 43 | count++; 44 | if (count % 8 == 0) 45 | printf("\n"); 46 | } 47 | printf("\n"); 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /ch07/exercise03.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 7 Exercise 3: 3 | 4 | // Write a program that reads integers until 0 is entered. After input 5 | // terminates, the program should report the total number of even integers 6 | // (excluding the 0) entered, the average value of the even integers, the total 7 | // number of odd integers entered, and the average value of the odd integers. 8 | 9 | #include 10 | #include 11 | 12 | #define STOP 0 13 | 14 | int main(void) 15 | { 16 | int even_count = 0, even_sum = 0, odd_count = 0, odd_sum = 0; 17 | float even_avg, odd_avg; 18 | int input; 19 | 20 | printf("Enter integers (0 to stop):\n"); 21 | while(scanf("%d", &input) == 1 && input != STOP) 22 | { 23 | if (input % 2 == 0) 24 | { 25 | even_count++; 26 | even_sum += input; 27 | } 28 | else 29 | { 30 | odd_count++; 31 | odd_sum += input; 32 | } 33 | } 34 | 35 | even_avg = even_sum / (float) even_count; 36 | odd_avg = odd_sum / (float) odd_count; 37 | 38 | printf("Number of even integers: %d\n", even_count); 39 | printf("Average value of even integers: %.2f\n", even_avg); 40 | printf("Number of odd integers: %d\n", odd_count); 41 | printf("Average value of odd integers: %.2f\n", odd_avg); 42 | 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /ch07/exercise04.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 7 Exercise 4 3 | 4 | // Using if else statements, write a program that reads input up to #, replaces 5 | // each period with an exclamation mark, replaces each exclamation mark 6 | // initially present with two exclamation marks, and reports at the end the 7 | // number of substitutions it has made. 8 | 9 | #include 10 | 11 | #define STOP '#' 12 | 13 | int main(void) 14 | { 15 | char ch; 16 | 17 | printf("Enter input (%c to exit):\n", STOP); 18 | while ((ch = getchar()) != STOP) 19 | { 20 | if (ch == '.') 21 | printf("!"); 22 | else if (ch == '!') 23 | printf("!!"); 24 | else 25 | printf("%c", ch); 26 | } 27 | 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /ch07/exercise05.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 7 Exercise 5 3 | 4 | // Redo exercise 4 using a switch. 5 | 6 | #include 7 | 8 | #define STOP '#' 9 | 10 | int main(void) 11 | { 12 | char ch; 13 | 14 | printf("Enter input (%c to exit):\n", STOP); 15 | while ((ch = getchar()) != STOP) 16 | { 17 | switch (ch) 18 | { 19 | case '.' : 20 | printf("!"); 21 | break; 22 | case '!' : 23 | printf("!!"); 24 | break; 25 | default : 26 | printf("%c", ch); 27 | } 28 | } 29 | 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /ch07/exercise06.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 7 Exercise 6: 3 | 4 | // Write a program that reads input up to # and reports the number of times that the 5 | // sequence ei occurs. 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #define STOP '#' 12 | 13 | int main(void) 14 | { 15 | char ch; 16 | unsigned int ei_count = 0; 17 | bool e_flag = false; 18 | 19 | printf("This program reads input and counts the number of times the\n" 20 | "sequence 'ei' occurs (case insensitive).\n"); 21 | printf("Enter input (%c to stop):\n", STOP); 22 | 23 | while ((ch = getchar()) != STOP) 24 | { 25 | ch = tolower(ch); 26 | if (ch == 'e') 27 | e_flag = true; 28 | else if (ch == 'i') 29 | { 30 | if (e_flag) 31 | ei_count++; 32 | e_flag = false; 33 | } 34 | else 35 | e_flag = false; 36 | 37 | } 38 | 39 | printf("The sequence 'ei' occurs %u times.\n", ei_count); 40 | 41 | return 0; 42 | } 43 | -------------------------------------------------------------------------------- /ch07/exercise07.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 7 Exercise 7: 3 | 4 | // Write a program that requests the hours worked in a week and then prints the 5 | // gross pay, the taxes, and the net pay. Assume the following: 6 | // a. Basic pay rate = $10.00/hr 7 | // b. Overtime (in excess of 40 hours) = time and a half 8 | // c. Tax rate: #15% of the first $300 9 | // 20% of the next $150 25% of the rest 10 | // Use #define constants, and don’t worry if the example does not conform to 11 | // current tax law. 12 | 13 | #include 14 | 15 | #define BASIC_RATE 10.0 16 | #define OVERTIME_HOURS 40.0 17 | #define OVERTIME_MULTIPLIER 1.5 18 | #define TAX_RATE_1 0.15 19 | #define TAX_BRACKET_1 300.0 20 | #define TAX_RATE_2 0.20 21 | #define TAX_BRACKET_2 450.0 22 | #define TAX_RATE_3 0.25 23 | 24 | float calculate_gross_pay(float hours); 25 | float calulate_taxes(float gross_pay); 26 | 27 | int main(void) 28 | { 29 | float hours, gross_pay, taxes; 30 | 31 | printf("Enter number of hours worked in a week: "); 32 | 33 | if (scanf("%f", &hours) == 1) 34 | { 35 | gross_pay = calculate_gross_pay(hours); 36 | taxes = calulate_taxes(gross_pay); 37 | 38 | printf("For %.1f hours of work you make $%.2f and pay $%.2f in taxes.\n", 39 | hours, gross_pay, taxes); 40 | } 41 | else 42 | printf("Invalid input...terminating.\n"); 43 | 44 | return 0; 45 | } 46 | 47 | float calculate_gross_pay(float hours) 48 | { 49 | if (hours > OVERTIME_HOURS) 50 | return OVERTIME_HOURS * BASIC_RATE + (hours - OVERTIME_HOURS) * BASIC_RATE * OVERTIME_MULTIPLIER; 51 | else 52 | return hours * BASIC_RATE; 53 | } 54 | 55 | float calulate_taxes(float gross_pay) 56 | { 57 | if (gross_pay > TAX_BRACKET_2) 58 | return TAX_RATE_3 * (gross_pay - TAX_BRACKET_2) + TAX_RATE_2 * (TAX_BRACKET_2 - TAX_BRACKET_1) + TAX_RATE_1 * TAX_BRACKET_1; 59 | else if (gross_pay > TAX_BRACKET_1) 60 | return TAX_RATE_2 * (gross_pay - TAX_BRACKET_1) + TAX_RATE_1 * TAX_BRACKET_1; 61 | else 62 | return TAX_RATE_1 * gross_pay; 63 | } 64 | -------------------------------------------------------------------------------- /ch07/exercise09.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 7 Exercise 09: 3 | 4 | // Write a program that accepts a positive integer as input and then displays 5 | // all the prime numbers smaller than or equal to that number. 6 | 7 | #include 8 | #include 9 | 10 | void flush_input_buffer(void); 11 | 12 | int main(void) 13 | { 14 | bool prime_flag; 15 | int limit; 16 | printf("Primes: this program prints all primes less than or equal to any positive integer.\n"); 17 | printf("Enter a positive integer: \n"); 18 | while (scanf("%d", &limit) != 1 || limit < 1) 19 | { 20 | flush_input_buffer(); 21 | printf("Enter a positive integer: \n"); 22 | } 23 | 24 | for (int i = 2; i <= limit; i++) 25 | { 26 | prime_flag = true; 27 | for (int j = 2; j < i; j++) // for all j less than i ... 28 | { 29 | if (i % j == 0) // if i is divisible by j ... 30 | { 31 | prime_flag = false; // then i is not prime 32 | break; // break out of inner loop 33 | } 34 | } 35 | if (prime_flag) 36 | printf("%d is prime.\n", i); 37 | } 38 | 39 | return 0; 40 | } 41 | 42 | void flush_input_buffer(void) 43 | { 44 | while (getchar() != '\n') 45 | ; 46 | } 47 | -------------------------------------------------------------------------------- /ch07/exercise10.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 7 Exercise 10 3 | 4 | // The 1988 United States Federal Tax Schedule was the simplest in recent 5 | // times. It had four categories, and each category had two rates. Here is a 6 | // summary (dollar amounts are taxable income): 7 | 8 | // Category Tax 9 | // Single 15% of first $17,850 plus 28% of excess 10 | // Head of Household 15% of first $23,900 plus 28% of excess 11 | // Married, Joint 15% of first $29,750 plus 28% of excess 12 | // Married, Separate 15% of first $14,875 plus 28% of excess 13 | 14 | // For example, a single wage earner with a taxable income of $20,000 owes 15 | // 0.15 × $17,850 + 0.28 × ($20,000−$17,850). Write a program that lets the 16 | // user specify the tax category and the taxable income and that then 17 | // calculates the tax. Use a loop so that the user can enter several tax cases. 18 | 19 | #include 20 | 21 | #define SINGLE 1 22 | #define HEAD_OF_HOUSEHOLD 2 23 | #define MARRIED_JOINT 3 24 | #define MARRIED_SEPARATE 4 25 | #define EXIT 5 26 | 27 | #define RATE_1 0.15f 28 | #define RATE_2 0.28f 29 | 30 | void flush_input_buffer(void); 31 | 32 | int main(void) 33 | { 34 | int category; 35 | float income, bracket, taxes; 36 | 37 | printf("US 1988 Tax Calculator\n"); 38 | 39 | while(1) 40 | { 41 | printf("1) Single 2) Head of Household 3) Married, Joint 4) Married Separate\n"); 42 | printf("Enter your tax category (1-4) or 5 to quit: "); 43 | scanf("%d", &category); 44 | 45 | switch (category) 46 | { 47 | case (SINGLE) : 48 | bracket = 17850.0; 49 | break; 50 | case (HEAD_OF_HOUSEHOLD) : 51 | bracket = 23900.0; 52 | break; 53 | case (MARRIED_JOINT) : 54 | bracket = 29750.0; 55 | break; 56 | case (MARRIED_SEPARATE) : 57 | bracket = 14875.0; 58 | break; 59 | case (EXIT) : 60 | printf("Bye.\n"); 61 | return 0; // Exit Program 62 | default : 63 | flush_input_buffer(); 64 | printf("Invalid input: please enter an integer between 1 and 5.\n"); 65 | continue; 66 | } 67 | printf("Enter your income: "); 68 | while (scanf("%f", &income) != 1 || income < 0) 69 | { 70 | flush_input_buffer(); 71 | printf("Invalid input: please enter a positive number.\n"); 72 | printf("Enter your income: "); 73 | } 74 | 75 | if (income > bracket) 76 | taxes = RATE_2 * (income - bracket) + RATE_1 * bracket; 77 | else 78 | taxes = RATE_1 * income; 79 | 80 | printf("You will owe $%.2f in taxes.\n\n", taxes); 81 | } 82 | } 83 | 84 | void flush_input_buffer(void) 85 | { 86 | while (getchar() != '\n') 87 | ; 88 | } 89 | -------------------------------------------------------------------------------- /ch08/README.md: -------------------------------------------------------------------------------- 1 | Chapter 8: Character Input/Output and Input Validation 2 | ====================================================== -------------------------------------------------------------------------------- /ch08/exercise01.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 8 Exercise 1: 3 | 4 | // Devise a program that counts the number of characters in its input up to the 5 | // end of file. 6 | 7 | #include 8 | 9 | int main(void) 10 | { 11 | int count = 0; 12 | 13 | while (getchar() != EOF) 14 | { 15 | count++; 16 | } 17 | printf("Character count: %d\n", count); 18 | 19 | return 0; 20 | } -------------------------------------------------------------------------------- /ch08/exercise02.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 8 Exercise 2: 3 | 4 | // Write a program that reads input as a stream of characters until 5 | // encountering EOF. Have the program print each input character and its ASCII 6 | // decimal value. Note that characters preceding the space character in the 7 | // ASCII sequence are nonprinting characters. Treat them specially. If the 8 | // nonprinting character is a newline or tab, print \n or \t, respectively. 9 | // Otherwise, use control-character notation. For instance, ASCII 1 is Ctrl+A, 10 | // which can be displayed as ^A. Note that the ASCII value for A is the value 11 | // for Ctrl+A plus 64. A similar relation holds for the other nonprinting 12 | // characters. Print 10 pairs per line, except start a fresh line each time a 13 | // newline character is encountered. (Note: The operating system may have 14 | // special interpretations for some control characters and keep them from 15 | // reaching the program.) 16 | 17 | #include 18 | 19 | int main(void) 20 | { 21 | int ch, char_count = 0; 22 | 23 | while ((ch = getchar()) != EOF) 24 | { 25 | if (ch >= ' ') 26 | printf("\'%c\': %d", ch, ch); 27 | else if (ch == '\n') 28 | printf("\'\\n\': %d", ch); 29 | else if (ch == '\t') 30 | printf("\'\\t\': %d", ch); 31 | else // ascii control characters 32 | printf("\'^%c\': %d", ch + 64, ch ); 33 | 34 | char_count++; 35 | if (char_count % 10 == 0) 36 | printf("\n"); // print new line for every 10 characters 37 | else 38 | printf(" "); // otherwise, print spaces 39 | } 40 | 41 | printf("\n"); 42 | 43 | return 0; 44 | } -------------------------------------------------------------------------------- /ch08/exercise03.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 8 Exercise 3: 3 | 4 | // Write a program that reads input as a stream of characters until 5 | // encountering EOF. Have it report the number of uppercase letters, the number 6 | // of lowercase letters, and the number of other characters in the input. You 7 | // may assume that the numeric values for the lowercase letters are sequential 8 | // and assume the same for uppercase. Or, more portably, you can use 9 | // appropriate classification functions from the ctype.h library. 10 | 11 | #include 12 | #include 13 | 14 | int main(void) 15 | { 16 | int ch; 17 | int uppercase_count = 0, lowercase_count = 0, other_count = 0; 18 | 19 | while ((ch = getchar()) != EOF) 20 | { 21 | if (isupper(ch)) 22 | uppercase_count++; 23 | else if (islower(ch)) 24 | lowercase_count++; 25 | else 26 | other_count++; 27 | } 28 | 29 | printf("Character Counts\n"); 30 | printf("Uppercase letters: %d\n", uppercase_count); 31 | printf("Lowercase letters: %d\n", lowercase_count); 32 | printf("Other: %d\n", other_count); 33 | 34 | return 0; 35 | } -------------------------------------------------------------------------------- /ch08/exercise04.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 8 Exercise 4: 3 | 4 | // Write a program that reads input as a stream of characters until 5 | // encountering EOF. Have it report the average number of letters per word. 6 | // Don’t count whitespace as being letters in a word. Actually, punctuation 7 | // shouldn’t be counted either, but don’t worry about that now. (If you do want 8 | // to worry about it, consider using the ispunct() function from the ctype.h 9 | // family.) 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | int main(void) 16 | { 17 | int ch; 18 | bool in_word = false; 19 | int letter_count = 0, word_count = 0; 20 | 21 | while ((ch = getchar()) != EOF) 22 | { 23 | if (isalpha(ch)) // if ch is a letter 24 | { 25 | letter_count++; 26 | // if not currently in a word, then switch state to in word 27 | // and increment the word count 28 | if (!in_word) 29 | { 30 | in_word = true; 31 | word_count++; 32 | } 33 | } 34 | // if ch is not a letter, set program state to out of word 35 | else 36 | in_word = false; 37 | } 38 | // divide letter count by word count to get average letters/word 39 | printf("Average letters per word: %.2f\n", (float) letter_count / word_count); 40 | 41 | return 0; 42 | } -------------------------------------------------------------------------------- /ch08/exercise05.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 8 Exercise 05: 3 | 4 | // Modify the guessing program of Listing 8.4 so that it uses a more 5 | // intelligent guessing strategy. For example, have the program initially guess 6 | // 50, and have it ask the user whether the guess is high, low, or correct. If, 7 | // say, the guess is low, have the next guess be halfway between 50 and 100, 8 | // that is, 75. If that guess is high, let the next guess be halfway between 75 9 | // and 50, and so on. Using this binary search strategy, the program quickly 10 | // zeros in on the correct answer, at least if the user does not cheat. 11 | 12 | #include 13 | 14 | int main(void) 15 | { 16 | // initial search parameters 17 | int upper_bound = 100; 18 | int lower_bound = 0; 19 | int guess = 50; 20 | 21 | char ch; 22 | 23 | printf("Pick an integer from 1 to 100. I will try to guess "); 24 | printf("it.\nRespond with a y if my guess is right, with a h if it's"); 25 | printf("\ntoo high and an l if it's too low.\n"); 26 | printf("Uh...is your number %d?\n", guess); 27 | 28 | while ((ch = getchar()) != 'y') 29 | { 30 | while (getchar() != '\n') // clear input stream 31 | ; 32 | if (ch == 'h') 33 | upper_bound = guess; 34 | else if (ch == 'l') 35 | lower_bound = guess; 36 | else 37 | { 38 | printf("Invalid valid input. Try again.\n"); 39 | continue; 40 | } 41 | guess = (upper_bound + lower_bound) / 2.0; 42 | printf("Well, then, is it %d?\n", guess); 43 | } 44 | 45 | printf("I knew I could do it!\n"); 46 | return 0; 47 | } -------------------------------------------------------------------------------- /ch08/exercise06.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 8 Exercise 6: 3 | 4 | // Modify the get_first() function of Listing 8.8 so that it returns the first 5 | // non- whitespace character encountered. Test it in a simple program. 6 | 7 | #include 8 | #include 9 | 10 | int get_first(void); 11 | 12 | int main(void) 13 | { 14 | int ch; 15 | 16 | printf("Test program for get_first():\n"); 17 | printf("Enter a line; you should see the first non-whitespace\n"); 18 | printf("character echoed in the terminal:\n"); 19 | 20 | ch = get_first(); 21 | printf("%c\n", ch); 22 | 23 | return 0; 24 | } 25 | 26 | int get_first(void) 27 | { 28 | // returns first non-whitespace character and clears 29 | // remaining input until next line break or EOF 30 | 31 | int ch, garbage; 32 | 33 | do { 34 | ch = getchar(); 35 | } 36 | while (isspace(ch)); 37 | 38 | 39 | while((garbage = getchar()) != '\n' && garbage != EOF) 40 | ; 41 | 42 | return ch; 43 | } -------------------------------------------------------------------------------- /ch08/exercise08.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 8 Exercise 8 3 | 4 | // Write a program that shows you a menu offering you the choice of addition, 5 | // subtraction, multiplication, or division. After getting your choice, the 6 | // program asks for two numbers, then performs the requested operation. The 7 | // program should accept only the offered menu choices. It should use type 8 | // float for the numbers and allow the user to try again if he or she fails to 9 | // enter a number. In the case of division, the program should prompt the user 10 | // to enter a new value if 0 is entered as the value for the second number. 11 | 12 | #include 13 | #include 14 | 15 | int get_first(void); 16 | void print_menu(void); 17 | float get_number(void); 18 | 19 | int main(void) 20 | { 21 | int operation; 22 | float num1, num2; 23 | 24 | print_menu(); 25 | while ((operation = get_first()) != 'q') 26 | { 27 | printf("Enter first number: "); 28 | num1 = get_number(); 29 | printf("Enter second number: "); 30 | num2 = get_number(); 31 | 32 | switch (operation) 33 | { 34 | case ('a') : 35 | printf("%.3f + %.3f = %.3f\n", num1, num2, num1 + num2); 36 | break; 37 | case ('s') : 38 | printf("%.3f - %.3f = %.3f\n", num1, num2, num1 - num2); 39 | break; 40 | case ('m') : 41 | printf("%.3f * %.3f = %.3f\n", num1, num2, num1 * num2); 42 | break; 43 | case ('d') : 44 | while (num2 == 0) 45 | { 46 | printf("Enter a number other than 0: "); 47 | num2 = get_number(); 48 | } 49 | printf("%.3f / %.3f = %.3f\n", num1, num2, num1 / num2); 50 | break; 51 | default : 52 | printf("I do not recognize that input. Try again."); 53 | } 54 | print_menu(); 55 | } 56 | 57 | 58 | } 59 | 60 | int get_first(void) 61 | { 62 | // return first non-whitespace character 63 | int ch; 64 | 65 | do ch = getchar(); while (isspace(ch)); 66 | 67 | while (getchar() != '\n') 68 | ; 69 | 70 | return ch; 71 | } 72 | 73 | 74 | void print_menu(void) 75 | { 76 | printf("Enter the operation of your choice:\n"); 77 | printf("a. add s. subtract\n"); 78 | printf("m. multiply d. divide\n"); 79 | printf("q. quit\n"); 80 | } 81 | 82 | float get_number(void) 83 | { 84 | int ch; 85 | float num; 86 | 87 | while (scanf("%f", &num) != 1) 88 | { 89 | while ((ch = getchar()) != '\n') // echo user input and clear stream 90 | putchar(ch); 91 | 92 | printf(" is not a number.\n"); 93 | printf("Please enter a number, such as 2.5, -1.78E8, or 3: "); 94 | } 95 | 96 | return num; 97 | } -------------------------------------------------------------------------------- /ch09/exercise01.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 9 Exercise 1: 3 | 4 | // Devise a function called min(x,y) that returns the smaller of two double 5 | // values. Test the function with a simple driver. 6 | 7 | #include 8 | 9 | double min(double, double); 10 | 11 | int main(void) 12 | { 13 | double x, y; 14 | 15 | printf("Enter two doubles (non-double input to quit): "); 16 | while (scanf("%lf %lf", &x, &y) == 2) 17 | { 18 | printf("The minimum of %.3f and %.3f is %.3f.\n", x, y, min(x,y)); 19 | printf("Enter two doubles (non-double input to quit): "); 20 | } 21 | 22 | return 0; 23 | } 24 | 25 | double min(double x, double y) 26 | { 27 | // return the minimum of x and y 28 | return x < y ? x : y; 29 | } -------------------------------------------------------------------------------- /ch09/exercise02.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 9 Exercise 2: 3 | 4 | // Devise a function chline(ch,i,j) that prints the requested character in 5 | // columns i through j. Test it in a simple driver. 6 | 7 | #include 8 | 9 | void chline(char, unsigned int, unsigned int); 10 | 11 | int main(void) 12 | { 13 | char ch; 14 | unsigned int i, j; 15 | 16 | printf("Enter a character and two integers: "); 17 | while (scanf("%c %u %u", &ch, &i, &j) == 3) 18 | { 19 | chline(ch, i, j); 20 | printf("\n"); 21 | 22 | while (getchar() != '\n') continue; // clear input 23 | 24 | printf("Enter a character and two integers: "); 25 | } 26 | 27 | return 0; 28 | } 29 | 30 | void chline(char ch, unsigned int i, unsigned int j) 31 | { 32 | unsigned int col; 33 | for (col = 1; col < i; col++) 34 | { 35 | putchar(' '); 36 | } 37 | 38 | for (; col <= j; col++) 39 | { 40 | putchar(ch); 41 | } 42 | } -------------------------------------------------------------------------------- /ch09/exercise03.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 9 Exercise 3 3 | 4 | // Write a function that takes three arguments: a character and two integers. 5 | // The character is to be printed. The first integer specifies the number of 6 | // times that the character is to be printed on a line, and the second integer 7 | // specifies the number of lines that are to be printed. Write a program that 8 | // makes use of this function. 9 | 10 | #include 11 | 12 | void printgrid(char ch, unsigned int cols, unsigned int rows); 13 | 14 | int main(void) 15 | { 16 | char ch; 17 | unsigned int rows, cols; 18 | 19 | printf("Enter a character, number of rows and number of columns: "); 20 | while (scanf("%c %u %u", &ch, &rows, &cols) == 3) 21 | { 22 | printgrid(ch, cols, rows); 23 | printf("Enter a character, number of rows and number of columns: "); 24 | } 25 | 26 | return 0; 27 | } 28 | 29 | void printgrid(char ch, unsigned int cols, unsigned int rows) 30 | { 31 | // prints given character in a block sized rows x cols 32 | for (unsigned int i = 0; i < rows; i++) 33 | { 34 | for (unsigned int j = 0; j < cols; j++) 35 | { 36 | putchar(ch); 37 | } 38 | putchar('\n'); 39 | } 40 | } -------------------------------------------------------------------------------- /ch09/exercise04.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 9 Exercise 4: 3 | 4 | // The harmonic mean of two numbers is obtained by taking the inverses of the 5 | // two numbers, averaging them, and taking the inverse of the result. Write a 6 | // function that takes two double arguments and returns the harmonic mean of 7 | // the two numbers. 8 | 9 | 10 | #include 11 | 12 | double harmonic_mean(double, double); 13 | 14 | int main(void) 15 | { 16 | double x, y; 17 | 18 | printf("Harmonic means\n"); 19 | printf("Enter two numbers: "); 20 | while (scanf("%lf %lf", &x, &y) == 2) 21 | { 22 | printf("%f\n", harmonic_mean(x, y)); 23 | 24 | printf("Enter two numbers: "); 25 | } 26 | 27 | return 0; 28 | } 29 | 30 | double harmonic_mean(double x, double y) 31 | { 32 | return 2 / (1 / x + 1 / y); 33 | } -------------------------------------------------------------------------------- /ch09/exercise05.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus: 2 | // Chapter 9 Exercise 5: 3 | 4 | // Write and test a function called larger_of() that replaces the contents of 5 | // two double variables with the maximum of the two values. For example, 6 | // larger_of(x,y) would reset both x and y to the larger of the two. 7 | 8 | #include 9 | 10 | void larger_of(double * x, double * y); 11 | 12 | int main(void) 13 | { 14 | double x, y; 15 | 16 | printf("Test larger_of() function\n"); 17 | printf("=========================\n"); 18 | printf("Enter two numbers x and y: "); 19 | while(scanf("%lf %lf", &x, &y) == 2) 20 | { 21 | printf("Before calling larger_of():\n"); 22 | printf("x = %f, y = %f\n", x, y); 23 | 24 | larger_of(&x, &y); 25 | 26 | printf("After calling larger_of():\n"); 27 | printf("x = %f, y = %f\n", x, y); 28 | 29 | printf("Enter two numbers x and y: "); 30 | } 31 | 32 | return 0; 33 | } 34 | 35 | void larger_of(double * x, double * y) 36 | { 37 | // replace contents of 38 | if (*x > *y) *y = *x; 39 | else *x = *y; 40 | } -------------------------------------------------------------------------------- /ch09/exercise06.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 9 Exercise 6: 3 | 4 | // Write and test a function that takes the addresses of three double variables 5 | // as arguments and that moves the value of the smallest variable into the 6 | // first variable, the middle value to the second variable, and the largest 7 | // value into the third variable. 8 | 9 | #include 10 | 11 | void sort_variables(double *x, double *y, double *z); 12 | 13 | int main(void) 14 | { 15 | double x, y, z; 16 | 17 | printf("Test sort_variables():\n"); 18 | printf("Enter three numbers x, y and z:\n"); 19 | while(scanf("%lf %lf %lf", &x, &y, &z) == 3) 20 | { 21 | putchar('\n'); 22 | printf("Before calling sort_variables:\n"); 23 | printf("x = %f, y = %f, z = %f\n", x, y, z); 24 | 25 | sort_variables(&x, &y, &z); 26 | 27 | putchar('\n'); 28 | printf("After calling sort_variables:\n"); 29 | printf("x = %f, y = %f, z = %f\n", x, y, z); 30 | 31 | putchar('\n'); 32 | 33 | printf("Enter three numbers x, y and z:\n"); 34 | } 35 | 36 | return 0; 37 | } 38 | 39 | void sort_variables(double *x, double *y, double *z) 40 | { 41 | double tmp; 42 | 43 | if (*x > *y) 44 | { 45 | // switch x and y 46 | tmp = *y; 47 | *y = *x; 48 | *x = tmp; 49 | } 50 | 51 | if (*y > *z) 52 | { 53 | // switch y and z 54 | tmp = *z; 55 | *z = *y; 56 | *y = tmp; 57 | 58 | if (*x > *y) 59 | { 60 | // switch x and y 61 | tmp = *y; 62 | *y = *x; 63 | *x = tmp; 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /ch09/exercise07.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 9 Exercise 7: 3 | 4 | // Write a program that reads characters from the standard input to 5 | // end-of-file. For each character, have the program report whether it is a 6 | // letter. If it is a letter, also report its numerical location in the 7 | // alphabet. For example, c and C would both be letter 3. Incorporate a 8 | // function that takes a character as an argument and returns the numerical 9 | // location if the character is a letter and that returns –1 otherwise. 10 | 11 | #include 12 | #include 13 | 14 | int letter_location(char ch); 15 | 16 | int main(void) 17 | { 18 | char ch; 19 | int location; 20 | 21 | while ((ch = getchar()) != EOF) 22 | { 23 | if ((location = letter_location(ch)) == -1) 24 | printf("%c is not a letter\n", ch); 25 | else 26 | printf("%c is a letter: location = %d\n", ch, location); 27 | } 28 | 29 | return 0; 30 | } 31 | 32 | int letter_location(char ch) 33 | { 34 | if (isalpha(ch)) 35 | { 36 | ch = tolower(ch); 37 | return (ch - 'a' + 1); 38 | } 39 | else 40 | return -1; 41 | } -------------------------------------------------------------------------------- /ch09/exercise08.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 9 Exercise 8 3 | 4 | // Chapter 6, “C Control Statements: Looping,” (Listing 6.20) shows a power() 5 | // function that returned the result of raising a type double number to a 6 | // positive integer value. Improve the function so that it correctly handles 7 | // negative powers. Also, build into the function that 0 to any power other 8 | // than 0 is 0 and that any number to the 0 power is 1. (It should report that 9 | // 0 to the 0 is undefined, then say it’s using a value of 1.) Use a loop. Test 10 | // the function in a program. 11 | 12 | #include 13 | #include // prototype for abs() 14 | 15 | double power(double base, int exponent); 16 | 17 | int main(void) 18 | { 19 | double base, output; 20 | int exponent; 21 | 22 | printf("Test power() function:\n"); 23 | printf("Enter a :double: base and :int: exponent: "); 24 | while (scanf("%lf %d", &base, &exponent) == 2) 25 | { 26 | output = power(base, exponent); 27 | 28 | printf("%f ^ %d = %f \n", base, exponent, output); 29 | 30 | printf("Enter a :double: base and :int: exponent: "); 31 | } 32 | 33 | return 0; 34 | } 35 | 36 | double power(double base, int exponent) 37 | { 38 | double power = base; 39 | 40 | if (base == 0) 41 | { 42 | if (exponent == 0) 43 | { 44 | printf("Warning: 0 ^ 0 is undefined. Using 1.\n"); 45 | return 1.0; 46 | } 47 | else 48 | return 0; 49 | } 50 | 51 | for (int i = 1; i < abs(exponent); i++) 52 | { 53 | power *= base; 54 | } 55 | 56 | if (exponent < 0) 57 | power = 1 / power; 58 | 59 | return power; 60 | } -------------------------------------------------------------------------------- /ch09/exercise09.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 9 Exercise 8 3 | 4 | // Redo Programming Exercise 8, but this time use a recursive function. 5 | 6 | #include 7 | #include // prototype for abs() 8 | 9 | double power(double base, int exponent); 10 | 11 | int main(void) 12 | { 13 | double base, output; 14 | int exponent; 15 | 16 | printf("Test power() function:\n"); 17 | printf("Enter a :double: base and :int: exponent: "); 18 | while (scanf("%lf %d", &base, &exponent) == 2) 19 | { 20 | output = power(base, exponent); 21 | 22 | printf("%f ^ %d = %f \n", base, exponent, output); 23 | 24 | printf("Enter a :double: base and :int: exponent: "); 25 | } 26 | 27 | return 0; 28 | } 29 | 30 | double power(double base, int exponent) 31 | { 32 | double dbl_power; 33 | 34 | // handle powers of zero 35 | if (base == 0) 36 | { 37 | if (exponent == 0) 38 | { 39 | printf("Warning: 0 ^ 0 is undefined. Using 1.\n"); 40 | return 1.0; 41 | } 42 | else 43 | return 0; 44 | } 45 | 46 | if (exponent == 0) return 1; // stop recursion 47 | 48 | dbl_power = base * power(base, abs(exponent) - 1); // recursion step 49 | 50 | // if exponent is negative, take reciprocal 51 | if (exponent < 0) dbl_power = 1 / dbl_power; 52 | 53 | return dbl_power; 54 | } -------------------------------------------------------------------------------- /ch09/exercise10.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 9 Exercise 10: 3 | 4 | // Generalize the to_binary() function of Listing 9.8 to a to_base_n() function 5 | // that takes a second argument in the range 2–10. It then should print the 6 | // number that is its first argument to the number base given by the second 7 | // argument. For example, to_ base_n(129,8) would display 201, the base-8 8 | // equivalent of 129. Test the function in a complete program. 9 | 10 | 11 | #include 12 | #include 13 | 14 | void to_base_n(int integer, int base); 15 | 16 | int main(void) { 17 | int integer, base; 18 | 19 | printf("Test to_base_n() function\n"); 20 | printf("Enter an integer in base 10 and a base to convert to: "); 21 | while (scanf("%d %d", &integer, &base) == 2) 22 | { 23 | to_base_n(integer, base); 24 | putchar('\n'); 25 | 26 | printf("Enter an integer in base 10 and a base to convert to: "); 27 | } 28 | 29 | return 0; 30 | } 31 | 32 | void to_base_n(int integer, int base) 33 | { 34 | // handle invalid bases 35 | if (base < 2 || 10 < base) 36 | { 37 | printf("Error: base must be between 2 and 10."); 38 | return; 39 | } 40 | 41 | // stop recursion 42 | if (integer == 0) return; 43 | 44 | // handle negative integers 45 | if (integer < 0) 46 | { 47 | putchar('-'); 48 | integer = abs(integer); 49 | } 50 | 51 | to_base_n(integer / base, base); 52 | printf("%d", integer % base); 53 | return; 54 | 55 | } -------------------------------------------------------------------------------- /ch09/exercise11.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 9 Exercise 11: 3 | 4 | // Write and test a Fibonacci() function that uses a loop instead of recursion 5 | // to calculate Fibonacci numbers. 6 | 7 | #include 8 | 9 | long Fibonacci(long n); 10 | 11 | int main(void) { 12 | long n; 13 | 14 | printf("Test Fibonacci() function\n"); 15 | printf("Enter an integer n: "); 16 | 17 | while (scanf("%ld", &n) == 1) 18 | { 19 | printf("Fibonacci #%ld = %ld\n", n, Fibonacci(n)); 20 | 21 | printf("Enter an integer n: "); 22 | } 23 | 24 | return 0; 25 | } 26 | 27 | long Fibonacci(long n) 28 | { 29 | // return nth Fibonacci number 30 | 31 | // handle invalid arguments 32 | if (n < 1) 33 | { 34 | printf("Error: n must be a positive integer.\n"); 35 | return -1; 36 | } 37 | 38 | long fib_n1 = 0, fib_n = 1, fib_n2; 39 | 40 | // n equals 1 or 2 41 | if (n == 1) return 0; 42 | if (n == 2) return 1; 43 | 44 | // n greater than or equal to 3 45 | for (long i = 3; i <= n; i++) 46 | { 47 | // update old values 48 | fib_n2 = fib_n1; 49 | fib_n1 = fib_n; 50 | fib_n = fib_n1 + fib_n2; 51 | } 52 | 53 | return fib_n; 54 | } -------------------------------------------------------------------------------- /ch10/exercise01.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 10 Exercise 1: 3 | 4 | // Modify the rain program in Listing 10.7 so that it does the calculations 5 | // using pointers instead of subscripts. (You still have to declare and 6 | // initialize the array.) 7 | 8 | #include 9 | #define MONTHS 12 // number of months in a year 10 | #define YEARS 5 // number of years of data 11 | 12 | int main(void) 13 | { 14 | // initializing rainfall data for 2010 - 2014 15 | const float rain[YEARS][MONTHS] = { 16 | {4.3,4.3,4.3,3.0,2.0,1.2,0.2,0.2,0.4,2.4,3.5,6.6}, 17 | {8.5,8.2,1.2,1.6,2.4,0.0,5.2,0.9,0.3,0.9,1.4,7.3}, 18 | {9.1,8.5,6.7,4.3,2.1,0.8,0.2,0.2,1.1,2.3,6.1,8.4}, 19 | {7.2,9.9,8.4,3.3,1.2,0.8,0.4,0.0,0.6,1.7,4.3,6.2}, 20 | {7.6,5.6,3.8,2.8,3.8,0.2,0.0,0.0,0.0,1.3,2.6,5.2} 21 | }; 22 | 23 | 24 | float subtot, total; 25 | 26 | // declare pointers 27 | const float (*year_ptr)[MONTHS]; 28 | const float *month_ptr; 29 | 30 | printf(" YEAR RAINFALL (inches)\n"); 31 | for (year_ptr = rain, total = 0; year_ptr < rain + YEARS; year_ptr++) 32 | { 33 | // for each year, sum rainfall for each month 34 | for (month_ptr = *year_ptr, subtot = 0; month_ptr < *year_ptr + MONTHS; month_ptr++) 35 | subtot += *month_ptr; 36 | 37 | printf("%5d %15.1f\n", (int) (2010 + (year_ptr - rain)), subtot); 38 | total += subtot; // total for all years } 39 | } 40 | 41 | printf("\nThe yearly average is %.1f inches.\n\n", total/YEARS); 42 | 43 | printf("MONTHLY AVERAGES:\n\n"); 44 | printf(" Jan Feb Mar Apr May Jun Jul Aug Sep Oct "); 45 | printf("Nov Dec\n"); 46 | 47 | int month, year; 48 | 49 | for (month = 0; month < MONTHS; month++) 50 | { 51 | // for each month, sum rainfall over years 52 | for (year = 0, subtot = 0; year < YEARS; year++) 53 | subtot += *(*(rain + year) + month); 54 | printf("%4.1f", subtot/YEARS); 55 | } 56 | 57 | printf("\n"); 58 | return 0; 59 | } -------------------------------------------------------------------------------- /ch10/exercise02.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 10 Exercise 2: 3 | 4 | // Write a program that initializes an array-of-double and then copies the 5 | // contents of the array into three other arrays. (All four arrays should be 6 | // declared in the main program.) To make the first copy, use a function with 7 | // array notation. To make the second copy, use a function with pointer 8 | // notation and pointer incrementing. Have the first two functions take as 9 | // arguments the name of the target array, the name of the source array, and 10 | // the number of elements to be copied. Have the third function take as 11 | // arguments the name of the target, the name of the source, and a pointer to 12 | // the element following the last element of the source. 13 | 14 | #include 15 | #define LENGTH 5 16 | 17 | // prototype declarations 18 | void copy_arr(double *target, double *source, int arr_len); // copy with array notation 19 | void copy_ptr(double *target, double *source, int arr_len); // copy with pointer notation 20 | void copy_ptrs(double *target, double *source_start, double *source_end); // copy with two pointers 21 | 22 | int main(void) 23 | { 24 | double source[LENGTH] = {1.1, 2.2, 3.3, 4.4, 5.5}; 25 | double target1[LENGTH]; 26 | double target2[LENGTH]; 27 | double target3[LENGTH]; 28 | 29 | // copy arrays 30 | copy_arr(target1, source, LENGTH); 31 | copy_ptr(target2, source, LENGTH); 32 | copy_ptrs(target3, source, source + LENGTH); 33 | 34 | // print array contents 35 | printf("%15s|%15s|%15s\n", "target1", "target2", "target3"); 36 | for (int i = 0; i < LENGTH; i++) 37 | printf("%15.3f|%15.3f|%15.3f\n", target1[i], target2[i], target3[i]); 38 | 39 | return 0; 40 | } 41 | 42 | void copy_arr(double *target, double *source, int arr_len) 43 | { 44 | // copy array using array notation 45 | 46 | for (int i = 0; i < arr_len; i++) 47 | { 48 | target[i] = source[i]; 49 | } 50 | } 51 | 52 | void copy_ptr(double *target, double *source, int arr_len) 53 | { 54 | // copy array using pointer notation 55 | 56 | for (int i = 0; i < arr_len; i++) 57 | { 58 | *(target + i) = *(source + i); 59 | } 60 | } 61 | 62 | void copy_ptrs(double *target, double *source_start, double *source_end) 63 | { 64 | // copy arr using pointer notation and pointer endpoint 65 | 66 | for (double *ptr = source_start; ptr < source_end; ptr++, target++) 67 | *target = *ptr; 68 | } 69 | -------------------------------------------------------------------------------- /ch10/exercise03.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 10 Exercise 3: 3 | 4 | // Write a function that returns the largest value stored in an array-of-int. 5 | // Test the function in a simple program. 6 | 7 | #include 8 | #include 9 | #include 10 | #define SIZE 10 11 | 12 | int max_int(int *arr, int arr_size); // function prototype 13 | 14 | int main(void) 15 | { 16 | int test[SIZE]; 17 | 18 | srand(time(NULL)); // seed random number generator 19 | 20 | // initialize test array with random ints between 0 and 99 21 | for (int i = 0; i < SIZE; i++) 22 | test[i] = rand() % 100; 23 | 24 | printf("The maximum of "); 25 | for (int i = 0; i < SIZE; i++) 26 | printf("%d ", test[i]); 27 | printf("is: %d\n", max_int(test, SIZE)); 28 | 29 | return 0; 30 | } 31 | 32 | int max_int(int *arr, int arr_size) 33 | { 34 | int max = arr[0]; 35 | for (int i = 1; i < arr_size; i++) 36 | { 37 | if (arr[i] > max) 38 | max = arr[i]; 39 | } 40 | 41 | return max; 42 | } 43 | -------------------------------------------------------------------------------- /ch10/exercise04.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 10 Exercise 4: 3 | 4 | // Write a function that returns the index of the largest value stored in an 5 | // array-of-double. Test the function in a simple program. 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #define SIZE 10 12 | 13 | int index_of_max(double *arr, int arr_size); 14 | 15 | int main(void) 16 | { 17 | // test index_of_max 18 | 19 | printf("Driver for index_of_max: returns index of the largest value stored " 20 | "in an array of doubles.\n"); 21 | putchar('\n'); 22 | 23 | double test[SIZE]; 24 | 25 | srand(time(NULL)); // seed random number generator 26 | 27 | // initialize test array with random doubles 28 | for (int i = 0; i < SIZE; i++) 29 | test[i] = rand() / (double) RAND_MAX; 30 | 31 | // print test array 32 | 33 | printf("%5s ", "Index"); 34 | for (int i = 0; i < SIZE; i++) 35 | printf("| %6d ", i); 36 | printf("\n"); 37 | printf("%5s ", "Value"); 38 | for (int i = 0; i < SIZE; i++) 39 | printf("| %6.4f ", test[i]); 40 | printf("\n"); 41 | printf("\n"); 42 | 43 | // print results 44 | printf("The maximum value occurs at index %d\n", index_of_max(test, SIZE)); 45 | 46 | return 0; 47 | } 48 | 49 | int index_of_max(double *arr, int arr_size) 50 | { 51 | // return index of max value in array of doubles 52 | 53 | int index_of_max = 0; 54 | for (int i = 1; i < arr_size; i++) 55 | if (*(arr + i) > *(arr + index_of_max)) 56 | index_of_max = i; 57 | 58 | return index_of_max; 59 | } -------------------------------------------------------------------------------- /ch10/exercise05.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 10 Exercise 5: 3 | 4 | // Write a function that returns the difference between the largest and 5 | // smallest elements of an array-of-double. Test the function in a simple 6 | // program 7 | 8 | #include 9 | 10 | double max_difference(double *arr, int arr_size); 11 | 12 | int main(void) 13 | { 14 | // test max difference 15 | 16 | double test[5] = {1.0, 3.4, 2.2, 0.9, 2.0}; 17 | 18 | // print test results 19 | printf("The difference between the largest and smallest values of "); 20 | for (int i = 0; i < 5; i++) 21 | printf("%.1f ", test[i]); 22 | printf("is %.1f\n", max_difference(test, 5)); 23 | 24 | return 0; 25 | } 26 | 27 | double max_difference(double *arr, int arr_size) 28 | { 29 | // return the difference between the largest and smallest elements 30 | // of an array-of-double 31 | 32 | double max = arr[0]; 33 | double min = arr[0]; 34 | 35 | for (int i = 0; i < arr_size; i++) 36 | { 37 | if (arr[i] > max) 38 | max = arr[i]; 39 | else if (arr[i] < min) 40 | min = arr[i]; 41 | } 42 | 43 | return max - min; 44 | } -------------------------------------------------------------------------------- /ch10/exercise06.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 10 Exercise 6: 3 | 4 | // Write a function that reverses the contents of an array of double and test 5 | // it in a simple program. 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | 12 | void reverse_array(double *arr, int arr_size); 13 | 14 | int main(void) 15 | { 16 | // test reverse_array() 17 | 18 | printf("Testing reverse_array()\n"); 19 | 20 | double test1[9]; 21 | double test2[10]; 22 | double test3[2]; 23 | 24 | srand(time(NULL)); 25 | 26 | // initialize test array 1 with 9 random doubles 27 | for (int i = 0; i < 9; i++) 28 | test1[i] = rand() / (double) RAND_MAX; 29 | 30 | // initialize test array 2 with 10 random doubles 31 | for (int i = 0; i < 10; i++) 32 | test2[i] = rand() / (double) RAND_MAX; 33 | 34 | // initialize test array 1 with 2 random doubles 35 | for (int i = 0; i < 2; i++) 36 | test3[i] = rand() / (double) RAND_MAX; 37 | 38 | // test array 1 39 | 40 | printf("First Test\n"); 41 | // print original array 42 | printf("%10s: ", "Original"); 43 | for (int i = 0; i < 9; i++) 44 | printf("%5.2f ", test1[i]); 45 | putchar('\n'); 46 | 47 | //print reversed array 48 | reverse_array(test1, 9); 49 | printf("%10s: ", "Reversed"); 50 | for (int i = 0; i < 9; i++) 51 | printf("%5.2f ", test1[i]); 52 | putchar('\n'); 53 | 54 | // test array 2 55 | 56 | printf("Second Test\n"); 57 | // print original array 58 | printf("%10s: ", "Original"); 59 | for (int i = 0; i < 10; i++) 60 | printf("%5.2f ", test2[i]); 61 | putchar('\n'); 62 | 63 | //print reversed array 64 | reverse_array(test2, 10); 65 | printf("%10s: ", "Reversed"); 66 | for (int i = 0; i < 10; i++) 67 | printf("%5.2f ", test2[i]); 68 | putchar('\n'); 69 | 70 | // test array 3 71 | 72 | printf("Third Test\n"); 73 | // print original array 74 | printf("%10s: ", "Original"); 75 | for (int i = 0; i < 2; i++) 76 | printf("%5.2f ", test3[i]); 77 | putchar('\n'); 78 | 79 | //print reversed array 80 | reverse_array(test3, 2); 81 | printf("%10s: ", "Reversed"); 82 | for (int i = 0; i < 2; i++) 83 | printf("%5.2f ", test3[i]); 84 | putchar('\n'); 85 | 86 | return 0; 87 | } 88 | 89 | void reverse_array(double *arr, int arr_size) 90 | { 91 | // reverse an array of double 92 | 93 | double tmp; 94 | 95 | for (int i = 0; i < arr_size / 2; i++) 96 | { 97 | // swap values between indexes i and (arr_size - 1 - i) 98 | tmp = arr[i]; 99 | arr[i] = arr[arr_size - 1 - i]; 100 | arr[arr_size - 1 - i] = tmp; 101 | } 102 | } -------------------------------------------------------------------------------- /ch10/exercise07.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 10 Exercise 7: 3 | 4 | // Write a program that initializes a two-dimensional array-of-double and uses 5 | // one of the copy functions from exercise 2 to copy it to a second two 6 | // dimensional array. (Because a two-dimensional array is an array of arrays, a 7 | // one-dimensional copy function can be used with each subarray.) 8 | 9 | #include 10 | #include 11 | 12 | void copy_ptr(double *target, double *source, int arr_len); 13 | void print_row(double (*arr)[10], int row); 14 | 15 | int main(void) 16 | { 17 | // copy one 10 by 10 array to another 10 by 10 array 18 | 19 | double source[10][10]; 20 | double target[10][10]; 21 | 22 | // initialize source array 23 | for (int i = 0; i < 10; i++) 24 | for (int j = 0; j < 10; j++) 25 | source[i][j] = rand() / (double) RAND_MAX; 26 | 27 | // copy source array to target 28 | for (int i = 0; i < 10; i++) 29 | copy_ptr(target[i], source[i], 10); 30 | 31 | // print arrays 32 | printf("%-50s", "Source"); 33 | printf(" "); 34 | printf("%-50s", "Target"); 35 | putchar('\n'); 36 | for (int i = 0; i < 103; i++) 37 | putchar('-'); 38 | putchar('\n'); 39 | for (int i = 0; i < 10; i++) 40 | { 41 | print_row(source, i); 42 | printf(" "); 43 | print_row(target, i); 44 | putchar('\n'); 45 | } 46 | 47 | return 0; 48 | } 49 | 50 | void copy_ptr(double *target, double *source, int arr_len) 51 | { 52 | // copy array using pointer notation 53 | 54 | for (int i = 0; i < arr_len; i++) 55 | { 56 | *(target + i) = *(source + i); 57 | } 58 | } 59 | 60 | void print_row(double (*arr)[10], int row) 61 | { 62 | // print a row from a n by 10 array of doubles 63 | 64 | for (int i = 0; i < 10; i++) 65 | { 66 | printf("%.2f ", arr[row][i]); 67 | } 68 | } -------------------------------------------------------------------------------- /ch10/exercise08.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 10 Exercise 08: 3 | 4 | // Use a copy function from Programming Exercise 2 to copy the third through 5 | // fifth elements of a seven-element array into a three-element array. The 6 | // function itself need not be altered; just choose the right actual arguments. 7 | // (The actual arguments need not be an array name and array size. They only 8 | // have to be the address of an array element and a number of elements to be 9 | // processed.) 10 | 11 | #include 12 | 13 | void copy_ptrs(double *target, double *source_start, double *source_end); 14 | 15 | int main(void) 16 | { 17 | double source[7] = {2.4, 5.9, 7.8, 1.5, 3.3, 5.3, 6.8}; 18 | double target[3]; 19 | 20 | copy_ptrs(target, source + 2, source + 5); 21 | 22 | // print arrays 23 | for (int i = 0; i < 7; i++) 24 | printf("%.1f ", source[i]); 25 | putchar('\n'); 26 | 27 | for (int i = 0; i < 3; i++) 28 | printf("%.1f ", target[i]); 29 | putchar('\n'); 30 | 31 | return 0; 32 | } 33 | 34 | void copy_ptrs(double *target, double *source_start, double *source_end) 35 | { 36 | // copy arr using pointer notation and pointer endpoint 37 | 38 | for (double *ptr = source_start; ptr < source_end; ptr++, target++) 39 | *target = *ptr; 40 | } -------------------------------------------------------------------------------- /ch10/exercise09.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 10 Exercise 9: 3 | 4 | // Write a program that initializes a two-dimensional 3×5 array-of-double and 5 | // uses a VLA- based function to copy it to a second two-dimensional array. 6 | // Also provide a VLA-based function to display the contents of the two arrays. 7 | // The two functions should be capable, in general, of processing arbitrary N×M 8 | // arrays. (If you don’t have access to a VLA-capable compiler, use the 9 | // traditional C approach of functions that can process an N×5 array). 10 | 11 | #include 12 | #define ROWS 3 13 | #define COLUMNS 5 14 | 15 | void copy_2dim_arr(int rows, int cols, double source[rows][cols], 16 | double target[rows][cols]); 17 | void print_2dim_arr(int rows, int cols, double arr[rows][cols]); 18 | 19 | int main(void) 20 | { 21 | double array1[ROWS][COLUMNS] = {{4.3, 5.7, 2.1, 6.6, .8}, 22 | {5.6, 23.5, 73.2, 12.3, 123}, 23 | {22.1, 35.3, 6.35, 0.132, 11.1}}; 24 | double array2[ROWS][COLUMNS]; 25 | 26 | // copy array1 to array2 27 | copy_2dim_arr(ROWS, COLUMNS, array1, array2); 28 | 29 | // print contents of arrays 30 | printf("Array 1:\n"); 31 | print_2dim_arr(ROWS, COLUMNS, array1); 32 | putchar('\n'); 33 | 34 | printf("Array2:\n"); 35 | print_2dim_arr(ROWS, COLUMNS, array2); 36 | 37 | return 0; 38 | } 39 | 40 | void copy_2dim_arr(int rows, int cols, double source[rows][cols], 41 | double target[rows][cols]) 42 | { 43 | // copy one two-dimensional array to another 44 | 45 | for (int i = 0; i < rows; i++) 46 | { 47 | for (int j = 0; j < cols; j++) 48 | { 49 | target[i][j] = source[i][j]; 50 | } 51 | } 52 | } 53 | 54 | void print_2dim_arr(int rows, int cols, double arr[rows][cols]) 55 | { 56 | // print the contents of a two-dimensional array 57 | 58 | for (int i = 0; i < rows; i++) 59 | { 60 | for (int j = 0; j < cols; j++) 61 | printf(" %10.3f ", arr[i][j]); 62 | 63 | putchar('\n'); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /ch10/exercise10.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 10 Exercise 10: 3 | 4 | // Write a function that sets each element in an array to the sum of the 5 | // corresponding elements in two other arrays. That is, if array 1 has the 6 | // values 2, 4, 5, and 8 and array 2 has the values 1, 0, 4, and 6, the 7 | // function assigns array 3 the values 3, 4, 9, and 14. The function should 8 | // take three array names and an array size as arguments. Test the function in 9 | // a simple program. 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | #define SIZE 10 16 | 17 | void add_arrays(int *addend1, int *addend2, int *sum, int array_length); 18 | 19 | int main(void) 20 | { 21 | // test add_arrays 22 | 23 | srand(time(NULL)); 24 | 25 | int array1[SIZE]; 26 | int array2[SIZE]; 27 | int sum[SIZE]; 28 | 29 | // initialize arrays with random ints 30 | for (int i = 0; i < SIZE; i++) 31 | { 32 | array1[i] = rand() % 20; 33 | array2[i] = rand() % 20; 34 | } 35 | 36 | // get sum of arrays 37 | add_arrays(array1, array2, sum, SIZE); 38 | 39 | // print arrays 40 | printf("%8s %8s %8s\n", "Array 1", "Array 2", "Sum"); 41 | for (int i = 0; i < SIZE; i++) 42 | printf("%8d %8d %8d\n", array1[i], array2[i], sum[i]); 43 | 44 | return 0; 45 | } 46 | 47 | void add_arrays(int *addend1, int *addend2, int *sum, int array_length) 48 | { 49 | // calculate elementwise sum of two arrays 50 | 51 | for (int *tar = sum; tar < sum + array_length; tar++, addend1++, addend2++) 52 | *tar = *addend1 + *addend2; 53 | } -------------------------------------------------------------------------------- /ch10/exercise11.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 10 Exercise 11: 3 | 4 | // Write a program that declares a 3×5 array of int and initializes it to some 5 | // values of your choice. Have the program print the values, double all the 6 | // values, and then display the new values. Write a function to do the 7 | // displaying and a second function to do the doubling. Have the functions take 8 | // the array name and the number of rows as arguments. 9 | 10 | #include 11 | 12 | void print_Nx5_int_array(int (*array)[5], int rows); 13 | void double_Nx5_int_array(int (*array)[5], int rows); 14 | 15 | int main(void) 16 | { 17 | int array[3][5] = {{ 2, 5, 6, 9, 1}, 18 | {23, 1, 5, 66, 54}, 19 | { 9, 73, 23, 39, 2}}; 20 | 21 | printf("Original array:\n"); 22 | print_Nx5_int_array(array, 3); 23 | 24 | // double array and print new values 25 | double_Nx5_int_array(array, 3); 26 | printf("Doubled array:\n"); 27 | print_Nx5_int_array(array, 3); 28 | 29 | return 0; 30 | } 31 | 32 | void print_Nx5_int_array(int (*array)[5], int rows) 33 | { 34 | // print the contents of an N x 5 array of ints 35 | 36 | for (int i = 0; i < rows; i++) 37 | { 38 | for (int j = 0; j < 5; ++j) 39 | { 40 | printf(" %5d ", array[i][j]); 41 | } 42 | putchar('\n'); 43 | } 44 | } 45 | 46 | void double_Nx5_int_array(int (*array)[5], int rows) 47 | { 48 | // double the elements of an N x 5 array of ints 49 | 50 | for (int i = 0; i < rows; ++i) 51 | for (int j = 0; j < 5; j++) 52 | array[i][j] *= 2; 53 | } -------------------------------------------------------------------------------- /ch10/exercise12.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 10 Exercise 11: 3 | 4 | // Rewrite the rain program in Listing 10.7 so that the main tasks are 5 | // performed by functions instead of in main(). 6 | 7 | #include 8 | #define MONTHS 12 // number of months in a year 9 | #define YEARS 5 // number of years of data 10 | 11 | void print_annual_average(int years, int months, const float data[years][months]); 12 | void print_monthly_averages(int years, int months, const float data[years][months]); 13 | 14 | int main(void) 15 | { 16 | // initializing rainfall data for 2010 - 2014 17 | const float rain[YEARS][MONTHS] = {{4.3,4.3,4.3,3.0,2.0,1.2,0.2,0.2,0.4,2.4,3.5,6.6}, 18 | {8.5,8.2,1.2,1.6,2.4,0.0,5.2,0.9,0.3,0.9,1.4,7.3}, 19 | {9.1,8.5,6.7,4.3,2.1,0.8,0.2,0.2,1.1,2.3,6.1,8.4}, 20 | {7.2,9.9,8.4,3.3,1.2,0.8,0.4,0.0,0.6,1.7,4.3,6.2}, 21 | {7.6,5.6,3.8,2.8,3.8,0.2,0.0,0.0,0.0,1.3,2.6,5.2}}; 22 | 23 | 24 | print_annual_average(YEARS, MONTHS, rain); 25 | print_monthly_averages(YEARS, MONTHS, rain); 26 | 27 | return 0; 28 | } 29 | 30 | void print_annual_average(int years, int months, const float data[years][months]) 31 | { 32 | float subtotal, total; 33 | 34 | printf(" YEAR RAINFALL (inches)\n"); 35 | 36 | for (int year = 0, total = 0; year < years; year++) 37 | { 38 | // for each year, sum rainfall for each month 39 | for (int month = 0, subtotal = 0; month < months; month++) 40 | subtotal += data[year][month]; 41 | 42 | printf("%5d %15.1f\n", 2010 + year, subtotal); 43 | total += subtotal; // total for all years 44 | } 45 | printf("\nThe yearly average is %.1f inches.\n\n", total/years); 46 | } 47 | 48 | void print_monthly_averages(int years, int months, const float data[years][months]) 49 | { 50 | float subtotal; 51 | 52 | printf("MONTHLY AVERAGES:\n\n"); 53 | printf(" Jan Feb Mar Apr May Jun Jul Aug Sep Oct "); printf(" Nov Dec\n"); 54 | 55 | for (int month = 0; month < months; month++) 56 | { 57 | // for each month, sum rainfall over years 58 | for (int year = 0, subtotal = 0; year < years; year++) 59 | subtotal += data[year][month]; 60 | 61 | printf("%4.1f ", subtotal/YEARS); 62 | } 63 | printf("\n"); 64 | } 65 | -------------------------------------------------------------------------------- /ch10/exercise13.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 10 Exercise 13: 3 | 4 | // Write a program that prompts the user to enter three sets of five double 5 | // numbers each. (You may assume the user responds correctly and doesn’t enter 6 | // non-numeric data.) The program should accomplish all of the following: 7 | // a. Store the information in a 3×5 array. 8 | // b. Compute the average of each set of five values. 9 | // c. Compute the average of all the values. 10 | // d. Determine the largest value of the 15 values. 11 | // e. Report the results. 12 | // Each major task should be handled by a separate function using the 13 | // traditional C approach to handling arrays. Accomplish task “b” by using a 14 | // function that computes and returns the average of a one-dimensional array; 15 | // use a loop to call this function three times. The other tasks should take 16 | // the entire array as an argument, and the functions performing tasks “c” and 17 | // “d” should return the answer to the calling program. 18 | 19 | #include 20 | #define ROWS 3 21 | #define COLUMNS 5 22 | 23 | double compute_row_average(double array[COLUMNS]); 24 | double compute_array_average(double (*array)[COLUMNS], int rows); 25 | double largest_value(double (*array)[COLUMNS], int rows); 26 | 27 | int main(void) 28 | { 29 | double data[ROWS][COLUMNS]; 30 | 31 | for (int i = 0; i < ROWS; i++) 32 | { 33 | printf("Enter set of %d doubles: ", COLUMNS); 34 | for (int j = 0; j < COLUMNS; j++) 35 | { 36 | scanf("%lf", data[i] + j); 37 | } 38 | } 39 | 40 | // print row averages 41 | printf("Row Averages:\n"); 42 | for (int i = 0; i < ROWS; i++) 43 | { 44 | printf("\tAverage for row %d: %.3f\n", i + 1, compute_row_average(data[i])); 45 | } 46 | 47 | // print array average 48 | printf("Average for entire array: %.3f\n", compute_array_average(data, ROWS)); 49 | 50 | // print largest value 51 | printf("Maximum array value: %.3f\n", largest_value(data, ROWS)); 52 | 53 | return 0; 54 | } 55 | 56 | double compute_row_average(double array[COLUMNS]) 57 | { 58 | double total = 0; 59 | for (int i = 0; i < COLUMNS; i++) 60 | total += array[i]; 61 | 62 | return total / COLUMNS; 63 | } 64 | 65 | double compute_array_average(double (*array)[COLUMNS], int rows) 66 | { 67 | double total = 0; 68 | for (int i = 0; i < rows; i++) 69 | for (int j = 0; j < COLUMNS; j++) 70 | total += array[i][j]; 71 | 72 | return total / (rows * COLUMNS); 73 | } 74 | 75 | double largest_value(double (*array)[COLUMNS], int rows) 76 | { 77 | double max = array[0][0]; 78 | for (int i = 0; i < rows; i++) 79 | for (int j = 0; j < COLUMNS; j++) 80 | if (array[i][j] > max) 81 | max = array[i][j]; 82 | 83 | return max; 84 | } -------------------------------------------------------------------------------- /ch10/exercise14.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 10 Exercise 14: 3 | 4 | // Do Programming Exercise 13, but use variable-length array function 5 | // parameters. 6 | 7 | 8 | #include 9 | #define ROWS 3 10 | #define COLUMNS 5 11 | 12 | double compute_row_average(double *array, int cols); 13 | double compute_array_average(int rows, int cols, double array[rows][cols]); 14 | double largest_value(int rows, int cols, double array[rows][cols]); 15 | 16 | int main(void) 17 | { 18 | double data[ROWS][COLUMNS]; 19 | 20 | for (int i = 0; i < ROWS; i++) 21 | { 22 | printf("Enter set of %d doubles: ", COLUMNS); 23 | for (int j = 0; j < COLUMNS; j++) 24 | { 25 | scanf("%lf", data[i] + j); 26 | } 27 | } 28 | 29 | // print row averages 30 | printf("Row Averages:\n"); 31 | for (int i = 0; i < ROWS; i++) 32 | { 33 | printf("\tAverage for row %d: %.3f\n", i + 1, 34 | compute_row_average(data[i], COLUMNS)); 35 | } 36 | 37 | // print array average 38 | printf("Average for entire array: %.3f\n", 39 | compute_array_average(ROWS, COLUMNS, data)); 40 | 41 | // print largest value 42 | printf("Maximum array value: %.3f\n", 43 | largest_value(ROWS, COLUMNS, data)); 44 | 45 | return 0; 46 | } 47 | 48 | double compute_row_average(double *array, int cols) 49 | { 50 | double total = 0; 51 | for (int i = 0; i < cols; i++) 52 | total += array[i]; 53 | 54 | return total / cols; 55 | } 56 | 57 | double compute_array_average(int rows, int cols, double array[rows][cols]) 58 | { 59 | double total = 0; 60 | for (int i = 0; i < rows; i++) 61 | for (int j = 0; j < cols; j++) 62 | total += array[i][j]; 63 | 64 | return total / (rows * cols); 65 | } 66 | 67 | double largest_value(int rows, int cols, double array[rows][cols]) 68 | { 69 | double max = array[0][0]; 70 | for (int i = 0; i < rows; i++) 71 | for (int j = 0; j < cols; j++) 72 | if (array[i][j] > max) 73 | max = array[i][j]; 74 | 75 | return max; 76 | } -------------------------------------------------------------------------------- /ch11/exercise01.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 11 Exercise 1: 3 | 4 | // Design and test a function that fetches the next n characters from input 5 | // (including blanks, tabs, and newlines), storing the results in an array 6 | // whose address is passed as an argument. 7 | 8 | #include 9 | #include 10 | 11 | #define SIZE 20 12 | 13 | char * sgetnchar(char *array, int n); 14 | 15 | int main(void) 16 | { 17 | // test sgetnchar 18 | 19 | char hello[SIZE] = "Hello, "; 20 | int space = SIZE - strlen(hello) - 1; 21 | 22 | printf("What's your name? (enter %d characters)\n", space); 23 | sgetnchar(hello + 7, space); 24 | puts(hello); 25 | 26 | return 0; 27 | } 28 | 29 | char * sgetnchar(char *array, int n) 30 | { 31 | // gets n characters from input and stores them in character array 32 | 33 | char ch; 34 | 35 | for (int i = 0; i < n; i++) 36 | { 37 | if ((ch = getchar()) == EOF) 38 | break; 39 | 40 | *(array + i) = ch; 41 | } 42 | 43 | return array; 44 | } -------------------------------------------------------------------------------- /ch11/exercise02.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 11 Exercise 2: 3 | 4 | // Modify and test the function in exercise 1 so that it stops after n 5 | // characters or after the first blank, tab, or newline, whichever comes 6 | // first. (Don’t just use scanf().) 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #define SIZE 20 13 | 14 | char * sgetnchar(char *array, int n); 15 | 16 | int main(void) 17 | { 18 | // test sgetnchar 19 | 20 | char hello[SIZE] = "Hello, "; 21 | int space = SIZE - strlen(hello) - 1; 22 | 23 | puts("What's your name?"); 24 | sgetnchar(hello + 7, space); 25 | puts(hello); 26 | 27 | return 0; 28 | } 29 | 30 | char * sgetnchar(char *array, int n) 31 | { 32 | // get characters from input and store them in character array, 33 | // stopping after n characters or first whitespace 34 | 35 | int i = 0; 36 | char ch; 37 | 38 | while ((ch = getchar()) != EOF && !isspace(ch) && i < n) 39 | { 40 | *(array + i) = ch; 41 | i++; 42 | } 43 | 44 | return array; 45 | } -------------------------------------------------------------------------------- /ch11/exercise03.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 11 Exercise 3: 3 | 4 | // Design and test a function that reads the first word from a line of input 5 | // into an array and discards the rest of the line. It should skip over leading 6 | // whitespace. Define a word as a sequence of characters with no blanks, tabs, 7 | // or newlines in it. 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #define SIZE 20 14 | 15 | char * getword(char *target); 16 | 17 | int main(void) 18 | { 19 | // test getword() 20 | 21 | char hello[SIZE] = "Hello, "; 22 | 23 | printf("What's your name?"); 24 | getword(hello + 7); 25 | puts(hello); 26 | 27 | return 0; 28 | } 29 | 30 | char * getword(char *target) 31 | { 32 | // read input into character array target 33 | // stop after first word or EOF 34 | // discard rest of the line 35 | 36 | char ch; 37 | int i = 0; 38 | bool inword = false; 39 | 40 | while ((ch = getchar()) != EOF) 41 | { 42 | if (isspace(ch)) 43 | { 44 | if (inword) 45 | break; // word is over, exit while loop 46 | else 47 | { 48 | continue; // skip leading whitespace 49 | } 50 | } 51 | 52 | // if ch is not whitespace 53 | if (!inword) 54 | inword = true; 55 | 56 | *(target + i) = ch; 57 | i++; 58 | } 59 | 60 | // discard rest of the line if any 61 | if (ch != '\n') 62 | while ((ch = getchar()) != '\n') 63 | continue; 64 | 65 | return target; 66 | } -------------------------------------------------------------------------------- /ch11/exercise04.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 11 Exercise 4: 3 | 4 | // Design and test a function like that described in Programming Exercise 3 5 | // except that it accepts a second parameter specifying the maximum number of 6 | // characters that can be read. 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #define SIZE 20 14 | 15 | char * getword(char *target, int max); 16 | 17 | int main(void) 18 | { 19 | // test getword() 20 | 21 | char hello[SIZE] = "Hello, "; 22 | int space = SIZE - strlen(hello) - 1; 23 | 24 | puts("What's your name?"); 25 | getword(hello + 7, space); 26 | puts(hello); 27 | 28 | return 0; 29 | } 30 | 31 | char * getword(char *target, int max) 32 | { 33 | // read input into character array target 34 | // stop after first word , EOF or max characters 35 | // discard rest of the line 36 | 37 | char ch; 38 | int i = 0; 39 | bool inword = false; 40 | 41 | while ((ch = getchar()) != EOF && i < max) 42 | { 43 | if (isspace(ch)) 44 | { 45 | if (inword) 46 | break; // word is over, exit while loop 47 | else 48 | { 49 | continue; // skip leading whitespace 50 | } 51 | } 52 | 53 | // if ch is not whitespace 54 | if (!inword) 55 | inword = true; 56 | 57 | *(target + i) = ch; 58 | i++; 59 | } 60 | 61 | // discard rest of the line if any 62 | if (ch != '\n') 63 | while ((ch = getchar()) != '\n') 64 | continue; 65 | 66 | return target; 67 | } -------------------------------------------------------------------------------- /ch11/exercise05.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 11 Exercise 5: 3 | 4 | // Design and test a function that searches the string specified by the first 5 | // function parameter for the first occurrence of a character specified by the 6 | // second function parameter. Have the function return a pointer to the 7 | // character if successful, and a null if the character is not found in the 8 | // string. (This duplicates the way that the library strchr() function works.) 9 | // Test the function in a complete program that uses a loop to provide input 10 | // values for feeding to the function. 11 | 12 | #include 13 | 14 | #define LIMIT 50 15 | 16 | char * findchar(char *str, const char ch); 17 | 18 | int main(void) 19 | { 20 | char string[LIMIT]; 21 | char *chloc; 22 | char ch; 23 | 24 | // test findchar() 25 | printf("Enter a string to search: "); 26 | fgets(string, LIMIT, stdin); 27 | while (string[0] != '\n') 28 | { 29 | printf("Enter a character to search for: "); 30 | ch = getchar(); 31 | // discard rest of line if any 32 | if (ch != '\n') 33 | while (getchar() != '\n') 34 | continue; 35 | 36 | chloc = findchar(string, ch); 37 | if (chloc == NULL) 38 | printf("Character %c not found in %s", ch, string); 39 | else 40 | printf("Character %c found at index %lu in %s", ch, chloc - string, string); 41 | 42 | // get new input 43 | printf("Enter a string to search (empty line to quit): "); 44 | fgets(string, LIMIT, stdin); 45 | } 46 | 47 | puts("Bye"); 48 | 49 | return 0; 50 | } 51 | 52 | char * findchar(char *str, const char ch) 53 | { 54 | // find and return pointer to first occurence of 55 | // char ch in string str. return NULL if not found 56 | 57 | while (*str != '\0') 58 | { 59 | if (*str == ch) 60 | return str; 61 | str++; 62 | } 63 | 64 | // if ch is not found, return null 65 | return NULL; 66 | } 67 | -------------------------------------------------------------------------------- /ch11/exercise06.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 11 Exercise 6: 3 | 4 | // Write a function called is_within() that takes a character and a string 5 | // pointer as its two function parameters. Have the function return a 6 | // nonzero value (true) if the character is in the string and zero (false) 7 | // otherwise. Test the function in a complete program that uses a loop to 8 | // provide input values for feeding to the function. 9 | 10 | #include 11 | 12 | #define LIMIT 50 13 | 14 | int is_within(char ch, const char *string); 15 | char * get(char *string, int n); 16 | 17 | int main(void) 18 | { 19 | // test is_within() 20 | 21 | char string[LIMIT]; 22 | char ch; 23 | 24 | printf("Enter a string to search: "); 25 | get(string, LIMIT); 26 | while (string[0] != '\0') 27 | { 28 | printf("Enter a character to search for: "); 29 | ch = getchar(); 30 | 31 | if (ch != '\n') 32 | while (getchar() != '\n') 33 | continue; 34 | 35 | char *contains = is_within(ch, string) ? "" : " not"; 36 | 37 | printf("\"%s\" does%s contain %c\n", string, contains, ch); 38 | 39 | printf("Enter a string to search (empty line to quit): "); 40 | get(string, LIMIT); 41 | } 42 | puts("Bye"); 43 | 44 | return 0; 45 | } 46 | 47 | int is_within(char ch, const char *string) 48 | { 49 | // returns 1 if char ch is in string 50 | // returns 0 otherwise 51 | 52 | while(*string != '\0') 53 | { 54 | if (*string == ch) 55 | return 1; 56 | 57 | string++; 58 | } 59 | 60 | return 0; 61 | } 62 | 63 | char * get(char *string, int n) 64 | { 65 | // wrapper for fgets that replaces first newline with null 66 | 67 | char *return_value = fgets(string, n, stdin); 68 | 69 | while (*string != '\0') 70 | { 71 | if (*string == '\n') 72 | { 73 | *string = '\0'; 74 | break; 75 | } 76 | 77 | string++; 78 | } 79 | 80 | return return_value; 81 | } -------------------------------------------------------------------------------- /ch11/exercise07.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 11 Exercise 7: 3 | 4 | // The strncpy(s1,s2,n) function copies exactly n characters from s2 to s1, 5 | // truncating s2 or padding it with extra null characters as necessary. The 6 | // target string may not be null-terminated if the length of s2 is n or more. 7 | // The function returns s1. Write your own version of this function; call it 8 | // mystrncpy(). Test the function in a complete program that uses a loop to 9 | // provide input values for feeding to the function. 10 | 11 | #include 12 | 13 | #define LIMIT 50 14 | 15 | char * mystrcpy(char *s1, char *s2, int n); 16 | char * get(char *string, int n); 17 | void clear_string(char * string, int n); 18 | 19 | int main(void) 20 | { 21 | char s1[LIMIT]; 22 | char s2[LIMIT]; 23 | int n; 24 | 25 | printf("Enter a string to copy: "); 26 | get(s2, LIMIT); 27 | while (s2[0] != '\0') 28 | { 29 | printf("How many characters do you want to copy? (maximum %d) ", LIMIT); 30 | scanf("%d", &n); 31 | 32 | while (getchar() != '\n') 33 | continue; 34 | 35 | if (n > LIMIT) 36 | n = LIMIT; 37 | 38 | printf("Original string: %s\n", s2); 39 | mystrcpy(s1, s2, n); 40 | printf("Copy: %s\n", s1); 41 | 42 | clear_string(s1, LIMIT); 43 | 44 | printf("Enter a string to copy (empty line to quit): "); 45 | get(s2, LIMIT); 46 | } 47 | 48 | puts("Bye"); 49 | 50 | return 0; 51 | } 52 | 53 | char * mystrcpy(char *s1, char *s2, int n) 54 | { 55 | // copy n characters from s2 to s1 56 | // warning: if length of s2 is n or greater 57 | // then s1 may not be null terminated 58 | 59 | int i = 0; 60 | 61 | // copy n characters or until null char 62 | while (s2[i] != '\0' && i < n) 63 | { 64 | s1[i] = s2[i]; 65 | i++; 66 | } 67 | 68 | // if i < n pad s1 with null character 69 | while (i < n) 70 | { 71 | s1[i] = '\0'; 72 | i++; 73 | } 74 | 75 | return s1; 76 | } 77 | 78 | char * get(char *string, int n) 79 | { 80 | // wrapper for fgets that replaces first newline with null 81 | 82 | char *return_value = fgets(string, n, stdin); 83 | 84 | while (*string != '\0') 85 | { 86 | if (*string == '\n') 87 | { 88 | *string = '\0'; 89 | break; 90 | } 91 | 92 | string++; 93 | } 94 | 95 | return return_value; 96 | } 97 | 98 | void clear_string(char *string, int n) 99 | { 100 | // replace first n characters in string with nulls 101 | 102 | for (int i = 0; i < n; i++) 103 | string[i] = '\0'; 104 | } -------------------------------------------------------------------------------- /ch11/exercise08.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 11 Exercise 8: 3 | 4 | // Write a function called string_in() that takes two string pointers as 5 | // arguments. If the second string is contained in the first string, have the 6 | // function return the address at which the contained string begins. For 7 | // instance, string_in("hats", "at") would return the address of the a in hats. 8 | // Otherwise, have the function return the null pointer. Test the function in a 9 | // complete program that uses a loop to provide input values for feeding to the 10 | // function. 11 | 12 | #include 13 | 14 | #define LIMIT 50 15 | 16 | char * string_in(char *string, char *substring); 17 | char * get(char *string, int n); 18 | 19 | int main(void) 20 | { 21 | // test string_in() 22 | 23 | char string[LIMIT]; 24 | char substring[LIMIT]; 25 | 26 | char *substr_loc; 27 | 28 | printf("Enter a string: "); 29 | get(string, LIMIT); 30 | while (string[0] != '\0') 31 | { 32 | printf("Enter a substring to look for: "); 33 | get(substring, LIMIT); 34 | 35 | substr_loc = string_in(string, substring); 36 | 37 | if (substr_loc == NULL) 38 | printf("%s not in %s\n", substring, string); 39 | else 40 | printf("%s found in %s at index %lu\n", 41 | substring, string, substr_loc - string); 42 | 43 | printf("Enter a string (empty line to quit): "); 44 | get(string, LIMIT); 45 | } 46 | 47 | puts("Bye"); 48 | 49 | return 0; 50 | } 51 | 52 | char * string_in(char *string, char *substring) 53 | { 54 | // checks if substring is in string 55 | // returns pointer to first location of substring 56 | // in string or NULL if substring not in string 57 | 58 | int i; 59 | 60 | while (*string != '\0') 61 | { 62 | i = 0; 63 | 64 | // check for substring at current location 65 | while (*(string + i) == *(substring + i)) 66 | { 67 | i++; 68 | 69 | // if next char in substring is null, then match 70 | // is found. return current location 71 | if (*(substring + i) == '\0') 72 | return string; 73 | } 74 | 75 | string++; 76 | } 77 | 78 | // no match 79 | return NULL; 80 | } 81 | 82 | 83 | char * get(char *string, int n) 84 | { 85 | // wrapper for fgets that replaces first newline with null 86 | 87 | char *return_value = fgets(string, n, stdin); 88 | 89 | while (*string != '\0') 90 | { 91 | if (*string == '\n') 92 | { 93 | *string = '\0'; 94 | break; 95 | } 96 | 97 | string++; 98 | } 99 | 100 | return return_value; 101 | } 102 | -------------------------------------------------------------------------------- /ch11/exercise09.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 11 Exercise 9 3 | 4 | // Write a function that replaces the contents of a string with the string 5 | // reversed. Test the function in a complete program that uses a loop to 6 | // provide input values for feeding to the function. 7 | 8 | #include 9 | 10 | #define LIMIT 50 11 | 12 | void reverse_string(char *string); 13 | char * get(char *string, int n); 14 | 15 | int main(void) 16 | { 17 | // test reverse_string() 18 | 19 | char string[LIMIT]; 20 | 21 | printf("Enter a string to reverse: "); 22 | get(string, LIMIT); 23 | while (string[0] != '\0') 24 | { 25 | reverse_string(string); 26 | printf("Your string reversed: %s\n", string); 27 | 28 | printf("Enter a string to reverse (empty line to quit): "); 29 | get(string, LIMIT); 30 | } 31 | 32 | puts("Bye"); 33 | return 0; 34 | } 35 | 36 | void reverse_string(char *start) 37 | { 38 | // replace contents of a string with the string reversed 39 | 40 | char *end = start; 41 | char tmp; 42 | 43 | // find location of the end of the string 44 | while (*(end + 1) != '\0') 45 | end++; 46 | 47 | // switch characters 48 | while (start < end) 49 | { 50 | tmp = *start; 51 | *start = *end; 52 | *end = tmp; 53 | 54 | start++; 55 | end--; 56 | } 57 | } 58 | 59 | 60 | char * get(char *string, int n) 61 | { 62 | // wrapper for fgets that replaces first newline with null 63 | 64 | char *return_value = fgets(string, n, stdin); 65 | 66 | while (*string != '\0') 67 | { 68 | if (*string == '\n') 69 | { 70 | *string = '\0'; 71 | break; 72 | } 73 | 74 | string++; 75 | } 76 | 77 | return return_value; 78 | } 79 | -------------------------------------------------------------------------------- /ch11/exercise10.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 11 Exercise 10: 3 | 4 | // Write a function that takes a string as an argument and removes the spaces 5 | // from the string. Test it in a program that uses a loop to read lines until 6 | // you enter an empty line. The program should apply the function to each input 7 | // string and display the result. 8 | 9 | #include 10 | 11 | #define LIMIT 50 12 | 13 | void remove_spaces(char *string); 14 | char * get(char *string, int n); 15 | 16 | int main(void) 17 | { 18 | // test remove_spaces() 19 | 20 | char string[LIMIT]; 21 | 22 | printf("Test remove_spaces()\n"); 23 | 24 | printf("Enter a string: "); 25 | get(string, LIMIT); 26 | while (string[0] != '\0') 27 | { 28 | remove_spaces(string); 29 | printf("Your string, without spaces: %s\n", string); 30 | 31 | printf("Enter a string (empty line to quit): "); 32 | get(string, LIMIT); 33 | } 34 | puts("Bye"); 35 | 36 | return 0; 37 | } 38 | 39 | void remove_spaces(char *string) 40 | { 41 | // remove all spaces from a string 42 | 43 | unsigned long spaces_found = 0; 44 | 45 | while (1) 46 | { 47 | if (*string == ' ') 48 | spaces_found++; 49 | else 50 | *(string - spaces_found) = *string; 51 | 52 | // if end of string, break 53 | if (*string == '\0') 54 | break; 55 | 56 | string++; 57 | } 58 | } 59 | 60 | char * get(char *string, int n) 61 | { 62 | // wrapper for fgets that replaces first newline with null 63 | 64 | char *return_value = fgets(string, n, stdin); 65 | 66 | while (*string != '\0') 67 | { 68 | if (*string == '\n') 69 | { 70 | *string = '\0'; 71 | break; 72 | } 73 | 74 | string++; 75 | } 76 | 77 | return return_value; 78 | } 79 | -------------------------------------------------------------------------------- /ch11/exercise12.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 11 Exercise 12: 3 | 4 | // Write a program that reads input up to EOF and reports the number of words, 5 | // the number of uppercase letters, the number of lowercase letters, the number 6 | // of punctuation characters, and the number of digits. Use the ctype.h family 7 | // of functions. 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | int main(void) 14 | { 15 | // read input to EOF and report number of words, lowercase letters, 16 | // uppercase letters, punct. marks and digits 17 | 18 | char ch; 19 | int upcase_letters, lowcase_letters, punct_chars, digits, words; 20 | upcase_letters = lowcase_letters = punct_chars = digits = words = 0; 21 | bool inword = false; 22 | 23 | while ((ch = getchar()) != EOF) 24 | { 25 | if (isalpha(ch)) 26 | { 27 | if (!inword) // count new word 28 | { 29 | inword = true; 30 | words++; 31 | } 32 | 33 | if (isupper(ch)) 34 | upcase_letters++; 35 | if (islower(ch)) 36 | lowcase_letters++; 37 | } 38 | else if (ispunct(ch)) 39 | { 40 | punct_chars++; 41 | 42 | if (ch != '-' && ch != '\'') 43 | inword = false; 44 | } 45 | else if (isdigit(ch)) 46 | { 47 | digits++; 48 | inword = false; 49 | } 50 | else if (isspace(ch)) 51 | inword = false; 52 | } 53 | 54 | printf("Number of %s: %d\n", "lowercase letters", lowcase_letters); 55 | printf("Number of %s: %d\n", "uppercase letters", upcase_letters); 56 | printf("Number of %s: %d\n", "punctuation characters", punct_chars); 57 | printf("Number of %s: %d\n", "digits", digits); 58 | printf("Number of %s: %d\n", "words", words); 59 | 60 | return 0; 61 | } 62 | -------------------------------------------------------------------------------- /ch11/exercise13.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 11 Exercise 13 3 | 4 | // Write a program that echoes the command-line arguments in reverse word 5 | // order. That is, if the command-line arguments are see you later, the program 6 | // should print later you see. 7 | 8 | #include 9 | 10 | int main(int argc, char *argv[]) 11 | { 12 | if (argc < 2) 13 | { 14 | printf("Error: at least one command-line argument required.\n"); 15 | return 1; 16 | } 17 | else 18 | for (int i = argc - 1; i > 0; i--) 19 | printf("%s ", argv[i]); 20 | 21 | puts(""); 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /ch11/exercise14.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 11 Exercise 14: 3 | 4 | // Write a power-law program that works on a command-line basis. The first 5 | // command-line argument should be the type double number to be raised to a 6 | // certain power, and the second argument should be the integer power. 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | void print_error_message(void); 13 | 14 | int main(int argc, char *argv[]) 15 | { 16 | double base; 17 | long power; 18 | char *end; 19 | 20 | if (argc != 3) 21 | { 22 | print_error_message(); 23 | return 1; 24 | } 25 | 26 | // get base 27 | end = argv[1]; 28 | while (*end != '\0') 29 | end++; 30 | base = strtod(argv[1], &end); 31 | 32 | if (*end) // error condition 33 | { 34 | print_error_message(); 35 | return 1; 36 | } 37 | 38 | // get exponent 39 | end = argv[2]; 40 | while (*end != '\0') 41 | end++; 42 | power = strtol(argv[2], &end, 10); 43 | 44 | if (*end) // error condition 45 | { 46 | print_error_message(); 47 | return 1; 48 | } 49 | 50 | printf("%f ^ %ld = %f\n", base, power, pow(base, power)); 51 | 52 | return 0; 53 | } 54 | 55 | void print_error_message(void) 56 | { 57 | puts("Usage: "); 58 | } 59 | -------------------------------------------------------------------------------- /ch11/exercise15.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 11 Exercise 15: 3 | 4 | // Use the character classification functions to prepare an implementation of 5 | // atoi(); have this version return the value of 0 if the input string is not a 6 | // pure number. 7 | 8 | #include 9 | #include 10 | 11 | int my_atoi(char *string); 12 | 13 | int main(int argc, char *argv[]) 14 | { 15 | // driver for my_atoi() 16 | 17 | int input; 18 | 19 | if (argc != 2) 20 | puts("Usage: "); 21 | else 22 | { 23 | input = my_atoi(argv[1]); 24 | printf("%d + 5 = %d\n", input, input + 5); 25 | printf("%d / 2 = %d\n", input, input / 2); 26 | printf("%d %% 3 = %d\n", input, input % 3); 27 | } 28 | 29 | return 0; 30 | } 31 | 32 | int my_atoi(char *string) 33 | { 34 | // convert string to integer 35 | // returns 0 on error 36 | 37 | int total = 0; 38 | 39 | while (*string != '\0') 40 | { 41 | if (!isdigit(*string)) 42 | // string is not a pure integer -- return 0 43 | return 0; 44 | else 45 | { 46 | total *= 10; // shift digits one place to left 47 | total += *string - '0'; // add newest digit in ones place 48 | } 49 | 50 | string++; 51 | } 52 | 53 | return total; 54 | } 55 | -------------------------------------------------------------------------------- /ch11/exercise16.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 11 Exercise 16: 3 | 4 | // Write a program that reads input until end-of-file and echoes it to the 5 | // display. Have the program recognize and implement the following command-line 6 | // arguments: 7 | // - p Print input as is 8 | // - u Map input to all uppercase 9 | // - l Map input to all lowercase 10 | // Also, if there are no command-line arguments, let the program behave as if 11 | // the –p argument had been used. 12 | 13 | #include 14 | #include 15 | 16 | void map_identity(void); 17 | void map_uppercase(void); 18 | void map_lowercase(void); 19 | 20 | int main(int argc, char *argv[]) 21 | { 22 | if (argc == 1) 23 | { 24 | map_identity(); 25 | return 0; 26 | } 27 | 28 | else if (argc > 2 || (argc == 2 && argv[1][0] != '-')) 29 | { 30 | printf("Usage: program_name [-p | -l | -u]\n"); 31 | return 1; 32 | } 33 | 34 | else 35 | switch(argv[1][1]) 36 | { 37 | case ('p'): 38 | map_identity(); 39 | break; 40 | case ('u'): 41 | map_uppercase(); 42 | break; 43 | case ('l'): 44 | map_lowercase(); 45 | break; 46 | default: 47 | printf("Usage: program_name [-p | -l | -u]\n"); 48 | return 1; 49 | } 50 | 51 | return 0; 52 | } 53 | 54 | void map_identity(void) 55 | { 56 | char ch; 57 | 58 | while((ch = getchar()) != EOF) 59 | putchar(ch); 60 | } 61 | 62 | void map_uppercase(void) 63 | { 64 | char ch; 65 | 66 | while((ch = getchar()) != EOF) 67 | { 68 | if (islower(ch)) 69 | ch = toupper(ch); 70 | putchar(ch); 71 | } 72 | } 73 | 74 | void map_lowercase(void) 75 | { 76 | char ch; 77 | 78 | while((ch = getchar()) != EOF) 79 | { 80 | if (isupper(ch)) 81 | ch = tolower(ch); 82 | putchar(ch); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /ch12/exercise01.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 12 Exercise 1: 3 | 4 | // Rewrite the program in Listing 12.4 so that it does not use global variables. 5 | 6 | #include 7 | 8 | void critic(int *units); 9 | 10 | int main(void) 11 | { 12 | int units; /* an optional redeclaration */ 13 | 14 | printf("How many pounds to a firkin of butter?\n"); 15 | scanf("%d", &units); 16 | while (units != 56) 17 | critic(&units); 18 | printf("You must have looked it up!\n"); 19 | 20 | return 0; 21 | } 22 | 23 | void critic(int *units) { 24 | printf("No luck, my friend. Try again.\n"); 25 | scanf("%d", units); 26 | } -------------------------------------------------------------------------------- /ch12/exercise02-b.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include "exercise02.h" 4 | 5 | #define METRIC 0 6 | #define US 1 7 | 8 | static int mode; 9 | static double distance; 10 | static double fuel; 11 | 12 | void clear_input_stream(void) 13 | { 14 | while (getchar() != '\n') 15 | continue; 16 | } 17 | 18 | void set_mode(int new_mode) 19 | { 20 | extern int mode; 21 | if (new_mode == METRIC || new_mode == US) 22 | mode = new_mode; 23 | else 24 | printf("Invalid mode specified. Mode %d(%s) used.\n", 25 | mode, mode == METRIC ? "metric" : "US"); 26 | } 27 | 28 | void get_info(void) 29 | { 30 | printf("Enter distance travelled in %s: ", 31 | mode == METRIC ? "kilometers" : "miles"); 32 | while (scanf("%lf", &distance) != 1) 33 | { 34 | clear_input_stream(); 35 | printf("Invalid input. Enter distance travelled in %s: ", 36 | mode == METRIC ? "kilometers" : "miles"); 37 | } 38 | 39 | printf("Enter fuel consumed in %s: ", 40 | mode == METRIC ? "liters" : "gallons"); 41 | while (scanf("%lf", &fuel) != 1) 42 | { 43 | clear_input_stream(); 44 | printf("Invalid input. Enter fuel consumed in %s: ", 45 | mode == METRIC ? "liters" : "gallons"); 46 | } 47 | } 48 | 49 | void show_info(void) 50 | { 51 | double efficiency; 52 | 53 | if (mode == METRIC) 54 | { 55 | efficiency = fuel / distance * 100; 56 | printf("Fuel consumption is %.3f liters per 100 kilometers.\n", 57 | efficiency); 58 | } 59 | else if (mode == US) 60 | { 61 | efficiency = distance / fuel; 62 | printf("Fuel consumption is %.3f miles per gallon.\n", 63 | efficiency); 64 | } 65 | else 66 | { 67 | printf("Error. Invalid mode: %d\n", mode); 68 | } 69 | 70 | } -------------------------------------------------------------------------------- /ch12/exercise02.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 12 Exercise 2: 3 | 4 | // Gasoline consumption commonly is computed in miles per gallon in the U.S. 5 | // and in liters per 100 kilometers in Europe. What follows is part of a 6 | // program that asks the user to choose a mode (metric or U.S.) and then 7 | // gathers data and computes fuel consumption. If the user enters an incorrect 8 | // mode, the program comments on that and uses the most recent mode. Supply a 9 | // header file and a pe12-2a.c source code file to make this work. The source 10 | // code file should define three file-scope, internal-linkage variables. One 11 | // represents the mode, one represents the distance, and one represents the 12 | // fuel consumed. The get_info() function prompts for data according to the 13 | // mode setting and stores the responses in the file-scope variables. The 14 | // show_info() function calculates and displays the fuel consumption based on 15 | // the mode setting. You can assume the user responds with numeric input. 16 | 17 | 18 | // compile with exercise02-b.c 19 | 20 | #include 21 | #include "exercise02.h" 22 | 23 | int main(void) 24 | { 25 | int mode; 26 | 27 | printf("Enter 0 for metric mode, 1 for US mode: "); 28 | scanf("%d", &mode); 29 | while (mode >= 0) 30 | { 31 | set_mode(mode); 32 | get_info(); 33 | show_info(); 34 | printf("Enter 0 for metric mode, 1 for US mode"); 35 | printf(" (-1 to quit): "); 36 | scanf("%d", &mode); 37 | } 38 | 39 | printf("Done.\n"); 40 | return 0; 41 | } -------------------------------------------------------------------------------- /ch12/exercise02.h: -------------------------------------------------------------------------------- 1 | // exercise02.h 2 | 3 | void set_mode(int mode); 4 | void get_info(void); 5 | void show_info(void); -------------------------------------------------------------------------------- /ch12/exercise03-b.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include "exercise03.h" 4 | 5 | #define METRIC 0 6 | #define US 1 7 | #define QUIT -1 8 | 9 | void clear_input_stream(void) 10 | { 11 | while (getchar() != '\n') 12 | continue; 13 | } 14 | 15 | void set_mode(int *mode) 16 | { 17 | int new_mode = 2; 18 | printf("Enter 0 for metric mode, 1 for US mode (-1 to quit): "); 19 | 20 | if (scanf("%d", &new_mode) != 1) 21 | clear_input_stream(); 22 | 23 | if (new_mode == METRIC || new_mode == US || new_mode == QUIT) 24 | *mode = new_mode; 25 | else 26 | { 27 | printf("Invalid mode specified. Mode %d(%s) used.\n", 28 | *mode, *mode == METRIC ? "metric" : "US"); 29 | } 30 | 31 | } 32 | 33 | void get_info(int mode, double *distance, double *fuel) 34 | { 35 | printf("Enter distance travelled in %s: ", 36 | mode == METRIC ? "kilometers" : "miles"); 37 | while (scanf("%lf", distance) != 1) 38 | { 39 | clear_input_stream(); 40 | printf("Invalid input. Enter distance travelled in %s: ", 41 | mode == METRIC ? "kilometers" : "miles"); 42 | } 43 | 44 | printf("Enter fuel consumed in %s: ", 45 | mode == METRIC ? "liters" : "gallons"); 46 | while (scanf("%lf", fuel) != 1) 47 | { 48 | clear_input_stream(); 49 | printf("Invalid input. Enter fuel consumed in %s: ", 50 | mode == METRIC ? "liters" : "gallons"); 51 | } 52 | } 53 | 54 | void show_info(int mode, double distance, double fuel) 55 | { 56 | double efficiency; 57 | 58 | if (mode == METRIC) 59 | { 60 | efficiency = fuel / distance * 100; 61 | printf("Fuel consumption is %.3f liters per 100 kilometers.\n", 62 | efficiency); 63 | } 64 | else if (mode == US) 65 | { 66 | efficiency = distance / fuel; 67 | printf("Fuel consumption is %.3f miles per gallon.\n", 68 | efficiency); 69 | } 70 | else 71 | { 72 | printf("Error. Invalid mode: %d\n", mode); 73 | } 74 | 75 | } -------------------------------------------------------------------------------- /ch12/exercise03.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 12 Exercise 3: 3 | 4 | // Redesign the program described in Programming Exercise 2 so that it uses 5 | // only automatic variables. Have the program offer the same user interface— 6 | // that is, it should prompt the user to enter a mode, and so on. You’ll have 7 | // to come up with a different set of function calls, however. 8 | 9 | 10 | // compile with exercise02-b.c 11 | 12 | #include 13 | #include "exercise03.h" 14 | 15 | int main(void) 16 | { 17 | int mode = 0; 18 | double distance, fuel; 19 | 20 | set_mode(&mode); 21 | while (mode >= 0) 22 | { 23 | get_info(mode, &distance, &fuel); 24 | show_info(mode, distance, fuel); 25 | set_mode(&mode); 26 | } 27 | 28 | printf("Done.\n"); 29 | return 0; 30 | } -------------------------------------------------------------------------------- /ch12/exercise03.h: -------------------------------------------------------------------------------- 1 | // exercise03.h 2 | // function prototypes for exercise 3 3 | 4 | void set_mode(int *mode); 5 | void get_info(int mode, double *distance, double *fuel); 6 | void show_info(int mode, double distance, double fuel); -------------------------------------------------------------------------------- /ch12/exercise04.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 12 Exercise 4: 3 | 4 | // Write and test in a loop a function that returns the number of times it has 5 | // been called. 6 | 7 | #include 8 | 9 | unsigned int counter(void); 10 | 11 | int main(void) 12 | { 13 | // test counter() 14 | int iterations = 0; 15 | printf("How many times do you want to call counter()? "); 16 | scanf("%d", &iterations); 17 | for (int i = 0; i < iterations; i++) 18 | printf("counter() returns %u\n", counter()); 19 | 20 | return 0; 21 | } 22 | 23 | unsigned int counter(void) 24 | { 25 | static unsigned int call_count = 0; 26 | return ++call_count; 27 | } -------------------------------------------------------------------------------- /ch12/exercise05.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 12 Exercise 5: 3 | 4 | // Write a program that generates a list of 100 random numbers in the range 5 | // 1–10 in sorted decreasing order. (You can adapt the sorting algorithm from 6 | // Chapter 11, “Character Strings and String Functions,” to type int. In this 7 | // case, just sort the numbers themselves.) 8 | 9 | #include 10 | #include 11 | 12 | void random_ints(int *int_array); 13 | 14 | int main(void) 15 | { 16 | // test random ints 17 | int int_array[100]; 18 | random_ints(int_array); 19 | 20 | for (int i = 0; i < 100; i++) 21 | { 22 | printf("%2d ", int_array[i]); 23 | if (i % 20 == 19) 24 | putchar('\n'); 25 | } 26 | 27 | putchar('\n'); 28 | return 0; 29 | } 30 | 31 | void random_ints(int *int_array) 32 | { 33 | int tmp; 34 | 35 | // initialize array 36 | for (int i = 0; i < 100; i++) 37 | int_array[i] = rand() % 10 + 1; 38 | 39 | // sort array in decreasing order 40 | for (int i = 0; i < 99; i++) 41 | for (int j = i + 1; j < 100; j++) 42 | { 43 | if (int_array[i] < int_array[j]) 44 | { 45 | tmp = int_array[i]; 46 | int_array[i] = int_array[j]; 47 | int_array[j] = tmp; 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /ch12/exercise06.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 12 Exercise 6: 3 | 4 | // Write a program that generates 1,000 random numbers in the range 1–10. Don’t 5 | // save or print the numbers, but do print how many times each number was 6 | // produced. Have the program do this for 10 different seed values. Do the 7 | // numbers appear in equal amounts? You can use the functions from this chapter 8 | // or the ANSI C rand() and srand() functions, which follow the same format 9 | // that our functions do. This is one way to examine the randomness of a 10 | // particular random-number generator. 11 | 12 | #include 13 | #include 14 | 15 | #define SIZE 1000 16 | 17 | 18 | void random_sample(void); 19 | 20 | int main(void) 21 | { 22 | for (int i = 1; i < 11; i++) 23 | { 24 | printf("Random Sample: run #%d\n", i); 25 | srand(i); 26 | random_sample(); 27 | putchar('\n'); 28 | } 29 | 30 | return 0; 31 | } 32 | 33 | void random_sample(void) 34 | { 35 | int counts[10] = {0,0,0,0,0,0,0,0,0,0}; 36 | const int RAND_LIMIT = (RAND_MAX / 10) * 10; 37 | int rand_int; 38 | 39 | int i = 0; 40 | while (i < SIZE) 41 | { 42 | rand_int = rand(); 43 | if (rand_int >= RAND_LIMIT) 44 | continue; 45 | else 46 | { 47 | rand_int %= 10; 48 | counts[rand_int]++; 49 | } 50 | i++; 51 | } 52 | puts("Counts"); 53 | for (int i = 0; i < 10; i++) 54 | printf("%2d: %3d ", i + 1, counts[i]); 55 | putchar('\n'); 56 | 57 | } -------------------------------------------------------------------------------- /ch12/exercise07-b.c: -------------------------------------------------------------------------------- 1 | // exercise07-b.c -- function definitions for exercise07.c 2 | 3 | #include "exercise07.h" 4 | #include 5 | #include 6 | 7 | static int rolldie(int sides) 8 | { 9 | // roll one n-sided die and return outcome 10 | 11 | return rand() % sides + 1; 12 | } 13 | 14 | int rolldice(int dice, int sides) 15 | { 16 | // roll multiple n-sided dice and return outcome 17 | 18 | int total = 0; 19 | 20 | for (int i = 0; i < dice; i++) 21 | total += rolldie(sides); 22 | 23 | return total; 24 | } 25 | 26 | void dicerolls(int sets, int dice, int sides) 27 | { 28 | // roll multiple sets of multiple n-sided dice and print results 29 | 30 | printf("Here are %d sets of %d %d-sided throws.\n", sets, dice, sides); 31 | for (int i = 0; i < sets; i++) 32 | printf("%2d ", rolldice(dice, sides)); 33 | putchar('\n'); 34 | } -------------------------------------------------------------------------------- /ch12/exercise07.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 12 Exercise 7: 3 | 4 | // Write a program that behaves like the modification of Listing 12.13, which 5 | // we discussed after showing the output of Listing 12.13. That is, have the 6 | // program produce output like the following: 7 | // > Enter the number of sets; enter q to stop: 18 8 | // > How many sides and how many dice? 6 3 9 | // > Here are 18 sets of 3 6-sided throws. 10 | // > 12 10 6 9 8 14 8 15 9 14 12 17 11 7 10 11 | // 13 8 14 12 | // > How many sets? Enter q to stop: q 13 | 14 | // compile with exercise07-b.c 15 | 16 | #include 17 | #include "exercise07.h" 18 | 19 | void clear_input_stream(void); 20 | 21 | int main(void) 22 | { 23 | int sets, dice, sides; 24 | 25 | puts("Enter the number of sets; enter q to stop."); 26 | while (scanf("%d", &sets) == 1 && sets > 0) 27 | { 28 | dice = sides = -1; 29 | printf("How many sides and how many dice? "); 30 | scanf("%d %d", &sides, &dice); 31 | while (dice < 0 || sides < 0) 32 | { 33 | clear_input_stream(); 34 | puts("Invalid input. Positive integers only."); 35 | puts("How many sides and how many dice? "); 36 | scanf("%d %d", &sides, &dice); 37 | } 38 | 39 | dicerolls(sets, dice, sides); 40 | 41 | puts("How many sets? Enter q to stop."); 42 | } 43 | 44 | return 0; 45 | } 46 | 47 | void clear_input_stream(void) 48 | { 49 | while (getchar() != '\n') 50 | continue; 51 | } 52 | -------------------------------------------------------------------------------- /ch12/exercise07.h: -------------------------------------------------------------------------------- 1 | // header file for exercise 7 2 | 3 | int rolldice(int dice, int sides); 4 | 5 | void dicerolls(int sets, int dice, int sides); -------------------------------------------------------------------------------- /ch12/exercise08.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 12 Exercise 8: 3 | 4 | // Here’s part of a program: 5 | 6 | // [omitted] 7 | 8 | // Complete the program by providing function definitions for make_array() and 9 | // show_array(). The make_array() function takes two arguments. The first is 10 | // the number of elements of an int array, and the second is a value that is to 11 | // be assigned to each element. The function uses malloc() to create an array 12 | // of a suitable size, sets each element to the indicated value, and returns a 13 | // pointer to the array. The show_array() function displays the contents, eight 14 | // numbers to a line. 15 | 16 | #include 17 | #include 18 | 19 | int * make_array(int elem, int val); 20 | 21 | void show_array(const int ar[], int n); 22 | 23 | int main(void) 24 | { 25 | int * pa; 26 | int size; 27 | int value; 28 | 29 | printf("Enter the number of elements: "); 30 | while (scanf("%d", &size) == 1 && size > 0) 31 | { 32 | printf("Enter the initialization value: "); 33 | scanf("%d", &value); 34 | 35 | pa = make_array(size, value); 36 | if (pa) 37 | { 38 | show_array(pa, size); 39 | free(pa); 40 | } 41 | printf("Enter the number of elements (<1 to quit): "); 42 | } 43 | printf("Done.\n"); 44 | return 0; 45 | } 46 | 47 | int * make_array(int elem, int val) 48 | { 49 | // generate and return pointer to a new array of ints 50 | // of length elem with each element initialized to val 51 | 52 | int *arr = (int *) malloc(elem * sizeof(int)); 53 | 54 | if (arr != NULL) 55 | for (int i = 0; i < elem; i++) 56 | arr[i] = val; 57 | 58 | return arr; 59 | } 60 | 61 | void show_array(const int ar[], int n) 62 | { 63 | // print contents of an array of ints, 8 elements to a line 64 | int i; 65 | for (i = 0; i < n; i++) 66 | { 67 | printf("%d ", ar[i]); 68 | if (i % 8 == 7) 69 | putchar('\n'); 70 | } 71 | if (i % 8 != 0) 72 | putchar('\n'); 73 | } -------------------------------------------------------------------------------- /ch13/data.txt: -------------------------------------------------------------------------------- 1 | 0 0 9 0 0 0 0 0 0 0 0 0 5 8 9 9 8 5 2 0 0 0 0 0 0 0 0 0 0 0 2 | 0 0 0 0 9 0 0 0 0 0 0 0 5 8 9 9 8 5 5 2 0 0 0 0 0 0 0 0 0 0 3 | 0 0 0 0 0 0 0 0 0 0 0 0 5 8 1 9 8 5 4 5 2 0 0 0 0 0 0 0 0 0 4 | 0 0 0 0 9 0 0 0 0 0 0 0 5 8 9 9 8 5 0 4 5 2 0 0 0 0 0 0 0 0 5 | 0 0 9 0 0 0 0 0 0 0 0 0 5 8 9 9 8 5 0 0 4 5 2 0 0 0 0 0 0 0 6 | 0 0 0 0 0 0 0 0 0 0 0 0 5 8 9 1 8 5 0 0 0 4 5 2 0 0 0 0 0 0 7 | 0 0 0 0 0 0 0 0 0 0 0 0 5 8 9 9 8 5 0 0 0 0 4 5 2 0 0 0 0 0 8 | 5 5 5 5 5 5 5 5 5 5 5 5 5 8 9 9 8 5 5 5 5 5 5 5 5 5 5 5 5 5 9 | 8 8 8 8 8 8 8 8 8 8 8 8 5 8 9 9 8 5 8 8 8 8 8 8 8 8 8 8 8 8 10 | 9 9 9 9 0 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 3 9 9 9 9 9 9 9 11 | 8 8 8 8 8 8 8 8 8 8 8 8 5 8 9 9 8 5 8 8 8 8 8 8 8 8 8 8 8 8 12 | 5 5 5 5 5 5 5 5 5 5 5 5 5 8 9 9 8 5 5 5 5 5 5 5 5 5 5 5 5 5 13 | 0 0 0 0 0 0 0 0 0 0 0 0 5 8 9 9 8 5 0 0 0 0 0 0 0 0 0 0 0 0 14 | 0 0 0 0 0 0 0 0 0 0 0 0 5 8 9 9 8 5 0 0 0 0 6 6 0 0 0 0 0 0 15 | 0 0 0 0 2 2 0 0 0 0 0 0 5 8 9 9 8 5 0 0 5 6 0 0 6 5 0 0 0 0 16 | 0 0 0 0 3 3 0 0 0 0 0 0 5 8 9 9 8 5 0 5 6 1 1 1 1 6 5 0 0 0 17 | 0 0 0 0 4 4 0 0 0 0 0 0 5 8 9 9 8 5 0 0 5 6 0 0 6 5 0 0 0 0 18 | 0 0 0 0 5 5 0 0 0 0 0 0 5 8 9 9 8 5 0 0 0 0 6 6 0 0 0 0 0 0 19 | 0 0 0 0 0 0 0 0 0 0 0 0 5 8 9 9 8 5 0 0 0 0 0 0 0 0 0 0 0 0 20 | 0 0 0 0 0 0 0 0 0 0 0 0 5 8 9 9 8 5 0 0 0 0 0 0 0 0 0 0 0 0 -------------------------------------------------------------------------------- /ch13/exercise01.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 13 Exercise 1: 3 | 4 | // Modify Listing 13.1 so that it solicits the user to enter the filename and 5 | // reads the user’s response instead of using command-line arguments. 6 | 7 | #include 8 | #include 9 | 10 | #define SLEN 81 11 | 12 | void get(char * string, int n); 13 | 14 | int main(void) 15 | { 16 | int ch; 17 | FILE * fp; 18 | char filename[SLEN]; 19 | unsigned long chcount = 0; 20 | 21 | printf("Enter a file name: "); 22 | get(filename, SLEN); 23 | 24 | if ((fp = fopen(filename, "r")) == NULL) 25 | { 26 | printf("Could not open file %s\n", filename); 27 | exit(EXIT_FAILURE); 28 | } 29 | 30 | while ((ch = getc(fp)) != EOF) 31 | { 32 | putc(ch, stdout); 33 | chcount++; 34 | } 35 | 36 | printf("File %s has %lu characters.\n", filename, chcount); 37 | 38 | fclose(fp); 39 | 40 | return 0; 41 | } 42 | 43 | void get(char * string, int n) 44 | { 45 | // wrapper for fgets - read from stdin and replace 46 | // first newline with null character 47 | 48 | fgets(string, n, stdin); 49 | 50 | while (*string != '\0') 51 | { 52 | if (*string == '\n') 53 | { 54 | *string = '\0'; 55 | break; 56 | } 57 | string++; 58 | } 59 | } -------------------------------------------------------------------------------- /ch13/exercise02.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 13 Exercise 2: 3 | 4 | // Write a file-copy program that takes the original filename and the copy file 5 | // from the command line. Use standard I/O and the binary mode, if possible. 6 | 7 | #include 8 | #include 9 | 10 | int main(int argc, char *argv[]) 11 | { 12 | int ch; 13 | FILE * fsource; 14 | FILE * fdest; 15 | 16 | if (argc != 3) 17 | { 18 | printf("Usage: %s source_file destination_file\n", argv[0]); 19 | exit(EXIT_FAILURE); 20 | } 21 | 22 | if ((fsource = fopen(argv[1], "rb")) == NULL) 23 | { 24 | fprintf(stderr, "Could not open file %s for read\n", argv[1]); 25 | exit(EXIT_FAILURE); 26 | } 27 | if ((fdest = fopen(argv[2], "wb")) == NULL) 28 | { 29 | fprintf(stderr, "Could not open file %s for write\n", argv[2]); 30 | exit(EXIT_FAILURE); 31 | } 32 | 33 | while ((ch = getc(fsource)) != EOF) 34 | putc(ch, fdest); 35 | 36 | fclose(fsource); 37 | fclose(fdest); 38 | 39 | return 0; 40 | } -------------------------------------------------------------------------------- /ch13/exercise03.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 13 Exercise 3: 3 | 4 | // Write a file copy program that prompts the user to enter the name of a text 5 | // file to act as the source file and the name of an output file. The program 6 | // should use the toupper() function from ctype.h to convert all text to 7 | // uppercase as it’s written to the output file. Use standard I/O and the text 8 | // mode. 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | #define SLEN 81 15 | 16 | void get(char * string, int n); 17 | 18 | int main(void) 19 | { 20 | int ch; 21 | FILE * fsource; 22 | FILE * fdest; 23 | char source[SLEN]; 24 | char dest[SLEN]; 25 | 26 | printf("Enter a source file: "); 27 | get(source, SLEN); 28 | printf("Enter a destination file: "); 29 | get(dest, SLEN); 30 | 31 | if ((fsource = fopen(source, "r")) == NULL) 32 | { 33 | fprintf(stderr, "Could not open file %s for read.\n", source); 34 | exit(EXIT_FAILURE); 35 | } 36 | if ((fdest = fopen(dest, "w")) == NULL) 37 | { 38 | fprintf(stderr, "Could not open file %s for write.\n", dest); 39 | exit(EXIT_FAILURE); 40 | } 41 | while ((ch = getc(fsource)) != EOF) 42 | { 43 | if (islower(ch)) 44 | ch = toupper(ch); 45 | putc(ch, fdest); 46 | } 47 | 48 | fclose(fsource); 49 | fclose(fdest); 50 | 51 | return 0; 52 | } 53 | 54 | void get(char * string, int n) 55 | { 56 | // wrapper for fgets - read from stdin and replace 57 | // first newline with null character 58 | 59 | fgets(string, n, stdin); 60 | 61 | while (*string != '\0') 62 | { 63 | if (*string == '\n') 64 | { 65 | *string = '\0'; 66 | break; 67 | } 68 | string++; 69 | } 70 | } -------------------------------------------------------------------------------- /ch13/exercise04.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 13 Exercise 4: 3 | 4 | // Write a program that sequentially displays onscreen all the files listed in 5 | // the command line. Use argc to control a loop. 6 | 7 | #include 8 | #include 9 | 10 | int main(int argc, char *argv[]) 11 | { 12 | FILE * fp; 13 | int ch; 14 | 15 | if (argc == 1) 16 | { 17 | printf("Usage: %s file1 file2 ...\n", argv[0]); 18 | exit(EXIT_FAILURE); 19 | } 20 | for (int i = 1; i < argc; i++) 21 | { 22 | if ((fp = fopen(argv[i], "r")) == NULL) 23 | { 24 | fprintf(stderr, "Could not open file %s.\n", argv[i]); 25 | exit(EXIT_FAILURE); 26 | } 27 | 28 | while ((ch = getc(fp)) != EOF) 29 | putc(ch, stdout); 30 | 31 | fclose(fp); 32 | } 33 | 34 | return 0; 35 | } -------------------------------------------------------------------------------- /ch13/exercise05.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 13 Exercise 05: 3 | 4 | // Modify the program in Listing 13.5 so that it uses a command-line interface 5 | // instead of an interactive interface. 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #define BUFSIZE 4096 12 | 13 | void append(FILE *source, FILE *dest); 14 | 15 | int main(int argc, char *argv[]) 16 | { 17 | FILE * fa; 18 | FILE * fs; 19 | int files = 0; 20 | int ch; 21 | 22 | if (argc < 3) 23 | { 24 | printf("Usage: %s targetfile sourcefile1 [sourcefile2] ...\n", argv[0]); 25 | exit(EXIT_FAILURE); 26 | } 27 | 28 | if ((fa = fopen(argv[1], "a+")) == NULL) 29 | { 30 | fprintf(stderr, "Could not open file %s\n", argv[1]); 31 | exit(EXIT_FAILURE); 32 | } 33 | 34 | if (setvbuf(fa, NULL, _IOFBF, BUFSIZE) != 0) 35 | { 36 | fprintf(stderr, "Could not create output buffer.\n"); 37 | exit(EXIT_FAILURE); 38 | } 39 | 40 | for (int i = 2; i < argc; i++) 41 | { 42 | if (strcmp(argv[i], argv[1]) == 0) 43 | { 44 | fprintf(stderr, "Can't append file to itself.\n"); 45 | } 46 | else if ((fs = fopen(argv[i], "r")) == NULL) 47 | { 48 | fprintf(stderr, "Could not open file %s\n", argv[i]); 49 | } 50 | else 51 | { 52 | if (setvbuf(fs, NULL, _IOFBF, BUFSIZE) != 0) 53 | { 54 | fprintf(stderr, "Could not create input buffer.\n"); 55 | continue; 56 | } 57 | append(fs, fa); 58 | if (ferror(fs) != 0) 59 | fprintf(stderr, "Error in reading file %s.\n", argv[i]); 60 | if (ferror(fa) != 0) 61 | fprintf(stderr, "Error in writing to file %s.\n", argv[1]); 62 | fclose(fs); 63 | files++; 64 | printf("File %s appended.\n", argv[i]); 65 | } 66 | } 67 | printf("Done appending. %d files appended.\n", files); 68 | 69 | rewind(fa); 70 | printf("%s contents:\n", argv[1]); 71 | while ((ch = getc(fa)) != EOF) 72 | putchar(ch); 73 | puts("Done displaying.\n"); 74 | fclose(fa); 75 | 76 | return 0; 77 | } 78 | 79 | void append(FILE *source, FILE *dest) 80 | { 81 | size_t bytes; 82 | static char temp[BUFSIZE]; 83 | 84 | while ((bytes = fread(temp, sizeof(char), BUFSIZE, source)) > 0) 85 | fwrite(temp, sizeof(char), bytes, dest); 86 | } -------------------------------------------------------------------------------- /ch13/exercise06.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 13 Exercise 6: 3 | 4 | // Programs using command-line arguments rely on the user’s memory of how to 5 | // use them correctly. Rewrite the program in Listing 13.2 so that, instead of 6 | // using command-line arguments, it prompts the user for the required 7 | // information. 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #define SLEN 81 14 | 15 | void get(char * string, int n); 16 | 17 | int main(void) 18 | { 19 | FILE *in; 20 | FILE *out; 21 | char source[SLEN]; 22 | char dest[SLEN]; 23 | int ch; 24 | unsigned int count = 0; 25 | 26 | printf("Enter a file to reduce: "); 27 | get(source, SLEN - 5); 28 | 29 | if ((in = fopen(source, "r")) == NULL) 30 | { 31 | fprintf(stderr, "Could not open file %s.\n", source); 32 | exit(EXIT_FAILURE); 33 | } 34 | 35 | strcpy(dest, source); 36 | strcat(dest, ".red"); 37 | if ((out = fopen(dest, "w")) == NULL) 38 | { 39 | fprintf(stderr, "Could not open file %s.\n", dest); 40 | exit(EXIT_FAILURE); 41 | } 42 | while ((ch = getc(in)) != EOF) 43 | if (count++ % 3 == 0) 44 | putc(ch, out); 45 | 46 | if (fclose(in) != 0) 47 | printf("Error in closing file %s.\n", source); 48 | if (fclose(out) != 0) 49 | printf("Error in closing file %s.\n", dest); 50 | 51 | return 0; 52 | } 53 | 54 | void get(char * string, int n) 55 | { 56 | // wrapper for fgets - read from stdin and replace 57 | // first newline with null character 58 | 59 | fgets(string, n, stdin); 60 | 61 | while (*string != '\0') 62 | { 63 | if (*string == '\n') 64 | { 65 | *string = '\0'; 66 | break; 67 | } 68 | string++; 69 | } 70 | } -------------------------------------------------------------------------------- /ch13/exercise07-mod.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 13 Exercise 7: 3 | 4 | // Write a program that opens two files. You can obtain the filenames either by 5 | // using command-line arguments or by soliciting the user to enter them. 6 | // a. Have the program print line 1 of the first file, line 1 of the second 7 | // file, line 2 of the first file, line 2 of the second file, and so on, 8 | // until the last line of the longer file (in terms of lines) is printed. 9 | // b. Modify the program so that lines with the same line number are printed 10 | // on the same line. 11 | 12 | #include 13 | #include 14 | 15 | #define LLEN 70 16 | 17 | void fget(char * string, int n, FILE *file); 18 | 19 | int main(int argc, char *argv[]) 20 | { 21 | FILE *file1, *file2; 22 | int ch; 23 | char tmp[LLEN]; 24 | 25 | if (argc < 3) 26 | { 27 | printf("Usage: %s file1 file2\n", argv[0]); 28 | exit(EXIT_FAILURE); 29 | } 30 | 31 | if ((file1 = fopen(argv[1], "r")) == NULL) 32 | { 33 | fprintf(stderr, "Could not open file %s.\n", argv[1]); 34 | exit(EXIT_FAILURE); 35 | } 36 | if ((file2 = fopen(argv[2], "r")) == NULL) 37 | { 38 | fprintf(stderr, "Could not open file %s.\n", argv[2]); 39 | exit(EXIT_FAILURE); 40 | } 41 | 42 | while (1) 43 | { 44 | tmp[0] = '\0'; 45 | fget(tmp, LLEN, file1); 46 | printf("%-*s\t", LLEN, tmp); 47 | 48 | tmp[0] = '\0'; 49 | fget(tmp, LLEN, file2); 50 | printf("%-*s\n", LLEN, tmp); 51 | 52 | if (feof(file1) && feof(file2)) 53 | break; 54 | } 55 | 56 | return 0; 57 | } 58 | 59 | void fget(char * string, int n, FILE *file) 60 | { 61 | // wrapper for fgets - replaces 62 | // first newline with null character 63 | 64 | fgets(string, n, file); 65 | 66 | while (*string != '\0') 67 | { 68 | if (*string == '\n') 69 | { 70 | *string = '\0'; 71 | break; 72 | } 73 | string++; 74 | } 75 | } -------------------------------------------------------------------------------- /ch13/exercise07.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 13 Exercise 7: 3 | 4 | // Write a program that opens two files. You can obtain the filenames either by 5 | // using command-line arguments or by soliciting the user to enter them. 6 | // a. Have the program print line 1 of the first file, line 1 of the second 7 | // file, line 2 of the first file, line 2 of the second file, and so on, 8 | // until the last line of the longer file (in terms of lines) is printed. 9 | // b. Modify the program so that lines with the same line number are printed 10 | // on the same line. 11 | 12 | #include 13 | #include 14 | 15 | #define LLEN 70 16 | 17 | void fget(char * string, int n, FILE *file); 18 | 19 | int main(int argc, char *argv[]) 20 | { 21 | FILE *file1, *file2; 22 | char tmp[LLEN]; 23 | int ch; 24 | 25 | if (argc < 3) 26 | { 27 | printf("Usage: %s file1 file2\n", argv[0]); 28 | exit(EXIT_FAILURE); 29 | } 30 | 31 | if ((file1 = fopen(argv[1], "r")) == NULL) 32 | { 33 | fprintf(stderr, "Could not open file %s.\n", argv[1]); 34 | exit(EXIT_FAILURE); 35 | } 36 | if ((file2 = fopen(argv[2], "r")) == NULL) 37 | { 38 | fprintf(stderr, "Could not open file %s.\n", argv[2]); 39 | exit(EXIT_FAILURE); 40 | } 41 | 42 | while (1) 43 | { 44 | fget(tmp, LLEN, file1); 45 | printf("%-*s\n", LLEN, tmp); 46 | fget(tmp, LLEN, file2); 47 | if (feof(file1) && feof(file2)) 48 | break; 49 | } 50 | 51 | return 0; 52 | } 53 | 54 | void fget(char * string, int n, FILE *file) 55 | { 56 | // wrapper for fgets - replaces 57 | // first newline with null character 58 | 59 | fgets(string, n, file); 60 | 61 | while (*string != '\0') 62 | { 63 | if (*string == '\n') 64 | { 65 | *string = '\0'; 66 | break; 67 | } 68 | string++; 69 | } 70 | } -------------------------------------------------------------------------------- /ch13/exercise08.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 13 Exercise 8 3 | 4 | // Write a program that takes as command-line arguments a character and zero or 5 | // more filenames. If no arguments follow the character, have the program read 6 | // the standard input. Otherwise, have it open each file in turn and report how 7 | // many times the character appears in each file. The filename and the 8 | // character itself should be reported along with the count. Include error- 9 | // checking to see whether the number of arguments is correct and whether the 10 | // files can be opened. If a file can’t be opened, have the program report that 11 | // fact and go on to the next file. 12 | 13 | 14 | #include 15 | #include 16 | 17 | int main(int argc, char *argv[]) 18 | { 19 | char character; 20 | int ch; 21 | 22 | if (argc < 2) 23 | { 24 | printf("Usage: %s [file1] [file2] ...\n", argv[0]); 25 | exit(EXIT_FAILURE); 26 | } 27 | 28 | character = *(argv[1]); 29 | 30 | if (argc == 2) 31 | { 32 | int count = 0; 33 | 34 | // read from stdin 35 | while ((ch == getchar()) != EOF) 36 | if (ch == character) 37 | count++; 38 | 39 | printf("Character count for %c in ...\n", character); 40 | printf("Standard in: %d\n", count); 41 | } 42 | else 43 | { 44 | FILE * fp; 45 | int counts[argc - 2]; 46 | for (int i = 2; i < argc; i++) 47 | { 48 | counts[i - 2] = 0; 49 | if ((fp = fopen(argv[i], "r")) == NULL) 50 | { 51 | fprintf(stderr, "Can't open file %s\n", argv[i]); 52 | continue; 53 | } 54 | 55 | while ((ch = getc(fp)) != EOF) 56 | if (ch == character) 57 | counts[i-2]++; 58 | 59 | fclose(fp); 60 | } 61 | 62 | printf("Character count for %c in ...\n", character); 63 | for (int i = 2; i < argc; i++) 64 | printf("%s: \t\t%d\n", argv[i], counts[i-2]); 65 | 66 | } 67 | 68 | return 0; 69 | } 70 | -------------------------------------------------------------------------------- /ch13/exercise09.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 13 Exercise 9: 3 | 4 | // Modify the program in Listing 13.3 so that each word is numbered according 5 | // to the order in which it was added to the list, starting with 1. Make sure 6 | // that, when the program is run a second time, new word numbering resumes 7 | // where the previous numbering left off. 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #define MAX 41 14 | 15 | int main(void) 16 | { 17 | FILE *fp; 18 | char words[MAX]; 19 | char line[MAX + 6]; 20 | int word_count = 1; 21 | 22 | if ((fp = fopen("wordy", "a+")) == NULL) 23 | { 24 | fprintf(stdout,"Can't open \"wordy\" file.\n"); 25 | exit(EXIT_FAILURE); 26 | } 27 | 28 | // count lines already written to file 29 | rewind(fp); 30 | while (fgets(line, MAX + 6, fp) != NULL) 31 | word_count++; 32 | 33 | puts("Enter words to add to the file; press the #"); 34 | puts("key at the beginning of a line to terminate."); 35 | while ((fscanf(stdin,"%40s", words) == 1) && (words[0] != '#')) 36 | fprintf(fp, "%d %s\n", word_count++, words); 37 | 38 | puts("File contents:"); 39 | rewind(fp); /* go back to beginning of file */ 40 | while (fgets(line, MAX + 6, fp) != NULL) 41 | fputs(line, stdout); 42 | puts("Done!"); 43 | 44 | if (fclose(fp) != 0) 45 | fprintf(stderr,"Error closing file\n"); 46 | 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /ch13/exercise10.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 13 Exercise 10: 3 | 4 | // Write a program that opens a text file whose name is obtained interactively. 5 | // Set up a loop that asks the user to enter a file position. The program then 6 | // should print the part of the file starting at that position and proceed to 7 | // the next newline character. Let negative or nonnumeric input terminate the 8 | // user-input loop. 9 | 10 | #include 11 | #include 12 | 13 | #define SLEN 81 14 | 15 | void get(char * string, int n); 16 | 17 | int main(void) 18 | { 19 | FILE *fp; 20 | char filename[SLEN]; 21 | long pos; 22 | int ch; 23 | 24 | printf("Enter a filename: "); 25 | get(filename, SLEN); 26 | 27 | if ((fp = fopen(filename, "r")) == NULL) 28 | { 29 | fprintf(stderr, "Could not open file %s.\n", filename); 30 | exit(EXIT_FAILURE); 31 | } 32 | 33 | printf("Enter a position: "); 34 | while (scanf("%ld", &pos) == 1) 35 | { 36 | if (pos < 0) 37 | break; 38 | 39 | fseek(fp, pos, SEEK_SET); 40 | while ((ch = getc(fp)) != EOF && ch != '\n') 41 | putchar(ch); 42 | putchar('\n'); 43 | 44 | printf("Enter a positition: "); 45 | } 46 | 47 | fclose(fp); 48 | puts("Done."); 49 | return 0; 50 | } 51 | 52 | void get(char * string, int n) 53 | { 54 | // wrapper for fgets - read from stdin and replace 55 | // first newline with null character 56 | 57 | fgets(string, n, stdin); 58 | 59 | while (*string != '\0') 60 | { 61 | if (*string == '\n') 62 | { 63 | *string = '\0'; 64 | break; 65 | } 66 | string++; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /ch13/exercise11.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 13 Exercise 11: 3 | 4 | // Write a program that takes two command-line arguments. The first is a 5 | // string; the second is the name of a file. The program should then search the 6 | // file, printing all lines containing the string. Because this task is line 7 | // oriented rather than character oriented, use fgets() instead of getc(). Use 8 | // the standard C library function strstr() (briefly described in exercise 7 of 9 | // Chapter 11) to search each line for the string. Assume no lines are longer 10 | // than 255 characters. 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | #define LINEMAX 255 17 | 18 | int main(int argc, char *argv[]) 19 | { 20 | FILE *fp; 21 | char line[LINEMAX]; 22 | 23 | if (argc != 3) 24 | { 25 | fprintf(stderr, "Usage: %s \n", argv[0]); 26 | exit(EXIT_FAILURE); 27 | } 28 | 29 | if ((fp = fopen(argv[2], "r")) == NULL) 30 | { 31 | fprintf(stderr, "Could not open file %s.\n", argv[2]); 32 | exit(EXIT_FAILURE); 33 | } 34 | 35 | while (fgets(line, LINEMAX, fp) != NULL) 36 | { 37 | if (strstr(line, argv[1]) != NULL) 38 | fputs(line, stdout); 39 | } 40 | 41 | fclose(fp); 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /ch14/exercise04.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 14 Exercise 4: 3 | 4 | // Write a program that creates a structure template with two members according 5 | // to the following criteria: 6 | // a. The first member is a social security number. The second member is a 7 | // structure with three members. Its first member contains a first name, its 8 | // second member contains a middle name, and its final member contains a last 9 | // name. Create and initialize an array of five such structures. Have the 10 | // program print the data in this format: 11 | // Dribble, Flossie M. –– 302039823 12 | // Only the initial letter of the middle name is printed, and a period is 13 | // added. Neither the initial (of course) nor the period should be printed if 14 | // the middle name member is empty. Write a function to do the printing; pass 15 | // the structure array to the function. 16 | // b. Modify part a. by passing the structure value instead of the address. 17 | 18 | #include 19 | #include 20 | 21 | #define LEN 5 22 | #define MAXNAME 20 23 | 24 | struct Name 25 | { 26 | char first[MAXNAME]; 27 | char middle[MAXNAME]; 28 | char last[MAXNAME]; 29 | }; 30 | 31 | struct Person 32 | { 33 | int ssn; 34 | struct Name name; 35 | }; 36 | 37 | void printpersona(struct Person *); // pass struct by address 38 | void printpersonb(struct Person); // pass struct by value 39 | 40 | int main(void) 41 | { 42 | struct Person people[LEN] = { 43 | {123456789, {"Marvin", "The", "Martian"}}, 44 | {987654321, {"Scrooge", "Mc", "Duck"}}, 45 | {888777666, {"Mantis", "Froggy", "Tobogan"}}, 46 | {123432467, {.first="Night", .last="Man"}}, 47 | {354257623, {.first="Day", .last="Man"}} 48 | }; 49 | 50 | // part a -- pass by address 51 | for (int i = 0; i < LEN; i++) 52 | printpersona(&people[i]); 53 | puts(""); 54 | 55 | // part b -- pass by value 56 | for (int i = 0; i < LEN; i++) 57 | printpersonb(people[i]); 58 | 59 | return 0; 60 | } 61 | 62 | 63 | void printpersona(struct Person *person) 64 | { 65 | printf("%s, %s ", person->name.last, person->name.first); 66 | if (person->name.middle[0] != '\0') 67 | printf("%c. ", toupper(person->name.middle[0])); 68 | printf("--- %d\n", person->ssn); 69 | } 70 | 71 | void printpersonb(struct Person person) 72 | { 73 | printf("%s, %s ", person.name.last, person.name.first); 74 | if (person.name.middle[0] != '\0') 75 | printf("%c. ", toupper(person.name.middle[0])); 76 | printf("--- %d\n", person.ssn); 77 | } -------------------------------------------------------------------------------- /ch14/exercise10.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 14 Exercise 10: 3 | 4 | // Write a program that implements a menu by using an array of pointers to 5 | // functions. For instance, choosing a from the menu would activate the 6 | // function pointed to by the first element of the array. 7 | 8 | 9 | #include 10 | #include 11 | #define NOPTIONS 5 12 | 13 | void menu(void); 14 | double sum(double, double); 15 | double difference(double, double); 16 | double power(double, double); 17 | double product(double, double); 18 | double quotient(double, double); 19 | 20 | int main(void) 21 | { 22 | // declare array of function pointers 23 | double (*funcs[NOPTIONS])(double, double) = {sum, difference, product, quotient, 24 | power}; 25 | double x, y; 26 | int ch; 27 | 28 | 29 | while (1) 30 | { 31 | menu(); 32 | if ((ch = getchar()) != '\n') 33 | while (getchar() != '\n') continue; 34 | ch -= 'a'; 35 | if (ch < 0 || ch > 5) 36 | { 37 | puts("This is not a valid option. Try again."); 38 | continue; 39 | } 40 | else if (ch == 5) 41 | break; 42 | 43 | printf("Enter two numbers: "); 44 | while(scanf("%lf %lf", &x, &y) != 2) 45 | { 46 | while (getchar() != '\n') continue; 47 | printf("Invalid input. Enter two numbers: "); 48 | } 49 | while (getchar() != '\n') continue; 50 | 51 | printf("%f\n", funcs[ch](x, y)); 52 | puts(""); 53 | } 54 | puts("Bye."); 55 | } 56 | 57 | void menu(void) 58 | { 59 | puts("Choose an operation:"); 60 | puts("a) add"); 61 | puts("b) subtract"); 62 | puts("c) multiply"); 63 | puts("d) divide"); 64 | puts("e) power"); 65 | puts("f) quit"); 66 | return; 67 | } 68 | 69 | double sum(double x, double y) 70 | { 71 | return x + y; 72 | } 73 | 74 | double difference(double x, double y) 75 | { 76 | return x - y; 77 | } 78 | 79 | double power(double x, double y) 80 | { 81 | return pow(x, y); 82 | } 83 | 84 | double product(double x, double y) 85 | { 86 | return x * y; 87 | } 88 | 89 | double quotient(double x, double y) 90 | { 91 | return x / y; 92 | } -------------------------------------------------------------------------------- /ch14/exercise11.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 14 Exercise 11: 3 | 4 | // Write a function called transform() that takes four arguments: the name of a 5 | // source array containing type double data, the name of a target array of type 6 | // double, an int representing the number of array elements, and the name of a 7 | // function (or, equivalently, a pointer to a function). The transform() 8 | // function should apply the indicated function to each element in the source 9 | // array, placing the return value in the target array. For example, the call 10 | // transform(source, target, 100, sin); 11 | // would set target[0] to sin(source[0]), and so on, for 100 elements. Test the 12 | // function in a program that calls transform() four times, using two functions 13 | // from the math.h library and two suitable functions of your own devising as 14 | // arguments to successive calls of the transform() function. 15 | 16 | #include 17 | #include 18 | 19 | #define ARRLENGTH 20 20 | 21 | void transform(const double * source, double * target, int n, double (*func)(double)); 22 | double squared(double); 23 | double cubed(double); 24 | 25 | int main(void) 26 | { 27 | // test transform function 28 | 29 | double source[ARRLENGTH]; 30 | double target[ARRLENGTH]; 31 | 32 | for (int i = 0; i < ARRLENGTH; i++) 33 | source[i] = i; 34 | 35 | transform(source, target, ARRLENGTH, sin); 36 | for (int i = 0; i < ARRLENGTH; i++) 37 | { 38 | printf("sin(%.2f) = %.2f\n", source[i], target[i]); 39 | } 40 | puts(""); 41 | 42 | transform(source, target, ARRLENGTH, tan); 43 | for (int i = 0; i < ARRLENGTH; i++) 44 | { 45 | printf("tan(%.2f) = %.2f\n", source[i], target[i]); 46 | } 47 | puts(""); 48 | 49 | transform(source, target, ARRLENGTH, squared); 50 | for (int i = 0; i < ARRLENGTH; i++) 51 | { 52 | printf("%.2f ^ 2 = %.2f\n", source[i], target[i]); 53 | } 54 | puts(""); 55 | 56 | transform(source, target, ARRLENGTH, cubed); 57 | for (int i = 0; i < ARRLENGTH; i++) 58 | { 59 | printf("%.2f ^ 3 = %.2f\n", source[i], target[i]); 60 | } 61 | puts(""); 62 | 63 | return 0; 64 | } 65 | 66 | void transform(const double * source, double * target, int n, double (*func)(double)) 67 | { 68 | for (int i = 0; i < n; i++) 69 | target[i] = func(source[i]); 70 | 71 | return; 72 | } 73 | 74 | double squared(double x) 75 | { 76 | return x * x; 77 | } 78 | 79 | double cubed(double x) 80 | { 81 | return x * x * x; 82 | } -------------------------------------------------------------------------------- /ch14/roster.txt: -------------------------------------------------------------------------------- 1 | 4 Jessie Joybat 5 2 1 1 2 | 10 Wade Boggs 5 3 4 1 3 | 0 Sleepy Dwarf 4 1 0 0 4 | 1 Grumpy Dwarf 3 2 1 1 5 | 2 Dopey Dwarf 6 4 0 2 6 | 10 Wade Boggs 3 2 0 1 7 | 3 Snow White 2 2 0 1 8 | 5 Pecorino Romano 4 0 1 0 9 | 6 Parmigiano Reggiano 2 1 0 0 -------------------------------------------------------------------------------- /ch15/exercise01.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 15 Exercise 1: 3 | 4 | // Write a function that converts a binary string to a numeric value. That is, 5 | // if you have 6 | // char * pbin = "01001001"; 7 | // you can pass pbin as an argument to the function and have the function 8 | // return an int value of 25. 9 | 10 | // NOTE: "01001001" in base10 is actually 73 11 | 12 | #include 13 | 14 | int parsebinarystring(const char * string); 15 | 16 | int main(void) 17 | { 18 | // test parsebinarystring() 19 | int result; 20 | char * binstring = "01001001"; 21 | printf("%s in base-10 is %d.\n", binstring, parsebinarystring(binstring)); 22 | 23 | return 0; 24 | } 25 | 26 | int parsebinarystring(const char * string) 27 | { 28 | // convert a binary string to a numeric value 29 | 30 | int retval = 0; 31 | while (*string != '\0') 32 | { 33 | retval <<= 1; 34 | if (*string == '1') 35 | retval |= 1; 36 | string++; 37 | } 38 | return retval; 39 | } -------------------------------------------------------------------------------- /ch15/exercise02.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 15 Exercise 2: 3 | 4 | // Write a program that reads two binary strings as command-line arguments and 5 | // prints the results of applying the ~ operator to each number and the results 6 | // of applying the &, |, and ^ operators to the pair. Show the results as 7 | // binary strings. (If you don’t have a command-line environment available, 8 | // have the program read the strings interactively.) 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | int parsebinarystring(const char * string); 15 | char * tobinarystring(int n, char * string, int strlen); 16 | 17 | int main(int argc, char *argv[]) 18 | { 19 | if (argc != 3) 20 | { 21 | fprintf(stderr, "Usage: %s \n", argv[0]); 22 | exit(EXIT_FAILURE); 23 | } 24 | 25 | int n = parsebinarystring(argv[1]); 26 | int m = parsebinarystring(argv[2]); 27 | int strlen = sizeof(int) * CHAR_BIT + 1; 28 | char binstring[strlen]; 29 | 30 | printf("~%s = %s\n", argv[1], tobinarystring(~n, binstring, strlen)); 31 | printf("~%s = %s\n", argv[2], tobinarystring(~m, binstring, strlen)); 32 | printf("%s & %s = %s\n", argv[1], argv[2], tobinarystring(n & m, binstring, strlen)); 33 | printf("%s | %s = %s\n", argv[1], argv[2], tobinarystring(n | m, binstring, strlen)); 34 | printf("%s ^ %s = %s\n", argv[1], argv[2], tobinarystring(n ^ m, binstring, strlen)); 35 | 36 | return 0; 37 | } 38 | 39 | int parsebinarystring(const char * string) 40 | { 41 | // convert a binary string to a numeric value 42 | 43 | int retval = 0; 44 | while (*string != '\0') 45 | { 46 | retval <<= 1; 47 | if (*string != '0' && *string != '1') 48 | { 49 | // handle input error 50 | fprintf(stderr, "Error: input string is not binary.\n"); 51 | return 0; 52 | } 53 | if (*string == '1') 54 | retval |= 1; 55 | string++; 56 | } 57 | return retval; 58 | } 59 | 60 | char * tobinarystring(int n, char * string, int strlen) 61 | { 62 | char * start = string; 63 | 64 | string += (strlen - 1); 65 | *string = '\0'; 66 | string--; 67 | 68 | if (n == 0) 69 | { 70 | *string = '0'; 71 | return string; 72 | } 73 | 74 | while (n != 0 && string >= start) 75 | { 76 | *string = (n & 1) + '0'; 77 | n = n >> 1; 78 | string--; 79 | } 80 | return ++string; 81 | } -------------------------------------------------------------------------------- /ch15/exercise03.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 15 Exercise 3: 3 | 4 | // Write a function that takes an int argument and returns the number of “on” 5 | // bits in the argument. Test the function in a program. 6 | 7 | #include 8 | #define CLEARINPUT while (getchar() != '\n') continue 9 | 10 | int onbits(int n); 11 | 12 | int main(void) 13 | { 14 | // test onbits 15 | 16 | int n, bits; 17 | 18 | printf("Enter an integer (non-integer to quit): "); 19 | while (scanf("%d", &n) == 1) 20 | { 21 | CLEARINPUT; 22 | 23 | bits = onbits(n); 24 | printf("There are %d on bits in %d\n", bits, n); 25 | 26 | printf("Enter an integer (non-integer to quit): "); 27 | } 28 | 29 | return 0; 30 | } 31 | 32 | int onbits(int n) 33 | { 34 | // returns number of bits in n set to 1 35 | int count = 0; 36 | while (n != 0) 37 | { 38 | if (n & 1) 39 | count++; 40 | n >>= 1; 41 | } 42 | 43 | return count; 44 | } -------------------------------------------------------------------------------- /ch15/exercise04.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 15 Exercise 4: 3 | 4 | // Write a function that takes two int arguments: a value and a bit position. 5 | // Have the function return 1 if that particular bit position is 1, and have it 6 | // return 0 otherwise. Test the function in a program. 7 | 8 | #include 9 | #include 10 | 11 | #define CLEARINPUT while (getchar() != '\n') continue 12 | 13 | int checkbit(int value, int position); 14 | 15 | int main(void) 16 | { 17 | // test checkbit() 18 | 19 | int value, position, ch; 20 | 21 | printf("Enter an integer: "); 22 | while (scanf("%d", &value) == 1) 23 | { 24 | printf("Enter a position: "); 25 | while (scanf("%d", &position) == 1) 26 | { 27 | printf("Position %d of %d is %d\n", position, value, 28 | checkbit(value, position)); 29 | printf("Enter a position: "); 30 | } 31 | CLEARINPUT; 32 | printf("\nEnter an integer: "); 33 | } 34 | 35 | puts("Bye."); 36 | return 0; 37 | } 38 | 39 | int checkbit(int value, int position) 40 | { 41 | // return the state of the bit in the given position of the integer value 42 | 43 | value >>= (position - 1); 44 | return value & 1; 45 | } 46 | -------------------------------------------------------------------------------- /ch15/exercise05.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 15 Exercise 5: 3 | 4 | // Write a function that rotates the bits of an unsigned int by a specified 5 | // number of bits to the left. For instance, rotate_l(x,4) would move the bits 6 | // in x four places to the left, and the bits lost from the left end would 7 | // reappear at the right end. That is, the bit moved out of the high-order 8 | // position is placed in the low-order position. Test the function in a 9 | // program. 10 | 11 | #include 12 | #include 13 | 14 | #define CLEARINPUT while (getchar() != '\n') continue 15 | 16 | unsigned int rotate_l(unsigned int value, int n); 17 | 18 | const unsigned int BITS = sizeof(unsigned int) * CHAR_BIT; 19 | const unsigned int LBITMASK = 1 << (BITS - 1); 20 | 21 | int main(void) 22 | { 23 | // test rotate_l() 24 | 25 | unsigned int value, rotated; 26 | int n; 27 | 28 | printf("Enter a non-negative integer value: "); 29 | while (scanf("%u", &value) == 1) 30 | { 31 | printf("Enter a number of positions to rotate: "); 32 | while (scanf("%d", &n) == 1) 33 | { 34 | puts("Before rotation:"); 35 | for (int i = 0; i < BITS; i++) 36 | { 37 | if ((value << i) & LBITMASK) 38 | putchar('1'); 39 | else 40 | putchar('0'); 41 | } 42 | putchar('\n'); 43 | printf("After rotation by %d positions:\n", n); 44 | rotated = rotate_l(value, n); 45 | for (int i = 0; i < BITS; i++) 46 | { 47 | if ((rotated << i) & LBITMASK) 48 | putchar('1'); 49 | else 50 | putchar('0'); 51 | } 52 | putchar('\n'); 53 | printf("Enter a number of positions to rotate: "); 54 | } 55 | CLEARINPUT; 56 | printf("\nEnter a non-negative integer value: "); 57 | } 58 | 59 | puts("Bye."); 60 | return 0; 61 | 62 | } 63 | 64 | unsigned int rotate_l(unsigned int value, int n) 65 | { 66 | // rotate the bits in value n postitions to the left 67 | 68 | int leftbit; 69 | 70 | for (int i = 0; i < n; i++) 71 | { 72 | leftbit = value & LBITMASK; 73 | value <<= 1; 74 | if (leftbit) 75 | value |= 1; 76 | } 77 | 78 | return value; 79 | } -------------------------------------------------------------------------------- /ch16/coordinates.c: -------------------------------------------------------------------------------- 1 | // coordinates.c -- implementation file for polar and cartesian coordinates 2 | 3 | #include "coordinates.h" 4 | #include 5 | 6 | Cartesian cartesianFromPolar(Polar coords) 7 | { 8 | Cartesian retval; 9 | 10 | retval.x = coords.magnitude * cos(coords.angle); 11 | retval.y = coords.magnitude * sin(coords.angle); 12 | 13 | return retval; 14 | } -------------------------------------------------------------------------------- /ch16/coordinates.h: -------------------------------------------------------------------------------- 1 | // coordinates.h 2 | 3 | #ifndef COORDINATES_H_ 4 | #define COORDINATES_H_ 5 | 6 | typedef struct polar 7 | { 8 | double angle; 9 | double magnitude; 10 | } Polar; 11 | 12 | typedef struct cartesian 13 | { 14 | double x; 15 | double y; 16 | } Cartesian; 17 | 18 | 19 | // Cartesian cartesianFromPolar(Polar): 20 | // converts polar coordinates to cartesian 21 | 22 | Cartesian cartesianFromPolar(Polar coords); 23 | 24 | #endif -------------------------------------------------------------------------------- /ch16/exercise01.h: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 16 Exercise 1: 3 | 4 | // Start developing a header file of preprocessor definitions that you want 5 | // to use. 6 | 7 | #ifndef EXERCISE01_H_ 8 | #define EXERCISE01_H_ 9 | 10 | #include 11 | 12 | #define CLEARINPUT while (getchar() != '\n') continue 13 | 14 | #endif -------------------------------------------------------------------------------- /ch16/exercise02.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 16 Exercise 2: 3 | 4 | // The harmonic mean of two numbers is obtained by taking the inverses of the 5 | // two numbers, averaging them, and taking the inverse of the result. Use a 6 | // #define directive to define a macro “function” that performs this operation. 7 | // Write a simple program that tests the macro. 8 | 9 | #include 10 | #include "exercise01.h" 11 | 12 | #define INVERSE(X) (1. / (X)) 13 | #define HARM_MEAN(X, Y) (1. / ((INVERSE(X) + INVERSE(Y)) / 2)) 14 | 15 | int main() 16 | { 17 | // test HARM_MEAN 18 | 19 | double x, y; 20 | printf("Enter two numbers: "); 21 | while (scanf("%lf %lf", &x, &y) == 2) 22 | { 23 | CLEARINPUT; 24 | printf("The harmonic mean of %.3f and %.3f is: %.3f.\n", x, y, 25 | HARM_MEAN(x, y)); 26 | 27 | printf("Enter two numbers: "); 28 | } 29 | puts("Bye."); 30 | } -------------------------------------------------------------------------------- /ch16/exercise03.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 16 Exercise 3: 3 | 4 | // Polar coordinates describe a vector in terms of magnitude and the 5 | // counterclockwise angle from the x-axis to the vector. Rectangular 6 | // coordinates describe the same vector in terms of x and y components (see 7 | // Figure 16.3). Write a program that reads the magnitude and angle (in 8 | // degrees) of a vector and then displays the x and y components. The relevant 9 | // equations are these: 10 | // x = r cos A y = r sin A 11 | // To do the conversion, use a function that takes a structure containing the 12 | // polar coordinates and returns a structure containing the rectangular 13 | // coordinates (or use pointers to such structures, if you prefer). 14 | 15 | // compile with coordinates.c 16 | 17 | #include 18 | #include "exercise01.h" 19 | #include "coordinates.h" 20 | 21 | int main() 22 | { 23 | Polar polar_coords; 24 | Cartesian cartesian_coords; 25 | 26 | printf("Enter an angle: "); 27 | while (scanf("%lf", &polar_coords.angle) == 1) 28 | { 29 | CLEARINPUT; 30 | printf("Enter a magnitude: "); 31 | while (scanf("%lf", &polar_coords.magnitude) != 1) 32 | { 33 | CLEARINPUT; 34 | printf("Enter a magnitude: "); 35 | } 36 | 37 | cartesian_coords = cartesianFromPolar(polar_coords); 38 | 39 | printf("angle: %.2f magnitude: %.2f\n", polar_coords.angle, 40 | polar_coords.magnitude); 41 | printf("x: %.2f y: %.2f\n", cartesian_coords.x, cartesian_coords.y); 42 | 43 | printf("Enter an angle: "); 44 | } 45 | puts("Bye."); 46 | } -------------------------------------------------------------------------------- /ch16/exercise04.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 16 Exercise 4: 3 | 4 | // The ANSI library features a clock() function with this description: 5 | // #include clock_t clock (void); 6 | // Here, clock_t is a type defined in time.h. The function returns the 7 | // processor time, which is given in some implementation-dependent units. (If 8 | // the processor time is unavailable or cannot be represented, the function 9 | // returns a value of -1.) However, CLOCKS_PER_SEC, also defined in time.h, is 10 | // the number of processor time units per second. Therefore, dividing the 11 | // difference between two return values of clock() by CLOCKS_PER_SEC gives you 12 | // the number of seconds elapsed between the two calls. Typecasting the values 13 | // to double before division enables you to get fractions of a second. Write a 14 | // function that takes a double argument representing a desired time delay and 15 | // then runs a loop until that amount of time has passed. Write a simple 16 | // program that tests the function. 17 | 18 | #include 19 | #include 20 | 21 | void timeout(double time); 22 | 23 | int main(void) 24 | { 25 | double time; 26 | 27 | printf("Enter desired time delay in seconds: "); 28 | while(scanf("%lf", &time) == 1) 29 | { 30 | puts("Starting."); 31 | timeout(time); 32 | printf("It is now %2f seconds later!\n", time); 33 | printf("Enter desired time delay in seconds: "); 34 | } 35 | puts("Bye."); 36 | } 37 | 38 | void timeout(double time) 39 | { 40 | clock_t start, end; 41 | 42 | start = clock(); 43 | 44 | while (((end = clock()) - start) / (double) CLOCKS_PER_SEC < time) 45 | continue; 46 | 47 | return; 48 | } -------------------------------------------------------------------------------- /ch16/exercise05.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus: 2 | // Chapter 16 Exercise 6: 3 | 4 | // Write a function that takes as arguments the name of an array of type int 5 | // elements, the size of an array, and a value representing the number of 6 | // picks. The function then should select the indicated number of items at 7 | // random from the array and prints them. No array element is to be picked more 8 | // than once. (This simulates picking lottery numbers or jury members.) Also, 9 | // if your implementation has time() (discussed in Chapter 12) or a similar 10 | // function available, use its output with srand() to initialize the rand() 11 | // random- number generator. Write a simple program that tests the function. 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #define ARR_SIZE 100 19 | 20 | void sample(int * arr, int arr_size, int n); 21 | 22 | int main(void) 23 | { 24 | // test sample() 25 | 26 | int array[ARR_SIZE]; 27 | for (int i = 0; i < ARR_SIZE; i++) 28 | array[i] = i; 29 | 30 | int n; 31 | printf("How many items would you like to sample: "); 32 | while(scanf("%d", &n) == 1 && n > 0) 33 | { 34 | sample(array, ARR_SIZE, n); 35 | printf("How many items would you like to sample: "); 36 | } 37 | 38 | puts("Bye."); 39 | } 40 | 41 | void sample(int * arr, int arr_size, int n) 42 | { 43 | // pick and print a sample of n items from arr at random 44 | 45 | if (n > arr_size) 46 | { 47 | printf("Error: sample size can not be larger than the size of the array being sampled.\n"); 48 | return; 49 | } 50 | 51 | bool chosen[arr_size]; 52 | for (int i = 0; i < arr_size; i++) 53 | chosen[i] = false; 54 | 55 | srand(time(NULL)); 56 | for (int i = 0; i < n; i++) 57 | { 58 | int index = rand() % arr_size; 59 | while (chosen[index]) // if index has already been chosen, pick again 60 | index = rand() % arr_size; 61 | printf("%d\n", arr[index]); 62 | chosen[index] = true; 63 | } 64 | return; 65 | } -------------------------------------------------------------------------------- /ch16/exercise06.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 16 Exercise 6: 3 | 4 | // Modify Listing 16.17 so that it uses an array of struct names elements (as 5 | // defined after the listing) instead of an array of double. Use fewer 6 | // elements, and initialize the array explicitly to a suitable selection of 7 | // names. 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #define NUM 15 14 | 15 | typedef struct name { 16 | char first[40]; 17 | char last[40]; 18 | } NAME; 19 | 20 | int comparenames(const void * p1, const void * p2); 21 | void printnames(const NAME * arr, int arr_size); 22 | 23 | int main(void) 24 | { 25 | NAME insideout[NUM] = { 26 | {"Amy", "Poehler"}, 27 | {"Phyllis", "Smith"}, 28 | {"Richard", "Kind"}, 29 | {"Bill", "Hader"}, 30 | {"Lewis", "Black"}, 31 | {"Mindy", "Kaling"}, 32 | {"Kaitlyn", "Dias"}, 33 | {"Diane", "Lane"}, 34 | {"Kyle", "MacLachlan"}, 35 | {"Paula", "Poundstone"}, 36 | {"Bobby", "Moynihan"}, 37 | {"Paula", "Pell"}, 38 | {"Dave", "Goelz"}, 39 | {"Frank", "Oz"}, 40 | {"Josh", "Cooley"}, 41 | }; 42 | 43 | puts("Here is the list of names:"); 44 | printnames(insideout, NUM); 45 | puts(""); 46 | 47 | qsort(insideout, NUM, sizeof(NAME), comparenames); 48 | 49 | puts("Here is the sorted list of names:"); 50 | printnames(insideout, NUM); 51 | } 52 | 53 | int comparenames(const void * p1, const void * p2) 54 | { 55 | NAME * name1 = (NAME *) p1; 56 | NAME * name2 = (NAME *) p2; 57 | 58 | int c = strcmp(name1->last, name2->last); 59 | return c ? c : strcmp(name1->first, name2->first); 60 | } 61 | 62 | void printnames(const NAME * arr, int arr_size) 63 | { 64 | for (int i = 0; i < arr_size; i++) 65 | printf("%s, %s\n", arr[i].last, arr[i].first); 66 | } -------------------------------------------------------------------------------- /ch16/exercise07.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 16 Exercise 7: 3 | 4 | // Here’s a partial program using a variadic function: 5 | 6 | // #include 7 | // #include 8 | // #include 9 | 10 | // void show_array(const double ar[], int n); 11 | // double * new_d_array(int n, ...); 12 | 13 | // int main() { 14 | // double * p1; 15 | // double * p2; 16 | // p1 = new_d_array(5, 1.2, 2.3, 3.4, 4.5, 5.6); 17 | // p2 = new_d_array(4, 100.0, 20.00, 8.08, -1890.0); 18 | // show_array(p1, 5); 19 | // show_array(p2, 4); 20 | // free(p1); 21 | // free(p2); 22 | // return 0; 23 | // } 24 | 25 | // The new_d_array() function takes an int argument and a variable number of 26 | // double arguments. The function returns a pointer to a block of memory 27 | // allocated by malloc(). The int argument indicates the number of elements to 28 | // be in the dynamic array, and the double values are used to initialize the 29 | // elements, with the first value being assigned to the first element, and so 30 | // on. Complete the program by providing the code for show_ array() and 31 | // new_d_array(). 32 | 33 | #include 34 | #include 35 | #include 36 | 37 | void show_array(const double ar[], int n); 38 | double * new_d_array(int n, ...); 39 | 40 | int main() 41 | { 42 | double * p1; 43 | double * p2; 44 | p1 = new_d_array(5, 1.2, 2.3, 3.4, 4.5, 5.6); 45 | p2 = new_d_array(4, 100.0, 20.00, 8.08, -1890.0); 46 | show_array(p1, 5); 47 | show_array(p2, 4); 48 | free(p1); 49 | free(p2); 50 | return 0; 51 | } 52 | 53 | void show_array(const double ar[], int n) 54 | { 55 | printf("{"); 56 | for (int i = 0; i < n; i++) 57 | { 58 | printf("%.3f", ar[i]); 59 | if (i < n - 1) 60 | printf(", "); 61 | if (i % 20 == 19) 62 | printf("\n"); 63 | } 64 | puts("}"); 65 | } 66 | 67 | double * new_d_array(int n, ...) 68 | { 69 | va_list ap; 70 | va_start(ap, n); 71 | 72 | double * arr = (double *) malloc(n * sizeof(double)); 73 | if (!arr) 74 | fprintf(stderr, "Could not allocate memory.\n"); 75 | else 76 | for (int i = 0; i < n; i++) 77 | arr[i] = va_arg(ap, double); 78 | 79 | return arr; 80 | } -------------------------------------------------------------------------------- /ch17/binary_search.c: -------------------------------------------------------------------------------- 1 | // binary_search.c -- an implementation of binary search for an array of integers 2 | 3 | #include "binary_search.h" 4 | 5 | static int binarysearch_aux(int * arr, int target, int low, int high); 6 | 7 | int binarysearch(int * arr, int arr_size, int target) 8 | { 9 | return binarysearch_aux(arr, target, 0, arr_size - 1); 10 | } 11 | 12 | 13 | static int binarysearch_aux(int * arr, int target, int low, int high) 14 | { 15 | // base case 16 | if (low == high) 17 | return arr[low] == target ? 1 : 0; 18 | 19 | // recursion case 20 | else 21 | { 22 | int mid = (low + high) / 2; 23 | if (arr[mid] < target) 24 | return binarysearch_aux(arr, target, mid + 1, high); 25 | else 26 | return binarysearch_aux(arr, target, low, mid); 27 | } 28 | } -------------------------------------------------------------------------------- /ch17/binary_search.h: -------------------------------------------------------------------------------- 1 | // binary_search.h -- header file for binary search implementation 2 | 3 | #ifndef BINARY_SEARCH_H_ 4 | #define BINARY_SEARCH_H_ 1 5 | 6 | int binarysearch(int * arr, int arr_size, int target); 7 | 8 | #endif 9 | 10 | -------------------------------------------------------------------------------- /ch17/exercise01.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 17 Exercise 1: 3 | 4 | // Modify Listing 17.2 so that it displays the movie list both in the original 5 | // order and in reverse order. One approach is to modify the linked-list 6 | // definition so that the list can be traversed in both directions. Another 7 | // approach is to use recursion. 8 | 9 | // compile with film.c 10 | 11 | #include 12 | #include 13 | #include 14 | #include "film.h" 15 | 16 | char * get(char * string, int n); 17 | 18 | int main(void) 19 | { 20 | List film_list = NULL; 21 | Film * current; 22 | char input[TSIZE]; 23 | 24 | puts("Enter first movie title:"); 25 | while (get(input, TSIZE) != NULL && input[0] != '\0') 26 | { 27 | current = (Film *) malloc(sizeof(Film)); 28 | if (current == NULL) 29 | { 30 | fprintf(stderr, "Could not allocate memory.\n"); 31 | exit(EXIT_FAILURE); 32 | } 33 | 34 | current->next = NULL; 35 | strcpy(current->title, input); 36 | printf("Enter your rating (0 - 10): "); 37 | scanf("%d", &(current->rating)); 38 | while (getchar() != '\n') continue; 39 | 40 | if (film_list == NULL) 41 | film_list = current; 42 | else 43 | add_film(film_list, current); 44 | 45 | puts("Enter next movie title (empty line to stop):"); 46 | } 47 | 48 | // show list of movies 49 | puts("Here is your list of movies:"); 50 | list_films(film_list); 51 | puts(""); 52 | 53 | // show list of movies in reverse order 54 | puts("Here is your list of movies in reverse order:"); 55 | reverse_list_films(film_list); 56 | 57 | // clean up 58 | delete_list(&film_list); 59 | 60 | } 61 | 62 | char * get(char * string, int n) 63 | { 64 | // wrapper for fgets that replaces first newline with null 65 | 66 | char *return_value = fgets(string, n, stdin); 67 | 68 | while (*string != '\0') 69 | { 70 | if (*string == '\n') 71 | { 72 | *string = '\0'; 73 | break; 74 | } 75 | string++; 76 | } 77 | 78 | return return_value; 79 | } 80 | -------------------------------------------------------------------------------- /ch17/exercise02.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 17 Exercise 2: 3 | 4 | // Suppose list.h (Listing 17.3) uses the following definition of a list: 5 | // typedef struct list { 6 | // Node * head; /* points to head of list */ 7 | // Node * end; /* points to end of list */ 8 | // } List; 9 | // Rewrite the list.c (Listing 17.5) functions to fit this definition and test 10 | // the resulting code with the films3.c (Listing 17.4) program. 11 | 12 | // Compile with list.c 13 | 14 | #include 15 | #include 16 | #include "list.h" 17 | 18 | void showmovies(Item item); 19 | char * get(char * st, int n); 20 | int main(void) 21 | { 22 | List movies; 23 | Item temp; 24 | 25 | /* initialize */ 26 | InitializeList(&movies); 27 | 28 | if (ListIsFull(&movies)) 29 | { 30 | fprintf(stderr,"No memory available! Bye!\n"); 31 | exit(1); 32 | } 33 | 34 | /* gather and store */ 35 | puts("Enter first movie title:"); 36 | while (get(temp.title, TSIZE) != NULL && temp.title[0] != '\0') 37 | { 38 | puts("Enter your rating <0-10>:"); 39 | scanf("%d", &temp.rating); 40 | while(getchar() != '\n') 41 | continue; 42 | 43 | if (AddItem(temp, &movies)==false) 44 | { 45 | fprintf(stderr,"Problem allocating memory\n"); 46 | break; 47 | } 48 | 49 | if (ListIsFull(&movies)) 50 | { 51 | puts("The list is now full."); 52 | break; 53 | } 54 | 55 | puts("Enter next movie title (empty line to stop):"); 56 | } 57 | 58 | /* display */ 59 | if (ListIsEmpty(&movies)) 60 | printf("No data entered. "); 61 | else 62 | { 63 | printf ("Here is the movie list:\n"); 64 | Traverse(&movies, showmovies); 65 | } 66 | 67 | printf("You entered %d movies.\n", ListItemCount(&movies)); 68 | 69 | /* clean up */ 70 | EmptyTheList(&movies); 71 | 72 | printf("Bye!\n"); 73 | return 0; 74 | } 75 | 76 | void showmovies(Item item) 77 | { 78 | printf("Movie: %s Rating: %d\n", item.title, item.rating); 79 | } 80 | 81 | char * get(char * string, int n) 82 | { 83 | // wrapper for fgets that replaces first newline with null 84 | 85 | char *return_value = fgets(string, n, stdin); 86 | 87 | while (*string != '\0') 88 | { 89 | if (*string == '\n') 90 | { 91 | *string = '\0'; 92 | break; 93 | } 94 | string++; 95 | } 96 | 97 | return return_value; 98 | } 99 | -------------------------------------------------------------------------------- /ch17/exercise03.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 17 Exercise 3: 3 | 4 | // Suppose list.h (Listing 17.3) uses the following definition of a list: 5 | 6 | // #define MAXSIZE 100 7 | // typedef struct list { 8 | // Item entries[MAXSIZE]; /* array of items */ 9 | // int items; /* number of items in list */ 10 | // } List; 11 | 12 | // Rewrite the list.c (Listing 17.5) functions to fit this definition and test 13 | // the resulting code with the films3.c (Listing 17.4) program. 14 | 15 | // compile with list2.c 16 | 17 | #include 18 | #include 19 | #include "list2.h" 20 | 21 | void showmovies(Item item); 22 | char * get(char * st, int n); 23 | int main(void) 24 | { 25 | List movies; 26 | Item temp; 27 | 28 | /* initialize */ 29 | InitializeList(&movies); 30 | 31 | if (ListIsFull(&movies)) 32 | { 33 | fprintf(stderr,"No memory available! Bye!\n"); 34 | exit(1); 35 | } 36 | 37 | /* gather and store */ 38 | puts("Enter first movie title:"); 39 | while (get(temp.title, TSIZE) != NULL && temp.title[0] != '\0') 40 | { 41 | puts("Enter your rating <0-10>:"); 42 | scanf("%d", &temp.rating); 43 | while(getchar() != '\n') 44 | continue; 45 | 46 | if (AddItem(temp, &movies)==false) 47 | { 48 | fprintf(stderr,"Problem allocating memory\n"); 49 | break; 50 | } 51 | 52 | if (ListIsFull(&movies)) 53 | { 54 | puts("The list is now full."); 55 | break; 56 | } 57 | 58 | puts("Enter next movie title (empty line to stop):"); 59 | } 60 | 61 | /* display */ 62 | if (ListIsEmpty(&movies)) 63 | printf("No data entered. "); 64 | else 65 | { 66 | printf ("Here is the movie list:\n"); 67 | Traverse(&movies, showmovies); 68 | } 69 | 70 | printf("You entered %d movies.\n", ListItemCount(&movies)); 71 | 72 | /* clean up */ 73 | EmptyTheList(&movies); 74 | 75 | printf("Bye!\n"); 76 | return 0; 77 | } 78 | 79 | void showmovies(Item item) 80 | { 81 | printf("Movie: %s Rating: %d\n", item.title, item.rating); 82 | } 83 | 84 | char * get(char * string, int n) 85 | { 86 | // wrapper for fgets that replaces first newline with null 87 | 88 | char *return_value = fgets(string, n, stdin); 89 | 90 | while (*string != '\0') 91 | { 92 | if (*string == '\n') 93 | { 94 | *string = '\0'; 95 | break; 96 | } 97 | string++; 98 | } 99 | 100 | return return_value; 101 | } 102 | -------------------------------------------------------------------------------- /ch17/exercise05.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 17 Exercise 5: 3 | 4 | // Write a program that lets you input a string. The program then should push 5 | // the characters of the string onto a stack, one by one (see review question 6 | // 5), and then pop the characters from the stack and display them. This 7 | // results in displaying the string in reverse order. 8 | 9 | #include 10 | #include "stack.h" 11 | 12 | int main(int argc, char *argv[]) 13 | { 14 | if (argc != 2) 15 | { 16 | printf("Usage: %s \n", argv[0]); 17 | return 1; 18 | } 19 | 20 | Stack character_stack; 21 | Stack * stack_ptr = InitializeStack(&character_stack); 22 | 23 | // for (char * pchar = argv[1]; *pchar != '\0'; pchar++) 24 | // printf("%c", *pchar); 25 | 26 | for (char * pchar = argv[1]; *pchar != '\0'; pchar++) 27 | PushItem(pchar, stack_ptr); 28 | 29 | char pch[1]; 30 | while (PopItem(pch, stack_ptr)) 31 | printf("%c", *pch); 32 | 33 | puts(""); 34 | 35 | } -------------------------------------------------------------------------------- /ch17/exercise06.c: -------------------------------------------------------------------------------- 1 | // C Primer Plus 2 | // Chapter 17 Exercise 6: 3 | 4 | // Write a function that takes three arguments: the name of an array of sorted 5 | // integers, the number of elements of the array, and an integer to seek. The 6 | // function returns the value 1 if the integer is in the array, and 0 if it 7 | // isn’t. Have the function use the binary search technique. 8 | 9 | // compile with binary_search.c 10 | 11 | #include 12 | #include "binary_search.h" 13 | 14 | int main(void) 15 | { 16 | // binarysearch() 17 | 18 | int arr[10] = {1, 4, 6, 9, 11, 12, 15, 19, 25, 40}; 19 | 20 | for (int i = 0; i < 15; i++) 21 | { 22 | printf("%d in array? %s\n", i, binarysearch(arr, 10, i) ? "yes" : "no"); 23 | } 24 | } -------------------------------------------------------------------------------- /ch17/film.c: -------------------------------------------------------------------------------- 1 | // film.c -- implementation file for linked film list 2 | 3 | #include "film.h" 4 | 5 | // delete the entire film list and free allocated memory 6 | void delete_list(List * list_ptr) 7 | { 8 | 9 | Film * tmp, * list = *list_ptr; 10 | while (list != NULL) 11 | { 12 | tmp = list->next; 13 | free(list); 14 | list = tmp; 15 | } 16 | 17 | *list_ptr = NULL; 18 | } 19 | 20 | // add a film to the list; 21 | void add_film(List filmlist, Film * new_film) 22 | { 23 | Film * film_ptr = filmlist; 24 | while (film_ptr->next != NULL) 25 | film_ptr = film_ptr->next; 26 | film_ptr->next = new_film; 27 | } 28 | 29 | // print the list of films in original order 30 | void list_films(List film_ptr) 31 | { 32 | while (film_ptr != NULL) 33 | { 34 | printf("%s: %d\n", film_ptr->title, film_ptr->rating); 35 | film_ptr = film_ptr->next; 36 | } 37 | } 38 | 39 | // print the list of films in reverse order 40 | void reverse_list_films(List film_ptr) 41 | { 42 | if (film_ptr == NULL) 43 | return; 44 | else 45 | { 46 | reverse_list_films(film_ptr->next); 47 | printf("%s: %d\n", film_ptr->title, film_ptr->rating); 48 | } 49 | } -------------------------------------------------------------------------------- /ch17/film.h: -------------------------------------------------------------------------------- 1 | #ifndef FILM_H_ 2 | #define FILM_H_ 1 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #define TSIZE 45 9 | 10 | typedef struct film 11 | { 12 | char title[TSIZE]; 13 | int rating; 14 | struct film * next; 15 | } Film; 16 | 17 | typedef Film * List; 18 | 19 | // delete the entire film list and free allocated memory 20 | void delete_list(List * list); 21 | 22 | // add a film to the list; 23 | void add_film(List filmlist, Film * item); 24 | 25 | // print the list of films in original order 26 | void list_films(List filmlist); 27 | 28 | // print the list of films in reverse order 29 | void reverse_list_films(List filmlist); 30 | 31 | #endif -------------------------------------------------------------------------------- /ch17/list.h: -------------------------------------------------------------------------------- 1 | /* list.h -- header file for a simple list type */ 2 | #ifndef LIST_H_ 3 | #define LIST_H_ 4 | 5 | #include 6 | #define TSIZE 45 /* size of array to hold title */ 7 | 8 | struct film 9 | { 10 | char title[TSIZE]; 11 | int rating; 12 | }; 13 | 14 | /* general type definitions */ 15 | typedef struct film Item; 16 | 17 | typedef struct node { 18 | Item item; 19 | struct node * next; 20 | } Node; 21 | 22 | typedef struct list { 23 | Node * head; 24 | Node * end; 25 | } List; 26 | 27 | /* function prototypes */ 28 | 29 | 30 | // operation: initialize a list 31 | // preconditions: plist points to a list 32 | // postcondition: the list is initialized to empty 33 | void InitializeList(List * plist); 34 | 35 | 36 | // operation: determine if list is empty 37 | // preconditions: plist points to an initialized list 38 | // postcondition: function returns true if list is empty 39 | // and false otherwise 40 | bool ListIsEmpty(const List *plist); 41 | 42 | 43 | // operation: determine if list is full 44 | // preconditions: plist points to an initialized list 45 | // postcondition: function returns true if list is full and false 46 | // otherwise 47 | bool ListIsFull(const List *plist); 48 | 49 | 50 | // operation: determine number of items in list 51 | // preconditions: plist points to an initialized list 52 | // postconditions: function returns number of items in list 53 | unsigned int ListItemCount(const List *plist); 54 | 55 | 56 | // operation: add item to end of list 57 | // preconditions: item is an item to be added to list 58 | // plist points to an initialized list 59 | // postcondition: if possible, function adds item to end 60 | // of list and returns True; otherwise the 61 | // function returns False 62 | bool AddItem(Item item, List * plist); 63 | 64 | 65 | // operation: apply a function to each item in list 66 | // preconditions: plist points to an initialized list 67 | // pfun points to a function that takes an 68 | // Item argument and has no return value 69 | // postcondition: the function pointed to by pfun is 70 | // executed once for each item in the list 71 | void Traverse (const List *plist, void (* pfun)(Item item) ); 72 | 73 | // operation: free allocated memory, if any 74 | // preconditions: plist points to an initialized list 75 | // postcondition: any memory allocated for the list is freed 76 | // and the list is set to empty 77 | void EmptyTheList(List * plist); 78 | 79 | #endif -------------------------------------------------------------------------------- /ch17/list2.c: -------------------------------------------------------------------------------- 1 | /* list.c -- functions supporting list operations */ 2 | 3 | #include 4 | #include 5 | #include "list2.h" 6 | 7 | /* interface functions */ 8 | 9 | /* set the list to empty */ 10 | void InitializeList(List * plist) 11 | { 12 | plist->items = 0; 13 | } 14 | 15 | /* returns true if list is empty */ 16 | bool ListIsEmpty(const List * plist) 17 | { 18 | return (plist->items == 0); 19 | } 20 | 21 | /* returns true if list is full */ 22 | bool ListIsFull(const List * plist) 23 | { 24 | return (plist->items == MAXSIZE); 25 | } 26 | 27 | /* returns number of items */ 28 | unsigned int ListItemCount(const List * plist) 29 | { 30 | return plist->items; 31 | } 32 | 33 | /* adds item to list */ 34 | bool AddItem(Item item, List * plist) 35 | { 36 | if (plist->items < MAXSIZE) 37 | { 38 | plist->entries[plist->items] = item; 39 | (plist->items)++; 40 | return true; 41 | } 42 | else 43 | return false; 44 | } 45 | 46 | /* traverses the list, calling *pfun on every item */ 47 | void Traverse (const List * plist, void (* pfun)(Item item) ) 48 | { 49 | for (int i = 0; i < plist->items; i++) 50 | (*pfun)(plist->entries[i]); 51 | } 52 | 53 | /* empty the list */ 54 | void EmptyTheList(List * plist) 55 | { 56 | plist->items=0; 57 | } 58 | -------------------------------------------------------------------------------- /ch17/list2.h: -------------------------------------------------------------------------------- 1 | /* list.h -- header file for a simple list type */ 2 | #ifndef LIST_H_ 3 | #define LIST_H_ 4 | 5 | #include 6 | #define TSIZE 45 /* size of array to hold title */ 7 | #define MAXSIZE 100 8 | 9 | struct film 10 | { 11 | char title[TSIZE]; 12 | int rating; 13 | }; 14 | 15 | /* general type definitions */ 16 | typedef struct film Item; 17 | 18 | typedef struct list { 19 | Item entries[MAXSIZE]; /* array of items */ 20 | int items; /* number of items in list */ 21 | } List; 22 | 23 | /* function prototypes */ 24 | 25 | // operation: initialize a list 26 | // preconditions: plist points to a list 27 | // postcondition: the list is initialized to empty 28 | void InitializeList(List * plist); 29 | 30 | 31 | // operation: determine if list is empty 32 | // preconditions: plist points to an initialized list 33 | // postcondition: function returns true if list is empty 34 | // and false otherwise 35 | bool ListIsEmpty(const List *plist); 36 | 37 | 38 | // operation: determine if list is full 39 | // preconditions: plist points to an initialized list 40 | // postcondition: function returns true if list is full and false 41 | // otherwise 42 | bool ListIsFull(const List *plist); 43 | 44 | 45 | // operation: determine number of items in list 46 | // preconditions: plist points to an initialized list 47 | // postconditions: function returns number of items in list 48 | unsigned int ListItemCount(const List *plist); 49 | 50 | 51 | // operation: add item to end of list 52 | // preconditions: item is an item to be added to list 53 | // plist points to an initialized list 54 | // postcondition: if possible, function adds item to end 55 | // of list and returns True; otherwise the 56 | // function returns False 57 | bool AddItem(Item item, List * plist); 58 | 59 | 60 | // operation: apply a function to each item in list 61 | // preconditions: plist points to an initialized list 62 | // pfun points to a function that takes an 63 | // Item argument and has no return value 64 | // postcondition: the function pointed to by pfun is 65 | // executed once for each item in the list 66 | void Traverse (const List *plist, void (* pfun)(Item item) ); 67 | 68 | // operation: free allocated memory, if any 69 | // preconditions: plist points to an initialized list 70 | // postcondition: any memory allocated for the list is freed 71 | // and the list is set to empty 72 | void EmptyTheList(List * plist); 73 | 74 | #endif -------------------------------------------------------------------------------- /ch17/pettree.h: -------------------------------------------------------------------------------- 1 | // pettree.h -- interface for a binary search tree linked list data type 2 | 3 | #ifndef PETTREE_H_ 4 | #define PETTREE_H_ 1 5 | 6 | #include 7 | 8 | #define STRLEN 30 9 | 10 | // Type definitions 11 | 12 | typedef struct pet 13 | { 14 | char type[STRLEN]; 15 | char name[STRLEN]; 16 | struct pet * next; 17 | } Pet; 18 | 19 | typedef Pet * List; 20 | 21 | typedef struct node { 22 | char name[STRLEN]; 23 | List head; 24 | struct node * left; 25 | struct node * right; 26 | } Node; 27 | 28 | typedef Node * Tree; 29 | 30 | // Operations 31 | 32 | // Operation: Initialize a Tree 33 | // Preconditions: ptree points to an unitialized Tree 34 | // Postconditions: ptree points to an initialized Tree 35 | Tree * InitializeTree(Tree * ptree); 36 | 37 | 38 | // Return true if Tree pointed to by ptree is empty, otherwise 39 | // return false 40 | bool TreeIsEmpty(const Tree * ptree); 41 | 42 | // Return true if Tree pointed to by ptree is full, otherwise 43 | // return false 44 | bool TreeIsFull(const Tree * ptree); 45 | 46 | // Add Pet item with given name and type to Tree pointed 47 | // to by ptree 48 | // Return: true if operation succeeds, otherwise false 49 | bool AddPet(Pet * ppet, Tree * ptree); 50 | 51 | // Find and remove the Node corresponding the to string word 52 | // in the Tree pointed to by ptree if it exists. 53 | // Return: true if the Node corresponding to word is found 54 | // and deleted, otherwise false 55 | bool DeletePet(Pet * ppet, Tree * ptree); 56 | 57 | // Search for Node corresponding to string name in Tree 58 | // pointed to by ptree. 59 | // Return: true if word is found in Tree, otherwise false 60 | bool InTree(Pet * ppet, const Tree * ptree); 61 | 62 | int TreeItemCount(Tree tree); 63 | 64 | // Visit each Node in Tree pointed to by ptree, calling 65 | // function pointed to by fn on each Pet member of each Node 66 | void TraverseTree(const Tree * ptree, void (*fn)(Pet)); 67 | 68 | // Search for Node matching string name and if found, call 69 | // function pointed to by fn on each Pet member of Node 70 | void ApplyToNode(Pet * ppet, const Tree * ptree, void (*fn)(Pet)); 71 | 72 | // Delete all Nodes in Tree pointed to by ptree and free all 73 | // allocated memory 74 | void DeleteAll(Tree * ptree); 75 | 76 | #endif -------------------------------------------------------------------------------- /ch17/queue.c: -------------------------------------------------------------------------------- 1 | // queue.c -- implementation of a queue type 2 | 3 | #include "queue.h" 4 | #include 5 | #include 6 | #include 7 | 8 | static void CopyToNode(Item item, Node * pnode) 9 | { 10 | pnode->item = item; 11 | } 12 | 13 | static void CopyToItem(Item * pitem, Node *pnode) 14 | { 15 | *pitem = pnode->item; 16 | } 17 | 18 | void InitializeQueue(Queue * pq) { 19 | pq->front = NULL; 20 | pq->rear = NULL; 21 | pq->items = 0; 22 | } 23 | 24 | bool QueueIsFull(const Queue * pq) { 25 | return pq->items == MAXQUEUE; 26 | } 27 | 28 | bool QueueIsEmpty(const Queue *pq) { 29 | return pq->items == 0; 30 | } 31 | 32 | int QueueItemCount(const Queue * pq){ 33 | return pq->items; 34 | } 35 | 36 | bool EnQueue(Item item, Queue * pq) { 37 | if (QueueIsFull(pq)) { 38 | return false; 39 | } 40 | 41 | Node * new = (Node *) malloc(sizeof(Node)); 42 | if (new == NULL) { 43 | fprintf(stderr, "Unable to allocate memory!\n"); 44 | exit(EXIT_FAILURE); 45 | } 46 | CopyToNode(item, new); 47 | new->next = NULL; 48 | 49 | if (QueueIsEmpty(pq)) { 50 | pq->front = new; 51 | } 52 | else { 53 | (pq->rear)->next = new; 54 | } 55 | pq->rear = new; 56 | pq->items++; // increment items count 57 | 58 | return true; 59 | } 60 | 61 | bool DeQueue(Item *pitem, Queue * pq){ 62 | if (QueueIsEmpty(pq)) { 63 | return false; 64 | } 65 | 66 | Node * first = pq->front; 67 | CopyToItem(pitem, first); 68 | pq->front = first->next; 69 | free(first); 70 | 71 | // decrement items count and set rear pointer to null if necessary 72 | pq->items--; 73 | if (pq->items == 0) { 74 | pq->rear = NULL; 75 | } 76 | return true; 77 | } 78 | 79 | void EmptyTheQueue(Queue * pq){ 80 | Item tmp; 81 | while (DeQueue(&tmp, pq)) 82 | continue; 83 | } -------------------------------------------------------------------------------- /ch17/stack.c: -------------------------------------------------------------------------------- 1 | // stack.c -- implementation file for stack type 2 | 3 | #include 4 | #include "stack.h" 5 | #include 6 | 7 | Stack * InitializeStack(Stack * pstack) 8 | { 9 | *pstack = NULL; 10 | return pstack; 11 | } 12 | 13 | bool PushItem(const char * pch, Stack * pstack) 14 | { 15 | Node * pnode = (Node *) malloc(sizeof(Node)); 16 | if (pnode == NULL) 17 | { 18 | fprintf(stderr, "Stack is full. Could not add item.\n"); 19 | return false; 20 | } 21 | else 22 | { 23 | pnode->item = *pch; 24 | pnode->previous = *pstack; 25 | *pstack = pnode; 26 | return true; 27 | } 28 | } 29 | 30 | bool PopItem(char * pch, Stack * pstack) 31 | { 32 | if (*pstack == NULL) 33 | return false; 34 | else 35 | { 36 | *pch = (*pstack)->item; 37 | Node * tmp = *pstack; 38 | *pstack = (*pstack)->previous; 39 | free(tmp); 40 | return true; 41 | } 42 | } 43 | 44 | void EmptyStack(Stack * pstack) 45 | { 46 | Node * tmp, * pnode = *pstack; 47 | while (pnode != NULL) 48 | { 49 | tmp = pnode->previous; 50 | free(pnode); 51 | pnode = tmp; 52 | } 53 | } -------------------------------------------------------------------------------- /ch17/stack.h: -------------------------------------------------------------------------------- 1 | #ifndef STACK_H_ 2 | #define STACK_H_ 1 3 | 4 | // stack.h -- header file for a stack type 5 | 6 | #include 7 | 8 | // Type definitions 9 | 10 | typedef struct node 11 | { 12 | char item; 13 | struct node * previous; 14 | } Node; 15 | 16 | typedef Node * Stack; 17 | 18 | // Operations 19 | 20 | // Initialize a list 21 | Stack * InitializeStack(Stack * pstack); 22 | 23 | // Attempt to add char ch to the stack pointed to by pstack. 24 | // Returns true if operation is successful, else false 25 | bool PushItem(const char * pch, Stack * pstack); 26 | 27 | // Pop item from stack and place in location pointed to by pch. 28 | // Returns true if operation succeeds, false if stack is empty 29 | bool PopItem(char *pch, Stack * pstack); 30 | 31 | // Empty Stack and free memory 32 | void EmptyStack(Stack * pstack); 33 | 34 | #endif -------------------------------------------------------------------------------- /ch17/tree.h: -------------------------------------------------------------------------------- 1 | // tree.h -- interface for a binary search tree data type 2 | 3 | #ifndef TREE_H_ 4 | #define TREE_H_ 1 5 | 6 | #include 7 | 8 | #define WORD_SIZE 30 9 | 10 | // Type definitions 11 | 12 | typedef struct 13 | { 14 | char word[WORD_SIZE]; 15 | int count; 16 | } Item; 17 | 18 | typedef struct node { 19 | Item item; 20 | struct node * left; 21 | struct node * right; 22 | } Node; 23 | 24 | typedef Node * Tree; 25 | 26 | // Operations 27 | 28 | // Operation: Initialize a Tree 29 | // Preconditions: ptree points to an unitialized Tree 30 | // Postconditions: ptree points to an initialized Tree 31 | Tree * InitializeTree(Tree * ptree); 32 | 33 | 34 | // Return true if Tree pointed to by ptree is empty, otherwise 35 | // return false 36 | bool TreeIsEmpty(const Tree * ptree); 37 | 38 | // Return true if Tree pointed to by ptree is full, otherwise 39 | // return false 40 | bool TreeIsFull(const Tree * ptree); 41 | 42 | // Add occurence of string word to Tree pointed to by ptree: 43 | // if a node corresponding to word already exists, increment 44 | // the count member of that node, otherwise create a new Node 45 | // and add it to the Tree, setting its count to 1. 46 | // Return: true if operation succeeds, otherwise false 47 | bool AddWord(const char * word, Tree * ptree); 48 | 49 | // Find and remove the Node corresponding the to string word 50 | // in the Tree pointed to by ptree if it exists. 51 | // Return: true if the Node corresponding to word is found 52 | // and deleted, otherwise false 53 | bool DeleteWord(const char * word, Tree * ptree); 54 | 55 | // Search for Node corresponding to string word in Tree 56 | // pointed to by ptree. 57 | // Return: true if word is found in Tree, otherwise false 58 | bool InTree(const char * word, const Tree * ptree); 59 | 60 | // Visit each Node in Tree pointed to by ptree, calling 61 | // function pointed to by fn on the Item member of each Node 62 | void ApplyToAll(const Tree * ptree, void (*fn)(Item)); 63 | 64 | // Search for Node matching string word and if found, call 65 | // function pointed to by fn on its item member 66 | void ApplyToNode(const char * word, const Tree * ptree, void (*fn)(Item)); 67 | 68 | // Delete all Nodes in Tree pointed to by ptree and free all 69 | // allocated memory 70 | void DeleteAll(Tree * ptree); 71 | 72 | #endif --------------------------------------------------------------------------------