├── .gitignore ├── ch02 ├── Exercises │ ├── 01.c │ ├── 02.c │ ├── 03.c │ └── 04.c └── Projects │ ├── 01.c │ ├── 02.c │ ├── 03.c │ ├── 04.c │ ├── 05.c │ ├── 06.c │ ├── 07.c │ └── 08.c ├── ch03 ├── Exercises │ ├── 01.c │ ├── 02.c │ ├── 03.txt │ ├── 04.txt │ ├── 05.txt │ └── 06.c └── Projects │ ├── 01.c │ ├── 02.c │ ├── 03.c │ ├── 04.c │ ├── 05.c │ └── 06.c ├── ch04 ├── Exercises │ ├── 01.txt │ ├── 02.txt │ ├── 03.txt │ ├── 04.txt │ ├── 05.txt │ ├── 06.txt │ ├── 07.txt │ ├── 08.txt │ └── 09.txt └── Projects │ ├── 01.c │ ├── 02.c │ ├── 03.c │ ├── 04.c │ ├── 05.c │ └── 06.c ├── ch05 ├── Exercises │ ├── 01.txt │ ├── 02.txt │ ├── 03.txt │ ├── 04.c │ ├── 05.c │ ├── 06.c │ ├── 07.c │ ├── 08.c │ ├── 09.txt │ ├── 10.txt │ └── 11.c └── Projects │ ├── 01.c │ ├── 02.c │ ├── 03.c │ ├── 04.c │ ├── 05.c │ ├── 06.c │ ├── 07.c │ ├── 08.c │ ├── 09.c │ ├── 10.c │ └── 11.c ├── ch06 ├── Exercises │ ├── 01.txt │ ├── 02.txt │ ├── 03.txt │ ├── 04.txt │ ├── 05.txt │ ├── 06.c │ ├── 07.c │ ├── 08.txt │ ├── 09.c │ ├── 10.txt │ ├── 11.txt │ ├── 12.c │ ├── 13.c │ └── 14.txt └── Projects │ ├── 01.c │ ├── 02.c │ ├── 03.c │ ├── 04.c │ ├── 05.c │ ├── 06.c │ ├── 07.c │ ├── 08.c │ ├── 09.c │ ├── 10.c │ ├── 11.c │ └── 12.c ├── ch07 ├── Exercises │ ├── 01.txt │ ├── 02.txt │ ├── 03.txt │ ├── 04.txt │ ├── 05.txt │ ├── 06.txt │ ├── 07.txt │ ├── 08.txt │ ├── 09.txt │ ├── 10.txt │ ├── 11.txt │ ├── 12.txt │ ├── 13.txt │ ├── 14.txt │ └── 15.c └── Projects │ ├── 01.c │ ├── 02.c │ ├── 03.c │ ├── 04.c │ ├── 05.c │ ├── 06.c │ ├── 07.c │ ├── 08.c │ ├── 09.c │ ├── 10.c │ ├── 11.c │ ├── 12.c │ ├── 13.c │ ├── 14.c │ └── 15.c ├── ch08 ├── Exercises │ ├── 01.txt │ ├── 02.txt │ ├── 03.txt │ ├── 04.txt │ ├── 05.c │ ├── 06.c │ ├── 07.c │ ├── 08.c │ ├── 09.c │ ├── 10.c │ └── 11.c └── Projects │ ├── 01.c │ ├── 02.c │ ├── 03.c │ ├── 04.c │ ├── 05.c │ ├── 06.c │ ├── 07.c │ ├── 08.c │ ├── 09.c │ ├── 10.c │ ├── 11.c │ ├── 12.c │ ├── 13.c │ ├── 14.c │ ├── 15.c │ ├── 16.c │ └── 17.c ├── ch09 ├── Exercises │ ├── 01.txt │ ├── 02.c │ ├── 03.c │ ├── 04.c │ ├── 05.c │ ├── 06.c │ ├── 07.txt │ ├── 08.txt │ ├── 09.txt │ ├── 10.c │ ├── 11.c │ ├── 12.c │ ├── 13.c │ ├── 14.txt │ ├── 15.txt │ ├── 16.c │ ├── 17.c │ ├── 18.c │ └── 19.c └── Projects │ ├── 01.c │ ├── 02.c │ ├── 03.c │ ├── 04.c │ ├── 05.c │ ├── 06.c │ ├── 07.c │ └── 08.c ├── ch10 ├── Exercises │ ├── 01.txt │ ├── 02.txt │ └── 03.txt └── Projects │ ├── 01.c │ ├── 02.c │ ├── 03.c │ ├── 04.c │ ├── 05.c │ ├── 06.c │ └── 07.c ├── ch11 ├── Exercises │ ├── 01.txt │ ├── 02.txt │ ├── 03.txt │ ├── 04.c │ ├── 05.c │ ├── 06.c │ ├── 07.c │ └── 08.c └── Projects │ ├── 01.c │ ├── 02.c │ ├── 03.c │ └── 04.c ├── ch12 ├── Exercises │ ├── 01.txt │ ├── 02.txt │ ├── 03.txt │ ├── 04.c │ ├── 05.txt │ ├── 06.c │ ├── 07.c │ ├── 08.c │ ├── 09.c │ ├── 10.c │ ├── 11.c │ ├── 12.c │ ├── 13.c │ ├── 14.c │ ├── 15.c │ ├── 16.c │ ├── 17.c │ └── 18.c └── Projects │ ├── 01.c │ ├── 02.c │ ├── 03.c │ ├── 04.c │ ├── 05.c │ ├── 06.c │ └── 07.c ├── ch13 ├── Exercises │ ├── 01.txt │ ├── 02.txt │ ├── 03.txt │ ├── 04.c │ ├── 05.c │ ├── 06.c │ ├── 07.txt │ ├── 08.txt │ ├── 09.txt │ ├── 10.txt │ ├── 11.c │ ├── 12.c │ ├── 13.c │ ├── 14.txt │ ├── 15.txt │ ├── 16.c │ ├── 17.c │ └── 18.c └── Projects │ ├── 01.c │ ├── 02a.c │ ├── 02b.c │ ├── 02c.c │ ├── 03.c │ ├── 04.c │ ├── 05.c │ ├── 06.c │ ├── 07.c │ ├── 08.c │ ├── 09.c │ ├── 10.c │ ├── 11.c │ ├── 12.c │ ├── 13.c │ ├── 14.c │ ├── 15.c │ ├── 16.c │ ├── 17.c │ └── 18.c ├── ch14 └── Exercises │ ├── 01.c │ ├── 02.c │ ├── 03.txt │ ├── 04.txt │ ├── 05.txt │ ├── 06.c │ ├── 07.txt │ ├── 08.c │ ├── 09.c │ ├── 10.txt │ ├── 11.c │ ├── 12.txt │ ├── 13.txt │ ├── 14.txt │ ├── 15.c │ └── 16.txt ├── ch15 ├── Exercises │ ├── 01.txt │ ├── 02.txt │ ├── 03.txt │ ├── 04.txt │ ├── 05.txt │ └── 06.txt └── Projects │ ├── 01 │ ├── justify.c │ ├── justify_after_change │ ├── justify_before_change │ ├── line.c │ ├── line.h │ ├── makefile │ ├── quote │ ├── word.c │ └── word.h │ ├── 02 │ ├── justify.c │ ├── line.c │ ├── line.h │ ├── makefile │ ├── quote │ ├── word.c │ └── word.h │ ├── 03 │ ├── makefile │ ├── quicksort │ ├── quicksort.c │ └── quicksort.h │ ├── 04 │ ├── makefile │ ├── readline.c │ ├── readline.h │ └── remind.c │ └── 05 │ ├── calc.c │ ├── makefile │ ├── stack.c │ └── stack.h ├── ch16 ├── Exercises │ ├── 01.txt │ ├── 02.c │ ├── 03.c │ ├── 04.c │ ├── 05.c │ ├── 06.c │ ├── 07.c │ ├── 08.txt │ ├── 09.c │ ├── 10.c │ ├── 11.txt │ ├── 12.txt │ ├── 13.txt │ ├── 14.c │ ├── 15.txt │ ├── 16.txt │ ├── 17.txt │ ├── 18.c │ ├── 19.txt │ ├── 20.c │ ├── 21.txt │ └── 22.txt └── Projects │ ├── 01.c │ ├── 02 │ ├── inventory.c │ ├── inventory.h │ ├── makefile │ ├── quicksort.c │ ├── quicksort.h │ ├── readline.c │ └── readline.h │ ├── 03 │ ├── inventory.c │ ├── inventory.h │ ├── makefile │ ├── quicksort.c │ ├── quicksort.h │ ├── readline.c │ └── readline.h │ ├── 04 │ ├── inventory.c │ ├── inventory.h │ ├── makefile │ ├── quicksort.c │ ├── quicksort.h │ ├── readline.c │ └── readline.h │ ├── 05.c │ └── 06.c ├── ch17 ├── Exercises │ ├── 18 │ │ ├── inventory.c │ │ ├── makefile │ │ ├── readline.c │ │ └── readline.h │ ├── 01.c │ ├── 02.c │ ├── 03.c │ ├── 04.c │ ├── 05.txt │ ├── 06.txt │ ├── 07.txt │ ├── 08.c │ ├── 09.txt │ ├── 10.txt │ ├── 11.txt │ ├── 12.txt │ ├── 13.txt │ ├── 14.txt │ ├── 15.txt │ ├── 16.c │ ├── 17.c │ ├── 19.c │ └── linked_list.c └── Projects │ ├── 01_02 │ ├── inventory.c │ ├── makefile │ ├── readline.c │ └── readline.h │ ├── 03 │ ├── inventory.c │ ├── makefile │ ├── readline.c │ └── readline.h │ ├── 04 │ ├── justify.c │ ├── line.c │ ├── line.h │ ├── makefile │ ├── newquote │ ├── quote │ ├── word.c │ └── word.h │ ├── 05_06.c │ └── 07.c ├── ch18 └── Exercises │ ├── 01.txt │ ├── 02.txt │ ├── 03.txt │ ├── 04.txt │ ├── 05.txt │ ├── 06.txt │ ├── 07.txt │ ├── 08.txt │ ├── 09.txt │ ├── 10.txt │ ├── 11.txt │ ├── 12.txt │ ├── 13.txt │ ├── 14.txt │ └── 15.txt ├── ch19 ├── Exercises │ ├── 01 │ │ └── queue.h │ ├── 02 │ │ ├── stack.h │ │ └── stack2.c │ ├── 03 │ │ ├── a │ │ │ ├── makefile │ │ │ ├── queue.c │ │ │ ├── queue.h │ │ │ └── queueclient.c │ │ └── b │ │ │ ├── makefile │ │ │ ├── queue.c │ │ │ ├── queue.h │ │ │ └── queueclient.c │ ├── 04 │ │ ├── a │ │ │ ├── makefile │ │ │ ├── stack.c │ │ │ ├── stack.h │ │ │ └── stackclient.c │ │ └── b │ │ │ ├── makefile │ │ │ ├── stack.c │ │ │ ├── stack.h │ │ │ └── stackclient.c │ ├── 05 │ │ └── queue.h │ ├── 06 │ │ ├── a │ │ │ ├── stackADT.c │ │ │ └── stackADT.h │ │ ├── b │ │ │ ├── stackADT2.c │ │ │ └── stackADT2.h │ │ └── c │ │ │ ├── stackADT.h │ │ │ └── stackADT3.c │ └── 07 │ │ ├── stackADT2.c │ │ └── stackADT2.h └── Projects │ ├── 01 │ ├── makefile │ ├── stack.c │ ├── stack.h │ └── stackclient.c │ ├── 02 │ ├── makefile │ ├── stack.c │ ├── stack.h │ └── stackclient.c │ ├── 03 │ ├── makefile │ ├── stackADT.h │ ├── stackADT3.c │ └── stackclient.c │ ├── 04 │ ├── makefile │ ├── stackADT.h │ ├── stackADT3.c │ └── stackclient.c │ ├── 05 │ ├── makefile │ ├── queue.h │ ├── queueADT.c │ └── queueclient.c │ ├── 06 │ ├── makefile │ ├── queue.h │ ├── queueADT.c │ └── queueclient.c │ └── 07 │ ├── makefile │ ├── queue.h │ ├── queueADT.c │ └── queueclient.c ├── ch20 ├── Exercises │ ├── 01.txt │ ├── 02.txt │ ├── 03.txt │ ├── 04_05.c │ ├── 06.c │ ├── 07.c │ ├── 08.txt │ ├── 09.c │ ├── 10.c │ ├── 11.txt │ ├── 12.txt │ ├── 13.txt │ ├── 14.c │ ├── 15.txt │ └── 16.c └── Projects │ └── 01.c ├── ch21 ├── Exercises │ ├── 01.txt │ ├── 02.txt │ ├── 03.txt │ ├── 04.txt │ ├── 05.txt │ ├── 06.txt │ ├── 06_helper.c │ └── 07.txt └── Projects │ └── 01.c ├── ch22 ├── Exercises │ ├── 01.txt │ ├── 02.txt │ ├── 03.txt │ ├── 04.txt │ ├── 05.txt │ ├── 06.c │ ├── 07.txt │ ├── 08.txt │ ├── 09.txt │ ├── 10.c │ ├── 11.txt │ ├── 12.c │ ├── 13.c │ ├── 14.c │ ├── 15.c │ └── 16.c └── Projects │ ├── 10 │ ├── inventory.h │ ├── inventory2.c │ ├── makefile │ ├── readline.c │ └── readline.h │ ├── 15 │ ├── inquote │ ├── justify │ ├── justify.c │ ├── line.c │ ├── line.h │ ├── makefile │ ├── outquote │ ├── word.c │ └── word.h │ ├── 01.c │ ├── 02.c │ ├── 03.c │ ├── 04.c │ ├── 05.c │ ├── 06.c │ ├── 07.c │ ├── 08 │ ├── inventory.c │ ├── inventory.h │ ├── makefile │ ├── readline.c │ └── readline.h │ ├── 09 │ ├── dump1 │ ├── dump2 │ ├── dumpmerge │ ├── inventory.h │ ├── makefile │ └── mergepartfiles.c │ ├── 11.c │ ├── 12.c │ ├── 13.c │ ├── 14.c │ ├── 16.c │ ├── 17.c │ ├── 18.c │ ├── 19a.c │ └── 19b.c └── ch23 └── Exercises └── 01.c /.gitignore: -------------------------------------------------------------------------------- 1 | ### https://raw.github.com/github/gitignore/b8da0e3a89f5d75acdb9d5fed06700bfff3695f9/C.gitignore 2 | 3 | # Object files 4 | *.o 5 | *.ko 6 | *.obj 7 | *.elf 8 | 9 | # Precompiled Headers 10 | *.gch 11 | *.pch 12 | 13 | # Libraries 14 | *.lib 15 | *.a 16 | *.la 17 | *.lo 18 | 19 | # Shared objects (inc. Windows DLLs) 20 | *.dll 21 | *.so 22 | *.so.* 23 | *.dylib 24 | 25 | # Executables 26 | *.exe 27 | *.out 28 | *.app 29 | *.i*86 30 | *.x86_64 31 | *.hex 32 | 33 | # Debug files 34 | *.dSYM/ 35 | 36 | 37 | -------------------------------------------------------------------------------- /ch02/Exercises/01.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | printf("hello, world\n"); 6 | return 0; 7 | } 8 | -------------------------------------------------------------------------------- /ch02/Exercises/02.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main (void) 4 | { 5 | printf("Parkinson's Law:\nWork expands so as to "); 6 | printf("fill the time\n"); 7 | printf("available for its completion.\n"); 8 | return 0; 9 | } 10 | -------------------------------------------------------------------------------- /ch02/Exercises/03.c: -------------------------------------------------------------------------------- 1 | /* Computes the dimensional weight of a 12" x 10" x 8" box */ 2 | 3 | #include 4 | 5 | int main(void) 6 | { 7 | int height = 8, length = 12, width = 10, volume = height * length * width; 8 | 9 | printf("Dimensions: %dx%dx%d\n", length, width, height); 10 | printf("Volume (cubic inches): %d\n", volume); 11 | printf("Dimensional weight (pounds): %d\n", (volume + 165) / 166); 12 | 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /ch02/Exercises/04.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int a,b,c; 4 | float d,e,f; 5 | 6 | int main() 7 | { 8 | printf("%d, %d, %d, %f, %f, %f"); 9 | } 10 | -------------------------------------------------------------------------------- /ch02/Projects/01.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | printf(" *\n"); 6 | printf(" *\n"); 7 | printf(" *\n"); 8 | printf("* *\n"); 9 | printf(" * *\n"); 10 | printf(" *\n"); 11 | } 12 | -------------------------------------------------------------------------------- /ch02/Projects/02.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define pi 3.14159 4 | #define frac 4.0f/3.0f 5 | 6 | int main(void) 7 | { 8 | float vol = frac * (pi * (10 * 10 * 10)); 9 | printf("%.2f", vol); 10 | } 11 | -------------------------------------------------------------------------------- /ch02/Projects/03.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define PI 3.14159 4 | #define FRAC 4.0f/3.0f 5 | 6 | float radius, volume; 7 | 8 | int main(void) 9 | { 10 | printf("Please enter the radius of the sphere: "); 11 | scanf("%f", &radius); 12 | volume = FRAC * (PI * (radius * radius * radius)); 13 | printf("%.2f", volume); 14 | } 15 | -------------------------------------------------------------------------------- /ch02/Projects/04.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | float amount; 4 | 5 | int main(void) 6 | { 7 | printf("Enter an amount: "); 8 | scanf("%f", &amount); 9 | printf("with tax added: $%.2f", amount * 1.05f); 10 | 11 | return 0; 12 | } 13 | -------------------------------------------------------------------------------- /ch02/Projects/05.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int x; 4 | 5 | int main(void) 6 | { 7 | printf("Enter a value: "); 8 | scanf("%d", &x); 9 | printf("%d", (3 * (x * x * x * x * x)) 10 | + (2 * (x * x * x * x)) 11 | - (5 * (x * x * x)) 12 | - (x * x) 13 | + (7 * x) 14 | - 6); 15 | 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /ch02/Projects/06.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int x; 4 | 5 | int main(void) 6 | { 7 | printf("Enter a value: "); 8 | scanf("%d", &x); 9 | printf("%d", ((((3 * x + 2) * x - 5) * x - 1) * x + 7) * x - 6); 10 | 11 | return 0; 12 | } 13 | -------------------------------------------------------------------------------- /ch02/Projects/07.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | int amount, twenties, tens, fives, ones; 6 | 7 | printf("Enter a dollar amount: "); 8 | scanf("%d", &amount); 9 | 10 | twenties = amount / 20; 11 | amount -= twenties * 20; 12 | tens = amount / 10; 13 | amount -= tens * 10; 14 | fives = amount / 5; 15 | amount -= fives * 5; 16 | ones = amount / 1; 17 | 18 | printf("$20 bills: %d\n", twenties); 19 | printf("$10 bills: %d\n", tens); 20 | printf(" $5 bills: %d\n", fives); 21 | printf(" $1 bills: %d\n", ones); 22 | 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /ch02/Projects/08.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | float loan, interest_rate, monthly_payment; 6 | 7 | printf("Enter amount of loan: "); 8 | scanf("%f", &loan); 9 | printf("Enter interest rate: "); 10 | scanf("%f", &interest_rate); 11 | printf("Enter monthly payment: "); 12 | scanf("%f", &monthly_payment); 13 | 14 | float monthly_interest = ((interest_rate / 100) / 12) + 1; 15 | 16 | loan *= monthly_interest; 17 | loan -= monthly_payment; 18 | printf("Balance remaining after first payment: $%.2f\n", loan); 19 | 20 | loan *= monthly_interest; 21 | loan -= monthly_payment; 22 | printf("Balance remaining after second payment: $%.2f\n", loan); 23 | 24 | loan *= monthly_interest; 25 | loan -= monthly_payment; 26 | printf("Balance remaining after third payment: $%.2f\n", loan); 27 | 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /ch03/Exercises/01.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | printf("%6d, %4d\n", 86, 1040); 6 | printf("%12.5e\n", 30.253); 7 | printf("%.4f\n", 83.162); 8 | printf("%-6.2g\n", .0000009979); 9 | 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /ch03/Exercises/02.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | float x = 123.456; 6 | 7 | printf("%-8.1e\n", x); 8 | printf("%10.6e\n", x); 9 | printf("%-8.3f\n", x); 10 | printf("%6.0f\n", x); 11 | 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /ch03/Exercises/06.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | int num1, denom1, num2, denom2, result_num, result_denom; 6 | 7 | printf("Enter first fraction: "); 8 | scanf("%d /%d", &num1, &denom1); 9 | 10 | printf("Enter second fraction: "); 11 | scanf("%d /%d", &num2, &denom2); 12 | 13 | result_num = num1 * denom2 + num2 * denom1; 14 | result_denom = denom1 * denom2; 15 | printf("The sum is %d/%d\n", result_num, result_denom); 16 | 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /ch03/Projects/01.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | int month, day, year; 6 | 7 | printf("Enter a date (mm/dd/yyyy): "); 8 | scanf("%d /%d /%d", &month, &day, &year); 9 | 10 | printf("You entered the date %.4d%.2d%.2d ", year, month, day); 11 | 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /ch03/Projects/02.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | int item_number, month, day, year; 6 | float unit_price; 7 | 8 | printf("Enter item number: "); 9 | scanf("%d", &item_number); 10 | 11 | printf("Enter unit price: "); 12 | scanf("%f", &unit_price); 13 | 14 | printf("Enter purchase date (mm/dd/yyyy): "); 15 | scanf("%d /%d /%d", &month, &day, &year); 16 | 17 | printf("Item\t\tUnit\t\tPurchase\n"); 18 | printf("\t\tPrice\t\tDate\n"); 19 | printf("%d\t\t$%6.2f\t\t%.2d/%.2d/%.4d", item_number, unit_price, month, day, year); 20 | 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /ch03/Projects/03.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | int gs1_pr, g_id, p_code, i_no, c_digit; 6 | 7 | printf("Enter ISBN: "); 8 | scanf("%d -%d -%d -%d -%d", &gs1_pr, &g_id, &p_code, &i_no, &c_digit); 9 | 10 | printf("GS1 prefix: %d\n" 11 | "Group identifier: %d\n" 12 | "Publisher code: %d\n" 13 | "Item number: %d\n" 14 | "Check digit: %d\n", 15 | gs1_pr, g_id, p_code, i_no, c_digit); 16 | 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /ch03/Projects/04.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | int area_code, exchange, subscriber_number; 6 | 7 | printf("Enter a telephone number (xxx) xxx-xxxx: "); 8 | scanf(" (%d )%d -%d", &area_code, &exchange, &subscriber_number); 9 | 10 | printf("You entered %d.%d.%d", area_code, exchange, subscriber_number); 11 | 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /ch03/Projects/06.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | int num1, denom1, num2, denom2, result_num, result_denom; 6 | 7 | printf("Enter two fractions separated by a plus sign: "); 8 | scanf("%d /%d +%d /%d", &num1, &denom1, &num2, &denom2); 9 | 10 | result_num = num1 * denom2 + num2 * denom1; 11 | result_denom = denom1 * denom2; 12 | printf("The sum is %d/%d\n", result_num, result_denom); 13 | 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /ch04/Exercises/01.txt: -------------------------------------------------------------------------------- 1 | (a) i = 5; j = 3; 2 | 3 | printf("%d %d", i / j, i % j); 4 | 5 | 5 / 3, 5 % 3 6 | 1, 2 7 | 8 | (b) i = 2; j = 3; 9 | 10 | printf("%d", (i + 10) % j); 11 | 12 | (2 + 10) % 3 13 | 12 % 3 14 | 4 15 | 16 | (c) i = 7; j = 8; k = 9; 17 | 18 | printf("%d", (i + 10) % k / j); 19 | 20 | ((7 + 10) % 9) / 8 21 | (17 % 9) / 8 22 | 8 / 8 23 | 1 24 | 25 | (d) i = 1; j = 2; k = 3; 26 | 27 | printf("%d", (i + 5) % (j + 2) / k); 28 | 29 | ((1 + 5) % (2 + 2)) / 3 30 | (6 % 4) / 3 31 | 2 / 3 32 | 0 33 | -------------------------------------------------------------------------------- /ch04/Exercises/02.txt: -------------------------------------------------------------------------------- 1 | If i and j are positive integers, does (-i)/j always have the same value as -(i/j)? 2 | 3 | Answer: Yes 4 | 5 | Rules for division 6 | Pos / Pos = Pos 7 | Pos / Neg = Neg 8 | Neg / Pos = Neg 9 | Neg / Neg = Pos 10 | 11 | Whenever one of the values is negative, we can change it to postive by removing the minus, 12 | carry out the division and then simply put the minus back on the result. 13 | 14 | E.g: 15 | 16 | 10 / 5 = 2 17 | 10 / -5 = -2 18 | -10 / 5 = -2 19 | -10 / -5 = 2 20 | -------------------------------------------------------------------------------- /ch04/Exercises/03.txt: -------------------------------------------------------------------------------- 1 | (a) 8 / 5 = 1 2 | (b) -8 / 5 = -1 or -2 3 | (c) 8 / -5 = -1 or -2 4 | (d) -8 / -5 = 1 or 2 5 | 6 | Division in C89 when the divisor and/or dividend is negative is implementation defined. This means the result 7 | may either be rounded toward 0 or negative infinity depending on the hardware / software implemented 8 | behaviour. 9 | -------------------------------------------------------------------------------- /ch04/Exercises/04.txt: -------------------------------------------------------------------------------- 1 | (a) 8 / 5 = 1 2 | (b) -8 / 5 = -1 3 | (c) 8 / -5 = -1 4 | (d) -8 / -5 = 1 5 | 6 | Division in C99 explicity rounds the result of division towards 0 when the divisor and/or dividend 7 | is negative. 8 | -------------------------------------------------------------------------------- /ch04/Exercises/05.txt: -------------------------------------------------------------------------------- 1 | (a) 8 % 5 = 3 2 | (b) -8 % 5 = -3 or 2 3 | (c) 8 % -5 = -3 or 2 4 | (d) -8 % -5 = -3 or 2 5 | 6 | C89's modulo operator is implementation defined, and therefore the result can either be positive or negative. 7 | 8 | E.g: 9 | 10 | Negative: 11 | -8 / 5 12 | -1 r-3 13 | -3 mod 14 | 15 | Positive: 16 | -8 / 5 17 | -8 = -2 * 5 + (2) 18 | 2 mod 19 | -------------------------------------------------------------------------------- /ch04/Exercises/06.txt: -------------------------------------------------------------------------------- 1 | (a) 8 % 5 = 3 2 | (b) -8 % 5 = -3 3 | (c) 8 % -5 = 3 4 | (d) -8 % -5 = -3 5 | 6 | C99's modulo operator is specified to always have the same sign as the divisor, and the division operator 7 | will always truncate the result towards 0. 8 | -------------------------------------------------------------------------------- /ch04/Exercises/07.txt: -------------------------------------------------------------------------------- 1 | E.g total is 20 2 | 3 | total-- 4 | 9 - (19 % 10) 5 | 9 - 9 6 | 0 7 | 8 | 10 - (20 % 10) 9 | 10 - 0 10 | 10 11 | 12 | The second technique doesn't work because we're providing a different divisor to 13 | the dividend 10, giving a vastly different result. 14 | -------------------------------------------------------------------------------- /ch04/Exercises/08.txt: -------------------------------------------------------------------------------- 1 | total = 15 2 | 3 | 9 - ((total - 1) % 10) 4 | 9 - ((15 - 1) % 10) 5 | 9 - (14 % 10) 6 | 9 - 4 7 | 5 8 | 9 | (10 - (total % 10)) % 10 10 | (10 - (15 % 10)) % 10 11 | (10 - 5) % 10 12 | 5 % 10 13 | 5 14 | 15 | Both expressions produce the same result. 16 | -------------------------------------------------------------------------------- /ch04/Exercises/09.txt: -------------------------------------------------------------------------------- 1 | (a) i = 7; j = 8; 2 | i *= j + 1; 3 | printf("%d %d", i, j); 4 | 5 | i = (i * (j + 1)) 6 | i = (7 * (8 + 1)) 7 | i = (7 * 9) 8 | i = 63; j = 8; 9 | 10 | (b) i = j = k = 1; 11 | i += j +=k; 12 | printf("%d %d %d", i, j, k); 13 | 14 | i = (j = (k = 1)) 15 | i = (j = 1) 16 | i = 1; j = 1; k = 1; 17 | 18 | i = i + (j = j + k) 19 | i = 1 + (j = 1 + 1) 20 | i = 1 + 2 21 | i = 3; j = 2; k = 1; 22 | 23 | (c) i = 1; j = 2; k = 3; 24 | i -= j -= k 25 | printf("%d %d %d", i, j, k); 26 | 27 | i = (i - (j = (j - k))) 28 | i = (1 - (j = (2 - 3))) 29 | i = (1 - (j = -1)) 30 | i = (1 - -1) 31 | i = 2; j = -1; k = 3; 32 | 33 | (d) i = 2; j = 1; k = 0; 34 | i *= j *= k; 35 | printf("%d %d %d", i, j, k); 36 | 37 | i = (i * (j = (j * k))) 38 | i = (2 * (j = (1 * 0))) 39 | i = (2 * (j = 0)) 40 | i = (2 * 0) 41 | i = 0; j = 0; k = 0; 42 | -------------------------------------------------------------------------------- /ch04/Projects/01.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | int num; 6 | 7 | printf("Enter a two-digit number: "); 8 | scanf("%d", &num); 9 | 10 | printf("The reversal is: %d%d", num % 10, num / 10); 11 | 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /ch04/Projects/02.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | int num, n1, n2, n3; 6 | 7 | printf("Enter a three-digit number: "); 8 | scanf("%d", &num); 9 | 10 | n1 = num / 100; 11 | n2 = (num % 100) / 10; 12 | n3 = (num % 100) % 10; 13 | printf("The reversal is: %d%d%d", n3, n2, n1); 14 | 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /ch04/Projects/03.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | int n1, n2, n3; 6 | 7 | printf("Enter a three-digit number: "); 8 | scanf("%1d%1d%1d", &n1, &n2, &n3); 9 | 10 | printf("The reversal is: %d%d%d", n3, n2, n1); 11 | 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /ch04/Projects/04.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | int num; 6 | printf("Enter a number between 0 and 32767: "); 7 | scanf("%d", &num); 8 | 9 | int n1, n2, n3, n4, n5; 10 | n1 = n2 = n3 = n4 = n5 = 0; 11 | 12 | n5 = num % 8; 13 | n4 = (num / 8) % 8; 14 | n3 = ((num / 8) / 8) % 8; 15 | n2 = (((num / 8) / 8) / 8) % 8; 16 | n1 = ((((num / 8) / 8) / 8) / 8) % 8; 17 | 18 | printf("In octal, your number is: %d%d%d%d%d", n1, n2, n3, n4, n5); 19 | 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /ch04/Projects/05.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | int d, i1, i2, i3, i4, i5, j1, j2, j3, j4, j5, 6 | first_sum, second_sum, total; 7 | 8 | printf("Enter the first 11 digits of a UPC: "); 9 | scanf("%1d%1d%1d%1d%1d%1d%1d%1d%1d%1d%1d", 10 | &d, &i1, &i2, &i3, &i4, &i5, 11 | &j1, &j2, &j3, &j4, &j5); 12 | 13 | first_sum = d + i2 + i4 + j1 + j3 + j5; 14 | second_sum = i1 + i3 + i5 + j2 + j4; 15 | total = 3 * first_sum + second_sum; 16 | 17 | printf("Check digit: %d\n", 9 - ((total - 1) % 10)); 18 | 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /ch04/Projects/06.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | int d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, 6 | first_sum, second_sum, total; 7 | 8 | printf("Enter the first 12 digits of an EAN: "); 9 | scanf("%1d%1d%1d%1d%1d%1d%1d%1d%1d%1d%1d%1d", 10 | &d1, &d2, &d3, &d4, &d5, 11 | &d6, &d7, &d8, &d9, &d10, 12 | &d11, &d12); 13 | 14 | first_sum = d2 + d4 + d6 + d8 + d10 + d12; 15 | second_sum = d1 + d3 + d5 + d7 + d9 + d11; 16 | total = 3 * first_sum + second_sum; 17 | 18 | printf("Check digit: %d\n", 9 - ((total - 1) % 10)); 19 | 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /ch05/Exercises/01.txt: -------------------------------------------------------------------------------- 1 | (a) i = 2; j = 3; 2 | k = i * j == 6; 3 | 4 | printf("%d", k); 5 | 6 | k = ((i * j) == 6) 7 | k = (6 == 6) 8 | k = 1 9 | 1 10 | 11 | (b) i = 5; j = 10; k = 1; 12 | 13 | printf("%d", k > i < j); 14 | 15 | (k > i) < j 16 | 0 < 10 17 | 1 18 | 19 | (c) i = 3; j = 2; k = 1; 20 | 21 | printf("%d", i < j == j < k); 22 | 23 | (i < j) == (j < k) 24 | (3 < 2) == (2 < 1) 25 | 0 == 0 26 | 1 27 | 28 | (d) i = 3; j = 4; k = 5; 29 | 30 | printf("%d", i % j + i < k); 31 | 32 | ((i % j) + i) < k 33 | (3 + 3) < 5 34 | 6 < 5 35 | 0 36 | -------------------------------------------------------------------------------- /ch05/Exercises/02.txt: -------------------------------------------------------------------------------- 1 | (a) i = 10; j = 5; 2 | printf("%d", !i < j); 3 | 4 | ((!i) < j) 5 | ((!10) < 5) 6 | (0 < 5) 7 | 1 8 | 9 | (b) i = 2; j = 1; 10 | printf("%d", !!i + !j); 11 | 12 | ((!(!i)) + (!j)) 13 | ((!(!2)) + (!1)) 14 | ((!(!2)) + 0) 15 | ((!0) + 0) 16 | (1 + 0) 17 | 1 18 | 19 | (c) i = 5; j = 0; k = -5; 20 | printf("%d", i && j || k); 21 | 22 | ((i && j) || k) 23 | ((5 && 0) || -5) 24 | (0 || -5) 25 | 1 26 | 27 | (d) i = 1; j = 2; k = 3; 28 | printf("%d", i < j || k); 29 | 30 | ((i < j) || k) 31 | ((1 < 3) || 3) 32 | (1 || 3) 33 | 1 34 | -------------------------------------------------------------------------------- /ch05/Exercises/04.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | int i, j; 6 | 7 | i = 1; j = 2; 8 | 9 | printf("%d\n", (i > j) - (i < j)); 10 | 11 | return 0; 12 | } 13 | -------------------------------------------------------------------------------- /ch05/Exercises/05.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | int n; 6 | n = 0; 7 | 8 | if (n >= 1 <= 10) 9 | printf("n is between 1 and 10\n"); 10 | 11 | /* The above if statement is legal, however it doesn't behave as we expect 12 | * What it evaluates to is ((n >= 1) <= 10), so when n is 0 it evaluates to: 13 | * (0 <= 10) -> 1 (true). However we only want it to return 'true' when 14 | * n is between 1 & 10 inclusive. 15 | * 16 | * To implement the behavior we want to compare n to both 1 and 10, and then ensure that both 17 | * are true by using the logical and operator '&&': 18 | */ 19 | 20 | if (n >= 1 && n <=10) //Relational operators have a higher precedence (7) than Logical and (12) 21 | printf("n is guaranteed to be between 1 and 10 if this printf is executed\n"); 22 | 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /ch05/Exercises/06.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | int n; 6 | n = 5; 7 | 8 | if (n == 1-10) 9 | printf("n is between 1 and 10\n"); 10 | 11 | /* Again, this if statement above behaves differently to what we want it to accomplish 12 | * (n == 1-10) evaluates to (n == (1-10)) as the additive operand has 13 | * a higher precedence (5) than the equality operand (8). 14 | * So what is really happening is checking if n is equivalent to -9, therefore 15 | * this printf statement would only execute if n had the value -9. 16 | */ 17 | 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /ch05/Exercises/07.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | int i; 6 | i = 17; 7 | 8 | printf("%d\n", i >= 0 ? 1 : -1); 9 | /* The above print statement contains a Conditional Expression (or ternary opeartor) 10 | * This is essentially a condensed if/else statement in the form: 11 | * Condition to check ? evaluate if true : evaluate if false 12 | * 13 | * So the above printf statement 14 | * means if (i >= 0) ? print 1 :else print -1. So therefore when i is 17, 1 is printed 15 | * as 17 is greater than or equal to 0. However if the value of i is -17 it prints -1 16 | * because -17 is not greater than or equal to 0. 17 | */ 18 | 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /ch05/Exercises/08.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define TRUE 1 4 | #define FALSE 0 5 | 6 | int main(void) 7 | { 8 | int teenager, age; 9 | 10 | age = 15; 11 | teenager = age >= 13 && age <= 19 ? TRUE : FALSE; 12 | printf("Age: %d\nTeenager: %d\n\n", age, teenager); 13 | 14 | 15 | age = 35; 16 | teenager = age >= 13 && age <= 19 ? TRUE : FALSE; 17 | printf("Age: %d\nTeenager: %d\n", age, teenager); 18 | 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /ch05/Exercises/09.txt: -------------------------------------------------------------------------------- 1 | The if statements are equivalent, the second one just evaluates in reverse 2 | 3 | if statement one: if statement two: 4 | 90 to positive infinity: A negative infinity to 59: F 5 | 80 to 89: B 60 to 69: D 6 | 70 to 79: C 70 to 79: C 7 | 60 to 69: D 80 to 89: B 8 | negative infinity to 59: F 90 to positive infinity: A 9 | -------------------------------------------------------------------------------- /ch05/Exercises/10.txt: -------------------------------------------------------------------------------- 1 | The switch statment evalutes 1 % 3 (the remainder of 1 / 3) and prints the result 2 | in string format. In this case 1 % 3 = 1, so case 0: is executed to print "one". 3 | -------------------------------------------------------------------------------- /ch05/Exercises/11.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | int area_code = 706; 6 | 7 | switch (area_code) { 8 | case 229: 9 | printf("Albany"); 10 | break; 11 | case 404: case 470: case 678: case 770: 12 | printf("Atlanta"); 13 | break; 14 | case 478: 15 | printf("Macon"); 16 | break; 17 | case 706: case 762: 18 | printf("Columbus"); 19 | break; 20 | case 912: 21 | printf("Savannah"); 22 | break; 23 | default: 24 | printf("Area code not recognized"); 25 | break; 26 | } 27 | 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /ch05/Projects/01.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | int num; 6 | 7 | printf("Enter a number: "); 8 | scanf("%d", &num); 9 | 10 | if ((num >= -9 && num <= 9)) 11 | printf("1 digit"); 12 | else if ((num >= 10 && num <= 99) || (num <= -10 && num >= -99)) 13 | printf("2 digits"); 14 | else if ((num >= 100 && num <= 999) || (num <= -100 && num >= -999)) 15 | printf("3 digits"); 16 | else if ((num >= 1000 && num <= 9999) || (num <= -1000 && num >= -9999)) 17 | printf("4 digits"); 18 | else if ((num >= 10000 && num <= 32767) || (num <= -10000 && num >= -32767)) 19 | printf("5 digits"); 20 | else 21 | printf("Integer overflow on 16 bit int"); 22 | 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /ch05/Projects/02.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | int hour, minute; 6 | 7 | printf("Enter a 24-hour time: "); 8 | scanf("%d :%d", &hour, &minute); 9 | 10 | int ampm_hour = hour >= 12 ? hour % 12 : hour; 11 | printf("Equivalent 12 hour time: %d:%d %s", ampm_hour, minute, ampm_hour <= 12 ? "AM" : "PM"); 12 | 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /ch05/Projects/04.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | int wind_speed; 6 | 7 | printf("Enter a wind speed(knots): "); 8 | scanf("%d", &wind_speed); 9 | 10 | if (wind_speed < 1) 11 | printf("Calm"); 12 | else if (wind_speed < 4) 13 | printf("Light air"); 14 | else if (wind_speed < 28) 15 | printf("Breeze"); 16 | else if (wind_speed < 48) 17 | printf("Gale"); 18 | else if (wind_speed < 64) 19 | printf("Storm"); 20 | else 21 | printf("Hurricane"); 22 | 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /ch05/Projects/05.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | int income; 6 | float tax_due; 7 | 8 | printf("Enter the amount of taxable income: "); 9 | scanf("%d", &income); 10 | 11 | if (income <= 750) 12 | tax_due = income * 0.01f; 13 | else if (income <= 2250) 14 | tax_due = 7.50f + ((income - 750) * 0.02f); 15 | else if (income <= 3750) 16 | tax_due = 37.50f + ((income - 2250) * 0.03f); 17 | else if (income <= 5250) 18 | tax_due = 82.50f + ((income - 3750) * 0.04f); 19 | else if (income <= 7000) 20 | tax_due = 142.50f + ((income - 5250) * 0.05f); 21 | else 22 | tax_due = 230.00f + ((income - 7000) * 0.06f); 23 | 24 | printf("Tax due: $%.2f", tax_due); 25 | 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /ch05/Projects/06.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | int d, i1, i2, i3, i4, i5, j1, j2, j3, j4, j5, c, 6 | first_sum, second_sum, total; 7 | 8 | printf("Enter the first (single) digit: "); 9 | scanf("%1d", &d); 10 | printf("Enter first group of five digits: "); 11 | scanf("%1d%1d%1d%1d%1d", &i1, &i2, &i3, &i4, &i5); 12 | printf("Enter second group of give digits: "); 13 | scanf("%1d%1d%1d%1d%1d", &j1, &j2, &j3, &j4, &j5); 14 | printf("Enter the last (single) digit: "); 15 | scanf("%1d", &c); 16 | 17 | first_sum = d + i2 + i4 + j1 + j3 + j5; 18 | second_sum = i1 + i3 + i5 + j2 + j4; 19 | total = 3 * first_sum + second_sum; 20 | 21 | printf("%s", c == (9 - ((total -1) % 10)) ? "VALID" : "NOT VALID"); 22 | 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /ch05/Projects/07.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | int i1, i2, i3, i4, largest, smallest; 6 | 7 | printf("Enter four integers: "); 8 | scanf("%d%d%d%d", &i1, &i2, &i3, &i4); 9 | 10 | if (i1 >= i2) { 11 | largest = i1; 12 | smallest = i2; 13 | } else { 14 | largest = i2; 15 | smallest = i1; 16 | } 17 | 18 | if (i3 > largest) 19 | largest = i3; 20 | else if (i3 < smallest) 21 | smallest = i3; 22 | 23 | if (i4 > largest) 24 | largest = i4; 25 | else if (i4 < smallest) 26 | smallest = i4; 27 | 28 | printf("Largest integer: %d\nSmallest integer: %d\n", largest, smallest); 29 | 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /ch05/Projects/10.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | int grade, grade_tens; 6 | 7 | printf("Enter numerical grade: "); 8 | scanf("%d", &grade); 9 | 10 | if (grade < 0 || grade > 100) { 11 | printf("Error, grade must be between 0 and 100."); 12 | return 0; 13 | } 14 | 15 | grade_tens = grade / 10; 16 | switch (grade_tens) { 17 | case 9: case 10: 18 | printf("Letter Grade: A"); 19 | break; 20 | case 8: 21 | printf("Letter Grade: B"); 22 | break; 23 | case 7: 24 | printf("Letter Grade: C"); 25 | break; 26 | case 6: 27 | printf("Letter Grade: D"); 28 | break; 29 | default: 30 | printf("Letter Grade: F"); 31 | break; 32 | } 33 | 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /ch06/Exercises/01.txt: -------------------------------------------------------------------------------- 1 | What output does the following program fragment produce? 2 | 3 | i = 1; 4 | while (i <= 128) { 5 | printf("%d ", i); 6 | i *= 2; 7 | } 8 | 9 | This loop will print powers of 2 from 2^0 to 2^7 on a single line separated by spaces: 10 | 1 2 4 8 16 32 64 128 11 | 12 | -------------------------------------------------------------------------------- /ch06/Exercises/02.txt: -------------------------------------------------------------------------------- 1 | What output does the following program produce? 2 | 3 | i = 9384; 4 | do { 5 | printf("%d ", i); 6 | i /= 10; 7 | } while (i > 0); 8 | 9 | This loop will print a line of values that are each one tenth of the previous value until the value is less than 0: 10 | 9384 938 94 9 11 | -------------------------------------------------------------------------------- /ch06/Exercises/05.txt: -------------------------------------------------------------------------------- 1 | Which one of the following statements is not equivalent to theother two (assuming that the 2 | loop bodies are the same)? 3 | 4 | (a) while (i < 10) {...} 5 | (b) for (; i < 10;) {...} 6 | (c) do {...} while (i < 10); 7 | 8 | Loop c is different to the other two, because a 'do while' loop is guaranteed to execute at least once. 9 | This is because the termination condition is checked after the loop body is executed. This means 10 | that when i is not less than 10, loop (a) and (b) won't be executed at all, but loop (c) will have 11 | executed once. 12 | -------------------------------------------------------------------------------- /ch06/Exercises/06.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | int i; 6 | for (i = 1; i <= 128; i *= 2) { printf("%d ", i); } 7 | 8 | return 0; 9 | } 10 | -------------------------------------------------------------------------------- /ch06/Exercises/07.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | int i; 6 | for (i = 9384; i > 0; i /= 10) { printf("%d ", i); } 7 | 8 | return 0; 9 | } 10 | -------------------------------------------------------------------------------- /ch06/Exercises/08.txt: -------------------------------------------------------------------------------- 1 | What output does the following for statement produce? 2 | 3 | for (i = 10; i >= 1; i /= 2) 4 | printf("%d ", i++); 5 | 6 | 7 | i = 10, print 10, increment i to 11, divide 11 by 2 8 | i = 5, print 5, increment i to 6, divide 6 by 2 9 | i = 3, print 3, increment i to 4, divide 4 by 2 10 | i = 2, print 2, increment i to 3, divide 3 by 2 11 | i = 1, print 1, increment i to 2, divide 2 by 2 12 | i = 1, print 1, increment i to 2, divide 2 by 2 13 | ...Infinite loop! 14 | -------------------------------------------------------------------------------- /ch06/Exercises/09.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | int i = 10; 6 | 7 | while (i >= 1) { 8 | printf("%d ", i++); 9 | i /= 2; 10 | } 11 | 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /ch06/Exercises/10.txt: -------------------------------------------------------------------------------- 1 | Show how to replace a continue statement by an equivalent goto statement. 2 | 3 | e.g print odd numbers: 4 | 5 | Using continue 6 | 7 | for (i = 0; i < 10; i++) { 8 | if (i % 2 == 0) 9 | continue; 10 | 11 | printf("%d ", i); 12 | } 13 | 14 | Using goto 15 | 16 | for (i = 0; i < 10; i++) { 17 | if (i % 2 == 0) 18 | goto done; 19 | 20 | printf("%d ", i); 21 | done:; 22 | } 23 | -------------------------------------------------------------------------------- /ch06/Exercises/11.txt: -------------------------------------------------------------------------------- 1 | What output does the following program fragment produce? 2 | 3 | sum = 0; 4 | for (i = 0; i < 10; i++) { 5 | if (i % 2) 6 | continue; 7 | sum += i; 8 | } 9 | printf("%d\n", sum); 10 | 11 | This program adds up all the odd numbers from 1 to 9 and prints the result. 12 | 1 + 3 + 5 + 7 + 9 = 25 13 | -------------------------------------------------------------------------------- /ch06/Exercises/12.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | int d, n, is_prime; 6 | 7 | is_prime = 1; 8 | n = 1429; 9 | printf("Checking if %d is prime\n", n); 10 | 11 | for (d = 2; (d * d) <= n; d++) { 12 | printf("Testing %d\n", d); 13 | 14 | if (n % d == 0) { 15 | is_prime = 0; 16 | break; 17 | } 18 | } 19 | 20 | printf("%d", is_prime); 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /ch06/Exercises/13.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | int m, n; 6 | m = 50; 7 | for (n = 0; m > 0; n++, m /= 2) 8 | /* empty loop body */ ; 9 | 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /ch06/Exercises/14.txt: -------------------------------------------------------------------------------- 1 | Find the error in the following program fragment and fix it. 2 | 3 | if (n % 2 == 0); 4 | printf("n is even\n"); 5 | 6 | The problem is the semicolon at the end of the if statement, by placing a semi colon here 7 | we are creating a null statement which ends the if prematurely. This means that the printf 8 | statement isn't inside the if statement and thus will always be executed. 9 | -------------------------------------------------------------------------------- /ch06/Projects/01.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | float number, largest; 6 | largest = 0.0f; 7 | 8 | for(;;) { 9 | printf("Enter a number(0 to terminate): "); 10 | scanf("%f", &number); 11 | 12 | if (number == 0.0f) 13 | break; 14 | 15 | if (number > largest) 16 | largest = number; 17 | } 18 | printf("The largest number entered was: %.3f", largest); 19 | 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /ch06/Projects/02.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | int n, m, temp; 6 | 7 | printf("Enter two integers: "); 8 | scanf("%d%d", &n, &m); 9 | 10 | while (n != 0) { 11 | temp = m % n; 12 | m = n; 13 | n = temp; 14 | } 15 | printf("Greatest common divisor: %d", m); 16 | 17 | return 0; 18 | } 19 | 20 | -------------------------------------------------------------------------------- /ch06/Projects/03.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | int num, denom, m, n, temp; 6 | 7 | printf("Enter a fraction: "); 8 | scanf("%d /%d", &num, &denom); 9 | 10 | m = num; 11 | n = denom; 12 | 13 | while (n != 0) { 14 | temp = m % n; 15 | m = n; 16 | n = temp; 17 | } 18 | 19 | printf("In lowest terms: %d/%d", num / m, denom / m); 20 | 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /ch06/Projects/05.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | int n; 6 | 7 | printf("Enter a positive integer: "); 8 | scanf("%d", &n); 9 | 10 | printf("The reversal is: "); 11 | do { 12 | printf("%d", n % 10); 13 | n /= 10; 14 | 15 | } while (n != 0); 16 | 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /ch06/Projects/06.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | int n; 6 | 7 | printf("Enter a number: "); 8 | scanf("%d", &n); 9 | 10 | int i; 11 | for (i = 2; i * i <= n; i += 2) 12 | printf("%d\n", i * i); 13 | 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /ch06/Projects/07.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | int i, n, odd, square; 6 | 7 | printf("This program prints a table of squres.\n"); 8 | printf("Enter a number of entries in table: "); 9 | scanf("%d", &n); 10 | 11 | for (i = 1, odd = 3, square = 1; i <= n; i++, square += odd, odd += 2) 12 | printf("%10d%10d\n", i, square); 13 | 14 | return 0; 15 | } 16 | 17 | -------------------------------------------------------------------------------- /ch06/Projects/08.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | int days_in_month, week_start; 6 | 7 | printf("Enter number of days in month: "); 8 | scanf("%d", &days_in_month); 9 | printf("Enter starting day of the week (1=Sun, 7=Sat): "); 10 | scanf("%d", &week_start); 11 | 12 | int i; 13 | int iterations_needed = days_in_month + (week_start - 1); 14 | int day = 1; 15 | 16 | for (i = 1; i <= iterations_needed; i++) { 17 | if (i < week_start) 18 | printf(" "); 19 | else 20 | printf("%3d", day++); 21 | 22 | if (i % 7 == 0) 23 | printf("\n"); 24 | } 25 | 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /ch06/Projects/09.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | float loan, interest_rate, monthly_payment; 6 | int no_of_payments; 7 | 8 | printf("Enter amount of loan: "); 9 | scanf("%f", &loan); 10 | printf("Enter interest rate: "); 11 | scanf("%f", &interest_rate); 12 | printf("Enter monthly payment: "); 13 | scanf("%f", &monthly_payment); 14 | printf("Enter number of payments: "); 15 | scanf("%d", &no_of_payments); 16 | 17 | float monthly_interest = ((interest_rate / 100) / 12) + 1; 18 | 19 | int i; 20 | for (i = 1; i <= no_of_payments; i++) { 21 | loan *= monthly_interest; 22 | loan -= monthly_payment; 23 | printf("Balance remaining after %d month(s): $%.2f\n", i, loan); 24 | } 25 | 26 | 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /ch06/Projects/11.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | int n; 6 | float e = 1.0f; 7 | 8 | printf("Enter a number: "); 9 | scanf("%d", &n); 10 | 11 | int i, factorial = 1; 12 | for (i = 1; i <= n; i++) { 13 | 14 | factorial *= i; 15 | e += (1.0f / factorial); 16 | } 17 | 18 | printf("%f", e); 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /ch06/Projects/12.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | float n, e = 1.0f; 6 | 7 | printf("Enter a small floating point number: "); 8 | scanf("%f", &n); 9 | 10 | int terms = 1, factorial = 1; 11 | for (;;) { 12 | 13 | factorial *= terms; 14 | 15 | if (1.0f / factorial < n) { 16 | printf("Term %d (1/%d!): %f which is lower than the threshold: %f\n", terms, terms, 1.0f / factorial, n); 17 | break; 18 | } 19 | 20 | e += (1.0f / factorial); 21 | printf("Term %d (1/%d!): %f, e is currently: %f\n", terms, terms, 1.0f / factorial, e); 22 | terms++; 23 | } 24 | 25 | printf("\nAdded %d terms, result is: %f", terms-1, e); 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /ch07/Exercises/01.txt: -------------------------------------------------------------------------------- 1 | Give the decimal value of each of the following integer constants: 2 | 3 | (a) 077 octal = 63 decimal (7 eights plus 7 ones) 4 | (b) 0x77 hexadecimal = 119 decimal (7 sixteens plus 7 ones) 5 | (c) 0XABC hexadecimal = 2748 decimal (10 two-hundred and fifty sixes plus 11 sixteens plus 12 ones) 6 | -------------------------------------------------------------------------------- /ch07/Exercises/03.txt: -------------------------------------------------------------------------------- 1 | Which of the following are not legal types in C? 2 | 3 | (a) short unsigned int 4 | (b) short float 5 | (c) long double 6 | (d) unsigned long 7 | 8 | The identifier in (b) 'short float' is not legal. 9 | Floating point numbers can only be represented by the floating types: 10 | float, double and long double 11 | 12 | -------------------------------------------------------------------------------- /ch07/Exercises/04.txt: -------------------------------------------------------------------------------- 1 | If c is a variable of type char, which one of the following statements is illegal? 2 | 3 | (a) i += c; /* i has type int */ 4 | (b) c = 2 * c - 1; 5 | (c) putchar(c); 6 | (d) printf(c); 7 | 8 | The printf statement in (d) isn't legal. 9 | We can either do: 10 | printf("%f", c); - This prints the character c represents. 11 | printf("%d", c); - This prints the number of the character in the ascii table. 12 | -------------------------------------------------------------------------------- /ch07/Exercises/05.txt: -------------------------------------------------------------------------------- 1 | Which of the following is not a legal way to write the number 65? (Assume 2 | that the character set is ASCII.) 3 | 4 | (a) 'A' 5 | (b) 0b1000001 6 | (c) 0101 7 | (d) 0x41 8 | 9 | Answer (b) is not legal as C doesn't allow us to write binary literals, 10 | even though the number 1000001 is 65 in binary it isn't legal in C. 11 | 12 | -------------------------------------------------------------------------------- /ch07/Exercises/06.txt: -------------------------------------------------------------------------------- 1 | For each of the following items of data, specify which one of the types char, 2 | short, int, or long is the smallest one guaranteed to be large enough to store 3 | the item. 4 | 5 | (a) Days in a month - Decimal: 31 Binary: 11111 (5 bits) char 6 | (b) Days in a year - Decimal: 365 Binary: 101101101 (9 bits) short 7 | (c) Minutes in a day - Decimal: 1440 Binary: 10110100000 (11 bits) short 8 | (d) Seconds in a day - Decimal: 86400 Binary: 10101000110000000 (17 bits) long 9 | 10 | 11 | -------------------------------------------------------------------------------- /ch07/Exercises/07.txt: -------------------------------------------------------------------------------- 1 | For each of the following character escapes, give the equivalent octal 2 | escape. (Assume that the character set is ASCII.) 3 | 4 | Escape seq. Value Octal escape 5 | (a) \b 8 \10 6 | (b) \n 10 \12 7 | (c) \r 13 \15 8 | (d) \t 9 \11 9 | -------------------------------------------------------------------------------- /ch07/Exercises/08.txt: -------------------------------------------------------------------------------- 1 | For each of the following character escapes, give the equivalent hexadecimal 2 | escape. (Assume that the character set is ASCII.) 3 | 4 | Escape seq. Value Hexadecimal escape 5 | (a) \b 8 \x08 6 | (b) \n 10 \x0a 7 | (c) \r 13 \x0d 8 | (d) \t 9 \x09 9 | -------------------------------------------------------------------------------- /ch07/Exercises/09.txt: -------------------------------------------------------------------------------- 1 | Suppose that i and j are variables of type int. What is the type of the expression 2 | i / j + 'a'? 3 | 4 | The type of this expression is an int. As the largest value in the expression is an 5 | int, the char 'a' is converted to an int so that the operation can be carried out. 6 | -------------------------------------------------------------------------------- /ch07/Exercises/10.txt: -------------------------------------------------------------------------------- 1 | Suppose that i is a variable of type int, j is a variable of type long, and k 2 | is a variable of type unsigned int. What is the type of the expression: 3 | i + (int) j * k? 4 | 5 | Order of Evaluation: 6 | int + (((int) long) * unsigned int) 7 | int + (int * unsigned int) 8 | int + unsigned int 9 | unsigned int 10 | -------------------------------------------------------------------------------- /ch07/Exercises/11.txt: -------------------------------------------------------------------------------- 1 | Suppose that i is a variable of type int, j is a variable of type long, and 2 | k is a variable of type double. What is the type of the expression: 3 | i * f / d? 4 | 5 | As double is the largest sized variable used in this operation, the other two 6 | values must be converted to a double so that the operation can be performed. 7 | This means that the expression evaluates to a double value. 8 | -------------------------------------------------------------------------------- /ch07/Exercises/12.txt: -------------------------------------------------------------------------------- 1 | Suppose that i is a variable of type int, f is a variable of type float, and d is 2 | a variable of type double. Explain what conversions take place during the 3 | execution of the following statement: 4 | d = i + f 5 | 6 | Order of evaluation: 7 | double = (int + float) 8 | double = float 9 | double 10 | 11 | As addition has a higher precedence than assignment, the value of i + f is converted 12 | to float. When assingment occurs, the expression on the right side is always converted 13 | to the type of the variable on the left side. This converts the float to a double. 14 | -------------------------------------------------------------------------------- /ch07/Exercises/13.txt: -------------------------------------------------------------------------------- 1 | Assume that a program contains the following declarations: 2 | 3 | char c = '\1'; 4 | short s = 2; 5 | int i = -3; 6 | long m = 5; 7 | float f = 6.5f; 8 | double d = 7.5; 9 | 10 | Give the value and the type of each expression listed below 11 | 12 | (a) c * i 1 * -3 Value = -3 Type = int 13 | (b) s + m 2 + 5 Value = 7 Type = long 14 | (c) f / c 6.5 / 1 Value = 6.5 Type = float 15 | (d) d / s 7.5 / 2 Value = 3.25 Type = double 16 | (e) f - d 6.5 - 7.5 Value = -1.0 Type = double 17 | (f) (int) f Value = 6 Type = int 18 | -------------------------------------------------------------------------------- /ch07/Exercises/14.txt: -------------------------------------------------------------------------------- 1 | Does the following statement always compute the fractional part of f correctly 2 | (assuming that f and frac_part are float variables)? 3 | 4 | frac_part = f - (int) f; 5 | 6 | This statement does compute the fractional part of f correctly because of 7 | operator precendence 8 | 9 | e.g: f = 5.6 10 | 11 | (frac_part = (5.6 - ((int) 5.6))); 12 | (frac_part = (5.6 - 5)); 13 | frac_part = 0.6; 14 | 15 | Order of presendence is 16 | Cast (3) 17 | Subtraction (5) 18 | Assignment (15) 19 | -------------------------------------------------------------------------------- /ch07/Exercises/15.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(void) 5 | { 6 | typedef int8_t Int8; 7 | typedef int16_t Int16; 8 | typedef int32_t Int32; 9 | 10 | printf("Size of int8: %zu byte (%zu bits).\n", sizeof(Int8), sizeof(Int8) * 8); 11 | printf("Size of int16: %zu bytes (%zu bits).\n", sizeof(Int16), sizeof(Int16) * 8); 12 | printf("Size of int32: %zu bytes (%zu bits).\n", sizeof(Int32), sizeof(Int32) * 8); 13 | 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /ch07/Projects/02.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | int i, n; 6 | 7 | printf("This program prints a table of squares.\n"); 8 | printf("Enter number of entries in table: "); 9 | scanf("%d", &n); 10 | getchar(); //remove the newline char from the buffer 11 | 12 | for (i = 1; i <= n; i++) { 13 | printf("%10d%10d\n", i, i * i); 14 | 15 | if (i % 24 == 0) { 16 | printf("Press Enter to continue..."); 17 | while (getchar() != '\n') 18 | ; 19 | } 20 | } 21 | 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /ch07/Projects/03.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | double n, sum = 0.0f; 6 | 7 | printf("This program sums a series of doubles.\n"); 8 | printf("Enter numbers (0 to terminate): "); 9 | 10 | scanf("%lf", &n); 11 | while (n != 0.0f) { 12 | sum += n; 13 | scanf("%lf", &n); 14 | } 15 | printf("The sum is: %lf\n", sum); 16 | 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /ch07/Projects/06.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | /* Compile using C99 or C11 standards, otherwise %zu format won't work */ 4 | int main (void) 5 | { 6 | printf("Size of int: %zu bytes\n", sizeof(int)); 7 | printf("Size of short: %zu bytes\n", sizeof(short)); 8 | printf("Size of long: %zu bytes\n", sizeof(long)); 9 | printf("Size of float: %zu bytes\n", sizeof(float)); 10 | printf("Size of double: %zu bytes\n", sizeof(double)); 11 | printf("Size of long double: %zu bytes\n", sizeof(long double)); 12 | 13 | return 0; 14 | } 15 | 16 | -------------------------------------------------------------------------------- /ch07/Projects/09.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(void) 5 | { 6 | int hour, minute, offset; 7 | char ampm; 8 | 9 | printf("Enter a 12-hour time: "); 10 | scanf("%d :%d %c", &hour, &minute, &m); 11 | 12 | offset = (toupper(ampm) == 'P' ? 12 : 0); 13 | hour = (hour == 12 ? 0 : hour); 14 | 15 | printf("Equivalent 24-hour time: %.2d:%.2d", hour + offset, minute); 16 | 17 | return 0; 18 | } 19 | 20 | -------------------------------------------------------------------------------- /ch07/Projects/10.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(void) 5 | { 6 | int vowels = 0; 7 | char ch; 8 | 9 | printf("Enter a sentence: "); 10 | while ((ch = getchar()) != '\n') { 11 | 12 | switch (toupper(ch)) { 13 | case 'A': case 'E': case 'I': case 'O': case 'U': 14 | vowels++; 15 | break; 16 | } 17 | } 18 | printf("Your sentence contains %d vowels.", vowels); 19 | 20 | return 0; 21 | } 22 | 23 | -------------------------------------------------------------------------------- /ch07/Projects/11.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(void) 5 | { 6 | char ch, initial; 7 | 8 | printf("Enter a first and last name: "); 9 | while ((ch = getchar()) == ' '); //Skip initial white space until first char 10 | initial = ch; 11 | while ((ch = getchar()) != ' '); //Skip chars after first char until whitespace 12 | 13 | while ((ch = getchar()) != '\n') { 14 | if (ch != ' ') 15 | putchar(ch); 16 | } 17 | printf(", %c.", initial); 18 | 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /ch07/Projects/13.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(void) 5 | { 6 | float character_count = 0.0f, word_count = 0.0f; 7 | char ch; 8 | 9 | printf("Enter a sentence: "); 10 | 11 | while ((ch = getchar()) != '\n') { 12 | 13 | if (ch == ' ') { //assume one space per word 14 | word_count++; 15 | continue; 16 | } 17 | 18 | character_count++; 19 | } 20 | word_count += 1; //last word isn't counted due to break on \n, so increment by one. 21 | printf("Average word length: %.1f", character_count / word_count); 22 | 23 | return 0; 24 | } 25 | 26 | 27 | -------------------------------------------------------------------------------- /ch07/Projects/14.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(void) 5 | { 6 | double x, y = 1, avgyxy; 7 | 8 | printf("Enter a positive number: "); 9 | scanf("%lf", &x); 10 | 11 | for (;;) { 12 | avgyxy = (y + x / y) / 2; 13 | if (fabs(y - avgyxy) < (.00001f * avgyxy)) 14 | break; 15 | 16 | y = avgyxy; 17 | printf("Average of y and x/y: %lf\n", y); 18 | } 19 | 20 | return 0; 21 | } 22 | 23 | -------------------------------------------------------------------------------- /ch07/Projects/15.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | int i, n; 6 | long double factorial = 1.0f; 7 | 8 | printf("Enter a positive integer: "); 9 | scanf("%d", &n); 10 | 11 | for (i = 1; i <= n; i++) { 12 | factorial *= i; 13 | } 14 | 15 | printf("Factorial of %d: %.0lf", n, factorial); 16 | 17 | return 0; 18 | } 19 | /* (a) Largest value of n that correctly prints its factorial (short): 7 20 | * (b) Largest value of n that correctly prints its factorial (int): 12 21 | * (c) Largest value of n that correctly prints its factorial (long): 12 22 | * (c) Largest value of n that correctly prints its factorial (long long): 12 23 | * (e) Largest value of n that correctly prints its factorial (float): 34 24 | * (f) Largest value of n that correctly prints its factorial (double): 170 25 | * (f) Largest value of n that correctly prints its factorial (long double): 1754 26 | */ 27 | -------------------------------------------------------------------------------- /ch08/Exercises/01.txt: -------------------------------------------------------------------------------- 1 | The number of elements in an array can be calculated using: 2 | sizeof (a) / sizeof(a[0]) 3 | 4 | It can also be calculated using the expression: 5 | sizeof (a) / sizeof(t) 6 | where t is the type of a's elements 7 | 8 | The second technique is considered inferior to the first because if we 9 | decide to change the type of element that 'a' stores later down the line, 10 | (for instance changing an int to a long, or a float to double). 11 | then we would need to refactor every call to sizeof(t) to the new element 12 | type so that we could correctly calculate the number of elements in the array. 13 | -------------------------------------------------------------------------------- /ch08/Exercises/02.txt: -------------------------------------------------------------------------------- 1 | Describe how to use a digit (in character form) as an array subscript. 2 | 3 | int number_count[10]; 4 | char seven = '7'; 5 | number_count[seven - '0']++; 6 | 7 | The above snippet should increment the seventh element in the number_count 8 | array by one. 9 | 10 | Ascii codes for 0 to 9 are 48 to 57. 11 | number_count['7' - '0']++; 12 | number_count[55 - 48]++; 13 | number_count[7]++; 14 | -------------------------------------------------------------------------------- /ch08/Exercises/03.txt: -------------------------------------------------------------------------------- 1 | Write a declaration of an array named weekend containing seven bool values. 2 | Include an initializer that makes the first and last values true; all other 3 | values should be false. 4 | 5 | #define true 1 6 | #define false 0 7 | typedef int bool; 8 | 9 | bool weekend[] = {true, false, false, false, false, false, true}; 10 | -------------------------------------------------------------------------------- /ch08/Exercises/04.txt: -------------------------------------------------------------------------------- 1 | Write a declaration of an array named weekend containing seven bool values. 2 | Include a designated initializer that makes the first and last values true. 3 | 4 | #include 5 | 6 | bool weekend[] = {true, [6] = true}; 7 | -------------------------------------------------------------------------------- /ch08/Exercises/05.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | int fib_numbers[40] = {0, 1}; 6 | int i; 7 | 8 | for (i = 2; i < sizeof(fib_numbers) / sizeof(fib_numbers[0]); i++) { 9 | 10 | fib_numbers[i] = fib_numbers[i - 2] + fib_numbers[i - 1]; 11 | } 12 | 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /ch08/Exercises/06.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | const int segments[10][7] = {{1, 1, 1, 1, 1, 1, 0}, 6 | {0, 1, 1, 0, 0, 0, 0}, 7 | {1, 1, 0, 1, 1, 0, 1}, 8 | {1, 1, 1, 1, 0, 0, 1}, 9 | {0, 1, 1, 0, 0, 1, 1}, 10 | {1, 0, 1, 1, 0, 1, 1}, 11 | {1, 0, 1, 1, 1, 1, 1}, 12 | {1, 1, 1, 0, 0, 0, 0}, 13 | {1, 1, 1, 1, 1, 1, 1}, 14 | {1, 1, 1, 1, 0, 1, 1}}; 15 | 16 | return 0; 17 | } 18 | 19 | -------------------------------------------------------------------------------- /ch08/Exercises/07.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | const int segments[10][7] = {{1, 1, 1, 1, 1, 1,}, 6 | {0, 1, 1}, 7 | {1, 1, 0, 1, 1, 0, 1}, 8 | {1, 1, 1, 1, 0, 0, 1}, 9 | {0, 1, 1, 0, 0, 1, 1}, 10 | {1, 0, 1, 1, 0, 1, 1}, 11 | {1, 0, 1, 1, 1, 1, 1}, 12 | {1, 1, 1}, 13 | {1, 1, 1, 1, 1, 1, 1}, 14 | {1, 1, 1, 1, 0, 1, 1}}; 15 | 16 | return 0; 17 | } 18 | 19 | -------------------------------------------------------------------------------- /ch08/Exercises/08.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | int temperature_readings[30][24] = {0}; 6 | 7 | return 0; 8 | } 9 | -------------------------------------------------------------------------------- /ch08/Exercises/10.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | char chess_board[8][8] = {{'r', 'n', 'b', 'q', 'k', 'b', 'n', 'r'}, 6 | {'p', 'p', 'p', 'p', 'p', 'p', 'p', 'p'}, 7 | {' ', '.', ' ', '.', ' ', '.', ' ', '.'}, 8 | {'.', ' ', '.', ' ', '.', ' ', '.', ' '}, 9 | {' ', '.', ' ', '.', ' ', '.', ' ', '.'}, 10 | {'.', ' ', '.', ' ', '.', ' ', '.', ' '}, 11 | {'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P'}, 12 | {'R', 'N', 'B', 'Q', 'K', 'B', 'N', 'R'}}; 13 | 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /ch08/Exercises/11.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main (void) 4 | { 5 | char checker_board[8][8] = {0}; 6 | 7 | int row, col; 8 | for (row = 0; row < 8; row++) { 9 | 10 | for (col = 0; col < 8; col++) { 11 | checker_board[row][col] = (row + col) % 2 == 0 ? 'B' : 'R'; 12 | printf("%c, ", checker_board[row][col]); 13 | } 14 | printf("\n"); 15 | } 16 | 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /ch08/Projects/01.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | int no_of_digits_seen[10] = {0}; 6 | int digit; 7 | long n; 8 | 9 | printf("Enter a number: "); 10 | scanf("%ld", &n); 11 | 12 | while (n > 0) { 13 | digit = n % 10; 14 | no_of_digits_seen[digit]++; 15 | n /= 10; 16 | } 17 | 18 | printf("Repeated digit(s): "); 19 | for (n = 0; n < 10; n++) { 20 | if (no_of_digits_seen[n] > 1) 21 | printf("%ld ", n); 22 | } 23 | 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /ch08/Projects/02.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | int no_of_digits_seen[10] = {0}; 6 | int digit; 7 | long n; 8 | 9 | printf("Enter a number: "); 10 | scanf("%ld", &n); 11 | 12 | while (n > 0) { 13 | digit = n % 10; 14 | no_of_digits_seen[digit]++; 15 | n /= 10; 16 | } 17 | 18 | printf("%-15s0 1 2 3 4 5 6 7 8 9\n", "Digit:"); 19 | printf("%-15s", "Occurences:"); 20 | for (n = 0; n < 10; n++) { 21 | printf("%-3d", no_of_digits_seen[n]); 22 | } 23 | 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /ch08/Projects/03.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | int no_of_digits_seen[10] = {0}; 6 | int digit; 7 | long n; 8 | 9 | for (;;) { 10 | 11 | printf("Enter a number (0 to terminate): "); 12 | scanf("%ld", &n); 13 | if (n <= 0) 14 | break; 15 | 16 | while (n > 0) { 17 | digit = n % 10; 18 | no_of_digits_seen[digit]++; 19 | n /= 10; 20 | } 21 | 22 | printf("%-15s0 1 2 3 4 5 6 7 8 9\n", "Digit:"); 23 | printf("%-15s", "Occurences:"); 24 | for (n = 0; n < 10; n++) { 25 | printf("%-3d", no_of_digits_seen[n]); 26 | no_of_digits_seen[n] = 0; 27 | } 28 | printf("\n\n"); 29 | } 30 | 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /ch08/Projects/04.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define LEN (int) (sizeof(a) / sizeof(a[0])) 4 | 5 | int main(void) 6 | { 7 | int a[10], i; 8 | 9 | printf("Enter %d numbers: ", LEN); 10 | for (i = 0; i < LEN; i++) 11 | scanf("%d", &a[i]); 12 | 13 | printf("In reverse order:"); 14 | for (i = LEN - 1; i >= 0; i--) 15 | printf(" %d", a[i]); 16 | printf("\n"); 17 | 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /ch08/Projects/05.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define NUM_RATES ((int) (sizeof(value) / sizeof(value[0]))) 4 | #define INITIAL_BALANCE 100.00 5 | 6 | int main(void) 7 | { 8 | int i, low_rate, num_years, month, year; 9 | double value[5]; 10 | 11 | printf("Enter interest rate: "); 12 | scanf("%d", &low_rate); 13 | printf("Enter number of years: "); 14 | scanf("%d", &num_years); 15 | 16 | printf("\nYears"); 17 | for (i = 0; i < NUM_RATES; i++) { 18 | printf("%8d%%", low_rate + i); 19 | value[i] = INITIAL_BALANCE; 20 | } 21 | printf("\n"); 22 | 23 | for (year = 1; year <= num_years; year++) { 24 | printf("%3d ", year); 25 | for (i = 0; i < NUM_RATES; i++) { 26 | for (month = 1; month <= 12; month++) 27 | value[i] *= ((double) (low_rate + i) / 12 / 100.0 + 1); 28 | printf("%9.2f", value[i]); 29 | } 30 | printf("\n"); 31 | } 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /ch08/Projects/12.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(void) 5 | { 6 | char ch; 7 | int word_value = 0; 8 | 9 | int scrabble_values[26] = { 10 | /* A B C D E F G H I J K L M */ 11 | 1, 3, 3, 2, 1, 4, 2, 4, 1, 8, 5, 1, 3, 12 | 13 | /* N O P Q R S T U V W X Y Z */ 14 | 1, 1, 3, 10, 1, 1, 1, 1, 4, 4, 8, 4, 10 15 | }; 16 | 17 | printf("Enter a word: "); 18 | 19 | while ((ch = getchar()) != '\n') 20 | word_value += scrabble_values[toupper(ch) - 'A']; 21 | 22 | printf("Scrabble value: %d", word_value); 23 | 24 | return 0; 25 | } 26 | 27 | -------------------------------------------------------------------------------- /ch08/Projects/13.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(void) 5 | { 6 | char ch, initial, surname[20] = {0}; 7 | int i, surname_length = 0; 8 | 9 | printf("Enter a first and last name: "); 10 | while ((ch = getchar()) == ' '); //Skip initial white space until first char 11 | initial = ch; 12 | while ((ch = getchar()) != ' '); //Skip chars after first char until whitespace 13 | 14 | for (i = 0; (ch = getchar()) != '\n' && i < 20; i++) { 15 | if (ch != ' ') { 16 | surname[i] = ch; 17 | surname_length++; 18 | } 19 | } 20 | 21 | for (i = 0; i < surname_length; i++) 22 | printf("%c", surname[i]); 23 | 24 | printf(", %c.", initial); 25 | 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /ch08/Projects/15.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | char ch, message[80] = {0}; 6 | int i, message_length = 0, shift_amount; 7 | 8 | printf("Enter message to be encrypted: "); 9 | for (i = 0; (ch = getchar()) != '\n' && i < 80; i++) { 10 | message[i] = ch; 11 | message_length++; 12 | } 13 | 14 | printf("Enter shift amount (1-25): "); 15 | scanf("%d", &shift_amount); 16 | 17 | printf("Encrypted message: "); 18 | for (i = 0; i < message_length; i++) { 19 | 20 | if (message[i] >= 'A' && message[i] <= 'Z') { 21 | printf("%c", ((message[i] - 'A') + shift_amount) % 26 + 'A'); 22 | } 23 | else if (message[i] >= 'a' && message[i] <= 'z') { 24 | printf("%c", ((message[i] - 'a') + shift_amount) % 26 + 'a'); 25 | } 26 | else { 27 | printf("%c", message[i]); 28 | } 29 | 30 | } 31 | 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /ch08/Projects/16.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main(void) 6 | { 7 | int i, letter_count[26] = {0}; 8 | char ch; 9 | bool is_anagram = true; 10 | 11 | printf("Enter first word: "); 12 | for (i = 0; (ch = getchar()) != '\n' && i < 30; i++) 13 | letter_count[toupper(ch) - 'A']++; 14 | 15 | printf("Enter second word: "); 16 | for (i = 0; (ch = getchar()) != '\n' && i < 30; i++) 17 | letter_count[toupper(ch) - 'A']--; 18 | 19 | 20 | for (i = 0; i < 26; i++) { 21 | if (letter_count[i] != 0) { 22 | is_anagram = false; 23 | break; 24 | } 25 | } 26 | 27 | printf("The words are "); 28 | if (is_anagram) 29 | printf("anagrams."); 30 | else 31 | printf("not anagrams."); 32 | 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /ch09/Exercises/01.txt: -------------------------------------------------------------------------------- 1 | The following function contains two errors: 2 | 3 | double triangle_area(double base, height) 4 | double product; 5 | { 6 | product = base * height; 7 | return product / 2; 8 | } 9 | 10 | The first error is that the second parameter 'height' isn't given a type. A 11 | specified type must be given to each parameter, even when they may all have the 12 | same type. 13 | 14 | The second error is that the local variable 'product' is not declared within 15 | the function body. All declarations belonging to a function must be written 16 | inside its curly braces. 17 | 18 | Corrected function: 19 | 20 | double triangle_area(double base, double height) 21 | { 22 | double product; 23 | 24 | product = base * height; 25 | return product / 2; 26 | } 27 | -------------------------------------------------------------------------------- /ch09/Exercises/02.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int check(int, int, int); 4 | 5 | int main(void) 6 | { 7 | 8 | printf("%d and %d: %d\n", 5, 10, check(5, 10, 15)); 9 | printf("%d and %d: %d\n", 2, 3, check(2, 3, 1)); 10 | return 0; 11 | } 12 | 13 | /* Checks whether the values x and y fall in the range 14 | * of 0 to n - 1. Returns 1 if true, 0 if false. 15 | */ 16 | int check(int x, int y, int n) 17 | { 18 | if ((x >= 0 && x < n - 1) && (y >= 0 && y < n - 1)) 19 | return 1; 20 | 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /ch09/Exercises/03.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int gcd(int, int); 4 | 5 | int main(void) 6 | { 7 | printf("GCD of %d and %d: %d", 12, 28, gcd(12, 28)); 8 | return 0; 9 | } 10 | 11 | /* Returns the greatest common divisor of the 12 | * two values m and n. 13 | */ 14 | int gcd(int m, int n) 15 | { 16 | int remainder; 17 | 18 | while (n > 0) { 19 | remainder = m % n; 20 | m = n; 21 | n = remainder; 22 | } 23 | 24 | return m; 25 | } 26 | -------------------------------------------------------------------------------- /ch09/Exercises/05.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int num_digits(int); 4 | 5 | int main(void) 6 | { 7 | printf("Number of digits in %d: %d", 1267123, num_digits(1267123)); 8 | return 0; 9 | } 10 | 11 | /* Returns the number of digits in n */ 12 | int num_digits(int n) 13 | { 14 | int digits = 0; 15 | 16 | while (n > 0) { 17 | n /= 10; 18 | digits++; 19 | } 20 | 21 | return digits; 22 | } 23 | 24 | -------------------------------------------------------------------------------- /ch09/Exercises/06.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int digit(int, int); 4 | 5 | int main(void) 6 | { 7 | printf("Digit %d (from right) in %d: %d", 4, 82934, digit(82934, 4)); 8 | return 0; 9 | } 10 | 11 | /* Return the kth digit in n (from the right) */ 12 | int digit(int n, int k) 13 | { 14 | int digit; 15 | 16 | while (k > 0) { 17 | digit = n % 10; 18 | n /= 10; 19 | k--; 20 | } 21 | return digit; 22 | } 23 | -------------------------------------------------------------------------------- /ch09/Exercises/07.txt: -------------------------------------------------------------------------------- 1 | Suppose that the function f has the following definition: 2 | int f(int a, int b) { ... } 3 | 4 | which of the following statements are legal? (Assume that i has type int 5 | and x has type double.) 6 | 7 | (a) i = f(83, 12); 8 | (b) x = f(83, 12); 9 | (c) i = f(3.15, 9.28); 10 | (d) x = f(3.15, 9.28); 11 | (e) f(83, 12); 12 | 13 | 14 | (a): Legal and normal behaviour. 15 | (b): Legal and assigns int result to double. 16 | (c): Legal, but loses decimal values as f's parameters are converted to int. 17 | (d): Legal, but loses decimal values as f's parameters are converted to int. 18 | (e): legal, but doesn't do anything with returned value. 19 | -------------------------------------------------------------------------------- /ch09/Exercises/08.txt: -------------------------------------------------------------------------------- 1 | Which of the following would be valid prototypes for a function that returns 2 | nothing and has one double parameter? 3 | 4 | (a) void f(double x); 5 | (b) void f(double); 6 | (c) void f(x); 7 | (d) f (double x); 8 | 9 | Both (a) and (b) are valid prototypes. (c) isn't valid because it doesn't provide 10 | the parameter x with a type. And (d) isn't valid because it doesn't specify the 11 | return type of f (so it defaults to int when we require void). 12 | -------------------------------------------------------------------------------- /ch09/Exercises/09.txt: -------------------------------------------------------------------------------- 1 | What will be the output of the following program? 2 | 3 | #include 4 | 5 | void swap(int a, int b); 6 | 7 | int main(void) 8 | { 9 | int i = 1, j = 2; 10 | 11 | swap(i, j); 12 | printf("i = %d, j = %d\n", i, j); 13 | return 0; 14 | } 15 | 16 | void swap (int a, int b) 17 | { 18 | int temp = a; 19 | a = b; 20 | b = temp; 21 | } 22 | 23 | We might expect that this simple program swaps the values of two integer variables, 24 | however it doesn't do this because the swap function only swaps copies of the 25 | variables i and j because functions pass parameters by value, rather than reference. 26 | To swap the variables i and j we need to pass two pointers that point to i and j 27 | to the swap function so that they can change them directly. 28 | -------------------------------------------------------------------------------- /ch09/Exercises/11.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define SIZE sizeof(grades) / sizeof(grades[0]) 4 | 5 | float compute_GPA(char grades[], int n); 6 | 7 | int main(void) 8 | { 9 | char grades[10] = {'A', 'A', 'D', 'F', 'C', 'B', 'D', 'B', 'A', 'C'}; 10 | 11 | printf("Average of all grades: %.2f", compute_GPA(grades, SIZE)); 12 | return 0; 13 | } 14 | 15 | float compute_GPA(char grades[], int n) 16 | { 17 | int i; 18 | float average = 0.0f; 19 | for (i = 0; i < n; i++) { 20 | switch (grades[i]) { 21 | case 'A': average += 4.0f; 22 | break; 23 | case 'B': average += 3.0f; 24 | break; 25 | case 'C': average += 2.0f; 26 | break; 27 | case 'D': average += 1.0f; 28 | break; 29 | } 30 | } 31 | 32 | return average / n; 33 | } 34 | -------------------------------------------------------------------------------- /ch09/Exercises/12.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | double inner_product(double a[], double b[], int n); 4 | 5 | int main(void) 6 | { 7 | double a[5] = {6, 3, 9, 12, 14}; 8 | double b[5] = {2, 17, 8, 5, 10}; 9 | 10 | printf("Inner product sum: %lf", inner_product(a, b, 5)); 11 | 12 | return 0; 13 | } 14 | 15 | double inner_product(double a[], double b[], int n) 16 | { 17 | int i; 18 | double sum = 0.0l; 19 | 20 | for (i = 0; i < n; i++) 21 | sum += a[i] * b[i]; 22 | 23 | return sum; 24 | } 25 | -------------------------------------------------------------------------------- /ch09/Exercises/15.txt: -------------------------------------------------------------------------------- 1 | The following (rather confusing) function finds the median of three numbers. Rewrite the 2 | function so that it has just one return statement. 3 | 4 | double median(double x, double y, double z) 5 | { 6 | if (x <= y) 7 | if (y <= z) return y; 8 | else if (x <= z) return z; 9 | else return x; 10 | if (z <= y) return y; 11 | if (x <= z) return x; 12 | return z; 13 | } 14 | 15 | 16 | Simpler version: 17 | 18 | double median(double x, double y, double z) 19 | { 20 | int median = x; 21 | 22 | if ((y - x) * (z - y) >= 0) 23 | median = y; 24 | else if ((z - y) * (x - z) >= 0) 25 | median = z; 26 | 27 | return median; 28 | } 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /ch09/Exercises/16.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int fact(int n); 4 | 5 | int main(void) 6 | { 7 | int n = 4; 8 | printf("%d! = %d", n, fact(n)); 9 | return 0; 10 | } 11 | 12 | /*Returns the factorial of n*/ 13 | int fact(int n) 14 | { 15 | return n <= 1 ? 1 : n * fact(n - 1); 16 | } 17 | -------------------------------------------------------------------------------- /ch09/Exercises/17.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int fact(int n); 4 | 5 | int main(void) 6 | { 7 | int n = 4; 8 | printf("%d! = %d", n, fact(n)); 9 | return 0; 10 | } 11 | 12 | /*Returns the factorial of n*/ 13 | int fact(int n) 14 | { 15 | int i, sum = 1; 16 | for (i = 2; i <= n; i++) 17 | sum *= i; 18 | 19 | return sum; 20 | } 21 | -------------------------------------------------------------------------------- /ch09/Exercises/18.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int gcd(int, int); 4 | 5 | int main(void) 6 | { 7 | printf("GCD of %d and %d: %d", 12, 28, gcd(12, 28)); 8 | return 0; 9 | } 10 | 11 | /* Returns the greatest common divisor of the 12 | * two values m and n. 13 | */ 14 | int gcd(int m, int n) 15 | { 16 | return n == 0 ? m : gcd(n, m % n); 17 | } 18 | -------------------------------------------------------------------------------- /ch09/Exercises/19.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void pb(int n); 4 | 5 | int main(void) 6 | { 7 | int n = 50; 8 | pb(n); 9 | return 0; 10 | } 11 | 12 | /* Function recursively divides a number by 2. 13 | * Once division has recursively evaluated to 0 14 | * the program returns up the stack frames printing 15 | * either a 0 or 1 by calculating the remainder of the division of n by 2 16 | * at that particular stack frame. */ 17 | void pb(int n) 18 | { 19 | if (n != 0) { 20 | pb(n / 2); 21 | putchar('0' + n % 2); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ch09/Projects/02.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | float calculate_tax_due(int income); 4 | 5 | int main(void) 6 | { 7 | int income; 8 | 9 | printf("Enter the amount of taxable income: "); 10 | scanf("%d", &income); 11 | printf("Tax due: $%.2f", calculate_tax_due(income)); 12 | 13 | return 0; 14 | } 15 | 16 | float calculate_tax_due(int income) 17 | { 18 | int tax_due; 19 | 20 | if (income <= 750) 21 | tax_due = income * 0.01f; 22 | else if (income <= 2250) 23 | tax_due = 7.50f + ((income - 750) * 0.02f); 24 | else if (income <= 3750) 25 | tax_due = 37.50f + ((income - 2250) * 0.03f); 26 | else if (income <= 5250) 27 | tax_due = 82.50f + ((income - 3750) * 0.04f); 28 | else if (income <= 7000) 29 | tax_due = 142.50f + ((income - 5250) * 0.05f); 30 | else 31 | tax_due = 230.00f + ((income - 7000) * 0.06f); 32 | 33 | return tax_due; 34 | } 35 | -------------------------------------------------------------------------------- /ch09/Projects/06.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int compute_polynomial(int x); 4 | 5 | int main(void) 6 | { 7 | int x; 8 | printf("Enter a value for x: "); 9 | scanf("%d", &x); 10 | printf("%d", compute_polynomial(x)); 11 | 12 | return 0; 13 | } 14 | 15 | int compute_polynomial(int x) 16 | { 17 | return ( (3 * (x * x * x * x * x)) 18 | + (2 * (x * x * x * x)) 19 | - (5 * (x * x * x)) 20 | - (x * x) 21 | + (7 * x) 22 | - 6); 23 | } 24 | -------------------------------------------------------------------------------- /ch09/Projects/07.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int power(int x, int n); 4 | 5 | int main(void) 6 | { 7 | 8 | int x, n; 9 | printf("Enter value and an exponent: "); 10 | scanf("%d %d", &x, &n); 11 | printf("%d to the %d = %d", x, n, power(x, n)); 12 | return 0; 13 | } 14 | 15 | int power(int x, int n) 16 | { 17 | if (n == 0) return 1; 18 | 19 | if (n % 2 == 0) { 20 | int i = power(x, n / 2); 21 | return i * i; 22 | } else { 23 | return x * power(x, n - 1); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /ch10/Exercises/01.txt: -------------------------------------------------------------------------------- 1 | The following programs outline shows only function definitions and variable 2 | declarations. 3 | 4 | int a; 5 | void f(int b) 6 | { 7 | int c; 8 | } 9 | void g(void) 10 | { 11 | int d; 12 | { 13 | int e; 14 | } 15 | } 16 | int main(void) 17 | { 18 | int f; 19 | } 20 | 21 | For each of the following scopes, list all variable and parameter names visible in 22 | that scope: 23 | 24 | (a) The f function: int a, int b, int c. 25 | (b) The g function: int a, int d. 26 | (c) The block in which e is declared: int a, int d, int e. 27 | (d) The main function: int a, int f. 28 | 29 | -------------------------------------------------------------------------------- /ch10/Exercises/02.txt: -------------------------------------------------------------------------------- 1 | The following program outline shows only function definitions and variable 2 | declarations. 3 | 4 | int b, c; 5 | 6 | void f(void) 7 | { 8 | int b, d; 9 | } 10 | void g(int a) 11 | { 12 | int c; 13 | { 14 | int a, d; 15 | } 16 | } 17 | int main(void) 18 | { 19 | int c, d; 20 | } 21 | 22 | For each of the following scopes, list all variable and parameter names visible 23 | in that scope. 24 | 25 | (a) The f function: b and d inside the f function. c external variable. 26 | (b) The g function: a (g parameter), b and c external variables. 27 | (c) The block in which a and d are declared: a and d inside the block, c inside g function, 28 | b external variable. 29 | (d) The main function: b external variable, c and d inside main function. 30 | -------------------------------------------------------------------------------- /ch10/Exercises/03.txt: -------------------------------------------------------------------------------- 1 | Suppose that a program has only one function (main). How many different variables named 2 | i could this program contain? 3 | 4 | One external, one inside main. one in every block / nested block within main. 5 | -------------------------------------------------------------------------------- /ch11/Exercises/01.txt: -------------------------------------------------------------------------------- 1 | If i is a variable and p points to i, which of the following expressions are 2 | aliases for i? 3 | 4 | (a) *p (c) *&p (e) *i (g) *&i 5 | (b) &p (d) &*p (f) &i (h) &*i 6 | 7 | a and g both are aliases for i. 8 | -------------------------------------------------------------------------------- /ch11/Exercises/02.txt: -------------------------------------------------------------------------------- 1 | If i is an int variable and p and q are pointers to int, which of the following 2 | assignments are legal? 3 | 4 | (a) p = i; (d) p = &q (g) p = *q 5 | (b) *p = &i; (e) p = *&q (h) *p = q; 6 | (c) &p = q; (f) p = q; (i) *p = *q; 7 | 8 | e, f, and i are legal assignments. 9 | -------------------------------------------------------------------------------- /ch11/Exercises/03.txt: -------------------------------------------------------------------------------- 1 | The following function supposedly computers the sum and average of the numbers in the 2 | array a, which has length n, avg and sum point to variables that the functions should 3 | modify. Unfortunately, the function contains several errors; find and correct them. 4 | 5 | void avg_sum(double a[], int n, double *avg, double *sum) 6 | { 7 | int i; 8 | 9 | sum = 0.0; 10 | for (i = 0; i < n; i++) 11 | sum += a[i]; 12 | avg = sum / n; 13 | } 14 | 15 | 16 | Corrected function: 17 | 18 | void avg_sum(double a[], int n, double *avg, double *sum) 19 | { 20 | int i; 21 | 22 | *sum = 0.0; 23 | for (i = 0; i < n; i++) 24 | *sum += a[i]; 25 | *avg = *sum / n; 26 | } 27 | -------------------------------------------------------------------------------- /ch11/Exercises/04.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void swap(int *p, int *q); 4 | 5 | int main(void) 6 | { 7 | int i = 5, j = 10; 8 | printf("i: %d, j: %d\n", i, j); 9 | swap(&i, &j); 10 | printf("i: %d, j: %d\n", i, j); 11 | 12 | return 0; 13 | } 14 | 15 | void swap(int *p, int *q) 16 | { 17 | int temp = *p; 18 | *p = *q; 19 | *q = temp; 20 | printf("Swapped\n"); 21 | } 22 | -------------------------------------------------------------------------------- /ch11/Exercises/05.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void split_time(long total_sec, int *hr, int *min, int *sec); 4 | 5 | int main(void) 6 | { 7 | long total_sec = 33621; 8 | int hour, minute, second; 9 | split_time(total_sec, &hour, &minute, &second); 10 | printf("Seconds elapsed since midnight: %ld\n", total_sec); 11 | printf("Hour: %d, Minute: %d, Second: %d\n", hour, minute, second); 12 | return 0; 13 | } 14 | 15 | void split_time(long total_sec, int *hr, int *min, int *sec) 16 | { 17 | *hr = total_sec / 3600; 18 | total_sec -= *hr * 3600; 19 | *min = total_sec / 60; 20 | total_sec -= *min * 60; 21 | *sec = total_sec; 22 | } 23 | -------------------------------------------------------------------------------- /ch11/Exercises/08.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define SIZE sizeof(a) / sizeof(a[0]) 4 | int *find_largest(int a[], int n); 5 | 6 | int main(void) 7 | { 8 | int i, a[10] = {1, 48, 24, 83, 76, 34, 74, 12, 84, 23}; 9 | 10 | printf("Array contents: "); 11 | for (i = 0; i < SIZE; i++) 12 | printf("%d ", a[i]); 13 | 14 | printf("\nLargest: %d", *find_largest(a, SIZE)); 15 | 16 | return 0; 17 | } 18 | 19 | /* Returns a pointer to the array element containing the largest value */ 20 | int *find_largest(int a[], int n) 21 | { 22 | int i, index_largest = 0; 23 | 24 | for (i = 0; i < n; i++) { 25 | if (a[i] > a[index_largest]) 26 | index_largest = i; 27 | } 28 | 29 | return &a[index_largest]; 30 | } 31 | -------------------------------------------------------------------------------- /ch11/Projects/01.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void pay_amount(int dollars, int *twenties, int *tens, 4 | int *fives, int *ones); 5 | 6 | int main(void) 7 | { 8 | int dollars, twenties, tens, fives, ones; 9 | 10 | printf("Enter a dollar amount: "); 11 | scanf("%d", &dollars); 12 | pay_amount(dollars, &twenties, &tens, &fives, &ones); 13 | 14 | printf("$20 bills: %d\n", twenties); 15 | printf("$10 bills: %d\n", tens); 16 | printf(" $5 bills: %d\n", fives); 17 | printf(" $1 bills: %d\n", ones); 18 | 19 | return 0; 20 | } 21 | 22 | void pay_amount(int dollars, int *twenties, int *tens, 23 | int *fives, int *ones) 24 | { 25 | *twenties = dollars / 20; 26 | dollars -= *twenties * 20; 27 | *tens = dollars / 10; 28 | dollars -= *tens * 10; 29 | *fives = dollars / 5; 30 | dollars -= *fives * 5; 31 | *ones = dollars / 1; 32 | } 33 | -------------------------------------------------------------------------------- /ch11/Projects/03.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void reduce(int numerator, int denominator, 4 | int *reduced_numerator, 5 | int *reduced_denominator); 6 | 7 | int main(void) 8 | { 9 | int num, denom, reduced_numerator = 0, reduced_denominator = 0; 10 | 11 | printf("Enter a fraction: "); 12 | scanf("%d /%d", &num, &denom); 13 | 14 | reduce(num, denom, &reduced_numerator, &reduced_denominator); 15 | 16 | printf("In lowest terms: %d/%d", reduced_numerator, reduced_denominator); 17 | 18 | return 0; 19 | } 20 | 21 | void reduce(int numerator, int denominator, 22 | int *reduced_numerator, int *reduced_denominator) 23 | { 24 | int temp, m = numerator, n = denominator; 25 | 26 | while (n != 0) { 27 | temp = m % n; 28 | m = n; 29 | n = temp; 30 | } 31 | 32 | *reduced_numerator = numerator / m; 33 | *reduced_denominator = denominator / m; 34 | } 35 | -------------------------------------------------------------------------------- /ch12/Exercises/01.txt: -------------------------------------------------------------------------------- 1 | Suppose that the following declarations are in effect: 2 | 3 | int a[] = {5, 15, 34, 54, 14, 2, 52, 72}; 4 | int *p = &a[1], *q = &a[5]; 5 | 6 | (a) What is the value of *(p + 3)? 14 7 | (b) What is the value of *(q - 3)? 34 8 | (c) What is the value of q - p? 4 9 | (d) Is the condition p < q true or false? true 10 | (e) Is the condition *p < *q true or false? false 11 | -------------------------------------------------------------------------------- /ch12/Exercises/02.txt: -------------------------------------------------------------------------------- 1 | Suppose that high, low, and middle are all pointer variables of the same type, and that 2 | low and high point to elements of an array. Why is the following statement illegal, and 3 | how could it be fixed? 4 | 5 | middle = (low + high) / 2; 6 | 7 | The expression low + high is not legal because we cannot add two pointers together. 8 | To get the middle element we can use subtraction: ((high - low) / 2) + low 9 | 10 | E.g Low = 23, High = 48; 11 | 12 | high - low = 25, / 2 = 12, + low = 35 13 | -------------------------------------------------------------------------------- /ch12/Exercises/03.txt: -------------------------------------------------------------------------------- 1 | What will be the contents of the a array after the following statements are executed? 2 | 3 | #define N 10 4 | 5 | int a[N] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; 6 | int *p = &a[0], *q = &a[N-1], temp; 7 | 8 | while (p < q) { 9 | temp = *p; 10 | *p++ = *q; 11 | *q-- = temp; 12 | } 13 | 14 | First iteration: 15 | p = &a[0], q = &a[9] (N-1) 16 | temp = element in a[0] (1) 17 | set element a[0] to the value in a[9] (10) 18 | p++ (p now points to &a[1]) 19 | a[9] = 1 20 | q-- (q now points to &a[8] (N-2)) 21 | 22 | End result (reverses the array by swapping elements at either side until middle is reached): 23 | 24 | {10, 9, 8, 7, 6, 5, 4, 3, 2, 1} 25 | -------------------------------------------------------------------------------- /ch12/Exercises/04.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define STACK_SIZE 100 5 | 6 | /* external variables */ 7 | int contents[STACK_SIZE]; 8 | int *top_ptr = &contents[0]; 9 | 10 | void make_empty(void) 11 | { 12 | top_ptr = &contents[0]; 13 | } 14 | 15 | bool is_empty(void) 16 | { 17 | return top_ptr == &contents[0]; 18 | } 19 | 20 | bool is_full(void) 21 | { 22 | return top_ptr == &contents[STACK_SIZE]; 23 | } 24 | 25 | void push(int i) 26 | { 27 | if (is_full()) 28 | printf("Full\n"); 29 | //stack_overflow(); 30 | else 31 | *top_ptr++ = i; 32 | } 33 | 34 | int pop(void) 35 | { 36 | if (is_empty()) 37 | printf("Empty\n"); 38 | //stack_underflow(); 39 | else 40 | return *--top_ptr; 41 | } 42 | 43 | int main(void) 44 | { 45 | return 0; 46 | } 47 | -------------------------------------------------------------------------------- /ch12/Exercises/05.txt: -------------------------------------------------------------------------------- 1 | Suppose that a is a one-dimensional array and p is a pointer variable. Assuming that the 2 | assignment p = a has just been performed, which of the following expessions are illegal 3 | because of mismatched types? Of the remaining expressions, which are true (have a nonzero 4 | value)? 5 | 6 | (a) p == a[0] Illegal - &a[0] compared to a[0] 7 | (b) p == &a[0] - Legal - &a[0] compared to &a[0] 8 | (c) *p == a[0] - Legal - *&a[0] (which is equivalent to a[0]) compared to a[0] 9 | (d) p[0] == a[0] Legal - *(p + 0) compared to a[0] 10 | 11 | (b), (c) and (d) are true because when p is assigned to a, it points to the first element 12 | in a (a[0]). 13 | -------------------------------------------------------------------------------- /ch12/Exercises/06.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int sum_array(const int a[], int n); 4 | int sum_array2(const int a[], int n); 5 | 6 | int main(void) 7 | { 8 | int a[5] = {10, 23, 4, 2, 17}; 9 | 10 | printf("Sum array 1: %d\n", sum_array(a, 5)); 11 | printf("Sum array 2: %d\n", sum_array2(a, 5)); 12 | return 0; 13 | } 14 | 15 | int sum_array(const int a[], int n) 16 | { 17 | int i, sum; 18 | 19 | sum = 0; 20 | for (i = 0; i < n; i++) 21 | sum += a[i]; 22 | return sum; 23 | } 24 | 25 | int sum_array2(const int a[], int n) 26 | { 27 | int sum = 0; 28 | const int *p; 29 | for (p = a; p < a + n; p++) 30 | sum += *p; 31 | return sum; 32 | } 33 | -------------------------------------------------------------------------------- /ch12/Exercises/07.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | bool search(const int a[], int n, int key); 5 | 6 | int main(void) 7 | { 8 | printf("%d\n", search((int []){1, 2, 3, 4, 5}, 5, 9)); 9 | return 0; 10 | } 11 | 12 | bool search(const int a[], int n, int key) 13 | { 14 | const int *p = a; 15 | 16 | while (p < a + n) { 17 | if (key == *p++) 18 | return true; 19 | } 20 | return false; 21 | } 22 | -------------------------------------------------------------------------------- /ch12/Exercises/08.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void store_zeros(int a[], int n); 4 | 5 | int main(void) 6 | { 7 | return 0; 8 | } 9 | 10 | void store_zeros(int a[], int n) 11 | { 12 | int *p; 13 | for (p = a; p < a + n; p++) 14 | *p = 0; 15 | } 16 | -------------------------------------------------------------------------------- /ch12/Exercises/09.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | double inner_product(const double *a, const double *b, int n); 4 | 5 | int main(void) 6 | { 7 | const double a[5] = {1, 2, 3, 4, 5}; 8 | const double b[5] = {1, 2, 3, 4, 5}; 9 | 10 | printf("Inner product: %f", inner_product(a, b, 5)); 11 | return 0; 12 | } 13 | 14 | double inner_product(const double *a, const double *b, int n) 15 | { 16 | double sum = 0; 17 | const double *a_ptr, *b_ptr; 18 | 19 | for (a_ptr = a, b_ptr = b; a_ptr < a + n && b_ptr < b + n; a_ptr++, b_ptr++) { 20 | printf("%f * %f = %f\n", *a_ptr, *b_ptr, *a_ptr * *b_ptr); 21 | sum += *a_ptr * *b_ptr; 22 | } 23 | 24 | return sum; 25 | } 26 | 27 | -------------------------------------------------------------------------------- /ch12/Exercises/10.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int *find_middle(int a[], int n); 4 | 5 | int main(void) 6 | { 7 | int a[5] = {1, 2, 3, 4, 5}; 8 | printf("Middle element: %d", *find_middle(a, 5)); 9 | return 0; 10 | } 11 | 12 | int *find_middle(int a[], int n) { 13 | return a + (n / 2); 14 | } 15 | -------------------------------------------------------------------------------- /ch12/Exercises/11.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define SIZE sizeof(a) / sizeof(a[0]) 4 | int *find_largest(int a[], int n); 5 | 6 | int main(void) 7 | { 8 | int i, a[10] = {1, 48, 24, 83, 76, 34, 74, 12, 84, 23}; 9 | 10 | printf("Array contents: "); 11 | for (i = 0; i < SIZE; i++) 12 | printf("%d ", a[i]); 13 | 14 | printf("\nLargest: %d", *find_largest(a, SIZE)); 15 | 16 | return 0; 17 | } 18 | 19 | /* Returns a pointer to the array element containing the largest value */ 20 | int *find_largest(int a[], int n) 21 | { 22 | int *p, *largest; 23 | 24 | for (p = a, largest = a; p < a + n; p++) { 25 | if (*p > *largest) 26 | largest = p; 27 | } 28 | return largest; 29 | } 30 | -------------------------------------------------------------------------------- /ch12/Exercises/13.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define N 20 4 | 5 | int main(void) 6 | { 7 | double ident[N][N]; 8 | double *p = &ident[0][0]; 9 | int zero_count = N - 1; 10 | 11 | for (p = &ident[0][0]; p <= &ident[N-1][N-1]; p++) { 12 | if (zero_count == N - 1) { 13 | *p = 1; 14 | zero_count = 0; 15 | } else { 16 | *p = 0; 17 | zero_count++; 18 | } 19 | } 20 | 21 | int row, col; 22 | for (row = 0; row < N; row++) { 23 | for (col = 0; col < N; col++) { 24 | printf("%.0f ", ident[row][col]); 25 | } 26 | printf("\n"); 27 | } 28 | 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /ch12/Exercises/14.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define DAYS 7 5 | #define HOURS 24 6 | 7 | bool search(const int a[], int n, int key); 8 | 9 | int main(void) 10 | { 11 | const int temperatures[DAYS][HOURS] = {[1][15] = 31}; 12 | int day; 13 | bool found = false; 14 | 15 | for (day = 0; day < DAYS; day++) { 16 | if (search(&temperatures[day][0], HOURS, 31)) { 17 | found = true; 18 | break; 19 | } 20 | } 21 | 22 | printf("Found: %s", found ? "True" : "False"); 23 | return 0; 24 | } 25 | 26 | bool search(const int a[], int n, int key) 27 | { 28 | const int *p = a; 29 | 30 | while (p < a + n) { 31 | if (key == *p++) 32 | return true; 33 | } 34 | return false; 35 | } 36 | -------------------------------------------------------------------------------- /ch12/Exercises/15.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define DAYS 7 5 | #define HOURS 24 6 | 7 | int main(void) 8 | { 9 | const int temperatures[DAYS][HOURS] = {[1][3] = 20, [1][15] = 31}, *p; 10 | int day = 1; 11 | 12 | printf("Temperatures for day %d: \n", day); 13 | for (p = temperatures[day]; p < temperatures[day] + HOURS; p++) { 14 | printf("%d ", *p); 15 | } 16 | 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /ch12/Exercises/17.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define ROWS 3 4 | #define COLS 5 5 | 6 | int sum_two_dimensional_array(const int *a, int n); 7 | 8 | int main(void) 9 | { 10 | const int a[ROWS][COLS] = { {1, 2, 3, 4, 5}, 11 | {4, 8, 8, 12, 3}, 12 | {3, 4, 8, 3, 12}}; 13 | 14 | printf("Sum: %d", sum_two_dimensional_array(a[0], ROWS * COLS)); 15 | 16 | return 0; 17 | } 18 | 19 | int sum_two_dimensional_array(const int *a, int n) 20 | { 21 | int sum = 0; 22 | const int *p; 23 | for (p = a; p < a + n; p++) 24 | sum += *p; 25 | return sum; 26 | } 27 | -------------------------------------------------------------------------------- /ch13/Exercises/03.txt: -------------------------------------------------------------------------------- 1 | Suppose that we call scanf as follows: 2 | 3 | scanf("%d%s%d", &i, s, &j); 4 | 5 | If the user enters 12abc34 56def78, what will be the values of i, s, and j after the 6 | call? (Assume that i and j are int variables and s is an array of characters.) 7 | 8 | %d will read any number of decimal digits, so the first call of %d will read 12, then it 9 | will encounter the character a which isn't a decimal digit, so it will put it back. 10 | This gives i the value 12. 11 | 12 | %s will read any number of non-whitespace characters, so will read abc34, then it will 13 | encounter the white space character which is put back. 14 | This gives s the value abc34. 15 | 16 | %d will ignore that previous whitespace character, and then read any number of decimal 17 | digits. It reads 56, then encounters the character s which is put back. 18 | This gives j the value 56. 19 | 20 | i = 12 21 | s = abc34 22 | j = 56 23 | -------------------------------------------------------------------------------- /ch13/Exercises/05.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void capitalize_a(char str[]); 5 | void capitalize_b(char *str); 6 | void print_str(char *str); 7 | 8 | int main(void) 9 | { 10 | char str[10] = "j9.d,c34p\0"; 11 | printf("Original String: "); 12 | print_str(str); 13 | 14 | capitalize_b(str); 15 | printf("Capitalized String: "); 16 | print_str(str); 17 | 18 | return 0; 19 | } 20 | 21 | void capitalize_a(char str[]) 22 | { 23 | int i = 0; 24 | while (str[i] != '\0') { 25 | str[i] = toupper(str[i++]); 26 | } 27 | } 28 | 29 | void capitalize_b(char *str) 30 | { 31 | char *p; 32 | for (p = str; *p; p++) { 33 | *p = toupper(*p); 34 | } 35 | } 36 | 37 | void print_str(char *str) 38 | { 39 | char *p; 40 | for (p = str; *p; p++) 41 | printf("%c", *p); 42 | printf("\n"); 43 | } 44 | 45 | -------------------------------------------------------------------------------- /ch13/Exercises/06.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void censor(char *str); 5 | 6 | int main(void) 7 | { 8 | char str[10] = "food fool\0"; 9 | printf("Original string: %s\n", str); 10 | censor(str); 11 | printf("Censored string: %s\n", str); 12 | return 0; 13 | } 14 | 15 | void censor(char *str) 16 | { 17 | char *p; 18 | for (p = str; *p; p++) 19 | if (*p == 'f' && *(p+1) == 'o' && *(p+2) == 'o') 20 | *p = *(p+1) = *(p+2) = 'x'; 21 | } 22 | -------------------------------------------------------------------------------- /ch13/Exercises/07.txt: -------------------------------------------------------------------------------- 1 | Suppose that str is an array of characters. Which one of the following statements is not 2 | equivalent to the other three? 3 | 4 | (a) *str = 0; 5 | (b) str[0] = '\0' 6 | (c) strcpy(str, ""); 7 | (d) strcat(str, ""); 8 | 9 | Statement d behaves differently to the others because strcat appends a null character to 10 | the end of str, rather than set the first element in str to be the null character which 11 | the other statements perform (strcpy does this because it overwrites the original string 12 | with ""). 13 | 14 | -------------------------------------------------------------------------------- /ch13/Exercises/08.txt: -------------------------------------------------------------------------------- 1 | What will be the value of the string s1 after the following statements have been executed? 2 | 3 | strcpy(str, "tire-bouchon"); 4 | str is currently: tire-bouchon\0 5 | 6 | strcpy(&str[4], "d-or-wi"); 7 | str is currently: tired-or-wi\0 8 | 9 | strcat(str, "red?"); 10 | str is currently: tired-or-wired?\0 11 | -------------------------------------------------------------------------------- /ch13/Exercises/09.txt: -------------------------------------------------------------------------------- 1 | What will be the value of the string s1 after the following statements have been executed? 2 | 3 | strcpy(s1, "computer"); 4 | strcpy(s2, "science"); 5 | if (strcmp(s1, s2) < 0) 6 | strcat(s1, s2); 7 | else 8 | strcat(s2, s1); 9 | s1[strlen(s1)-6] = '\0'; 10 | 11 | after strcmp and strcat: computerscience\0 12 | after s1[strlen(s1)-6] = '\0': strlen(s1) = 15 - 6 = 9, s1[9] = c 13 | s1 is "computers\0" after s1[9] changed to '\0'. 14 | -------------------------------------------------------------------------------- /ch13/Exercises/10.txt: -------------------------------------------------------------------------------- 1 | The following function supposedly creates an identical copy of a string. What's wrong with 2 | the function? 3 | 4 | char *duplicate(const char *p) 5 | { 6 | char *q; 7 | 8 | strcpy(q, p); 9 | return q; 10 | } 11 | 12 | q has been declared as a pointer to a char, however it has not been initialized 13 | so currently points nowhere in particular. We need to initialize it to point 14 | somewhere that will be large enough to accomodate a copy of the string pointed 15 | to by p includings its nul terminating char. 16 | 17 | To return a variable initialized within a function, we also need to make it 18 | static as the storage duration of variables defined within blocks is automatic 19 | by default. 20 | -------------------------------------------------------------------------------- /ch13/Exercises/11.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int strcmp(char *s, char *t); 4 | 5 | int main(void) 6 | { 7 | char *str1 = "computer"; 8 | char *str2 = "science"; 9 | printf("%d", strcmp(str1, str2)); 10 | return 0; 11 | } 12 | 13 | int strcmp(char *s, char *t) 14 | { 15 | while (s == t) { 16 | if (!*s) 17 | return 0; 18 | } 19 | return *s - *t; 20 | } 21 | -------------------------------------------------------------------------------- /ch13/Exercises/12.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void get_extension(const char *file_name, char *extension); 5 | 6 | int main(void) 7 | { 8 | char filename[] = "memo.txt"; 9 | char extension[20]; 10 | get_extension(filename, extension); 11 | printf("Filename: %s, Extension: %s", filename, extension); 12 | return 0; 13 | } 14 | 15 | void get_extension(const char *file_name, char *extension) 16 | { 17 | 18 | while (*file_name) { 19 | if (*file_name++ == '.') { 20 | strcpy(extension, file_name); 21 | return; 22 | } 23 | } 24 | 25 | strcpy(extension, ""); 26 | } 27 | 28 | -------------------------------------------------------------------------------- /ch13/Exercises/13.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void build_index_url(const char *domain, char *index_url); 5 | 6 | int main(void) 7 | { 8 | const char domain[] = "knking.com"; 9 | char index_url[50]; 10 | build_index_url(domain, index_url); 11 | printf("Domain: %s, index_url: %s", domain, index_url); 12 | return 0; 13 | } 14 | 15 | void build_index_url(const char *domain, char *index_url) 16 | { 17 | strcpy(index_url, "http://www."); 18 | strcat(index_url, domain); 19 | strcat(index_url, "/index.html"); 20 | } 21 | 22 | -------------------------------------------------------------------------------- /ch13/Exercises/14.txt: -------------------------------------------------------------------------------- 1 | What does the following program print? 2 | 3 | #include 4 | 5 | int main(void) 6 | { 7 | char s[] = "Hsjodi", *p; 8 | 9 | for (p = s; *p; p++) 10 | --*p; 11 | puts(s); 12 | return 0; 13 | } 14 | 15 | The program prints: Grinch 16 | 17 | --*p first gets the value pointed to by p, the decrements it. This is because the indirection 18 | operator and prefix decrement operator are of the same precedence, and right associative. 19 | -------------------------------------------------------------------------------- /ch13/Exercises/15.txt: -------------------------------------------------------------------------------- 1 | Let f be the following function: 2 | 3 | int f(char *s, char *t) 4 | { 5 | char *p1, *p2; 6 | 7 | for (p1 = s; *p1; p1++) { 8 | for (p2 = t; *p2; p2++) 9 | if (*p1 == *p2) break; 10 | if (*p2 == '\0') break; 11 | } 12 | return p1 - s; 13 | } 14 | 15 | (a) What is the value of f("abcd", "babc")? Pointer to s[3] minus pointer to s[0] = 3. 16 | (b) What is the value of f("abcd", "bcd")? Pointer to s[0] minus pointer to s[0] = 0. 17 | (c) In general, what value does f return when passed two strings s and t? 18 | It returns the address of the pointer of the first character in s that doesn't have 19 | a matching character in t minus the address of the first character in s. This is 20 | equivalent to returning the index of that particular character in s. 21 | -------------------------------------------------------------------------------- /ch13/Exercises/16.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int count_spaces(const char *s); 4 | 5 | int main(void) 6 | { 7 | const char str1[] = "Testing the count spaces function."; 8 | printf("Number of spaces: %d", count_spaces(str1)); 9 | return 0; 10 | } 11 | 12 | int count_spaces(const char *s) 13 | { 14 | int count = 0; 15 | 16 | while (*s) 17 | if (*s++ == ' ') 18 | count++; 19 | return count; 20 | } 21 | 22 | -------------------------------------------------------------------------------- /ch13/Exercises/17.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | bool test_extension(const char *file_name, const char *extension); 7 | 8 | int main(void) 9 | { 10 | const char file_name[] = "memo.txt"; 11 | const char extension[] = "TXT"; 12 | printf("%s", test_extension(file_name, extension) ? "True" : "False"); 13 | return 0; 14 | } 15 | 16 | bool test_extension(const char *file_name, const char *extension) 17 | { 18 | while (*file_name++ != '.'); 19 | 20 | if (strlen(file_name) != strlen(extension)) 21 | return false; 22 | 23 | while (*file_name) 24 | if (!toupper(*file_name++) == toupper(*extension++)) 25 | return false; 26 | return true; 27 | } 28 | -------------------------------------------------------------------------------- /ch13/Exercises/18.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void remove_filename(char *url); 4 | 5 | int main(void) 6 | { 7 | char url[] = "http://www.knking.com/index.html"; 8 | printf("Whole URL: %s\n", url); 9 | remove_filename(url); 10 | printf("URL without file name: %s", url); 11 | return 0; 12 | } 13 | 14 | void remove_filename(char *url) 15 | { 16 | while (*url++); /* Empty body */ 17 | while (*url-- != '/'); /* Empty body */ 18 | *++url = '\0'; 19 | } 20 | -------------------------------------------------------------------------------- /ch13/Projects/04.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(int argc, char *argv[]) 5 | { 6 | int i; 7 | for (i = argc - 1; i >= 1; i--) 8 | printf("%s ", argv[i]); 9 | 10 | printf("\n"); 11 | 12 | char **p; 13 | for (p = argv + argc - 1; p > argv; p--) 14 | printf("%s ", *p); 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /ch13/Projects/05.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(int argc, char* argv[]) 5 | { 6 | int sum = 0; 7 | char **p; 8 | 9 | for (p = argv + 1; p < argv + argc; p++) 10 | sum += atoi(*p); 11 | 12 | printf("Total: %d", sum); 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /ch13/Projects/08.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define MAX_LEN 30 5 | 6 | int compute_scrabble_value(const char *word); 7 | 8 | const int scrabble_values[26] = { 9 | /* A B C D E F G H I J K L M */ 10 | 1, 3, 3, 2, 1, 4, 2, 4, 1, 8, 5, 1, 3, 11 | /* N O P Q R S T U V W X Y Z */ 12 | 1, 1, 3, 10, 1, 1, 1, 1, 4, 4, 8, 4, 10 }; 13 | 14 | int main(void) 15 | { 16 | const char word[MAX_LEN + 1]; 17 | printf("Enter a word: "); 18 | scanf("%s", word); 19 | printf("Scrabble value: %d", compute_scrabble_value(word)); 20 | 21 | return 0; 22 | } 23 | 24 | int compute_scrabble_value(const char *word) 25 | { 26 | const char *p = word; 27 | int total = 0; 28 | 29 | while (*p) { 30 | total += scrabble_values[toupper(*p++) - 'A']; 31 | } 32 | 33 | return total; 34 | } 35 | 36 | -------------------------------------------------------------------------------- /ch13/Projects/09.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define MAX_LEN 100 5 | 6 | int compute_vowel_count(const char *sentence); 7 | 8 | int main(void) 9 | { 10 | char sentence[MAX_LEN+1]; 11 | 12 | printf("Enter a sentence: "); 13 | fgets(sentence, sizeof(sentence), stdin); 14 | printf("Your sentence contains %d vowels.", compute_vowel_count(sentence)); 15 | 16 | return 0; 17 | } 18 | 19 | int compute_vowel_count(const char *sentence) 20 | { 21 | const char *p = sentence; 22 | int vowel_count = 0; 23 | 24 | while (*p) { 25 | switch(toupper(*p++)) { 26 | case 'A': case 'E': case 'I': case 'O': case 'U': 27 | vowel_count++; 28 | break; 29 | } 30 | } 31 | return vowel_count; 32 | } 33 | -------------------------------------------------------------------------------- /ch13/Projects/10.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define MAX_LEN 100 5 | 6 | void reverse_name(char *name); 7 | 8 | int main(void) 9 | { 10 | char name[MAX_LEN+1]; 11 | printf("Enter a first and last name: "); 12 | 13 | fgets(name, sizeof(name), stdin); 14 | reverse_name(name); 15 | 16 | return 0; 17 | } 18 | 19 | void reverse_name(char *name) 20 | { 21 | char *p = name, initial; 22 | 23 | while (*p && *p == ' ') 24 | p++; 25 | initial = *p++; 26 | 27 | while (*p && *p++ != ' '); 28 | 29 | while (*p && *p != '\n') 30 | putchar(*p++); 31 | printf(", %c.", initial); 32 | } 33 | -------------------------------------------------------------------------------- /ch13/Projects/13.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define LEN 80 + 1 4 | 5 | void encrypt(char *message, int shift); 6 | 7 | int main(void) 8 | { 9 | char message[LEN]; 10 | int shift_amount; 11 | 12 | printf("Enter message to be encrypted: "); 13 | fgets(message, LEN, stdin); 14 | printf("Enter shift amount (1-25): "); 15 | scanf("%d", &shift_amount); 16 | encrypt(message, shift_amount); 17 | 18 | return 0; 19 | } 20 | 21 | void encrypt(char *message, int shift) 22 | { 23 | char *p; 24 | 25 | printf("Encrypted message: "); 26 | for (p = message; *p; p++) { 27 | 28 | if (*p >= 'A' && *p <= 'Z') 29 | printf("%c", ((*p - 'A') + shift) % 26 + 'A'); 30 | else if (*p >= 'a' && *p <= 'z') 31 | printf("%c", ((*p - 'a') + shift) % 26 + 'a'); 32 | else 33 | printf("%c", *p); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /ch13/Projects/16.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define N 50 5 | 6 | void reverse(char *message); 7 | 8 | int main(void) 9 | { 10 | char message[N+1]; 11 | 12 | printf("Enter message: "); 13 | fgets(message, sizeof(message), stdin); 14 | if (message[strlen(message) - 1] == '\n') { 15 | message[strlen(message) - 1] = '\0'; 16 | } 17 | reverse(message); 18 | printf("Reversed message: %s", message); 19 | 20 | return 0; 21 | } 22 | 23 | void reverse(char *message) 24 | { 25 | char temp; 26 | char *left = message; 27 | while (*message) { 28 | message++; 29 | } 30 | char *right = --message; /* - ignore the '\0' char */ 31 | 32 | for (; left < right; left++, right--) { 33 | temp = *left; 34 | *left = *right; 35 | *right = temp; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /ch13/Projects/17.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #define N 50 7 | 8 | bool is_palindrome(const char *message); 9 | 10 | int main(void) 11 | { 12 | char message[N+1]; 13 | 14 | printf("Enter message: "); 15 | fgets(message, sizeof(message), stdin); 16 | if (message[strlen(message)-1] == '\n') { 17 | message[strlen(message)-1] = '\0'; 18 | } 19 | printf("%spalindrome", is_palindrome(message) ? "" : "Not a "); 20 | return 0; 21 | } 22 | 23 | bool is_palindrome(const char *message) 24 | { 25 | const char *left = message; 26 | while (*message) { 27 | message++; 28 | } 29 | const char *right = --message; 30 | 31 | for (; left < right; left++, right--) { 32 | if (!(*left == *right)) 33 | return false; 34 | } 35 | return true; 36 | } 37 | -------------------------------------------------------------------------------- /ch13/Projects/18.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(void) 5 | { 6 | const char *months[] = { 7 | "January", "February", "March", "April", 8 | "May", "June", "July", "August", 9 | "September", "October", "November", "December" 10 | }; 11 | int month, day, year; 12 | 13 | printf("Enter a date (mm/dd/yyyy): "); 14 | scanf(" %2d /%2d /%4d", &month, &day, &year); 15 | printf("You entered the date : %s %d, %d", *(months + (month-1)), day, year); 16 | } 17 | -------------------------------------------------------------------------------- /ch14/Exercises/01.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define CUBE(x) ((x) * (x) * (x)) 4 | #define REM(n) ((n) % 4) 5 | #define PROD(x, y) ((x) + (y) < 100 ? 1 : 0) 6 | 7 | int main(void) 8 | { 9 | int x = 3, y = 100; 10 | float a = 5.6, b = 10.2; 11 | printf("%f\n", CUBE(a)); 12 | printf("%d\n", REM(x)); 13 | printf("%d\n", PROD(x, y)); 14 | } 15 | -------------------------------------------------------------------------------- /ch14/Exercises/02.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define NELEMS(a) ((unsigned int) (sizeof(a)) / (sizeof(a[0]))) 4 | 5 | int main(void) 6 | { 7 | int a[932]; 8 | printf("%zu\n", NELEMS(a)); 9 | } 10 | -------------------------------------------------------------------------------- /ch14/Exercises/03.txt: -------------------------------------------------------------------------------- 1 | Let DOUBLE be the following macro: 2 | 3 | #define DOUBLE(x) 2*x 4 | 5 | (a) What is the value of DOUBLE(1+2)? 2*1+2 = 4 6 | (b) What is the value of 4/DOUBLE(2)? 4/2*2 = 4 7 | (c) Fix the definition of DOUBLE: 8 | #define DOUBLE(x) (2*(x)) 9 | -------------------------------------------------------------------------------- /ch14/Exercises/04.txt: -------------------------------------------------------------------------------- 1 | For each of the following macros, give an example that illustrates a proble with the macro 2 | and show how to fix it. 3 | 4 | (a) #define AVG(x,y) (x-y)/2 5 | problem: 6 | AVG(2+2, 3+3); preprocessor replacement: (2+2-3+3)/2. Evaluates to 2 7 | To fix we need parentheses around individual function arguments, and the entire replacement list 8 | #define AVG(x,y) (((x)-(y))/2)) 9 | 10 | (b) #define AREA(x,y) (x) * (y) 11 | problem: 12 | sum = 5 / AREA(2,5); preprocessor replacement: 5 / (2) * (5). Evalutes to 10 13 | To fix we need parentheses around the replacement list 14 | #define AREA(x,y) ((x) * (y)) 15 | -------------------------------------------------------------------------------- /ch14/Exercises/06.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define DISP(f,x) (printf("%s(%g) = %g\n", (#f), (x), (f(x)))) 5 | #define DISP2(f,x,y) (printf("%s(%g,%g) = %g\n", (#f), (x), (y), (f((x),(y))))) 6 | 7 | int main(void) 8 | { 9 | DISP(sqrt, 1024.0); 10 | DISP2(pow, 32.0, 2.0); 11 | return 0; 12 | } 13 | -------------------------------------------------------------------------------- /ch14/Exercises/08.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | /* Macro to stringize the values of the macro __LINE__ */ 4 | #define STRINGIZE(x) #x 5 | 6 | /* We need to expand the __LINE__ macro to its integer value first before stringizing it, 7 | otherwise STRINGIZE would only convert the macro name __LINE__ to string */ 8 | #define EXPAND_TO_STRING(x) STRINGIZE(x) 9 | 10 | /* We can now call EXPAND_TO_STRING on __LINE__ (we do not need to do this with __FILE 11 | * because the __FILE__ macro expands to a string). We could however invoke 12 | * EXPAND_TO_STRING on the __FILE__ macro if we wanted quotes around the filename. 13 | * */ 14 | #define LINE_FILE "Line " EXPAND_TO_STRING(__LINE__) " of file " __FILE__ 15 | 16 | int main(void) 17 | { 18 | const char *str = LINE_FILE; 19 | printf("%s\n", str); 20 | } 21 | -------------------------------------------------------------------------------- /ch14/Exercises/09.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define CHECK(x,y,n) (((x) >= 0 && (x) <= ((n)-1)) && ((y) >= 0 && (y) <= ((n)-1))) 4 | #define MEDIAN(x,y,z) (((x) - (y)) * ((z) - (x)) >= 0 ? x : ((y) - (x)) * ((z) - (y)) >= 0 ? y : z) 5 | #define POLYNOMIAL(x) ( (3 * ((x) * (x) * (x) * (x) * (x))) \ 6 | +(2 * ((x) * (x) * (x) * (x))) \ 7 | -(5 * ((x) * (x) * (x))) \ 8 | -((x) * (x)) + (7 * (x)) - 6 ) 9 | 10 | int main(void) 11 | { 12 | int x, y, n; 13 | x = 5; y = 10, n = 11; 14 | 15 | printf("CHECK(%d,%d,%d) = %d\n", x, y, n, CHECK(x,y,n)); 16 | printf("MEDIAN(%d,%d,%d) = %d\n", x, y, n, MEDIAN(x,y,n)); 17 | printf("POLYNOMIAL(%d) = %d\n", x+1, POLYNOMIAL(x+1)); 18 | } 19 | -------------------------------------------------------------------------------- /ch14/Exercises/10.txt: -------------------------------------------------------------------------------- 1 | Functions can often (but not always) be written as parameterized macros. Discuss what 2 | characteristics of a function would make it unsuitable as a macro. 3 | 4 | Functions that may often be passed arguments with side effects of assignment, such as the 5 | arguments supplied with the prefix and postfix operators shouldn't be used in a macro 6 | 7 | We can see from question 5 how this can cause unexpected behavior because the macro is passed 8 | a value with a postfix increment operator, and is then replaced multiple times in a ternary 9 | operation by the preprocessor. This caused the value i to be incremented by different amounts 10 | depending on how much of the condition was checked, and whether the condition evaluated to false. 11 | 12 | A function wouldn't have this problem because passing a value of ++i would create a copy of what 13 | that expression evaluates to, and then provide it to the function. 14 | 15 | 16 | -------------------------------------------------------------------------------- /ch14/Exercises/11.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define ERROR(str, arg) (fprintf(stderr, (str), (arg))) 4 | 5 | int main(void) 6 | { 7 | int index = 10; 8 | ERROR("Range error: index = %d\n", index); 9 | } 10 | -------------------------------------------------------------------------------- /ch14/Exercises/12.txt: -------------------------------------------------------------------------------- 1 | Suppose that the macro M has been defined as follows: 2 | 3 | #define M 10 4 | 5 | Which of the following tests will fail? 6 | 7 | (a) #if M succeed 8 | (b) #ifdef M succeed 9 | (c) #ifndef M fail 10 | (d) #if defined(M) succeed 11 | (e) #if !defined(M) fail 12 | -------------------------------------------------------------------------------- /ch14/Exercises/13.txt: -------------------------------------------------------------------------------- 1 | (a) Show what the following program will look like after preprocessing. You may ignore 2 | any lines added to the program as a result of including the header. 3 | 4 | #include 5 | 6 | #define N 100 7 | 8 | void f(void); 9 | 10 | int main(void) 11 | { 12 | f(); 13 | #ifdef N 14 | #undef N 15 | #endif 16 | return 0; 17 | } 18 | 19 | void f(void) 20 | { 21 | #if define(N) 22 | printf("N is %d\n", N); 23 | #else 24 | printf("N is undefined\n"); 25 | #endif 26 | } 27 | 28 | After preprocessing: 29 | 30 | void f(void); 31 | 32 | int main(void) 33 | { 34 | f(); 35 | return 0; 36 | } 37 | 38 | void f(void) 39 | { 40 | printf("N is undefined\n"); 41 | } 42 | 43 | (b) What will be the output of this program? It will print: N is undefined 44 | -------------------------------------------------------------------------------- /ch14/Exercises/15.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | //#define ENLGISH 4 | //#define FRENCH 5 | #define SPANISH 6 | 7 | int main(void) 8 | { 9 | #if defined(ENGLISH) 10 | printf("Insert Disk 1\n"); 11 | #elif defined(FRENCH) 12 | printf("Inserez Le Disque 1\n"); 13 | #elif defined(SPANISH) 14 | printf("Inserte El Disco 1\n"); 15 | #endif 16 | } 17 | -------------------------------------------------------------------------------- /ch14/Exercises/16.txt: -------------------------------------------------------------------------------- 1 | Assume that the following macro definitions are in effect: 2 | 3 | #define IDENT(x) PRAGMA(ident #x) 4 | #define PRAGMA(x) _Pragma(#x) 5 | 6 | What will the following line look like after macro expansion? 7 | 8 | IDENT(foo) 9 | 10 | 11 | The C99 standard states: 12 | A parameter in the replacement list, unless preceded by a # or ## preprocessing token or 13 | followed by a ## preprocessing token, is replaced by the corresponding argument after all 14 | macros contained therein have been expanded. 15 | 16 | Therefore the parameter in IDENT is stringized before being expanded to the PRAGMA macro: 17 | PRAGMA(ident "foo") 18 | 19 | This expands the PRAGMA macro to: 20 | _Pragma(#ident #"foo") 21 | 22 | which stringizes the arguments to: 23 | _Pragma("ident" "\"foo\"") 24 | 25 | which is finally destringized by _Pragma to: 26 | #pragma ident "foo" 27 | -------------------------------------------------------------------------------- /ch15/Exercises/02.txt: -------------------------------------------------------------------------------- 1 | Which of the following should not be put in a header file? Why not? 2 | 3 | (a) Function Prototypes 4 | (b) Function Definitions 5 | (c) Macro Definitions 6 | (d) Type Definitions 7 | 8 | Answer: (b) 9 | You shouldn't define any functions in a header file, only declare their prototypes. If a 10 | function is defined within a header file, then any source file that includes the header file 11 | will need to compile that function. This would cause the function to be compiled multiple times 12 | instead of once if it was listed in a source file. Compiling the same function multiple times 13 | will cause an error at the linking stage, because a linker only expects each function to be 14 | defined once. 15 | -------------------------------------------------------------------------------- /ch15/Exercises/03.txt: -------------------------------------------------------------------------------- 1 | We saw that writing #include instead of #include "file" may not work if file is 2 | one that we've written. Would there be any problem with writing #include "file" instead of 3 | #include if file is a system header? 4 | 5 | The second way will also work, the only difference is that it will search the current 6 | directory for that particular header file before searching the directory in which the 7 | system header files are. 8 | 9 | This can be different though if you have a header file 10 | declared in your working directory that matches a header file in the system header files 11 | directory. 12 | 13 | E.g If you defined your own header file as stdbool.h then: 14 | 15 | #include "stdbool.h" will include your working directory version of stdbool.h 16 | 17 | however writing: 18 | 19 | #include will include the version residing in the system header files directory. 20 | -------------------------------------------------------------------------------- /ch15/Exercises/05.txt: -------------------------------------------------------------------------------- 1 | Suppose that a program consists of three source files - main.c, f1.c, and f2.c - plus two 2 | header files, f1.h and f2.h. All three source files include f1.h, but only f1.c and f2.c 3 | include f2.h. Write a makefile for this program, assuming that the compiler is gcc and that 4 | the executable file is to be named demo. 5 | 6 | 7 | demo: main.o f1.o f2.o 8 | gcc -o demo main.o f1.o f2.o 9 | 10 | main.o: main.c f1.h 11 | gcc -c main.c 12 | 13 | f1.o: f1.h f2.h 14 | gcc -c f1.c 15 | 16 | f2.o: f1.h f2.h 17 | gcc -c f2.c 18 | -------------------------------------------------------------------------------- /ch15/Exercises/06.txt: -------------------------------------------------------------------------------- 1 | The following questions refer to the program described in the exercise prior. 2 | 3 | (a) Which files need to be compiled when the program is built for the first time? 4 | main.c, f1.c, f2.c. 5 | 6 | (b) If f1.c is changed after the program has been built, which files need to be recompiled? 7 | f1.c 8 | 9 | (c) If f1.h is changed after the program has been built, which files need to be recompiled? 10 | main.c, f1.c, f2.c 11 | 12 | (d) If f2.h is changed after the program has been built, which files need to be recompiled? 13 | f1.c, f2.c 14 | -------------------------------------------------------------------------------- /ch15/Projects/01/justify_after_change: -------------------------------------------------------------------------------- 1 | C is quirky, flawed, and an enormous success. Although 2 | accidents of history surely helped, it evidently satisfied a 3 | need for a system implementation language efficient enough 4 | to displace assembly language, yet sufficiently abstract and 5 | fluent to describe algorithms and interactions in a wide 6 | variety of environments. 7 | -------------------------------------------------------------------------------- /ch15/Projects/01/justify_before_change: -------------------------------------------------------------------------------- 1 | C is quirky, flawed, and an enormous success. Although 2 | accidents of history surely helped, it evidently satisfied a 3 | need for a system implementation language efficient enough 4 | to displace assembly language, yet sufficiently abstract and 5 | fluent to describe algorithms and interactions in a wide 6 | variety of environments. 7 | -------------------------------------------------------------------------------- /ch15/Projects/01/makefile: -------------------------------------------------------------------------------- 1 | justify: justify.o word.o line.o 2 | gcc -o justify justify.o word.o line.o 3 | 4 | justify.o: justify.c word.h word.h 5 | gcc -c justify.c 6 | 7 | word.o: word.c word.h 8 | gcc -c word.c 9 | 10 | line.o: line.c line.h 11 | gcc -c line.c 12 | -------------------------------------------------------------------------------- /ch15/Projects/01/quote: -------------------------------------------------------------------------------- 1 | C is quirky, flawed, and an 2 | enormous success. Although accidents of history 3 | surely helped, it evidently satisfied a need 4 | 5 | for a system implementation language efficient 6 | enough to displace assembly language, 7 | yet sufficiently abstract and fluent to describe 8 | algorithms and interactions in a wide variety 9 | of environments. 10 | -------------------------------------------------------------------------------- /ch15/Projects/02/makefile: -------------------------------------------------------------------------------- 1 | justify: justify.o word.o line.o 2 | gcc -o justify justify.o word.o line.o 3 | 4 | justify.o: justify.c word.h word.h 5 | gcc -c justify.c 6 | 7 | word.o: word.c word.h 8 | gcc -c word.c 9 | 10 | line.o: line.c line.h 11 | gcc -c line.c 12 | -------------------------------------------------------------------------------- /ch15/Projects/02/quote: -------------------------------------------------------------------------------- 1 | C is quirky, flawed, and an 2 | enormous success. Although accidents of history 3 | surely helped, it evidently satisfied a need 4 | 5 | for a system implementation language efficient 6 | enough to displace assembly language, 7 | yet sufficiently abstract and fluent to describe 8 | algorithms and interactions in a wide variety 9 | of environments. 10 | -------------------------------------------------------------------------------- /ch15/Projects/03/makefile: -------------------------------------------------------------------------------- 1 | quicksort: quicksort.o 2 | gcc -o quicksort quicksort.o 3 | 4 | quicksort.o: quicksort.c quicksort.h 5 | gcc -c quicksort.c 6 | -------------------------------------------------------------------------------- /ch15/Projects/03/quicksort: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fordea/c-programming-a-modern-approach/f03ecea21ac119d38863673a92896973dd963038/ch15/Projects/03/quicksort -------------------------------------------------------------------------------- /ch15/Projects/03/quicksort.h: -------------------------------------------------------------------------------- 1 | #ifndef QUICKSORT_H 2 | #define QUICKSORT_H 3 | 4 | /* Sorts the integer array a using the quicksort algorithm */ 5 | void quicksort(int a[], int low, int high); 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /ch15/Projects/04/makefile: -------------------------------------------------------------------------------- 1 | remind: remind.o readline.o 2 | gcc -o remind remind.o readline.o 3 | 4 | remind.o: remind.c readline.h 5 | gcc -c remind.c 6 | 7 | readline.o: readline.c readline.h 8 | gcc -c readline.c 9 | -------------------------------------------------------------------------------- /ch15/Projects/04/readline.c: -------------------------------------------------------------------------------- 1 | #include "readline.h" 2 | 3 | int read_line(char str[], int n) 4 | { 5 | int ch, i = 0; 6 | 7 | while ((ch = getchar()) != '\n') 8 | if (i < n) 9 | str[i++] = ch; 10 | str[i] = '\0'; 11 | return i; 12 | } 13 | -------------------------------------------------------------------------------- /ch15/Projects/04/readline.h: -------------------------------------------------------------------------------- 1 | #ifndef READLINE_H 2 | #define READLINE_H 3 | 4 | int read_line(char str[], int n); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /ch15/Projects/05/makefile: -------------------------------------------------------------------------------- 1 | calc: calc.o stack.o 2 | gcc -o calc calc.o stack.o 3 | 4 | calc.o: calc.c stack.h 5 | gcc -c calc.c 6 | 7 | stack.o: stack.c stack.h 8 | gcc -c stack.c 9 | -------------------------------------------------------------------------------- /ch15/Projects/05/stack.h: -------------------------------------------------------------------------------- 1 | #ifndef STACK_H 2 | #define STACK_H 3 | 4 | /* Empties the stack */ 5 | void make_empty(void); 6 | 7 | /* Returns true if stack is empty, else false */ 8 | bool is_empty(void); 9 | 10 | /* Returns true if stack is full, else false */ 11 | bool is_full(void); 12 | 13 | /* Pushes integer i onto the top of the stack */ 14 | void push(int i); 15 | 16 | /* Removes the top item from the stack and returns it */ 17 | int pop(void); 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /ch16/Exercises/01.txt: -------------------------------------------------------------------------------- 1 | In the following declarations, the x and y structures have members named x and y: 2 | 3 | struct { int x, y; } x; 4 | struct { int x, y; } y; 5 | 6 | Are these declarations legal on an individual basis? Could both declarations appear as 7 | shown in a program? 8 | 9 | Both statements are legal on an individual basis, and together. All the variables declared 10 | within a struct have block scope, meaning the variables x and y inside struct x cannot see 11 | the variables x and y inside struct y. It's also fine for a variable inside a struct to share 12 | the same name as the struct itself, because the only way we can access that variable is by 13 | appending it to the struct name with a period. 14 | 15 | So in this example we can access the struct variables via: 16 | struct x: 17 | x.x 18 | x.y 19 | 20 | struct y: 21 | y.x 22 | y.y 23 | -------------------------------------------------------------------------------- /ch16/Exercises/02.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | struct { 6 | double real; 7 | double imaginary; 8 | } c1 = {0.0, 1.0}, 9 | c2 = {1.0, 0.0}, 10 | c3; 11 | 12 | c1 = c2; 13 | 14 | c3.real = c1.real + c2.real; 15 | c3.imaginary = c1.imaginary + c2.imaginary; 16 | 17 | printf("Struct c1: real = %.1f, imaginary = %.1f\n", c1.real, c1.imaginary); 18 | printf("Struct c2: real = %.1f, imaginary = %.1f\n", c2.real, c2.imaginary); 19 | printf("Struct c3: real = %.1f, imaginary = %.1f\n", c3.real, c3.imaginary); 20 | } 21 | -------------------------------------------------------------------------------- /ch16/Exercises/03.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | struct complex { 4 | double real; 5 | double imaginary; 6 | }; 7 | 8 | struct complex make_complex(double real, double imaginary) 9 | { 10 | struct complex newcomplex; 11 | newcomplex.real = real; 12 | newcomplex.imaginary = imaginary; 13 | 14 | return newcomplex; 15 | } 16 | 17 | struct complex add_complex(struct complex s1, struct complex s2) 18 | { 19 | struct complex newcomplex; 20 | newcomplex.real = s1.real + s2.real; 21 | newcomplex.imaginary = s1.imaginary + s2.imaginary; 22 | 23 | return newcomplex; 24 | } 25 | 26 | int main(void) 27 | { 28 | struct complex c1, c2, c3; 29 | } 30 | 31 | 32 | -------------------------------------------------------------------------------- /ch16/Exercises/04.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | typedef struct { 4 | double real; 5 | double imaginary; 6 | } Complex; 7 | 8 | Complex make_complex(double real, double imaginary) 9 | { 10 | Complex newcomplex; 11 | newcomplex.real = real; 12 | newcomplex.imaginary = imaginary; 13 | 14 | return newcomplex; 15 | } 16 | 17 | Complex add_complex(Complex s1, Complex s2) 18 | { 19 | Complex newcomplex; 20 | newcomplex.real = s1.real + s2.real; 21 | newcomplex.imaginary = s1.imaginary + s2.imaginary; 22 | 23 | return newcomplex; 24 | } 25 | 26 | int main(void) 27 | { 28 | Complex c1, c2, c3; 29 | } 30 | 31 | 32 | -------------------------------------------------------------------------------- /ch16/Exercises/08.txt: -------------------------------------------------------------------------------- 1 | struct color { 2 | int red; 3 | int green; 4 | int blue; 5 | }; 6 | 7 | const struct color MAGENTA_A = {255, 0, 255}; 8 | 9 | const struct color MAGENTA_B = {.red = 255, .blue = 255};: 10 | -------------------------------------------------------------------------------- /ch16/Exercises/11.txt: -------------------------------------------------------------------------------- 1 | Suppose that s is the following structure: 2 | 3 | struct { 4 | double a; 5 | union { 6 | char b[4]; 7 | double c; 8 | int d; 9 | } e; 10 | char f[4]; 11 | } s; 12 | 13 | If char values occupy one byte, int values occupy four bytes, and double values 14 | occupy eight bytes, how much space will a C compiler allocate for s? (Assume 15 | that the compiler leaves no "holes" between members.) 16 | 17 | a = 8 bytes 18 | e = 8 bytes (double largest in union) 19 | f = 4 bytes 20 | 21 | Total 20 bytes 22 | -------------------------------------------------------------------------------- /ch16/Exercises/12.txt: -------------------------------------------------------------------------------- 1 | Suppose that u is the following union: 2 | 3 | union { 4 | double a; 5 | struct { 6 | char b[4]; 7 | double c; 8 | int d; 9 | } e; 10 | char f[4]; 11 | } u; 12 | 13 | If char values occupy one byte, int values occupy four bytes, and double 14 | values occupy eight bytes, how much space will a C compiler allocate for u? 15 | (Assume that the compiler leaves no "holes" between members.) 16 | 17 | e is largest member in union u. 18 | e is size 4 + 8 + 4 = 16 19 | Total 16 bytes 20 | -------------------------------------------------------------------------------- /ch16/Exercises/15.txt: -------------------------------------------------------------------------------- 1 | (a) Declare a tag for an enumeration whose values represent the seven days of the week. 2 | enum day {MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY}; 3 | 4 | (b) Use typedef to define a name for the enumeration of part (a) 5 | typedef enum {MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY} Day; 6 | 7 | -------------------------------------------------------------------------------- /ch16/Exercises/16.txt: -------------------------------------------------------------------------------- 1 | Which of the following statements about enumeration constants are true? 2 | 3 | (a) An enumeration constants may represent any integer specified by the 4 | programmer. 5 | True 6 | 7 | (b) Enumeration constants have exactly the same properties as constants 8 | created using #define. 9 | False - Enumerations can have function / block scope unlike #define constants. 10 | 11 | (c) Enumeration constants have the values 0, 1, 2... by default. 12 | True 13 | 14 | (d) All constants in an enumeration must have different values. 15 | False 16 | 17 | (e) Enumeration constants may be used as integers in expressions. 18 | True 19 | -------------------------------------------------------------------------------- /ch16/Exercises/17.txt: -------------------------------------------------------------------------------- 1 | Suppose that b and i are declared as follows: 2 | 3 | enum {FALSE, TRUE} b; 4 | int i; 5 | 6 | Which of the following statements are legal? Which ones are "safe" (always yield 7 | a meaningful result)? 8 | 9 | (a) b = FALSE; Legal & Safe 10 | (b) b = i; Legal & Unsafe, i could be outside the range of b's values 11 | (c) b++; Legal & Unsafe, b could be increased outside the range of b's values 12 | (d) i = b; Legal & Safe 13 | (e) i = 2 * b + 1; Legal & Safe 14 | -------------------------------------------------------------------------------- /ch16/Exercises/19.txt: -------------------------------------------------------------------------------- 1 | struct pinball_machine { 2 | char name[41]; 3 | int year; 4 | enum {EM, SS} type; 5 | int players; 6 | }; 7 | -------------------------------------------------------------------------------- /ch16/Exercises/20.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | enum {NORTH, SOUTH, EAST, WEST} direction; 4 | 5 | int main(void) 6 | { 7 | int x = 0, y = 0; 8 | 9 | direction = SOUTH; 10 | printf("%d\n", direction); 11 | 12 | switch (direction) { 13 | case EAST: x++; 14 | break; 15 | case WEST: x--; 16 | break; 17 | case SOUTH: y++; 18 | break; 19 | case NORTH: y--; 20 | break; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /ch16/Exercises/21.txt: -------------------------------------------------------------------------------- 1 | What are the integer values of the enumeration constants in each of the following 2 | declarations? 3 | 4 | (a) enum {NUL, SOH, STX, ETX}; 5 | NUL is 0, SOH is 1, STX is 2, and ETX is 3. 6 | 7 | (b) enum {VT = 11, FF, CR}; 8 | VT is 11, FF is 12, and CR is 13. 9 | 10 | (c) enum {SO = 14, SI, DLE, CAN = 24, EM}; 11 | SO is 14, SI is 15, DLE is 16, CAN is 24, and EM is 25. 12 | 13 | (d) enum {ENQ = 45, ACK, BEL, LF = 37, ETB, ESC}; 14 | ENQ is 45, ACK is 46, BEL is 47, LF is 37, ETB is 38, and ESC is 39. 15 | -------------------------------------------------------------------------------- /ch16/Exercises/22.txt: -------------------------------------------------------------------------------- 1 | enum chess_pieces {KING, QUEEN, ROOK, BISHOP, KNIGHT, PAWN}; 2 | 3 | (a) const int piece_value[6] = {200, 9, 5, 3, 3, 1}; 4 | 5 | (b) const int piece_value[6] = { 6 | [KING] = 200, 7 | [QUEEN] = 9, 8 | [ROOK] = 5, 9 | [BISHOP] = 3, 10 | [KNIGHT] = 3, 11 | [PAWN] = 1 12 | }; 13 | -------------------------------------------------------------------------------- /ch16/Projects/02/inventory.h: -------------------------------------------------------------------------------- 1 | #ifndef INVENTORY_H 2 | #define INVENTORY_H 3 | 4 | #define NAME_LEN 25 5 | #define MAX_PARTS 100 6 | 7 | struct part { 8 | int number; 9 | char name[NAME_LEN+1]; 10 | int on_hand; 11 | } inventory[MAX_PARTS]; 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /ch16/Projects/02/makefile: -------------------------------------------------------------------------------- 1 | inventory: inventory.o readline.o quicksort.o 2 | gcc -o inventory.out inventory.o readline.o quicksort.o 3 | 4 | inventory.o: inventory.c inventory.h readline.h quicksort.h 5 | gcc -c inventory.c 6 | 7 | readline.o: readline.c readline.h 8 | gcc -c readline.c 9 | 10 | quicksort.o: quicksort.c quicksort.h inventory.h 11 | gcc -c quicksort.c 12 | 13 | -------------------------------------------------------------------------------- /ch16/Projects/02/quicksort.h: -------------------------------------------------------------------------------- 1 | #ifndef QUICKSORT_H 2 | #define QUICKSORT_H 3 | 4 | #include "inventory.h" 5 | /* Sorts a struct part array a using the quicksort algorithm */ 6 | void quicksort(struct part a[], int low, int high); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /ch16/Projects/02/readline.c: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * From C PROGRAMMING: A MODERN APPROACH, Second Edition * 3 | * By K. N. King * 4 | * Copyright (c) 2008, 1996 W. W. Norton & Company, Inc. * 5 | * All rights reserved. * 6 | * This program may be freely distributed for class use, * 7 | * provided that this copyright notice is retained. * 8 | *********************************************************/ 9 | 10 | /* readline.c (Chapter 16, page 395) */ 11 | 12 | #include 13 | #include 14 | #include "readline.h" 15 | 16 | int read_line(char str[], int n) 17 | { 18 | int ch, i = 0; 19 | 20 | while (isspace(ch = getchar())) 21 | ; 22 | while (ch != '\n' && ch != EOF) { 23 | if (i < n) 24 | str[i++] = ch; 25 | ch = getchar(); 26 | } 27 | str[i] = '\0'; 28 | return i; 29 | } 30 | -------------------------------------------------------------------------------- /ch16/Projects/03/inventory.h: -------------------------------------------------------------------------------- 1 | #ifndef INVENTORY_H 2 | #define INVENTORY_H 3 | 4 | #define NAME_LEN 25 5 | #define MAX_PARTS 100 6 | 7 | struct part { 8 | int number; 9 | char name[NAME_LEN+1]; 10 | int on_hand; 11 | }; 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /ch16/Projects/03/makefile: -------------------------------------------------------------------------------- 1 | inventory: inventory.o readline.o quicksort.o 2 | gcc -o inventory.out inventory.o readline.o quicksort.o 3 | 4 | inventory.o: inventory.c inventory.h readline.h quicksort.h 5 | gcc -c inventory.c 6 | 7 | readline.o: readline.c readline.h 8 | gcc -c readline.c 9 | 10 | quicksort.o: quicksort.c quicksort.h inventory.h 11 | gcc -c quicksort.c 12 | 13 | -------------------------------------------------------------------------------- /ch16/Projects/03/quicksort.h: -------------------------------------------------------------------------------- 1 | #ifndef QUICKSORT_H 2 | #define QUICKSORT_H 3 | 4 | #include "inventory.h" 5 | /* Sorts a struct part array a using the quicksort algorithm */ 6 | void quicksort(struct part a[], int low, int high); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /ch16/Projects/03/readline.c: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * From C PROGRAMMING: A MODERN APPROACH, Second Edition * 3 | * By K. N. King * 4 | * Copyright (c) 2008, 1996 W. W. Norton & Company, Inc. * 5 | * All rights reserved. * 6 | * This program may be freely distributed for class use, * 7 | * provided that this copyright notice is retained. * 8 | *********************************************************/ 9 | 10 | /* readline.c (Chapter 16, page 395) */ 11 | 12 | #include 13 | #include 14 | #include "readline.h" 15 | 16 | int read_line(char str[], int n) 17 | { 18 | int ch, i = 0; 19 | 20 | while (isspace(ch = getchar())) 21 | ; 22 | while (ch != '\n' && ch != EOF) { 23 | if (i < n) 24 | str[i++] = ch; 25 | ch = getchar(); 26 | } 27 | str[i] = '\0'; 28 | return i; 29 | } 30 | -------------------------------------------------------------------------------- /ch16/Projects/04/inventory.h: -------------------------------------------------------------------------------- 1 | #ifndef INVENTORY_H 2 | #define INVENTORY_H 3 | 4 | #define NAME_LEN 25 5 | #define MAX_PARTS 100 6 | 7 | struct part { 8 | int number; 9 | char name[NAME_LEN+1]; 10 | int on_hand; 11 | float price; 12 | }; 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /ch16/Projects/04/makefile: -------------------------------------------------------------------------------- 1 | inventory: inventory.o readline.o quicksort.o 2 | gcc -o inventory.out inventory.o readline.o quicksort.o 3 | 4 | inventory.o: inventory.c inventory.h readline.h quicksort.h 5 | gcc -c inventory.c 6 | 7 | readline.o: readline.c readline.h 8 | gcc -c readline.c 9 | 10 | quicksort.o: quicksort.c quicksort.h inventory.h 11 | gcc -c quicksort.c 12 | 13 | -------------------------------------------------------------------------------- /ch16/Projects/04/quicksort.h: -------------------------------------------------------------------------------- 1 | #ifndef QUICKSORT_H 2 | #define QUICKSORT_H 3 | 4 | #include "inventory.h" 5 | /* Sorts a struct part array a using the quicksort algorithm */ 6 | void quicksort(struct part a[], int low, int high); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /ch16/Projects/04/readline.c: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * From C PROGRAMMING: A MODERN APPROACH, Second Edition * 3 | * By K. N. King * 4 | * Copyright (c) 2008, 1996 W. W. Norton & Company, Inc. * 5 | * All rights reserved. * 6 | * This program may be freely distributed for class use, * 7 | * provided that this copyright notice is retained. * 8 | *********************************************************/ 9 | 10 | /* readline.c (Chapter 16, page 395) */ 11 | 12 | #include 13 | #include 14 | #include "readline.h" 15 | 16 | int read_line(char str[], int n) 17 | { 18 | int ch, i = 0; 19 | 20 | while (isspace(ch = getchar())) 21 | ; 22 | while (ch != '\n' && ch != EOF) { 23 | if (i < n) 24 | str[i++] = ch; 25 | ch = getchar(); 26 | } 27 | str[i] = '\0'; 28 | return i; 29 | } 30 | -------------------------------------------------------------------------------- /ch17/Exercises/01.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void *my_malloc(int bytes) 5 | { 6 | void *p; 7 | 8 | if ((p = malloc(bytes)) == NULL) { 9 | printf("Error, malloc failed.\n"); 10 | exit(EXIT_FAILURE); 11 | } 12 | 13 | return p; 14 | } 15 | 16 | int main(void) 17 | { 18 | char *p = my_malloc(10); 19 | } 20 | -------------------------------------------------------------------------------- /ch17/Exercises/02.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | void *duplicate(char * str) 6 | { 7 | char *duped_str; 8 | 9 | if ((duped_str = malloc(strlen(str) + 1)) == NULL) { 10 | printf("Error: malloc failed"); 11 | exit(EXIT_FAILURE); 12 | } 13 | 14 | strcpy(duped_str, str); 15 | return duped_str; 16 | } 17 | 18 | int main(void) 19 | { 20 | char *str = "testing."; 21 | char *str2 = duplicate(str); 22 | 23 | printf("Original String: %s\n", str); 24 | printf("Duplicated String: %s\n", str2); 25 | } 26 | -------------------------------------------------------------------------------- /ch17/Exercises/03.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int *create_array(int n, int initial_value) 5 | { 6 | int *p, *p2; 7 | if ((p = malloc(n * sizeof(int))) == NULL) { 8 | return NULL; 9 | } 10 | 11 | for (p2 = p; p2 < p + n; p2++) 12 | *p2 = initial_value; 13 | 14 | return p; 15 | } 16 | 17 | int main(void) 18 | { 19 | int *arr = create_array(20, 7); 20 | int *p = arr; 21 | 22 | while (p < arr + 20) 23 | printf("%d ", *p++); 24 | printf("\n"); 25 | 26 | } 27 | -------------------------------------------------------------------------------- /ch17/Exercises/04.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(void) 5 | { 6 | struct point { int x, y; }; 7 | struct rectangle { struct point upper_left, lower_right; }; 8 | struct rectangle *p; 9 | 10 | if ((p = malloc(sizeof(struct rectangle))) == NULL) { 11 | printf("Error, malloc failed."); 12 | exit(EXIT_FAILURE); 13 | } 14 | 15 | p->upper_left.x = 10; 16 | p->upper_left.y = 25; 17 | p->lower_right.x = 20; 18 | p->lower_right.y = 15; 19 | 20 | printf("Rectangle upper left = %d,%d\n", p->upper_left.x, p->upper_left.y); 21 | printf("Rectangle lower right = %d,%d\n", p->lower_right.x, p->lower_right.y); 22 | 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /ch17/Exercises/05.txt: -------------------------------------------------------------------------------- 1 | Suppose that f and p are declared as follows: 2 | 3 | struct { 4 | union { 5 | char a, b; 6 | int c; 7 | } d; 8 | int e[5]; 9 | } f, *p = &f; 10 | 11 | Which of the following statements are legal? 12 | 13 | (a) p->b = ' '; Illegal. To access b we must use p->d.b = ' '; 14 | (b) p->e[3] = 10; Legal. 15 | (c) (*p).d.a = '*'; Legal. 16 | (d) p->d->c = 20; Illegal. d isn't a pointer. we must use p->d.c = 20; 17 | -------------------------------------------------------------------------------- /ch17/Exercises/06.txt: -------------------------------------------------------------------------------- 1 | Modify the delete_fromt_list function so that it only uses one pointer variable 2 | instead of two. 3 | 4 | void *delete_from_list(struct node **pp, int n) 5 | { 6 | struct node entry = *pp; 7 | 8 | while (entry) { 9 | if (entry->value == n) { 10 | *pp = entry->next; 11 | free(entry); 12 | } 13 | pp = &entry->next; 14 | entry = entry->next; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /ch17/Exercises/09.txt: -------------------------------------------------------------------------------- 1 | True or false: If x is a structure and a is a member of that structure, then 2 | (&x)->a is the same as x.a. 3 | 4 | True 5 | 6 | &x is the address of the structure x, so it's a pointer to x. To get a value 7 | from a pointer to a structure we can either do (*(&x)).a or we can use the 8 | structure member operator -> (&x)->a. We must use parentheses around &x 9 | because -> has higher precedence than &. If we didn't specify parentheses it 10 | would be evaluated as follows: &(x->a) which is illegal because x is a structure, 11 | not a pointer to a structure. 12 | -------------------------------------------------------------------------------- /ch17/Exercises/10.txt: -------------------------------------------------------------------------------- 1 | Modify the print_part function of Section 16.2 so that its parameter is a 2 | pointer to a part strucutre. Use the -> operator in your answer. 3 | 4 | Original: 5 | 6 | void print_part(struct part p) 7 | { 8 | printf("Part number: %d\n", p.number); 9 | printf("Part name: %s\n", p.name); 10 | printf("Quantity on hand: %d\n", p.on_hand); 11 | } 12 | 13 | Modified: 14 | 15 | void print_part(struct part *p) 16 | { 17 | printf("Part number: %d\n", p->number); 18 | printf("Part name: %s\n", p->name); 19 | printf("Quantity on hand: %d\n", p->on_hand); 20 | } 21 | -------------------------------------------------------------------------------- /ch17/Exercises/11.txt: -------------------------------------------------------------------------------- 1 | Write the following function: 2 | 3 | int count_occurrences(struct node *list, int n); 4 | 5 | The list parameter points to a linked list; the function should return the 6 | number of times n appears in this list. Assume the node structure is the one 7 | defined in section 17.5. 8 | 9 | int count_occurrences(struct node *list, int n) 10 | { 11 | int total = 0; 12 | 13 | while (list) { 14 | if (list->value == n) 15 | total++; 16 | list = list->next; 17 | } 18 | return total; 19 | } 20 | -------------------------------------------------------------------------------- /ch17/Exercises/12.txt: -------------------------------------------------------------------------------- 1 | Write the following function: 2 | 3 | struct node *find_last(struct node *list, int n); 4 | 5 | The list parameter points to a linked list. The function should return a 6 | pointer to the last node that contains n; it should return NULL if n doesn't 7 | appear in the list. Assume that the node structure is the one defined in 8 | Section 17.5. 9 | 10 | struct node *find_last(struct node *list, int n) 11 | { 12 | struct node *last = NULL; 13 | 14 | while (list) { 15 | if (list->value == n) 16 | last = list; 17 | list = list->next; 18 | } 19 | return last; 20 | } 21 | -------------------------------------------------------------------------------- /ch17/Exercises/14.txt: -------------------------------------------------------------------------------- 1 | Modify the delete_from_list function (Section 17.5) so that its first 2 | parameter has tupe struct node ** (a pointer to a pointer to the first node in 3 | a list) and its return type is void. delete_from list must modify its 4 | first argument to point to the list after the desired node has been deleted. 5 | 6 | void *delte_from_list(struct node **pp, int n) 7 | { 8 | struct node *entry = *pp; 9 | 10 | while (entry) { 11 | if (entry->value == n) { 12 | *pp = entry->next; 13 | free(entry); 14 | } 15 | pp = &entry->next; 16 | entry = entry->next; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /ch17/Exercises/16.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int sum(int (*f)(int), int start, int end); 4 | int square(int i); 5 | int cube(int i); 6 | 7 | int main(void) 8 | { 9 | /* Sum the square of all numbers from 1..10 inclusive */ 10 | printf("sum: %d\n", sum(square, 1, 10)); 11 | /* Sum the cube of all numbers from 7..11 inclusive */ 12 | printf("sum: %d\n", sum(cube, 7, 11)); 13 | return 0; 14 | } 15 | 16 | int sum(int (*f)(int), int start, int end) 17 | { 18 | int sum = 0; 19 | while (start <= end) { 20 | sum += (*f)(start); 21 | start++; 22 | } 23 | return sum; 24 | } 25 | 26 | int square(int i) 27 | { 28 | return i * i; 29 | } 30 | 31 | int cube(int i) 32 | { 33 | return i * i * i; 34 | } 35 | -------------------------------------------------------------------------------- /ch17/Exercises/17.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int comparison(const void *i, const void *j); 6 | 7 | int main(void) 8 | { 9 | int a[100], i; 10 | srand(time(NULL)); 11 | 12 | printf("Unsorted array:\n"); 13 | for (i = 0; i < 100; i++) { 14 | a[i] = rand() % 100 + 1; // generate random number between 1 and 100 15 | printf("%d ", a[i]); 16 | } 17 | printf("\n\n"); 18 | 19 | /* qsort(a + 49, 50, sizeof(int), comparison); */ 20 | qsort(a + (sizeof(a) / sizeof(a[0])) - 50, 50, sizeof(int), comparison); 21 | 22 | printf("Sorted second half:\n"); 23 | for (i = 0; i < 100; i++) { 24 | printf("%d ", a[i]); 25 | } 26 | printf("\n"); 27 | 28 | return 0; 29 | } 30 | 31 | int comparison(const void *i, const void *j) 32 | { 33 | return *((int *)i) - *((int *)j); 34 | } 35 | -------------------------------------------------------------------------------- /ch17/Exercises/18/makefile: -------------------------------------------------------------------------------- 1 | inventory: inventory.o readline.o 2 | gcc -o inventory.out inventory.o readline.o 3 | 4 | inventory.o: inventory.c readline.h 5 | gcc -c inventory.c 6 | 7 | readline.o: readline.c readline.h 8 | gcc -c readline.c 9 | -------------------------------------------------------------------------------- /ch17/Exercises/18/readline.c: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * From C PROGRAMMING: A MODERN APPROACH, Second Edition * 3 | * By K. N. King * 4 | * Copyright (c) 2008, 1996 W. W. Norton & Company, Inc. * 5 | * All rights reserved. * 6 | * This program may be freely distributed for class use, * 7 | * provided that this copyright notice is retained. * 8 | *********************************************************/ 9 | 10 | /* readline.c (Chapter 16, page 395) */ 11 | 12 | #include 13 | #include 14 | #include "readline.h" 15 | 16 | int read_line(char str[], int n) 17 | { 18 | int ch, i = 0; 19 | 20 | while (isspace(ch = getchar())) 21 | ; 22 | while (ch != '\n' && ch != EOF) { 23 | if (i < n) 24 | str[i++] = ch; 25 | ch = getchar(); 26 | } 27 | str[i] = '\0'; 28 | return i; 29 | } 30 | -------------------------------------------------------------------------------- /ch17/Projects/01_02/makefile: -------------------------------------------------------------------------------- 1 | inventory: inventory.o readline.o 2 | gcc -o inventory.out inventory.o readline.o 3 | 4 | inventory.o: inventory.c readline.h 5 | gcc -c inventory.c 6 | 7 | readline.o: readline.c readline.h 8 | gcc -c readline.c 9 | -------------------------------------------------------------------------------- /ch17/Projects/01_02/readline.c: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * From C PROGRAMMING: A MODERN APPROACH, Second Edition * 3 | * By K. N. King * 4 | * Copyright (c) 2008, 1996 W. W. Norton & Company, Inc. * 5 | * All rights reserved. * 6 | * This program may be freely distributed for class use, * 7 | * provided that this copyright notice is retained. * 8 | *********************************************************/ 9 | 10 | /* readline.c (Chapter 16, page 395) */ 11 | 12 | #include 13 | #include 14 | #include "readline.h" 15 | 16 | int read_line(char str[], int n) 17 | { 18 | int ch, i = 0; 19 | 20 | while (isspace(ch = getchar())) 21 | ; 22 | while (ch != '\n' && ch != EOF) { 23 | if (i < n) 24 | str[i++] = ch; 25 | ch = getchar(); 26 | } 27 | str[i] = '\0'; 28 | return i; 29 | } 30 | -------------------------------------------------------------------------------- /ch17/Projects/03/makefile: -------------------------------------------------------------------------------- 1 | inventory: inventory.o readline.o 2 | gcc -o inventory.out inventory.o readline.o 3 | 4 | inventory.o: inventory.c readline.h 5 | gcc -c inventory.c 6 | 7 | readline.o: readline.c readline.h 8 | gcc -c readline.c 9 | -------------------------------------------------------------------------------- /ch17/Projects/03/readline.c: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * From C PROGRAMMING: A MODERN APPROACH, Second Edition * 3 | * By K. N. King * 4 | * Copyright (c) 2008, 1996 W. W. Norton & Company, Inc. * 5 | * All rights reserved. * 6 | * This program may be freely distributed for class use, * 7 | * provided that this copyright notice is retained. * 8 | *********************************************************/ 9 | 10 | /* readline.c (Chapter 16, page 395) */ 11 | 12 | #include 13 | #include 14 | #include "readline.h" 15 | 16 | int read_line(char str[], int n) 17 | { 18 | int ch, i = 0; 19 | 20 | while (isspace(ch = getchar())) 21 | ; 22 | while (ch != '\n' && ch != EOF) { 23 | if (i < n) 24 | str[i++] = ch; 25 | ch = getchar(); 26 | } 27 | str[i] = '\0'; 28 | return i; 29 | } 30 | -------------------------------------------------------------------------------- /ch17/Projects/04/makefile: -------------------------------------------------------------------------------- 1 | justify: justify.o word.o line.o 2 | gcc -o justify.out justify.o word.o line.o 3 | 4 | justify.o: justify.c word.h word.h 5 | gcc -c justify.c 6 | 7 | word.o: word.c word.h 8 | gcc -c word.c 9 | 10 | line.o: line.c line.h 11 | gcc -c line.c 12 | -------------------------------------------------------------------------------- /ch17/Projects/04/newquote: -------------------------------------------------------------------------------- 1 | C is quirky, flawed, and an enormous success. Although 2 | accidents of history surely helped, it evidently satisfied a 3 | need for a system implementation language efficient enough 4 | to displace assembly language, yet sufficiently abstract and 5 | fluent to describe algorithms and interactions in a wide 6 | variety of environments. 7 | -------------------------------------------------------------------------------- /ch17/Projects/04/quote: -------------------------------------------------------------------------------- 1 | C is quirky, flawed, and an 2 | enormous success. Although accidents of history 3 | surely helped, it evidently satisfied a need 4 | 5 | for a system implementation language efficient 6 | enough to displace assembly language, 7 | yet sufficiently abstract and fluent to describe 8 | algorithms and interactions in a wide variety 9 | of environments. 10 | -------------------------------------------------------------------------------- /ch18/Exercises/02.txt: -------------------------------------------------------------------------------- 1 | Answer each of the following questions with auto, extern, registers, and/or 2 | static. 3 | 4 | (a) Which storage class is used primarily to indicate that a variable or 5 | function can be shared by several files? extern. 6 | 7 | (b) Suppose that a variable x is to be shared by several functions in one file 8 | but hidden from functions in other files. Which storage class should x 9 | be declared to have? static. 10 | 11 | (c) Which storage classes can affect the storage duration of a variable? 12 | static (when declared in a block it provides static storage duration.) 13 | extern (when declared in a block it provides static storage duration.) 14 | -------------------------------------------------------------------------------- /ch18/Exercises/03.txt: -------------------------------------------------------------------------------- 1 | List the storage duration (static or automatic), scope (block or file), and linkage 2 | (internal, external, or none) of each variable and parameter in the following file: 3 | 4 | extern float a; 5 | 6 | void f(register double b) 7 | { 8 | static int c; 9 | auto char d; 10 | } 11 | 12 | a: 13 | storage duration: static. 14 | scope: file. 15 | linkage: external. 16 | 17 | b: 18 | storage duration: automatic. 19 | scope: block. 20 | linkage: None. 21 | 22 | c: 23 | storage duration: static. 24 | scope: block. 25 | linkage: none. 26 | 27 | d: 28 | storage duration: automatic. 29 | scope: block. 30 | linkage: none. 31 | -------------------------------------------------------------------------------- /ch18/Exercises/04.txt: -------------------------------------------------------------------------------- 1 | Let f be the following function. What will be the value of f(10) if f has 2 | never been called before? What will be the value of f(10) if f has been called 3 | five times previously? 4 | 5 | int f(int i) 6 | { 7 | static int j = 0; 8 | return i * j++; 9 | } 10 | 11 | Value of f(10) (Never called before): 0 12 | 13 | Value of f(10) (Called five times before): 50 14 | -------------------------------------------------------------------------------- /ch18/Exercises/08.txt: -------------------------------------------------------------------------------- 1 | Write a complete description of the type of x as specified by each of the 2 | following declarations. 3 | 4 | (a) char (*x[10])(int); 5 | x is an 6 | array with size 10 of 7 | pointers to 8 | functions with one int argument 9 | with the return type char 10 | 11 | (b) int (*x(int))[5]; 12 | x is a function 13 | with one int parameter 14 | that returns a pointer 15 | to an array with size 5 of 16 | integers. 17 | 18 | 19 | (c) float *(*x(void))(int) 20 | x is a function 21 | with no arguments 22 | that returns a pointer 23 | to a function with one int argument 24 | that returns a pointer to a float 25 | 26 | (d) void (*x(int, void *y)(int))) (int); 27 | x is a function 28 | with two arguments: int and a pointer to a function with one int argument with return type void. 29 | that returns a pointer to 30 | a function that takes one int argument 31 | with return type void 32 | -------------------------------------------------------------------------------- /ch18/Exercises/09.txt: -------------------------------------------------------------------------------- 1 | Use a series of type definitions to simply each of the declarations 2 | in Exercise 8. 3 | 4 | (a) char (*x[10])(int); 5 | 6 | typedef char Fcn(int); 7 | typedef Fcn *Fcn_ptr; 8 | typedef Fcn_ptr Fcn_ptr_array[10] 9 | Fcn_ptr_array x; 10 | 11 | (b) int (*x(int))[5]; 12 | 13 | typedef int Arr[5]; 14 | typedef Arr Fcn(int) 15 | Fcn *x; 16 | 17 | (c) float *(*x(void))(int); 18 | 19 | typedef float *Outer_Fcn(int); 20 | typedef Outer_Fcn *Inner_fcn(void); 21 | Inner_Fcn x; 22 | 23 | (d) void (*x(int, void (*y)(int)))(int); 24 | 25 | typedef void Outer_Fcn(int); 26 | typedef void *Arg_Fcn(int); 27 | typedef Outer_Fcn *Inner_fcn(int, Arg_Fcn); 28 | Outer_Fcn x; 29 | -------------------------------------------------------------------------------- /ch18/Exercises/10.txt: -------------------------------------------------------------------------------- 1 | Write declarations for the following variables and functions: 2 | 3 | (a) p is a pointer to a function with a character pointer argument that returns 4 | a character pointer. 5 | 6 | char *(*p)(char *)); 7 | 8 | (b) f is a function with two arguments: p, a pointer to a structure with tag t, 9 | and n, a long integer. f returns a pointer to a function that has no 10 | arguments and returns nothing. 11 | 12 | void *f(struct t *p, long n)(void); 13 | 14 | (c) a is an array of four pointers to functions that have no arguments and 15 | return nothing. The elements of a initially point to functions named 16 | insert, search, update, and print. 17 | 18 | void (*a[])(void) = {insert, search, update, print}; 19 | 20 | (d) b is an array of 10 pointers to functions with two int arguments that 21 | return structures with tag t. 22 | 23 | struct t (*b[10])(int, int); 24 | -------------------------------------------------------------------------------- /ch18/Exercises/11.txt: -------------------------------------------------------------------------------- 1 | In sectin 18.4, we saw that the following declarations are illegal: 2 | 3 | int f(int)[]; /* functions can't return arrays */ 4 | int g(int)(int) /* functions can't return functions */ 5 | int a[10](int); /* array elements can't be functions */ 6 | 7 | We can, however achieve similar effects by using pointers: a function can 8 | return a pionter to the first element in an array, a function can return a 9 | pointer to a function, and the elements of an array can be pointers to functions. 10 | Revise each of these declarations accordingly. 11 | 12 | 13 | int *f(int); 14 | int (*g(int))(int) 15 | int (*a[10])(int); 16 | -------------------------------------------------------------------------------- /ch18/Exercises/13.txt: -------------------------------------------------------------------------------- 1 | Which of the following declarations are legal? (Assume that PI is a macro that 2 | represents 3.14159.) 3 | 4 | (a) char c = 65; Legal. 5 | 6 | (b) static int i = 5, j = i * i; Illegal. 7 | static storage duration variables require a constant expression for 8 | initialization. 9 | 10 | (c) double d = 2 * PI; Legal. 11 | 12 | (d) double angles[] = {0, PI / 2, PI, 3 * PI / 2}; Legal. 13 | -------------------------------------------------------------------------------- /ch18/Exercises/14.txt: -------------------------------------------------------------------------------- 1 | Which kind of variables cannot be initialized? 2 | 3 | (a) Array variables. 4 | (b) Enumeration variables. 5 | (c) Structure variables. 6 | (d) Union variables. 7 | (e) None of the above. 8 | 9 | Answer: e 10 | -------------------------------------------------------------------------------- /ch18/Exercises/15.txt: -------------------------------------------------------------------------------- 1 | Which property of a variable dtermines whether or not it has a default initial value? 2 | 3 | (a) Storage duration 4 | (b) Scope 5 | (c) Linkage 6 | (d) Type 7 | 8 | Answer: a, A variable with static storage duration will have a default zero value, 9 | corresponding to the type of the variable (e.g. int will be 0, float 0.0, and 10 | pointers will be NULL.) 11 | -------------------------------------------------------------------------------- /ch19/Exercises/01/queue.h: -------------------------------------------------------------------------------- 1 | #ifndef QUEUE_H 2 | #define QUEUE_H 3 | 4 | #include 5 | 6 | typedef int Item; 7 | typedef struct queue_type *Queue; 8 | 9 | /* Appends Item i to the end of the queue */ 10 | void enqueue(Item i); 11 | 12 | /* Removes and returns Item i from the front of the queue */ 13 | Item dequeue(void); 14 | 15 | /* Returns but doesn't remove Item i from the front of the queue */ 16 | Item get_first(void); 17 | 18 | /* Returns but doesn't remove Item i from the end of the queue */ 19 | Item get_last(void); 20 | 21 | /* Returns true if the queue is empty */ 22 | bool is_empty(void); 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /ch19/Exercises/02/stack.h: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * From C PROGRAMMING: A MODERN APPROACH, Second Edition * 3 | * By K. N. King * 4 | * Copyright (c) 2008, 1996 W. W. Norton & Company, Inc. * 5 | * All rights reserved. * 6 | * This program may be freely distributed for class use, * 7 | * provided that this copyright notice is retained. * 8 | *********************************************************/ 9 | 10 | /* stack.h (Chapter 19, page 488) */ 11 | 12 | #ifndef STACK_H 13 | #define STACK_H 14 | 15 | #include /* C99 only */ 16 | 17 | void make_empty(void); 18 | bool is_empty(void); 19 | bool is_full(void); 20 | void push(int i); 21 | int pop(void); 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /ch19/Exercises/03/a/makefile: -------------------------------------------------------------------------------- 1 | queueclient: queueclient.o queue.o 2 | gcc -o queueclient.out queueclient.o queue.o 3 | 4 | queueclient.o: queueclient.c queue.h 5 | gcc -c queueclient.c 6 | 7 | queue.o: queue.c queue.h 8 | gcc -c queue.c 9 | -------------------------------------------------------------------------------- /ch19/Exercises/03/a/queue.h: -------------------------------------------------------------------------------- 1 | #ifndef QUEUE_H 2 | #define QUEUE_H 3 | 4 | #include 5 | 6 | typedef int Item; 7 | 8 | /* typedef struct queue_type *Queue; */ 9 | 10 | /* Appends Item i to the end of the queue */ 11 | void enqueue(Item i); 12 | 13 | /* Removes and returns Item i from the front of the queue */ 14 | Item dequeue(void); 15 | 16 | /* Returns but doesn't remove Item i from the front of the queue */ 17 | Item get_first(void); 18 | 19 | /* Returns but doesn't remove Item i from the end of the queue */ 20 | Item get_last(void); 21 | 22 | /* Returns the number of items currently in the queue */ 23 | int items_in_queue(void); 24 | 25 | /* Returns true if the queue is empty */ 26 | bool is_empty(void); 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /ch19/Exercises/03/a/queueclient.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "queue.h" 3 | 4 | int main(void) 5 | { 6 | enqueue(4); 7 | enqueue(5); 8 | enqueue(6); 9 | printf("dequeued: %d\n", dequeue()); 10 | printf("first in queue: %d\n", get_first()); 11 | printf("last in queue: %d\n", get_last()); 12 | printf("dequeued: %d\n", dequeue()); 13 | enqueue(63); 14 | enqueue(233); 15 | enqueue(783); 16 | printf("dequeued: %d\n", dequeue()); 17 | printf("Is empty? %d\n", is_empty()); 18 | printf("first in queue: %d\n", get_first()); 19 | printf("last in queue: %d\n", get_last()); 20 | printf("Items currently in queue: %d\n", items_in_queue()); 21 | } 22 | -------------------------------------------------------------------------------- /ch19/Exercises/03/b/makefile: -------------------------------------------------------------------------------- 1 | queueclient: queueclient.o queue.o 2 | gcc -o queueclient.out queueclient.o queue.o 3 | 4 | queueclient.o: queueclient.c queue.h 5 | gcc -c queueclient.c 6 | 7 | queue.o: queue.c queue.h 8 | gcc -c queue.c 9 | -------------------------------------------------------------------------------- /ch19/Exercises/03/b/queue.h: -------------------------------------------------------------------------------- 1 | #ifndef QUEUE_H 2 | #define QUEUE_H 3 | 4 | #include 5 | 6 | typedef int Item; 7 | 8 | /* typedef struct queue_type *Queue; */ 9 | 10 | /* Appends Item i to the end of the queue */ 11 | void enqueue(Item i); 12 | 13 | /* Removes and returns Item i from the front of the queue */ 14 | Item dequeue(void); 15 | 16 | /* Returns but doesn't remove Item i from the front of the queue */ 17 | Item get_first(void); 18 | 19 | /* Returns but doesn't remove Item i from the end of the queue */ 20 | Item get_last(void); 21 | 22 | /* Returns the number of items currently in the queue */ 23 | int items_in_queue(void); 24 | 25 | /* Returns true if the queue is empty */ 26 | bool is_empty(void); 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /ch19/Exercises/03/b/queueclient.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "queue.h" 3 | 4 | int main(void) 5 | { 6 | enqueue(4); 7 | enqueue(5); 8 | enqueue(6); 9 | printf("dequeued: %d\n", dequeue()); 10 | printf("first in queue: %d\n", get_first()); 11 | printf("last in queue: %d\n", get_last()); 12 | printf("dequeued: %d\n", dequeue()); 13 | enqueue(63); 14 | enqueue(233); 15 | enqueue(783); 16 | printf("dequeued: %d\n", dequeue()); 17 | printf("Is empty? %d\n", is_empty()); 18 | printf("first in queue: %d\n", get_first()); 19 | printf("last in queue: %d\n", get_last()); 20 | printf("Items currently in queue: %d\n", items_in_queue()); 21 | } 22 | -------------------------------------------------------------------------------- /ch19/Exercises/04/a/makefile: -------------------------------------------------------------------------------- 1 | stackclient: stackclient.o stack.o 2 | gcc -o stackclient.out stackclient.o stack.o 3 | 4 | stackclient.o: stackclient.c stack.h 5 | gcc -c stackclient.c 6 | 7 | stack.o: stack.c stack.h 8 | gcc -c stack.c 9 | -------------------------------------------------------------------------------- /ch19/Exercises/04/a/stack.h: -------------------------------------------------------------------------------- 1 | #ifndef STACK_H 2 | #define STACK_H 3 | 4 | typedef struct stack_type *Stack; 5 | typedef int Item; 6 | 7 | Stack create(void); 8 | void destroy(Stack s); 9 | void make_empty(Stack s); 10 | bool is_empty(const Stack s); 11 | bool is_full(const Stack s); 12 | void push(Stack s, Item i); 13 | Item pop(Stack s); 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /ch19/Exercises/04/a/stackclient.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "stack.h" 4 | 5 | int main(void) 6 | { 7 | Stack s1 = create(); 8 | Stack s2 = create(); 9 | push(s1, 39); 10 | push(s2, 83); 11 | printf("%d\n", pop(s1)); 12 | printf("%d\n", pop(s2)); 13 | destroy(s1); 14 | destroy(s2); 15 | } 16 | -------------------------------------------------------------------------------- /ch19/Exercises/04/b/makefile: -------------------------------------------------------------------------------- 1 | stackclient: stackclient.o stack.o 2 | gcc -o stackclient.out stackclient.o stack.o 3 | 4 | stackclient.o: stackclient.c stack.h 5 | gcc -c stackclient.c 6 | 7 | stack.o: stack.c stack.h 8 | gcc -c stack.c 9 | -------------------------------------------------------------------------------- /ch19/Exercises/04/b/stack.h: -------------------------------------------------------------------------------- 1 | #ifndef STACK_H 2 | #define STACK_H 3 | 4 | typedef struct stack_type *Stack; 5 | typedef int Item; 6 | 7 | Stack create(); 8 | void destroy(Stack s); 9 | void make_empty(Stack s); 10 | bool is_empty(const Stack s); 11 | bool is_full(const Stack s); 12 | void push(Stack s, Item i); 13 | Item pop(Stack s); 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /ch19/Exercises/04/b/stackclient.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "stack.h" 4 | 5 | int main(void) 6 | { 7 | Stack s1 = create(); 8 | Stack s2 = create(); 9 | push(s1, 39); 10 | push(s2, 83); 11 | push(s2, 344); 12 | push(s2, 78); 13 | printf("%d\n", pop(s1)); 14 | printf("%d\n", pop(s2)); 15 | printf("%d\n", pop(s2)); 16 | printf("%d\n", pop(s2)); 17 | destroy(s1); 18 | destroy(s2); 19 | } 20 | -------------------------------------------------------------------------------- /ch19/Exercises/05/queue.h: -------------------------------------------------------------------------------- 1 | #ifndef QUEUE_H 2 | #define QUEUE_H 3 | 4 | #include 5 | 6 | #define MAX 100 7 | 8 | typedef struct queue_type { 9 | Item contents[MAX]; 10 | int idx_first_item; 11 | int idx_new_item; 12 | int num_items; 13 | } *Queue; 14 | 15 | /* Appends Item i to the end of the Queue q */ 16 | void enqueue(Queue q, Item i); 17 | 18 | /* Removes and returns Item i from the front of the Queue q */ 19 | Item dequeue(Queue q); 20 | 21 | /* Returns but doesn't remove Item i from the front of the Queue q */ 22 | Item get_first(Queue q); 23 | 24 | /* Returns but doesn't remove Item i from the end of the Queue q */ 25 | Item get_last(Queue q); 26 | 27 | /* Returns true if the Queue q is empty */ 28 | bool is_empty(Queue q); 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /ch19/Projects/01/makefile: -------------------------------------------------------------------------------- 1 | stackclient: stackclient.o stack.o 2 | gcc -o stackclient.out stackclient.o stack.o 3 | 4 | stackclient.o: stackclient.c stack.h 5 | gcc -c stackclient.c 6 | 7 | stack.o: stack.c stack.h 8 | gcc -c stack.c 9 | -------------------------------------------------------------------------------- /ch19/Projects/01/stack.h: -------------------------------------------------------------------------------- 1 | #ifndef STACK_H 2 | #define STACK_H 3 | 4 | typedef struct stack_type *Stack; 5 | typedef int Item; 6 | 7 | Stack create(); 8 | void destroy(Stack s); 9 | void make_empty(Stack s); 10 | bool is_empty(const Stack s); 11 | bool is_full(const Stack s); 12 | void push(Stack s, Item i); 13 | Item pop(Stack s); 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /ch19/Projects/01/stackclient.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "stack.h" 4 | 5 | int main(void) 6 | { 7 | Stack s = create(); 8 | char ch; 9 | 10 | printf("Enter parentheses and/or braces: "); 11 | while ((ch = getchar()) != '\n') 12 | { 13 | if (ch == '{' || ch == '(') 14 | { 15 | push(s, ch); 16 | } 17 | else if (ch == '}' && pop(s) != '{') 18 | { 19 | printf("Parentheses not nested properly."); 20 | break; 21 | } 22 | else if (ch == ')' && pop(s) != '(') 23 | { 24 | printf("Parentheses not nested properly."); 25 | break; 26 | } 27 | } 28 | 29 | if (is_empty(s)) 30 | printf("All parentheses and braces are matched"); 31 | else 32 | printf("Parentheses and braces are not matched"); 33 | 34 | destroy(s); 35 | 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /ch19/Projects/02/makefile: -------------------------------------------------------------------------------- 1 | stackclient: stackclient.o stack.o 2 | gcc -o stackclient.out stackclient.o stack.o 3 | 4 | stackclient.o: stackclient.c stack.h 5 | gcc -c stackclient.c 6 | 7 | stack.o: stack.c stack.h 8 | gcc -c stack.c 9 | -------------------------------------------------------------------------------- /ch19/Projects/02/stack.h: -------------------------------------------------------------------------------- 1 | #ifndef STACK_H 2 | #define STACK_H 3 | 4 | typedef struct stack_type *Stack; 5 | typedef int Item; 6 | 7 | Stack create(); 8 | void destroy(Stack s); 9 | void make_empty(Stack s); 10 | bool is_empty(const Stack s); 11 | bool is_full(const Stack s); 12 | void push(Stack s, Item i); 13 | Item pop(Stack s); 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /ch19/Projects/03/makefile: -------------------------------------------------------------------------------- 1 | stackclient: stackclient.o stackADT3.o 2 | gcc -o stackclient.out stackclient.o stackADT3.o 3 | 4 | stackclient.o: stackclient.c stackADT.h 5 | gcc -c stackclient.c 6 | 7 | stackADT3.o: stackADT3.c stackADT.h 8 | gcc -c stackADT3.c 9 | -------------------------------------------------------------------------------- /ch19/Projects/04/makefile: -------------------------------------------------------------------------------- 1 | stackclient: stackclient.o stackADT3.o 2 | gcc -o stackclient.out stackclient.o stackADT3.o 3 | 4 | stackclient.o: stackclient.c stackADT.h 5 | gcc -c stackclient.c 6 | 7 | stackADT3.o: stackADT3.c stackADT.h 8 | gcc -c stackADT3.c 9 | -------------------------------------------------------------------------------- /ch19/Projects/05/makefile: -------------------------------------------------------------------------------- 1 | queueclient: queueclient.o queueADT.o 2 | gcc -o queueclient.out queueclient.o queueADT.o 3 | 4 | queueclient.o: queueclient.c queue.h 5 | gcc -c queueclient.c 6 | 7 | queueADT.o: queueADT.c queue.h 8 | gcc -c queueADT.c 9 | -------------------------------------------------------------------------------- /ch19/Projects/05/queue.h: -------------------------------------------------------------------------------- 1 | #ifndef QUEUE_H 2 | #define QUEUE_H 3 | 4 | #include 5 | 6 | typedef int Item; 7 | typedef struct queue_type *Queue; 8 | 9 | /* Creates and returns a Queue */ 10 | Queue create(void); 11 | 12 | /* Destroys the Queue q */ 13 | void destroy(Queue q); 14 | 15 | /* Appends Item i to the end of the Queue q */ 16 | void enqueue(Queue q, Item i); 17 | 18 | /* Removes and returns Item i from the front of the Queue q */ 19 | Item dequeue(Queue q); 20 | 21 | /* Returns but doesn't remove Item i from the front of the Queue q */ 22 | Item peek_front(Queue q); 23 | 24 | /* Returns but doesn't remove Item i from the end of the Queue q */ 25 | Item peek_end(Queue q); 26 | 27 | /* Returns true if the Queue q is empty */ 28 | bool is_empty(Queue q); 29 | 30 | /* Returns true if the Queue q is full */ 31 | bool is_full(Queue q); 32 | 33 | /* Removes all items from Queue q */ 34 | void empty_queue(Queue q); 35 | 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /ch19/Projects/05/queueclient.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "queue.h" 3 | 4 | int main(void) 5 | { 6 | Queue q1 = create(); 7 | Queue q2 = create(); 8 | 9 | enqueue(q1, 10); 10 | enqueue(q1, 39); 11 | enqueue(q1, 83); 12 | printf("peek at front of q1: %d\n", peek_front(q1)); 13 | printf("peek at end of q1: %d\n", peek_end(q1)); 14 | printf("Is q1 full? %s\n", is_full(q1) ? "Yes" : "No"); 15 | printf("Is q1 empty? %s\n", is_empty(q1) ? "Yes" : "No"); 16 | printf("Is q2 empty? %s\n", is_empty(q2) ? "Yes" : "No"); 17 | 18 | enqueue(q2, 74); 19 | enqueue(q2, 8); 20 | printf("dequeued %d from q1\n", dequeue(q1)); 21 | printf("dequeued %d from q2\n", dequeue(q2)); 22 | 23 | empty_queue(q1); 24 | printf("Is q1 empty? %s\n", is_empty(q1) ? "Yes" : "No"); 25 | 26 | destroy(q1); 27 | destroy(q2); 28 | 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /ch19/Projects/06/makefile: -------------------------------------------------------------------------------- 1 | queueclient: queueclient.o queueADT.o 2 | gcc -o queueclient.out queueclient.o queueADT.o 3 | 4 | queueclient.o: queueclient.c queue.h 5 | gcc -c queueclient.c 6 | 7 | queueADT.o: queueADT.c queue.h 8 | gcc -c queueADT.c 9 | -------------------------------------------------------------------------------- /ch19/Projects/06/queue.h: -------------------------------------------------------------------------------- 1 | #ifndef QUEUE_H 2 | #define QUEUE_H 3 | 4 | #include 5 | 6 | typedef int Item; 7 | typedef struct queue_type *Queue; 8 | 9 | /* Creates and returns a Queue of size n */ 10 | Queue create(int n); 11 | 12 | /* Destroys the Queue q */ 13 | void destroy(Queue q); 14 | 15 | /* Appends Item i to the end of the Queue q */ 16 | void enqueue(Queue q, Item i); 17 | 18 | /* Removes and returns Item i from the front of the Queue q */ 19 | Item dequeue(Queue q); 20 | 21 | /* Returns but doesn't remove Item i from the front of the Queue q */ 22 | Item peek_front(Queue q); 23 | 24 | /* Returns but doesn't remove Item i from the end of the Queue q */ 25 | Item peek_end(Queue q); 26 | 27 | /* Returns true if the Queue q is empty */ 28 | bool is_empty(Queue q); 29 | 30 | /* Returns true if the Queue q is full */ 31 | bool is_full(Queue q); 32 | 33 | /* Removes all items from Queue q */ 34 | void empty_queue(Queue q); 35 | 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /ch19/Projects/06/queueclient.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "queue.h" 3 | 4 | int main(void) 5 | { 6 | Queue q1 = create(5); 7 | Queue q2 = create(10); 8 | 9 | enqueue(q1, 10); 10 | enqueue(q1, 39); 11 | enqueue(q1, 83); 12 | printf("peek at front of q1: %d\n", peek_front(q1)); 13 | printf("peek at end of q1: %d\n", peek_end(q1)); 14 | printf("Is q1 full? %s\n", is_full(q1) ? "Yes" : "No"); 15 | printf("Is q1 empty? %s\n", is_empty(q1) ? "Yes" : "No"); 16 | printf("Is q2 empty? %s\n", is_empty(q2) ? "Yes" : "No"); 17 | 18 | enqueue(q2, 74); 19 | enqueue(q2, 8); 20 | printf("dequeued %d from q1\n", dequeue(q1)); 21 | printf("dequeued %d from q2\n", dequeue(q2)); 22 | 23 | empty_queue(q1); 24 | printf("Is q1 empty? %s\n", is_empty(q1) ? "Yes" : "No"); 25 | 26 | destroy(q1); 27 | destroy(q2); 28 | 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /ch19/Projects/07/makefile: -------------------------------------------------------------------------------- 1 | queueclient: queueclient.o queueADT.o 2 | gcc -o queueclient.out queueclient.o queueADT.o 3 | 4 | queueclient.o: queueclient.c queue.h 5 | gcc -c queueclient.c 6 | 7 | queueADT.o: queueADT.c queue.h 8 | gcc -c queueADT.c 9 | -------------------------------------------------------------------------------- /ch19/Projects/07/queue.h: -------------------------------------------------------------------------------- 1 | #ifndef QUEUE_H 2 | #define QUEUE_H 3 | 4 | #include 5 | 6 | typedef int Item; 7 | typedef struct queue_type *Queue; 8 | 9 | /* Creates and returns a Queue */ 10 | Queue create(void); 11 | 12 | /* Destroys the Queue q */ 13 | void destroy(Queue q); 14 | 15 | /* Appends Item i to the end of the Queue q */ 16 | void enqueue(Queue q, Item i); 17 | 18 | /* Removes and returns Item i from the front of the Queue q */ 19 | Item dequeue(Queue q); 20 | 21 | /* Returns but doesn't remove Item i from the front of the Queue q */ 22 | Item peek_front(Queue q); 23 | 24 | /* Returns but doesn't remove Item i from the end of the Queue q */ 25 | Item peek_end(Queue q); 26 | 27 | /* Returns true if the Queue q is empty */ 28 | bool is_empty(Queue q); 29 | 30 | /* Returns true if the Queue q is full */ 31 | bool is_full(Queue q); 32 | 33 | /* Removes all items from Queue q */ 34 | void empty_queue(Queue q); 35 | 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /ch19/Projects/07/queueclient.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "queue.h" 3 | 4 | int main(void) 5 | { 6 | Queue q1 = create(); 7 | Queue q2 = create(); 8 | 9 | enqueue(q1, 10); 10 | enqueue(q1, 39); 11 | enqueue(q1, 83); 12 | printf("peek at front of q1: %d\n", peek_front(q1)); 13 | printf("peek at end of q1: %d\n", peek_end(q1)); 14 | printf("Is q1 full? %s\n", is_full(q1) ? "Yes" : "No"); 15 | printf("Is q1 empty? %s\n", is_empty(q1) ? "Yes" : "No"); 16 | printf("Is q2 empty? %s\n", is_empty(q2) ? "Yes" : "No"); 17 | 18 | enqueue(q2, 74); 19 | enqueue(q2, 8); 20 | printf("dequeued %d from q1\n", dequeue(q1)); 21 | printf("dequeued %d from q2\n", dequeue(q2)); 22 | 23 | empty_queue(q1); 24 | printf("Is q1 empty? %s\n", is_empty(q1) ? "Yes" : "No"); 25 | 26 | destroy(q1); 27 | destroy(q2); 28 | 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /ch20/Exercises/03.txt: -------------------------------------------------------------------------------- 1 | Explain what effect the following macro has on its arguments. You may assume 2 | that the arguments have the same type. 3 | 4 | #define M(x,y) ((x)^=(y), (y)^=(x), (x)^=(y)) 5 | This macro swaps two values stored in x and y in place (without using a third variable). 6 | 7 | For instance lets say we have two variables x and y with the following values: 8 | x = 23 (decimal), 10111 (binary) 9 | y = 12 (decimal), 01100 (binary) 10 | 11 | 12 | x = x ^ y: 13 | 10111 14 | ^ 15 | 01100 16 | = 17 | 11011, x is now 11011 (27 in decimal) 18 | 19 | 20 | y = y ^ x: 21 | 01100 22 | ^ 23 | 11011 24 | = 25 | 10111, y is now 10111 (23 in decimal) 26 | 27 | 28 | x = x ^ y: 29 | 11011 30 | ^ 31 | 10111 32 | = 33 | 01100, x is now 01100 (12 in decimal) 34 | 35 | x is now 12 36 | y is now 23 37 | -------------------------------------------------------------------------------- /ch20/Exercises/06.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | unsigned short swap_bytes(unsigned short i); 5 | unsigned short swap_bytes_condensed(unsigned short i); 6 | 7 | int main(void) 8 | { 9 | unsigned short value; 10 | printf("Enter a hexadecimal number (up to four digits): "); 11 | scanf("%4hx", &value); 12 | /* printf("Number with bytes swapped: %hx\n", swap_bytes(value)); */ 13 | printf("Number with bytes swapped: %hx\n", swap_bytes_condensed(value)); 14 | } 15 | 16 | unsigned short swap_bytes(unsigned short i) 17 | { 18 | unsigned short b0_in_b1_place = i << 8; 19 | unsigned short b1_in_b0_place = i >> 8; 20 | 21 | return b0_in_b1_place | b1_in_b0_place; 22 | } 23 | 24 | unsigned short swap_bytes_condensed(unsigned short i) 25 | { 26 | return (i << 8) | (i >> 8); 27 | } 28 | -------------------------------------------------------------------------------- /ch20/Exercises/11.txt: -------------------------------------------------------------------------------- 1 | Each fo the following macros defines the position of a single bit within 2 | and integer: 3 | 4 | #define SHIFT_BIT 1 5 | #define CTRL_BIT 2 6 | #define ALT_BIT 4 7 | 8 | The following statement is supposed to test whether any of the three bits have 9 | been set, but it never displays the specified message. Explain why the statement 10 | doesn't work and show how to fix it. Assume that key_code is an int variable. 11 | 12 | if (key_code & (SHIFT_BIT | CTRL_BIT | ALT_BIT) == 0) 13 | printf("No modifier keys pressed\n"); 14 | 15 | This statement doesn't work because of operator precedence, as the equality 16 | operator has higher precedence than bitwise and, we need to use parentheses as 17 | follows: 18 | 19 | if ((key_code & (SHIFT_BIT | CTRL_BIT | ALT_BIT)) == 0) 20 | printf("No modifier keys pressed\n"); 21 | 22 | This ensures that we & the two ints first and then compare the result to 0. 23 | -------------------------------------------------------------------------------- /ch20/Exercises/12.txt: -------------------------------------------------------------------------------- 1 | The following function supposedly combines two bytes to form an unsigned 2 | short integer. Explain why the function doesn't work and show how to fix it. 3 | 4 | unsigned short create_short(unsigned char high_byte, unsighed char low_byte) 5 | { 6 | return high_byte << 8 + low_byte; 7 | } 8 | 9 | Again, the problem with this function is caused by operator precedence, The 10 | addition operator has a higher precedence than the bitwise left shift operator, 11 | so we must enclose the bitwise left shift operation in parentheses: 12 | 13 | return (high_byte << 8) + low_byte; 14 | -------------------------------------------------------------------------------- /ch20/Exercises/13.txt: -------------------------------------------------------------------------------- 1 | If n is an unsigned int variable, what effect does the following statement 2 | have on the bits in n? 3 | 4 | n &= n - 1; 5 | 6 | This statement will remove the least significant 1 bit from n. 7 | 8 | E.g (Assuming rightmost bit is least significant): 9 | if n is 10110, then after this statement it would be 10100 because: 10 | 10110 11 | & 12 | 10101 13 | = 14 | 10100 15 | 16 | This is an efficient way of counting the number of 1 bits in a number should it 17 | be used in a loop that terminates when n is 0. The number of iterations will be 18 | dependent on the number of 1 bits, rather than the total number of bits. 19 | -------------------------------------------------------------------------------- /ch20/Exercises/14.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | struct float_value { 6 | unsigned int fraction: 23; /* ordering using gcc */ 7 | unsigned int exponent: 8; 8 | unsigned int sign: 1; 9 | }; 10 | 11 | int main(void) 12 | { 13 | struct float_value fv; 14 | 15 | fv.sign = 1; 16 | fv.exponent = pow(2, 8) - 1; 17 | fv.fraction = pow(2, 23) - 1; 18 | 19 | printf("%zu\n", sizeof(struct float_value)); 20 | printf("%x\n", fv.sign); 21 | printf("%x\n", fv.exponent); 22 | printf("%x\n", fv.fraction); 23 | } 24 | -------------------------------------------------------------------------------- /ch20/Exercises/15.txt: -------------------------------------------------------------------------------- 1 | (a) Assume that the variable s has been declared as follows: 2 | 3 | struct { 4 | int flag: 1; 5 | } s; 6 | 7 | With some compilers, executing the following statements causes 1 to be displayed, 8 | but with other compilers, the output is -1. Explain the reason for this 9 | behavior. 10 | 11 | s.flag = 1; 12 | printf("%d\n", s.flag); 13 | 14 | This happens because the usage of int is ambigious in the case of a bit field 15 | structure, because the storage of bits in a bit field is implemenation defined. 16 | In the case of int, a compiler may treat the high-order bit as a sign bit. 17 | 18 | (b) How can this problem be avoided? 19 | To prevent the ambiguity caused by declaring a bit-field structure member 20 | as int, all that needs to be done is to provide it with the type specifier signed or 21 | unsigned depending on whether you want to high-order bit to be a signed-bit 22 | or not. 23 | -------------------------------------------------------------------------------- /ch20/Projects/01.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | union { 4 | float value; 5 | struct float_value { 6 | unsigned int fraction: 23; 7 | unsigned int exponent: 8; 8 | unsigned int sign: 1; 9 | } m; 10 | } f; 11 | 12 | int main(void) 13 | { 14 | f.m.sign = 1; 15 | f.m.exponent = 128; 16 | f.m.fraction = 0; 17 | 18 | printf("%.1f\n", f.value); 19 | } 20 | -------------------------------------------------------------------------------- /ch21/Exercises/02.txt: -------------------------------------------------------------------------------- 1 | Find a standard header in which a macro hides a function. 2 | 3 | The assert.h standard header contains a macro hiding the assert function: 4 | 5 | # define assert(expr) \ 6 | ((expr) \ 7 | ? __ASSERT_VOID_CAST (0) \ 8 | : __assert_fail (__STRING(expr), __FILE__, __LINE__, __ASSERT_FUNCTION)) 9 | 10 | 11 | /* The following is not at all used here but needed for standard 12 | compliance. */ 13 | extern void __assert (const char *__assertion, const char *__file, int __line) 14 | __THROW __attribute__ ((__noreturn__)); 15 | -------------------------------------------------------------------------------- /ch21/Exercises/03.txt: -------------------------------------------------------------------------------- 1 | When a macro hides a function, which must come first in the header file: the 2 | macro definition or the function prototype? 3 | 4 | When a macro definition hides a function, the preprocessor must have some 5 | prior knowledge that there is a function with a matching name, therefore its 6 | prototype must appear before the macro definition whether in the same file 7 | or another file that is included before the macro definition. 8 | 9 | This also prevents another issue which may occur if a macro were defined 10 | before a function with the same name. Would the preprocessor treat the 11 | function identifier as a macro being used? and thus replace the function 12 | identifier with the replacement list of the macro. 13 | -------------------------------------------------------------------------------- /ch21/Exercises/07.txt: -------------------------------------------------------------------------------- 1 | In which standard header would you expect to find each of the following? 2 | 3 | (a) A function that determines the current day of the week. 4 | time.h 5 | 6 | (b) A function that tests whether a character is a digit. 7 | ctype.h 8 | 9 | (c) A macro that gives the largest unsigned int value. 10 | limits.h 11 | 12 | (d) A function that rounds a floating-point number to the next higher integer. 13 | math.h 14 | 15 | (e) A macro that specifies the number of bits in a character. 16 | limits.h 17 | 18 | (f) A macro that specifies the number of significant digits in a double value. 19 | float.h 20 | 21 | (g) A function that searches a string for a particular character. 22 | string.h 23 | 24 | (h) A function that opens a file for reading. 25 | stdio.h 26 | -------------------------------------------------------------------------------- /ch21/Projects/01.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct s { 5 | char a; 6 | int b[2]; 7 | float c; 8 | }; 9 | 10 | int main(void) 11 | { 12 | printf("%ld\n", offsetof(struct s, a)); 13 | printf("%ld\n", offsetof(struct s, b[0])); 14 | printf("%ld\n", offsetof(struct s, b[1])); 15 | printf("%ld\n", offsetof(struct s, c)); 16 | 17 | /* List of "holes": 18 | * 3 byte hole after member a (offset of b[0] is 4) 19 | * No other holes present in struct s 20 | */ 21 | } 22 | -------------------------------------------------------------------------------- /ch22/Exercises/01.txt: -------------------------------------------------------------------------------- 1 | Indicate whether each of the following files is more likely to contain text data 2 | or binary data: 3 | 4 | (a) A file of object code produced by a C compiler. 5 | Binary data. 6 | 7 | (b) A program listing produced by a C compiler. 8 | Text data. 9 | 10 | (c) An email message sent from one computer to another 11 | Text data. 12 | 13 | (d) A file containing a graphics image. 14 | Binary data. 15 | -------------------------------------------------------------------------------- /ch22/Exercises/02.txt: -------------------------------------------------------------------------------- 1 | Indicat which mode string is most likely to be passed to fopen in each of the 2 | following situations: 3 | 4 | (a) A database management system opens a file containing records to be updated. 5 | Most likely binary data, needs read and write permissions and to insert data. 6 | r+b 7 | 8 | 9 | (b) A mail program opens a file of saved messages so that it can add additional 10 | messages to the end. 11 | Most likely text data, needs write permissions and to append data. 12 | a 13 | 14 | (c) A graphics program opens a file containing a picture to be displayed on the 15 | screen 16 | Most likely binary data, needs read permissions. 17 | rb 18 | 19 | (d) An operating system command interpreter opens a "shell script" (or "batch 20 | file") containing commands to be executed. 21 | Most likely text data, needs read permissions. 22 | r 23 | -------------------------------------------------------------------------------- /ch22/Exercises/03.txt: -------------------------------------------------------------------------------- 1 | Find the error in the following program fragment and show how to fix it. 2 | 3 | FILE *fp; 4 | 5 | if (fp = fopen(filename, "r")) { 6 | //read characters until end-of-file 7 | } 8 | fclose(fp); 9 | 10 | 11 | The error is that the program fragment always attempts to close the file 12 | pointed to by fp, however if fopen failed then fp would be a null pointer. 13 | Attempting to call fclose on a null pointer is an error. 14 | 15 | Fixed version: 16 | 17 | FILE *fp 18 | 19 | if (fp = fopen(filename, "r")) { 20 | //read characters until end-of-file; 21 | } 22 | else { 23 | printf("Error, cannot open file: %s\n", filename); 24 | exit(EXIT_FAILURE); 25 | } 26 | fclose(fp); 27 | -------------------------------------------------------------------------------- /ch22/Exercises/04.txt: -------------------------------------------------------------------------------- 1 | Show how each of the following numbers will look if displayed by printf with 2 | %#012.5g as the conversion specification: 3 | 4 | # = flag (octal numbers begin with 0, nonzero hex with 0x or 0X, floating point 5 | always have decimal point, trailing zeros aren't removed from numbers printed 6 | using g or G. 7 | 8 | 0 = flag (Numbers are padded with leading zeros up to the field width.) 9 | 12 = min field width 10 | .5 = precision 11 | g = conversion specifier (double to f or e). e if exp < -4 or >= precision (5) 12 | 13 | (a) 83.7361 Exponent = 1 (f specifier) 14 | 00000083.736 15 | 16 | 17 | (b) 29748.6607 Exponent = 4 (f specifier) 18 | 00000029749. 19 | 20 | 21 | (c) 1054932234.0 Exponent = 9 (e specifier) 22 | 001.0549e+09 23 | 24 | 25 | (d) 0.0000235218 Exponent = -5 (e specifier) 26 | 002.3522e-05 27 | -------------------------------------------------------------------------------- /ch22/Exercises/05.txt: -------------------------------------------------------------------------------- 1 | Is there any difference between the printf conversion specifications %.4d and 2 | %04d? If so, explain what it is. 3 | 4 | These expressions are equivalent. 5 | 6 | As the conversion specifier is d, we must be dealing with an int value. 7 | The first expression '%.4d' contains the precision '.4'. 8 | When the precision modifier is applied to an int value, it signifies the minimum 9 | number of digits that must be printed (leading zeros added if the number has 10 | fewer digits). 11 | 12 | The second expression '%04d' contains the flag 0 (zero) which means that leading 13 | zeros are padded up to the field width. As the field width is 4, this means 14 | that any integers with 3 digits or fewer will have leading zeros added. 15 | -------------------------------------------------------------------------------- /ch22/Exercises/06.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | int widget = 3; 6 | 7 | printf("%d widget%s\n", widget, widget != 1 ? "s" : ""); 8 | widget = 1; 9 | printf("%d widget%s\n", widget, widget != 1 ? "s" : ""); 10 | } 11 | -------------------------------------------------------------------------------- /ch22/Exercises/07.txt: -------------------------------------------------------------------------------- 1 | Suppose that we call scanf as follows: 2 | 3 | n = scanf("%d%f%d", &i, &x, &j); 4 | 5 | (i, j, and n are int variables and x is a float variable.) Assuming that the 6 | input stream contains the characters shown, give the values of i, j, n, and x 7 | after the call. In addition, indicate which characters were consumed by the call. 8 | 9 | (a) 10•20•30▫ 10 | i = 10, j = 30, n = 3, x = 20.0 11 | 12 | (b) 1.0•2.0•3.0▫ 13 | i = 1, j = 2, n = 3, x = 0.0 14 | 15 | (c) 0.1•0.2•0.3▫ 16 | i = 0, j = 0, n = 3, x = 0.1 17 | 18 | (d) .1•.2•.3▫ 19 | i = undefined (not set), j = undefined (not set), n = 0, x = undefined (not set) 20 | -------------------------------------------------------------------------------- /ch22/Exercises/08.txt: -------------------------------------------------------------------------------- 1 | In previous chapters, we've used the scanf format string " %c" when we wanted to 2 | skip white-space characters and read a nonblank character. Some programmers use 3 | "%1s" instead. Are the two techniques equivalent? If not, what are the 4 | differences? 5 | 6 | They are similar but not identical. The difference being that a null character 7 | will be inserted at the end of the char array when %s is used (as strings are 8 | null terminated). 9 | -------------------------------------------------------------------------------- /ch22/Exercises/09.txt: -------------------------------------------------------------------------------- 1 | Which one of the following calls is not a valid way of reading one character 2 | from the standard input stream? 3 | 4 | (a) getch() 5 | (b) getchar() 6 | (c) getc(stdin) 7 | (d) fgetc(stdin) 8 | 9 | Answer: a 10 | getch() behaves differently than the other three because it doesn't read 11 | from a buffer (so it doesn't read from the stdin input stream), getch() instead 12 | waits for a character to be input when it is called, and then immediately 13 | returns the input character without the user pressing the Enter key. 14 | -------------------------------------------------------------------------------- /ch22/Exercises/12.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int count_periods(const char *filename) 4 | { 5 | FILE *fp; 6 | int n = 0; 7 | int ch; 8 | if ((fp = fopen(filename, "r")) != NULL) { 9 | while ((ch = fgetc(fp)) != EOF) 10 | if (ch == '.') 11 | n++; 12 | fclose(fp); 13 | } 14 | return n; 15 | } 16 | 17 | int main(void) { 18 | printf("periods: %d\n", count_periods("testperiods")); 19 | } 20 | -------------------------------------------------------------------------------- /ch22/Exercises/15.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define RECORD_BYTES 64L 4 | 5 | int main(void) 6 | { 7 | FILE *fp; 8 | long int n = 30; 9 | 10 | /* Part (a) Move to beginning of Record n */ 11 | fseek(fp, n * RECORD_BYTES, SEEK_SET); 12 | 13 | /* Part (b) Move to beginning of last Record */ 14 | fseek(fp, -RECORD_BYTES, SEEK_END); 15 | 16 | /* Part (c) Move to beginning of next record */ 17 | fseek(fp, RECORD_BYTES, SEEK_CUR); 18 | 19 | /* Part (d) Move to beginning of Record that's two Records back */ 20 | fseek(fp, 2 * (-RECORD_BYTES), SEEK_CUR); 21 | 22 | fclose(fp); 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /ch22/Exercises/16.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | char str[] = "$%###1,162,620*$!234"; 6 | /* char str[] = "#989"; */ 7 | char sales_rank[sizeof(str)]; 8 | 9 | sscanf(str, 10 | str[0] == '#' ? "%*[#]%[0123456789,]" : "%*[^#]%*[#]%[0123456789,]", 11 | sales_rank); 12 | 13 | printf("%s\n", sales_rank); 14 | 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /ch22/Projects/02.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main(int argc, char *argv[]) 6 | { 7 | FILE *fp; 8 | 9 | if (argc != 2) { 10 | printf("Usage: programname filename\n"); 11 | exit(EXIT_FAILURE); 12 | } 13 | 14 | if ((fp = fopen(argv[1], "r")) == NULL) { 15 | printf("%s can't be opened.\n", argv[1]); 16 | exit(EXIT_FAILURE); 17 | } 18 | 19 | int ch; 20 | while ((ch = getc(fp)) != EOF) { 21 | putchar(toupper(ch)); 22 | } 23 | fclose(fp); 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /ch22/Projects/03.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(int argc, char *argv[]) 5 | { 6 | FILE *fp; 7 | int ch; 8 | 9 | if (argc < 2) { 10 | printf("Usage: programname filename(s).\n"); 11 | exit(EXIT_FAILURE); 12 | } 13 | 14 | for (int i = 1; i < argc; ++i) { 15 | if ((fp = fopen(argv[i], "r")) == NULL) { 16 | printf("Error, cannot open file: %s\n", argv[i]); 17 | exit(EXIT_FAILURE); 18 | } 19 | else { 20 | while ((ch = getc(fp)) != EOF) { 21 | putchar(ch); 22 | } 23 | fclose(fp); 24 | } 25 | } 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /ch22/Projects/08/inventory.h: -------------------------------------------------------------------------------- 1 | #ifndef INVENTORY_H 2 | #define INVENTORY_H 3 | 4 | #define NAME_LEN 25 5 | #define MAX_PARTS 100 6 | 7 | struct part { 8 | int number; 9 | char name[NAME_LEN+1]; 10 | int on_hand; 11 | } inventory[MAX_PARTS]; 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /ch22/Projects/08/makefile: -------------------------------------------------------------------------------- 1 | inventory: inventory.o readline.o 2 | gcc -o inventory.out inventory.o readline.o 3 | 4 | inventory.o: inventory.c inventory.h readline.h 5 | gcc -c inventory.c 6 | 7 | readline.o: readline.c readline.h 8 | gcc -c readline.c 9 | -------------------------------------------------------------------------------- /ch22/Projects/08/readline.c: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * From C PROGRAMMING: A MODERN APPROACH, Second Edition * 3 | * By K. N. King * 4 | * Copyright (c) 2008, 1996 W. W. Norton & Company, Inc. * 5 | * All rights reserved. * 6 | * This program may be freely distributed for class use, * 7 | * provided that this copyright notice is retained. * 8 | *********************************************************/ 9 | 10 | /* readline.c (Chapter 16, page 395) */ 11 | 12 | #include 13 | #include 14 | #include "readline.h" 15 | 16 | int read_line(char str[], int n) 17 | { 18 | int ch, i = 0; 19 | 20 | while (isspace(ch = getchar())) 21 | ; 22 | while (ch != '\n' && ch != EOF) { 23 | if (i < n) 24 | str[i++] = ch; 25 | ch = getchar(); 26 | } 27 | str[i] = '\0'; 28 | return i; 29 | } 30 | -------------------------------------------------------------------------------- /ch22/Projects/09/dump1: -------------------------------------------------------------------------------- 1 | Hammer DrillNails 2 | SpannerWrenchScrewdriverShovel -------------------------------------------------------------------------------- /ch22/Projects/09/dump2: -------------------------------------------------------------------------------- 1 | Lawnmower Rake SawLight bulb #Paint6Torchlight -------------------------------------------------------------------------------- /ch22/Projects/09/dumpmerge: -------------------------------------------------------------------------------- 1 | Hammer DrillNails 2 | Spanner Rake WrenchScrewdriverSawShovelLight bulb #Paint6Torchlight -------------------------------------------------------------------------------- /ch22/Projects/09/inventory.h: -------------------------------------------------------------------------------- 1 | #ifndef INVENTORY_H 2 | #define INVENTORY_H 3 | 4 | #define NAME_LEN 25 5 | #define MAX_PARTS 100 6 | 7 | struct part { 8 | int number; 9 | char name[NAME_LEN+1]; 10 | int on_hand; 11 | } inventory[MAX_PARTS]; 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /ch22/Projects/09/makefile: -------------------------------------------------------------------------------- 1 | mergepartfiles: mergepartfiles.o 2 | gcc -std=c99 -o mergepartfiles.out mergepartfiles.o 3 | 4 | mergepartfiles.o: mergepartfiles.c inventory.h 5 | gcc -std=c99 -c mergepartfiles.c 6 | -------------------------------------------------------------------------------- /ch22/Projects/10/inventory.h: -------------------------------------------------------------------------------- 1 | #ifndef INVENTORY_H 2 | #define INVENTORY_H 3 | 4 | #define NAME_LEN 25 5 | #define MAX_PARTS 100 6 | 7 | struct part { 8 | int number; 9 | char name[NAME_LEN+1]; 10 | int on_hand; 11 | } inventory[MAX_PARTS]; 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /ch22/Projects/10/makefile: -------------------------------------------------------------------------------- 1 | inventory2: inventory2.o readline.o 2 | gcc -o inventory2.out inventory2.o readline.o 3 | 4 | inventory2.o: inventory2.c inventory.h readline.h 5 | gcc -c inventory2.c 6 | 7 | readline.o: readline.c readline.h 8 | gcc -c readline.c 9 | -------------------------------------------------------------------------------- /ch22/Projects/10/readline.c: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * From C PROGRAMMING: A MODERN APPROACH, Second Edition * 3 | * By K. N. King * 4 | * Copyright (c) 2008, 1996 W. W. Norton & Company, Inc. * 5 | * All rights reserved. * 6 | * This program may be freely distributed for class use, * 7 | * provided that this copyright notice is retained. * 8 | *********************************************************/ 9 | 10 | /* readline.c (Chapter 16, page 395) */ 11 | 12 | #include 13 | #include 14 | #include "readline.h" 15 | 16 | int read_line(char str[], int n) 17 | { 18 | int ch, i = 0; 19 | 20 | while (isspace(ch = getchar())) 21 | ; 22 | while (ch != '\n' && ch != EOF) { 23 | if (i < n) 24 | str[i++] = ch; 25 | ch = getchar(); 26 | } 27 | str[i] = '\0'; 28 | return i; 29 | } 30 | -------------------------------------------------------------------------------- /ch22/Projects/11.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define DATE_SIZE 10 4 | int main(void) 5 | { 6 | char date[DATE_SIZE + 1]; 7 | int month, day, year; 8 | printf("Enter a date (mm-dd-yyyy or mm/dd/yyyy): "); 9 | fgets(date, DATE_SIZE, stdin); 10 | sscanf(date,"%d%*[-/]%d%*[-/]%d", &month, &day, &year); 11 | printf("Month: %d\nDay: %d\nYear: %d\n", month, day, year); 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /ch22/Projects/15/inquote: -------------------------------------------------------------------------------- 1 | C is quirky, flawed, and an 2 | enormous success. Although accidents of history 3 | surely helped, it evidently satisfied a need 4 | 5 | for a system implementation language efficient 6 | enough to displace assembly language, 7 | yet sufficiently abstract and fluent to describe 8 | algorithms and interactions in a wide variety 9 | of environments. 10 | -------------------------------------------------------------------------------- /ch22/Projects/15/justify: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fordea/c-programming-a-modern-approach/f03ecea21ac119d38863673a92896973dd963038/ch22/Projects/15/justify -------------------------------------------------------------------------------- /ch22/Projects/15/makefile: -------------------------------------------------------------------------------- 1 | justify: justify.o word.o line.o 2 | gcc -o justify justify.o word.o line.o 3 | 4 | justify.o: justify.c word.h word.h 5 | gcc -c justify.c 6 | 7 | word.o: word.c word.h 8 | gcc -c word.c 9 | 10 | line.o: line.c line.h 11 | gcc -c line.c 12 | -------------------------------------------------------------------------------- /ch22/Projects/15/outquote: -------------------------------------------------------------------------------- 1 | C is quirky, flawed, and an enormous success. Although 2 | accidents of history surely helped, it evidently satisfied a 3 | need for a system implementation language efficient enough 4 | to displace assembly language, yet sufficiently abstract and 5 | fluent to describe algorithms and interactions in a wide 6 | variety of environments. -------------------------------------------------------------------------------- /ch23/Exercises/01.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | float round_nearest(float num, int decimal_places); 6 | 7 | int main(void) 8 | { 9 | float num; 10 | int dp; 11 | printf("Enter a floating-point number and decimal places to round it to: "); 12 | if (scanf("%f %d", &num, &dp) != 2) { 13 | fprintf(stderr, "Enter a floating point number followed by a space, then the number of decimal places to round it to.\n"); 14 | exit(EXIT_FAILURE); 15 | } 16 | num = round_nearest(num, dp); 17 | printf("Result: %.*f\n", dp, num); 18 | return 0; 19 | } 20 | 21 | float round_nearest(float num, int decimal_places) 22 | { 23 | int power = pow(10, decimal_places); 24 | return nearbyint(num * power) / power; 25 | } 26 | --------------------------------------------------------------------------------