--------- ch2/pay.c :------------------------- CUT HERE ---- #include <stdio.h> #define FICA_PERCENTAGE 0.0765 /************************************************************/ /* This program reads in a worker's total hours and hourly */ /* rate of pay, and calculates the worker's gross and */ /* net pay by deducting the required FICA contributions. */ /************************************************************/ main() { int hours_worked; float hourly_rate, gross_pay, net_pay, fica_deduction; /************************************************************/ /* Read in hours worked and hourly rate of pay. */ /************************************************************/ printf("Simple Payroll Program:\n"); printf("-----------------------\n\n"); printf("Enter the number of hours worked: "); scanf("%d", &hours_worked); printf("Enter the hourly rate of pay: "); scanf("%f", &hourly_rate); /************************************************************/ /* Calculate and print gross pay and net pay. */ /************************************************************/ gross_pay = hours_worked * hourly_rate; fica_deduction = gross_pay * FICA_PERCENTAGE; net_pay = gross_pay - fica_deduction; printf("\nHours Worked: %d\n", hours_worked); printf("Hourly Rate: $%5.2f\n", hourly_rate); printf("Gross Pay: $%5.2f\n", gross_pay); printf("FICA Deduction: $%5.2f\n", fica_deduction); printf("Net Pay: $%5.2f\n", net_pay); return 0; } --------- ch3/travel.c :------------------------- CUT HERE ---- #include <stdio.h> #define MINS_PER_HOUR 60 /***********************************************************/ /* This program reads in the distance to be covered on a */ /* trip, our average speed, and our departure time. */ /* It calculates and prints our travel time and estimated */ /* arrival time. */ /***********************************************************/ main() { int depart_hours, depart_mins, hours, mins, arrival_hours, arrival_mins; float distance, speed, travel_time; /***********************************************************/ /* Read in the distance, speed, and departure time. */ /* Departure time is in the form hh:mm. */ /***********************************************************/ printf("Travel calculation program:\n\n"); printf("Distance to be traveled (miles): "); scanf("%f", &distance); printf("Speed of travel (mph): "); scanf("%f", &speed); printf("Departure (military) time (hh:mm): "); scanf("%d:%d", &depart_hours, &depart_mins); /***********************************************************/ /* Calculate travel time and arrival time. */ /***********************************************************/ travel_time = distance / speed; hours = travel_time; mins = (travel_time - hours) * MINS_PER_HOUR; arrival_hours = (depart_hours + hours + (depart_mins + mins) / MINS_PER_HOUR) % 24; arrival_mins = (depart_mins + mins) % MINS_PER_HOUR; /***********************************************************/ /* Print results. */ /***********************************************************/ printf("\nDistance: %5.2f miles.\n", distance); printf("Speed: %5.2f mph.\n", speed); printf("Departure time: %.2d:%.2d.\n", depart_hours, depart_mins); printf("Travel time: %.2d:%.2d.\n", hours, mins); printf("Arrival time: %.2d:%.2d.\n", arrival_hours, arrival_mins); return 0; } --------- ch5/grades.c :------------------------- CUT HERE ---- #include <stdio.h> #define TRUE 1 #define FALSE 0 #define HW_PERC 0.15 #define FIN_PERC 0.25 /**************************************************/ /* This program allows the user to perform grade */ /* calculations, based on the following: */ /* */ /* Three homework assignments, each worth 15%. */ /* Two midterm examinations, each worth 15%. */ /* One final exam, worth 25%. */ /* */ /* The program calculates any one of these items, */ /* or the final grade, in terms of the other six. */ /* */ /**************************************************/ main() { int choice, hw1_flag = TRUE, hw2_flag = TRUE, hw3_flag = TRUE, mt1_flag = TRUE, mt2_flag = TRUE, fin_flag = TRUE, grd_flag = TRUE; float homework_1, homework_2, homework_3, midterm_1, midterm_2, final_exam, final_grade; /**************************************************/ /* Print menu and obtain user choice for the item */ /* to be calculated. */ /**************************************************/ printf("Grade Calculation Program\n\n"); printf("Please select the item to be calculated:\n"); printf(" (you'll be asked to enter the others).\n\n"); printf("Homework #1: (1)\n"); printf("Homework #2: (2)\n"); printf("Homework #3: (3)\n"); printf("Midterm #1: (4)\n"); printf("Midterm #2: (5)\n"); printf("Final Exam : (6)\n"); printf("Final Grade: (7)\n\n"); printf("Please enter your choice: "); scanf("%d", &choice); if ((choice < 1) || (choice > 7)) { printf("Incorrect Choice !\n"); return 1; } /**************************************************/ /* Input all items except the one chosen. */ /**************************************************/ printf("You have chosen to calculate "); switch (choice) { case 1: hw1_flag = FALSE; printf("Homework 1."); break; case 2: hw2_flag = FALSE; printf("Homework 2."); break; case 3: hw3_flag = FALSE; printf("Homework 3."); break; case 4: mt1_flag = FALSE; printf("Midterm 1."); break; case 5: mt2_flag = FALSE; printf("Midterm 2."); break; case 6: fin_flag = FALSE; printf("the Final Exam."); break; case 7: grd_flag = FALSE; printf("the Final Grade."); break; } printf("\nYou'll now be asked to enter the other items.\n\n"); if (hw1_flag) { printf("Please Enter Homework #1: "); scanf("%f", &homework_1); } if (hw2_flag) { printf("Please Enter Homework #2: "); scanf("%f", &homework_2); } if (hw3_flag) { printf("Please Enter Homework #3: "); scanf("%f", &homework_3); } if (mt1_flag) { printf("Please Enter Midterm #1: "); scanf("%f", &midterm_1); } if (mt2_flag) { printf("Please Enter Midterm #2: "); scanf("%f", &midterm_2); } if (fin_flag) { printf("Please Enter Final Exam: "); scanf("%f", &final_exam); } if (grd_flag) { printf("Please Enter Final Grade: "); scanf("%f", &final_grade); } /**************************************************/ /* Calculate and print the item chosen. */ /**************************************************/ switch (choice) { case 1: homework_1 = (final_grade - (homework_2 + homework_3 + midterm_1 + midterm_2) * HW_PERC - final_exam * FIN_PERC) / HW_PERC; printf("Homework #1 = %5.2f\n", homework_1); break; case 2: homework_2 = (final_grade - (homework_1 + homework_3 + midterm_1 + midterm_2) * HW_PERC - final_exam * FIN_PERC) / HW_PERC; printf("Homework #2 = %5.2f\n", homework_2); break; case 3: homework_3 = (final_grade - (homework_1 + homework_2 + midterm_1 + midterm_2) * HW_PERC - final_exam * FIN_PERC) / HW_PERC; printf("Homework #3 = %5.2f\n", homework_3); break; case 4: midterm_1 = (final_grade - (homework_1 + homework_2 + homework_3 + midterm_2) * HW_PERC - final_exam * FIN_PERC) / HW_PERC; printf("Midterm #1 = %5.2f\n", midterm_1); break; case 5: midterm_2 = (final_grade - (homework_1 + homework_2 + homework_3 + midterm_1) * HW_PERC - final_exam * FIN_PERC) / HW_PERC; printf("Midterm #2 = %5.2f\n", midterm_2); break; case 6: final_exam = (final_grade - (homework_1 + homework_2 + homework_3 + midterm_1 + midterm_2) * HW_PERC ) / FIN_PERC; printf("Final Exam = %5.2f\n", final_exam); break; case 7: final_grade = (homework_1 + homework_2 + homework_3 + midterm_1 + midterm_2) * HW_PERC + final_exam * FIN_PERC; printf("Final Grade = %5.2f\n", final_grade); break; } return 0; } --------- ch6/amort.c :------------------------- CUT HERE ---- #include <stdio.h> /************************************************************/ /* This program reads in a loan amount, an interest rate, */ /* and a monthly payment, and prints an amortization table, */ /* listing the loan balance at the end of each period. */ /************************************************************/ main() { float balance, interest, payment; int i; /************************************************************/ /* Read in balance, interest rate, and payment. */ /************************************************************/ printf("Amortization Table Program:\n\n"); printf("Enter starting balance: "); scanf("%f", &balance); printf("Enter interest rate: "); scanf("%f", &interest); printf("Enter monthly payment: "); scanf("%f", &payment); /************************************************************/ /* Loop to calculate and print the remaining balance at */ /* the end of each period. */ /************************************************************/ i = 0; printf("\nAmortization Table:\n\n"); printf("Period Balance\n"); printf("-------------------\n"); while (balance > 0) { i++; balance = balance + (balance * interest / 12) - payment; printf("%5d %10.2f\n", i, balance); } return 0; } --------- ch6/knight.c :------------------------- CUT HERE ---- #include <stdio.h> #define NROWS 8 #define NCOLS 8 #define FALSE 0 #define TRUE 1 main() { int knight_row, knight_col; int line, row, col, i, j; int filled; printf("Chess Knight Program\n"); /*********************************/ /* Read knight_row, knight_col */ /* until they are both in range. */ /*********************************/ do { printf("Enter knight's coordinates: "); scanf("%d %d", &knight_row, &knight_col); } while ((knight_row < 1) || (knight_row > NROWS) || (knight_col < 1) || (knight_col > NCOLS)); /*********************************/ /* Print 2 * NROWS + 1 rows */ /*********************************/ for (line = 1; line <= 2 * NROWS + 1; line++) { row = line / 2; if (line % 2 != 0) { /**********************************************/ /* Odd line number: print one row of +---+'s */ /**********************************************/ printf("+"); for (col = 1; col <= NCOLS; col++) printf("---+"); printf("\n"); } else { /**********************************************/ /* Even line number: print one row of vertical*/ /* bars, with '*'s and a K where appropriate. */ /**********************************************/ printf("|"); for (col = 1; col <= NCOLS; col++) { filled = FALSE; /********************************************/ /* If a K belongs here, print it. */ /********************************************/ if ((row == knight_row) && (col == knight_col)) { printf(" K |"); filled = TRUE; continue; } /********************************************/ /* If a '*' belongs here, print it. */ /********************************************/ for (i = -2; i <= 2; i++) { for (j = -2; j <= 2; j++) { if ((i == j) || (i == -j) || (i == 0) || (j == 0)) continue; if ((knight_row + i == row) && (knight_col + j == col)) { printf(" * |"); filled = TRUE; } } } /*********************************************/ /* Print a vertical bar if slot not filled. */ /*********************************************/ if (!filled) printf(" |"); } printf("\n"); } } return 0; } --------- ch7/wac.c :------------------------- CUT HERE ---- #include <stdio.h> #include <ctype.h> #define IN_WORD 1 #define OUT_WORD 2 #define IN_COMMENT 3 /**************************************************************/ /* Description: Program that loops to process all input */ /* characters. Letters are formed into words while delimiters */ /* are ignored. Any invalid characters encountered are */ /* reported as errors. Also ignored are any comments, denoted */ /* by a slash, up to the eol. Invalid characters within */ /* comments are ignored, and do not produce an error message. */ /* */ /* The program itself is organized based on a finite-state */ /* automaton structure, shown in the table below. */ /* */ /* Note the abbreviations: */ /* */ /* ch: inchar */ /* nc: number of chars */ /* nw: number of words */ /* nl: number of lines */ /* st: state */ /* */ /**************************************************************/ /* Input IN_WORD OUT_WORD IN_COMMENT */ /* char */ /*------------------------------------------------------------*/ /* letter putchar(ch) putchar(ch) nc++ */ /* or nc++ nc++ st=IN_COMMENT */ /* digit st=IN_WORD st=IN_WORD */ /*------------------------------------------------------------*/ /* .,:;[]{}() putchar(\n) nc++ nc++ */ /* etc. nc++ nw++ st=OUT_WORD st=IN_COMMENT */ /* st=OUT_WORD */ /*------------------------------------------------------------*/ /* \n putchar(\n) nc++ nc++ */ /* nc++ nw++ nl++ nl++ nl++ */ /* st=OUT_WORD st=OUT_WORD st=OUT_WORD */ /*------------------------------------------------------------*/ /* / putchar(\n) nc++ nc++ */ /* nc++ nw++ st=IN_COMMENT st=IN_COMMENT */ /* st=IN_COMM */ /*------------------------------------------------------------*/ /* all putchar(\n) ERROR nc++ */ /* others ERROR nc++ st=IN_COMMENT */ /* nw++ nc++ st=OUT_WORD */ /* st=OUT_WORD */ /**************************************************************/ main() { int inchar; int nchars = 0, nwords = 0, nlines = 0; int state; state = OUT_WORD; /* initial state */ /************************************************************/ /* Loop through input file, reading one character at a time.*/ /************************************************************/ while ((inchar = getchar()) != EOF) { nchars++; /************************************************/ /* Check if inchar is a letter or digit. */ /************************************************/ if (isalnum(inchar)) switch (state) { case IN_WORD: case OUT_WORD: putchar(inchar); state = IN_WORD; break; case IN_COMMENT: break; } /************************************************/ /* Check if inchar is punctuator, space, or tab.*/ /************************************************/ else if ((inchar == ',') || (inchar == '.') || (inchar == ':') || (inchar == ';') || (inchar == '_') || (inchar == '"') || (inchar == '-') || (inchar == '?') || (inchar == '!') || (inchar == '(') || (inchar == ')') || (inchar == '{') || (inchar == '}') || (inchar == '[') || (inchar == ']') || (inchar == ' ') || (inchar == '\t')) switch (state) { case IN_WORD: putchar('\n'); nwords++; case OUT_WORD: state = OUT_WORD; break; case IN_COMMENT: break; } /************************************************/ /* Check if inchar is new-line. */ /************************************************/ else if ((inchar == '\n')) switch (state) { case IN_WORD: putchar('\n'); nwords++; case OUT_WORD: case IN_COMMENT: nlines++; state = OUT_WORD; break; } /************************************************/ /* Check if inchar begins a comment. */ /************************************************/ else if ((inchar == '/')) switch (state) { case IN_WORD: putchar('\n'); nwords++; case OUT_WORD: case IN_COMMENT: state = IN_COMMENT; break; } /************************************************/ /* Anything else must be an invalid character. */ /************************************************/ else switch (state) { case IN_WORD: putchar('\n'); nwords++; case OUT_WORD: printf("ERROR!!! Illegal character (%c).\n", inchar); state = OUT_WORD; break; case IN_COMMENT: break; } } printf("\n\nNumber of characters: %d\n", nchars); printf("Number of words: %d\n", nwords); printf("Number of lines: %d\n", nlines); return 0; } --------- ch8/bubsort.c :------------------------- CUT HERE ---- #include <stdio.h> #define MAXARRAY 100 main() { int a[MAXARRAY]; int last, index, top, temp; /*********************************************************/ /* Read numbers into the array until a -1 appears. */ /* Check the array index so it doesn't go out of bounds. */ /*********************************************************/ index = 0; printf("Bubble Sort Program.\n"); printf("Please enter integers, ending with -1\n"); do { scanf("%d", &temp); if (index >= MAXARRAY) { printf("EXCEEDED ARRAY SIZE of %d!\n\n", MAXARRAY); break; } else { a[index] = temp; index++; } } while (temp != -1); last = index - 1; /*********************************************************/ /* Print out the numbers that were read in. */ /*********************************************************/ printf("NUMBERS READ IN: (%d)", last); for (index = 0; index < last; index++) { if (index % 10 == 0) printf("\n"); printf("%5d", a[index]); } printf("\n\n"); /*********************************************************/ /* PERFORM THE BUBBLE SORT. */ /*********************************************************/ for (top = last - 1; top >= 1; top--) for (index = 0; index < top; index++) if (a[index] > a[index + 1]) { temp = a[index]; a[index] = a[index + 1]; a[index + 1] = temp; } /*********************************************************/ /* Print out the sorted numbers. */ /*********************************************************/ printf("SORTED NUMBERS: (%d)", last); for (index = 0; index < last; index++) { if (index % 10 == 0) printf("\n"); printf("%5d", a[index]); } printf("\n\n"); return 0; } --------- ch8/large.c :------------------------- CUT HERE ---- #include <stdio.h> #define MAXSIZE 3000 #define MAXFACT 1000 #define FALSE 0 #define TRUE 1 /****************************************************/ /* Program to calculate the factorial of MAXFACT. */ /****************************************************/ main() { int large[MAXSIZE] = {0}; int n, index, carry, product, last_digit, line_counter, panic; panic = FALSE; large[0] = 1; last_digit = 0; /***************************************************/ /* Process each value of n, from 1 to MAXFACT. */ /***************************************************/ for (n = 1; n <= MAXFACT; n++) { /*************************************************/ /* Calculate digits 1 through 'last_digit' */ /*************************************************/ carry = 0; for (index = 0; index <= last_digit; index++) { product = large[index] * n + carry; large[index] = product % 10; carry = product / 10; } /*************************************************/ /* Take the carry past 'last_digit'; strip the */ /* digits off 'carry' until it becomes zero. */ /* Careful: here we can exceed the array bounds.*/ /*************************************************/ while (carry) { /***********************************************/ /* Peel the least significant digit off carry, */ /* place it in large[index], and increment */ /* 'index'. If index goes out of bounds, print */ /* an error message and break out of the loop. */ /***********************************************/ large[index] = carry % 10; carry = carry / 10; index++; if (index >= MAXSIZE) { printf("OUT OF SPACE\n"); panic = TRUE; break; } } last_digit = index - 1; if (panic) break; /*************************************************/ /* Print large number at 50 digits per line. */ /*************************************************/ line_counter = 0; printf("%d! has %d digits:\n", n, last_digit + 1); for (index = last_digit; index >= 0; index--) { printf("%1d", large[index]); line_counter++; if (line_counter % 50 == 0) printf("\n"); } printf("\n\n"); } return 0; } --------- ch9/plot.c :------------------------- CUT HERE ---- #include <stdio.h> #include <math.h> #define MAX_COLUMNS 60 float xl, xu, delta, ymin, ymax; void print_header(); void get_domain_parameters(); void calculate_min_max(); void print_plot_header(); void print_plot_footer(); void print_plot(); main() { print_header(); get_domain_parameters(); calculate_min_max(); print_plot(); return 0; } void print_header() { printf("\n==============================================\n"); printf(" Sine Function Plotting Program\n"); printf("==============================================\n"); printf("\n"); } void get_domain_parameters() { printf("Please enter lower bound for domain: "); scanf("%f", &xl); printf("Please enter upper bound for domain: "); scanf("%f", &xu); printf("Please enter interval over domain: "); scanf("%f", &delta); printf("\nYou entered the following domain parameters:\n"); printf(" ===========================================\n"); printf(" Lower bound for domain: %f\n", xl); printf(" Upper bound for domain: %f\n", xu); printf(" Increment value : %f\n", delta); printf(" ===========================================\n\n"); } void calculate_min_max() { float x, y; ymin = sin(xl); ymax = sin(xl); for (x = xl; x <= xu; x += delta) { y = sin(x); if (y < ymin) ymin = y; if (y > ymax) ymax = y; } } void print_plot_header() { printf(" %3.1f", ymin); printf(" %3.1f", (ymin + ymax) / 2); printf(" %3.1f\n", ymax); printf(" +"); printf("-----------------------------+"); printf("------------------------------+\n"); } void print_plot_footer() { printf(" +"); printf("-----------------------------+"); printf("------------------------------+\n"); printf(" %3.1f", ymin); printf(" %3.1f", (ymin + ymax) / 2); printf(" %3.1f\n", ymax); } void print_plot() { int scale_index, i, previous; float x; char A[MAX_COLUMNS]; for (i = 0; i < MAX_COLUMNS; i++) A[i] = ' '; x = xl; previous = 0; print_plot_header(); /*************************************************************/ /* Loop through values of x in the domain, in incs of delta */ /*************************************************************/ while (x <= xu) { /***********************************************************/ /* Calculate scale_index: number of spaces to the left of */ /* the asterisk. Keep track of previous location of the */ /* asterisk. In each iteration, place a space in the */ /* previous location, and an asterisk in the current one. */ /***********************************************************/ scale_index = (sin(x) - ymin) * MAX_COLUMNS / (ymax - ymin) - 0.5; A[previous] = ' '; A[scale_index] = '*'; previous = scale_index; printf("%5.2f |", x); for (i = 0; i < MAX_COLUMNS; i++) putchar(A[i]); printf("|\n"); x = x + delta; } print_plot_footer(); } --------- ch9/sort.c :------------------------- CUT HERE ---- #include <stdio.h> #define ARRAY_SIZE 30 int get_input(int a[]); void print_array(int a[], int n); int max(int a[], int n); void sort(int a[], int n); main() { int n; int a[ARRAY_SIZE]; n = get_input(a); print_array(a, n); sort(a, n); print_array(a, n); return 0; } int get_input(int a[]) { int index = 0, temp; printf("Please enter integers, ending with -1.\n"); do { scanf("%d", &temp); if (index >= ARRAY_SIZE) { printf("EXCEEDED ARRAY SIZE of %d!\n\n", ARRAY_SIZE); break; } else { a[index] = temp; index++; } } while (temp != -1); return index - 1; } void print_array(int a[], int n) { int i; printf("Array a:\n"); printf(" +----+\n"); for (i = 0; i < n; i++) printf("%3d|%4d|\n", i, a[i]); printf(" +----+\n"); } int max(int a[], int n) { int max_value, max_index = 0, i; max_value = a[max_index]; for (i = 0; i <= n; i++) if (a[i] > max_value) { max_value = a[i]; max_index = i; } return max_index; } void sort(int a[], int n) { int largest, temp; if (n <= 1) return; largest = max(a, n - 1); temp = a[largest]; a[largest] = a[n - 1]; a[n - 1] = temp; sort(a, n - 1); } --------- ch10/sets.c :------------------------- CUT HERE ---- #include <stdio.h> #define MAX_SET_SIZE 50 #define TRUE 1 #define FALSE 0 void create_set(int a[]); void read_set(int a[]); void print_set(int a[]); void union_set(int a[], int b[], int c[]); void intersect_set(int a[], int b[], int c[]); void enter_set(int v, int a[]); int element_of(int v, int a[]); main() { int a[MAX_SET_SIZE]; int b[MAX_SET_SIZE]; int c[MAX_SET_SIZE]; read_set(a); read_set(b); printf("Set A: "); print_set(a); printf("Set B: "); print_set(b); union_set(a, b, c); printf("Set C: Union of A and B: "); print_set(c); intersect_set(a, b, c); printf("Set C: Intersection of A and B: "); print_set(c); return 0; } void create_set(int a[]) { a[0] = 0; } void read_set(int a[]) { int value; create_set(a); printf("Enter set values, ending with -1.\n"); scanf("%d", &value); while (value != -1) { enter_set(value, a); scanf("%d", &value); } } void print_set(int a[]) { int i; printf("{"); if (a[0] >= 1) printf("%d", a[1]); for (i = 2; i <= a[0]; i++) printf(",%d", a[i]); printf("}\n"); } void union_set(int a[], int b[], int c[]) { int i; create_set(c); for (i = 1; i <= a[0]; i++) enter_set(a[i], c); for (i = 1; i <= b[0]; i++) enter_set(b[i], c); } void intersect_set(int a[], int b[], int c[]) { int i; create_set(c); for (i = 1; i <= a[0]; i++) if (element_of(a[i], b)) enter_set(a[i], c); } void enter_set(int v, int a[]) { if (a[0] == MAX_SET_SIZE) printf("MAX SET SIZE EXCEEDED\n"); else if (!element_of(v, a)) { a[0]++; a[a[0]] = v; } } int element_of(int v, int a[]) { int i; for (i = 1; i <= a[0]; i++) if (a[i] == v) return TRUE; return FALSE; } --------- ch11/complex.c :------------------------- CUT HERE ---- #include <stdio.h> /*---------------------------------------------------------------*/ /* This program adds, subtracts, or multiplies complex numbers. */ /* In all the functions below, r represents the real component */ /* and i represents the imaginary component. */ /*---------------------------------------------------------------*/ void add(float r1, float i1, float r2, float i2, float *r3, float *i3); void subtract(float r1, float i1, float r2, float i2, float *r3, float *i3); void multiply(float r1, float i1, float r2, float i2, float *r3, float *i3); void read_nums(float *r1, float *i1, float *r2, float *i2); void read_num(float *r, float *i); void print_complex(float r, float i); main() { float r1, r2, r3, i1, i2, i3; char c; printf("COMPLEX NUMBER ARITHMETIC PROGRAM:\n\n"); while (1) { printf("1) Add two complex numbers\n"); printf("2) Subtract two complex numbers\n"); printf("3) Multiply two complex numbers\n"); printf("4) Quit\n\n"); printf("Choose an option (1 - 4): "); scanf("%c", &c); switch (c) { case '1': read_nums(&r1, &i1, &r2, &i2); add(r1, i1, r2, i2, &r3, &i3); print_complex(r3, i3); break; case '2': read_nums(&r1, &i1, &r2, &i2); subtract(r1, i1, r2, i2, &r3, &i3); print_complex(r3, i3); break; case '3': read_nums(&r1, &i1, &r2, &i2); multiply(r1, i1, r2, i2, &r3, &i3); print_complex(r3, i3); break; case '4': return 0; } } return 0; } void add(float r1, float i1, float r2, float i2, float *r3, float *i3) { *r3 = r1 + r2; *i3 = i1 + i2; } void subtract(float r1, float i1, float r2, float i2, float *r3, float *i3) { *r3 = r1 - r2; *i3 = i1 - i2; } void multiply(float r1, float i1, float r2, float i2, float *r3, float *i3) { *r3 = r1 * r2 - i1 * i2; *i3 = ((r1 * i2) + (r2 * i1)); } void read_nums(float *r1, float *i1, float *r2, float *i2) { printf("Reading the first number ...\n"); read_num(r1, i1); printf("Reading the second number ...\n"); read_num(r2, i2); } void read_num(float *r, float *i) { printf("Please type the real component: "); /* r and i are pointers; the & operator is unnecessary */ scanf("%f", r); printf("\n"); printf("Please type the imaginary component: "); scanf("%f", i); printf("\n"); } void print_complex(float r3, float i3) { printf("The operation yields %6.3f + %6.3fi\n\n", r3, i3); } --------- ch12/matrix.c :------------------------- CUT HERE ---- #include <stdio.h> #define N 3 void multiply(int *mat1, int *mat2, int *mat3); void fill_zero(int *mat); void read_matrix(int *mat); void print_matrix(const int *mat); main() { int mat1[N][N]; int mat2[N][N]; int mat3[N][N]; printf("MATRIX MULTIPLICATION PROGRAM:\n\n"); fill_zero(mat1[0]); fill_zero(mat2[0]); fill_zero(mat3[0]); printf("Reading the first matrix ...\n"); read_matrix(mat1[0]); printf("Reading the second matrix ...\n"); read_matrix(mat2[0]); multiply(mat1[0], mat2[0], mat3[0]); printf("The resulting matrix is:\n"); print_matrix(mat3[0]); return 0; } void multiply(int *mat1, int *mat2, int *mat3) { int row1, col2; int *p1row, *p1, *p2, *p3; /* traverse all of mat3 */ for (p3 = mat3; p3 < mat3 + N * N; p3++) { /* Get the current row number */ row1 = (p3 - mat3) / N; /* Get the current col number */ col2 = (p3 - mat3) % N; /* Pointer to first row, current column in mat2*/ p2 = mat2 + col2; /* Pointer to start of current row in mat1 */ p1row = mat1 +row1 * N; /* Traverse the current row */ for (p1 = p1row; p1 < p1row + N; p1++){ /* Multiply values from mat1 and mat2; */ /* Add result to position in mat3. */ *p3 += *p1 * *p2; /* Move pointer in mat2 to next row. */ p2 += N; } } } void read_matrix(int *mat) { int i; for (i = 0; i < N * N; i++) { printf("Please type the element in row %d, column %d: ", i / N + 1, i % N +1); scanf("%d", mat++); } printf("\n\n"); } void print_matrix(const int *mat) { int i, j; for (i = 0; i < N; i++) { for (j = 0; j < N; j++) printf("%3i ", *mat++); printf("\n"); } } void fill_zero(int *mat) { int i; for (i = 0; i < N * N; i++) *mat++ = 0; } --------- ch13/indented.indenter.c :------------------------- CUT HERE ---- #include <stdio.h> #include <string.h> #define LINE_SIZE 512 #define TAB '\t' /********************************************************/ /* This program indents the source text of a C program. */ /* It requires that every bracket ('{') be the first */ /* non-space character in the line. Lines of maximum */ /* length 512 can be handled. The number of characters */ /* to indent is taken as a program parameter. */ /********************************************************/ void remove_spaces(char *s); void add_spaces(char *s, int curr_indent); main(int argc, char *argv[]) { int curr_indent = 0, indent; char line[LINE_SIZE]; if (argc != 2) { printf("INDENTER needs an integer value\n"); } else { indent = argv[1][0] - '0'; while (gets(line) > 0) { remove_spaces(line); switch (line[0]) { case '\n': break; case '{' : { add_spaces(line, curr_indent); curr_indent += indent; break; } case '}' : { curr_indent -= indent; add_spaces(line, curr_indent); break; } default : { add_spaces(line, curr_indent); } } puts(line); } } return 0; } void remove_spaces(char *s) { int i = 0; char p[LINE_SIZE]; strcpy(p, ""); strcpy(p, s); while ((p[i] == ' ') || (p[i] == TAB)) { i++; } strcpy(s, &p[i]); } void add_spaces(char *s, int curr_indent) { char p[LINE_SIZE]; int i = 0; strcpy(p, ""); while (i++ < curr_indent) { strcat(p, " "); } strcat(p, s); strcpy(s, p); } --------- ch13/indenter.c :------------------------- CUT HERE ---- #include <stdio.h> #include <string.h> #define LINE_SIZE 512 #define TAB '\t' /********************************************************/ /* This program indents the source text of a C program. */ /* It requires that every bracket ('{') be the first */ /* non-space character in the line. Lines of maximum */ /* length 512 can be handled. The number of characters */ /* to indent is taken as a program parameter. */ /********************************************************/ void remove_spaces(char *s); void add_spaces(char *s, int curr_indent); main(int argc, char *argv[]) { int curr_indent = 0, indent; char line[LINE_SIZE]; if (argc != 2) { printf("INDENTER needs an integer value\n"); } else { indent = argv[1][0] - '0'; while (gets(line) > 0) { remove_spaces(line); switch (line[0]) { case '\n': break; case '{' : { add_spaces(line, curr_indent); curr_indent += indent; break; } case '}' : { curr_indent -= indent; add_spaces(line, curr_indent); break; } default : { add_spaces(line, curr_indent); } } puts(line); } } return 0; } void remove_spaces(char *s) { int i = 0; char p[LINE_SIZE]; strcpy(p, ""); strcpy(p, s); while ((p[i] == ' ') || (p[i] == TAB)) { i++; } strcpy(s, &p[i]); } void add_spaces(char *s, int curr_indent) { char p[LINE_SIZE]; int i = 0; strcpy(p, ""); while (i++ < curr_indent) { strcat(p, " "); } strcat(p, s); strcpy(s, p); } --------- ch14/stacks1.c :------------------------- CUT HERE ---- /*************************************************************/ /* This program implements one STACK, with basic operations */ /* push, pop, and init. */ /* The operations are implemented via macros to contrast */ /* their performance versus functions. */ /*************************************************************/ #include <stdio.h> #include <time.h> /* to access the internal clock */ #define MAX_STACK_SIZE 1024 #define count(s) s[0] /* s[0] contains the current number of elements */ #define init(s) \ do { \ for (i = 1; i < MAX_STACK_SIZE; i++) \ s[i] = 0; \ count(s) = 0; \ } while (0) #define push(e, s) \ do { \ if (count(s) < stack_size) \ s[stack_size - count(s)++] = e; \ else \ printf("Stack's full.\n"); \ } while (0); #define pop(e, s) \ do { \ if (count(s) == 0) \ printf("The stack is empty.\n"); \ else \ e = s[stack_size - (count(s)--) + 1]; \ } while (0) main() { int i, e, stack_size; int s[MAX_STACK_SIZE]; clock_t first_tick; printf("Enter number of values to be reversed: "); scanf("%d", &stack_size); if (stack_size > MAX_STACK_SIZE) { printf("Maximum stack size allowed is %d.\n", MAX_STACK_SIZE - 1); exit(1); } first_tick = clock(); init(s); for (i = 1; i <= stack_size; i++) push(i, s); printf("The reversed list is :\n"); for (i = 1; i <= stack_size; i++) { pop(e, s); printf("%d, ", e); } printf("\n"); printf("Elapsed time: %d\n", (int)(clock() - first_tick)); return 0; } --------- ch14/stacks2.c :------------------------- CUT HERE ---- /*************************************************************/ /* This program implements one STACK, with basic operations */ /* push, pop, and init. */ /* The operations are implemented via functions to contrast */ /* their performance versus macros. */ /*************************************************************/ #include <stdio.h> #include <time.h> /* to access the internal clock */ #define MAX_STACK_SIZE 1024 #define count(s) s[0] /* s[0] contains the current number of elements */ int stack_size = 0; void init(int *s); void push(int e, int *s); int pop(int *s); main() { int i, e; int s[MAX_STACK_SIZE]; clock_t first_tick; printf("Enter number of values to be reversed: "); scanf("%d", &stack_size); if (stack_size > MAX_STACK_SIZE) { printf("Maximum stack size allowed is %d.\n", MAX_STACK_SIZE - 1); exit(1); } first_tick = clock(); init(s); for (i = 1; i <= stack_size; i++) push(i, s); printf("The reversed list is:\n"); for (i = 1; i <= stack_size; i++) { e = pop(s); printf("%d, ", e); } printf("\n"); printf("Elapsed time: %d.\n", (int)(clock() - first_tick)); return 0; } void init(int *s) { int i; for (i = 1; i < MAX_STACK_SIZE; i++) s[i] = 0; count(s) = 0; } void push(int e, int *s) { if (count(s) < stack_size) s[stack_size - count(s)++] = e; else printf("Stack is full.\n"); } int pop(int *s) { if (count(s) == 0) { printf("The stack is empty.\n"); exit(1); } else return (s[stack_size - count(s)-- + 1]); } --------- ch14/stacks3.c :------------------------- CUT HERE ---- /*************************************************************/ /* This program implements one STACK, with basic operations */ /* push, pop, and init. */ /* The operations are implemented via macros, using macros */ /* to allow stack elements to be of various types. */ /*************************************************************/ #include <stdio.h> #define MAX_STACK_SIZE 12 #define FALSE 0 #define TRUE 1 #define INT TRUE #define CHAR FALSE #define FLOAT FALSE #define count(s) s[0] #if INT #define TYPE int #elif FLOAT #define TYPE float #else #define TYPE char #endif int stack_size = 0; void init(TYPE *s); void push(TYPE e, TYPE *s); TYPE pop(TYPE *s); main(int argc, char *argv[]) { TYPE e; int i; TYPE s[MAX_STACK_SIZE]; printf("Enter number of values to be reversed: "); scanf("%d", &stack_size); if (stack_size > MAX_STACK_SIZE) { printf("Maximum stack size allowed is %d.\n", MAX_STACK_SIZE - 1); exit(1); } printf("This program reverses a list of values of type "); #if INT printf("int."); #elif FLOAT printf("float."); #else printf("char."); #endif printf("\n\n"); init(s); for (i = 0; i < stack_size; i++) { printf("Enter value #%1d: ", i); #if INT scanf("%d", &e); #elif FLOAT scanf("%f", &e); #else scanf(" %c", &e); #endif push(e, s); } for (i = 1; i <= stack_size; i++) { e = pop(s); #if INT printf("%d,", e); #elif FLOAT printf("%6.3f,", e); #else printf("%c,", e); #endif } printf("\n"); return 0; } void init(TYPE *s) { int i; for (i = 1; i < MAX_STACK_SIZE; i++) s[i] = 0; count(s) = 0; } void push(TYPE e, TYPE *s) { if (count(s) < stack_size) s[stack_size - (int)count(s)++] = e; else printf("The Stack is full.\n"); } TYPE pop(TYPE *s) { if (count(s) == 0) { printf("The Stack is empty.\n"); exit(1); } else return (s[stack_size - (int)(count(s)--) + 1]); } --------- ch15/bool/bool.h :------------------------- CUT HERE ---- /**********************/ /* bool.h */ /**********************/ #ifndef BOOL_H #define BOOL_H #define TRUE 1 #define FALSE 0 typedef int Bool; extern Bool i_exist; int logical_and(Bool a, Bool b); void print_bool(Bool b); #endif --------- ch15/bool/booltest.c :------------------------- CUT HERE ---- /*************************/ /* booltest.c */ /*************************/ #include <stdio.h> #include "bool.h" main() { Bool a = TRUE; Bool b = FALSE; print_bool(logical_and(a, b)); print_bool(i_exist); return 0; } --------- ch15/bool/Makefile :------------------------- CUT HERE ---- bool: booltest.o bool.o gcc -Wall -o bool booltest.o bool.o bool.o: bool.c gcc -Wall -c bool.c booltest.o: booltest.c gcc -Wall -c booltest.c clean: rm -f *.o bool --------- ch15/bool/bool.c :------------------------- CUT HERE ---- /**********************/ /* bool.c */ /**********************/ #include <stdio.h> #include "bool.h" Bool logical_and(Bool a, Bool b) { return (a && b); } void print_bool(Bool b) { printf("%s\n", (b ? "TRUE" : "FALSE")); } Bool i_exist = TRUE; --------- ch15/sets/Makefile :------------------------- CUT HERE ---- testset: testset.o set.o commandline.o menu.o gcc -Wall -o testset menu.o testset.o set.o commandline.o testset.o: testset.c commandline.h set.h bool.h gcc -Wall -c testset.c commandline.o: commandline.c commandline.h gcc -Wall -c commandline.c set.o: set.c set.h gcc -Wall -c set.c menu.o: menu.c menu.h gcc -Wall -c menu.c clean: rm -f *.o testset --------- ch15/sets/commandline.h :------------------------- CUT HERE ---- /**************************************/ /* File: commandline.h */ /**************************************/ #ifndef COMMAND_LINE_H #define COMMAND_LINE_H char *program_argument(char *flag, char *name, int argc, char *argv[]); int program_flag(char *flag, int argc, char *argv[]); void commandline(int argc, char *argv[]); #endif --------- ch15/sets/menu.c :------------------------- CUT HERE ---- /*******************************/ /* File: menu.c */ /*******************************/ #include <stdio.h> #include "bool.h" #include "set.h" #include "menu.h" void main_menu_loop() { int done, user_choice; int a[MAX_SET_SIZE]; int b[MAX_SET_SIZE]; int c[MAX_SET_SIZE]; done = FALSE; while (!done) { printf("SET MANIPULATION PROGRAM:\n\n"); printf("Main Menu:\n"); printf("1. Union of sets.\n"); printf("2. Intersection of sets.\n"); printf("3. Difference between sets.\n"); printf("4. Quit this program.\n\n"); printf("Your selection (by number): "); scanf("%d", &user_choice); switch (user_choice) { case 1: read_sets(a, b); union_set(a, b, c); printf("Set C: Union of A and B:\n"); print_set(c); break; case 2: read_sets(a, b); intersect_set(a, b, c); printf("Set C: Intersection of A and B:\n"); print_set(c); break; case 3: read_sets(a, b); difference_set(a, b, c); printf("Set C: Difference between A and B:\n"); print_set(c); break; case 4: done = TRUE; printf("Bye!\n"); break; default: printf("INVALID MENU SELECTION\n\n"); } } } --------- ch15/sets/set.c :------------------------- CUT HERE ---- /******************************/ /* File: set.c */ /******************************/ #include <stdio.h> #include "bool.h" #include "set.h" void create_set(int a[]) { a[0] = 0; } void read_set(int a[]) { int value; create_set(a); printf("Enter set values, end with -1.\n"); scanf("%d", &value); while (value != -1) { enter_set(value, a); scanf("%d", &value); } } void read_sets(int a[], int b[]) { read_set(a); read_set(b); printf("Set A:\n"); print_set(a); printf("Set B:\n"); print_set(b); } void print_set(int a[]) { int i; printf("{"); for (i = 1; i <= a[0]; i++) { printf("%d", a[i]); if (i < a[0]) printf(", "); if (i % elements_per_line == 0) printf("\n"); } printf("}\n"); } void union_set(int a[], int b[], int c[]) { int i; create_set(c); for (i = 1; i <= a[0]; i++) enter_set(a[i], c); for (i = 1; i <= b[0]; i++) enter_set(b[i], c); } void intersect_set(int a[], int b[], int c[]) { int i; create_set(c); for (i = 1; i <= a[0]; i++) if (element_of(a[i], b)) enter_set(a[i], c); } void difference_set(int a[], int b[], int c[]) { int i; create_set(c); for (i = 1; i <= a[0]; i++) if (!element_of(a[i], b)) enter_set(a[i], c); } void enter_set(int v, int a[]) { if (a[0] == MAX_SET_SIZE) printf("MAX SET SIZE EXCEEDED\n"); else if (!element_of(v, a)) { a[0]++; a[a[0]] = v; } } Bool element_of(int v, int a[]) { int i; for (i = 1; i <= a[0]; i++) if (a[i] == v) return TRUE; return FALSE; } --------- ch15/sets/bool.h :------------------------- CUT HERE ---- /*******************************/ /* File: bool.h */ /*******************************/ #ifndef BOOL_H #define BOOL_H #define TRUE 1 #define FALSE 0 typedef int Bool; #endif --------- ch15/sets/menu.h :------------------------- CUT HERE ---- /*******************************/ /* File: menu.h */ /*******************************/ #ifndef MENU_H #define MENU_H void main_menu_loop(); #endif --------- ch15/sets/set.h :------------------------- CUT HERE ---- /******************************/ /* File: set.h */ /******************************/ #ifndef SET_H #define SET_H #include "bool.h" #define MAX_SET_SIZE 50 int elements_per_line; void create_set(int a[]); void read_set(int a[]); void read_sets(int a[], int b[]); void print_set(int a[]); void union_set(int a[], int b[], int c[]); void intersect_set(int a[], int b[], int c[]); void difference_set(int a[], int b[], int c[]); void enter_set(int v, int a[]); Bool element_of(int v, int a[]); #endif --------- ch15/sets/testset.c :------------------------- CUT HERE ---- /**********************************/ /* File: testset.c */ /**********************************/ #include <stdio.h> #include "bool.h" #include "commandline.h" #include "set.h" #include "menu.h" main(int argc, char *argv[]) { commandline(argc, argv); main_menu_loop(); return 0; } --------- ch15/sets/commandline.c :------------------------- CUT HERE ---- /**************************************/ /* File: commandline.c */ /**************************************/ #include "commandline.h" #include "set.h" char *program_argument(char *flag, char *name, int argc, char *argv[]) { int position = program_flag(flag, argc, argv); if (position) return (argv[position + 1]); else return name; } int program_flag(char *flag, int argc, char *argv[]) { int index = 0; char *base; char *fl; while (index < argc) { base = argv[index]; fl = flag; while ((*base == *fl) & (*fl != '\0')) { base++; fl++; } if (*base == *fl) return index; else index++; } return 0; } int str_to_int(char *s) { int i = 0; char c; while ((c = *s++) != '\0') i = i * 10 + c - '0'; return i; } void commandline(int argc, char *argv[]) { elements_per_line = str_to_int(program_argument("-p", "20", argc, argv)); } --------- ch16/bank.short.c :------------------------- CUT HERE ---- #include <stdio.h> #include <string.h> typedef struct { char name[20]; int type; float balance; } Bank_account; Bank_account make_account(const char *name, int type, float balance); void print_account(Bank_account b); main() { Bank_account account1, account2; account1 = make_account("John Smith", 1, 23.50); account2 = make_account("Mary Jones", 2, 18.23); print_account(account1); print_account(account2); return 0; } Bank_account make_account(const char *name, int type, float balance) { Bank_account b; strcpy(b.name, name); b.type = type; b.balance = balance; return b; } void print_account(Bank_account b) { printf("%s: ", b.name); printf("%s account has a balance of ", (b.type == 1) ? "savings" : "checking"); printf("%5.2f\n", b.balance); } --------- ch16/bank/Makefile :------------------------- CUT HERE ---- bank: bank.o account.o gcc -Wall bank.o account.o -o bank bank.o: bank.c gcc -c -Wall bank.c account.o: account.c gcc -c -Wall account.c clean: rm -f *.o --------- ch16/bank/account.h :------------------------- CUT HERE ---- /********************************/ /* account.h */ /********************************/ #ifndef ACCOUNT_H #define ACCOUNT_H #include <stdio.h> typedef enum {SAVINGS, CHECKING} Account_type; /* savings account */ struct saving { int interest; /* Interest paid */ float max_withdraw; /* Maximum withdrawal */ }; /* checking account */ struct check { float max_overdraw; /* Maximum overdraft permitted */ float overdraw; /* Current overdraft */ float interest; /* Interest charged on overdrawn amount */ }; typedef struct { int number; /* Account number */ Account_type type; /* Savings or checking */ float balance; /* Account balance */ union { struct saving s; /* savings account, or */ struct check c; /* checking account */ } item; } Account; void clear_accounts(Account bank[], int max_accounts); void insert_account(Account bank[], int max_accounts); void transactions(Account bank[], int max_accounts); #endif --------- ch16/bank/account.c :------------------------- CUT HERE ---- /********************************/ /* account.c */ /********************************/ #include "account.h" void clear_accounts(Account bank[], int max_accounts) { int i; for (i = 0; i < max_accounts; i++) bank[i].number = -1; /* -1 indicates an available cell */ } void display_account(Account bank[], int account) { if (bank[account].type == SAVINGS) printf("SAVINGS ACCOUNT #%d\n", bank[account].number); else printf("CHECKING ACCOUNT #%d\n", bank[account].number); printf("Balance: $%5.2f\n", bank[account].balance); if (bank[account].type == SAVINGS) { printf("Maximum daily withdrawal: $%5.2f\n", bank[account].item.s.max_withdraw); printf("Interest earned: %d\n", bank[account].item.s.interest); } else { /* CHECKING */ printf("Amount currently overdrawn: $%5.2f\n", bank[account].item.c.overdraw); if (bank[account].item.c.overdraw != bank[account].item.c.max_overdraw) printf("You can overdraw yourself by $%5.2f\n", bank[account].item.c.max_overdraw - bank[account].item.c.overdraw); printf("Interest charged for overdrawing: $%5.2f\n", bank[account].item.c.interest); } } void deposit(Account bank[], int account) { float amount; printf("Deposit Amount? "); scanf("%f", &amount); if (bank[account].type == SAVINGS) bank[account].balance += amount; else if (bank[account].item.c.overdraw == 0) bank[account].balance += amount; else if (amount > bank[account].item.c.overdraw) { bank[account].balance = amount - bank[account].item.c.overdraw; bank[account].item.c.overdraw = 0; } else bank[account].item.c.overdraw -= amount; } void withdraw(Account bank[], int account) { float amount; printf("Withdrawal amount ? "); scanf("%f", &amount); if (bank[account].type == SAVINGS) if ((bank[account].balance >= amount) && (bank[account].item.s.max_withdraw >= amount)) bank[account].balance -= amount; else printf("We cannot satisfy your request. " "Please check your balance.\n"); else /* CHECKING */ if (bank[account].item.c.overdraw == 0 && bank[account].balance > 0) if (amount <= bank[account].balance) bank[account].balance -= amount; else /* withdrawal will cause overdraw */ if (amount <= (bank[account].balance + (bank[account].item.c.max_overdraw - bank[account].item.c.overdraw))) { bank[account].item.c.overdraw = amount - bank[account].balance + bank[account].item.c.overdraw; bank[account].balance = 0; } else /* withdrawal exceeds max_overdraw */ printf("We cannot satisfy your request. " "Please check your balance\n"); else /* account already overdrawn */ if (amount <= (bank[account].item.c.max_overdraw - bank[account].item.c.overdraw)) /* withdrawal still covered under max_overdraw */ bank[account].item.c.overdraw += amount; else /* withdrawal exceeds max_overdraw */ printf("We cannot satisfy your request. " "Please check your balance\n"); } void transactions(Account bank[], int max_accounts) { int account, choice = 1; printf("Account number: "); scanf("%d", &account); if (account >= 0 && account < max_accounts) if (bank[account].number != -1) do { display_account(bank, account); printf("\n\n1. Make a deposit\n"); printf("2. Make a withdrawal\n"); printf("3. Close your account\n"); printf("4. Exit\n\n"); printf("Please choose an option: "); scanf("%d", &choice); switch (choice) { case 1: deposit(bank, account); break; case 2: withdraw(bank, account); break; case 3: bank[account].number = -1; printf("Your account has been terminated.\n"); printf(" We'll keep your balance as a fee " "for services rendered\n"); choice = 4; break; case 4: printf("Thanks for preferring us!\n\n"); break; default: printf("Sorry. That's not an option.\n\n"); } } while (choice != 4); else printf("Account not open.\n"); else printf("Invalid account number\n"); } void get_initial_deposit(Account bank[], int account) { float amount; printf("Initial deposit? "); scanf("%f", &amount); bank[account].balance = amount; } void open_savings(Account bank[], int account) { bank[account].type = SAVINGS; get_initial_deposit(bank, account); /* The initial deposit determines the interest */ if (bank[account].balance > 100000) { bank[account].item.s.interest = 30; bank[account].item.s.max_withdraw = bank[account].balance / 15; } else if (bank[account].balance > 50000) { bank[account].item.s.interest = 20; bank[account].item.s.max_withdraw = bank[account].balance / 10; } else { bank[account].item.s.interest = 10; bank[account].item.s.max_withdraw = bank[account].balance / 5; } } void open_checking(Account bank[], int account) { bank[account].type = CHECKING; bank[account].item.c.overdraw = 0; get_initial_deposit(bank, account); if (bank[account].balance > 100000) { bank[account].item.c.max_overdraw = bank[account].balance / 15; bank[account].item.c.interest = 23.5; } else if (bank[account].balance > 50000) { bank[account].item.c.max_overdraw = bank[account].balance / 10; bank[account].item.c.interest = 17.5; } else { bank[account].item.c.max_overdraw = bank[account].balance / 5; bank[account].item.c.interest = 8.5; } } void insert_account(Account bank[], int max_accounts) { int account, choice; /* Find first unoccupied account */ for (account = 0; bank[account].number != -1 && account < max_accounts; account++); if (account == max_accounts) printf("Sorry, we have our hands full at the moment!"); else { bank[account].number = account; printf("Your account number is: %d\n\n", account); printf("What kind of account do you wish?\n\n"); printf("1. Savings account\n"); printf("2. Checking account\n\n"); printf("Please choose an option: "); scanf("%d", &choice); switch (choice) { case 1: open_savings(bank, account); break; case 2: open_checking(bank, account); break; default: printf("Sorry. That's not a option\n"); } } } --------- ch16/bank/bank.c :------------------------- CUT HERE ---- /********************************/ /* bank.c */ /********************************/ #include <stdio.h> #include "account.h" #define MAX_ACCOUNTS 25 main() { int choice; Account bank[MAX_ACCOUNTS]; clear_accounts(bank, MAX_ACCOUNTS); printf(" ALMOST A BANK!\n\n"); printf("We'll keep your money safe\n"); printf(" (at least for a while)"); do { printf("\n\n1. Create a new account.\n"); printf("2. Transact on an existing account.\n"); printf("3. Exit.\n\n"); printf("Please choose an option: "); scanf("%d", &choice); switch (choice) { case 1: insert_account(bank, MAX_ACCOUNTS); break; case 2: transactions(bank, MAX_ACCOUNTS); break; case 3: printf("It has been a pleasure serving you!\n"); break; default : printf("Sorry. That's not an option\n"); } } while (choice != 3); return 0; } --------- ch17/sets/Makefile :------------------------- CUT HERE ---- sets: sets.o node.o gcc sets.o node.o -o sets sets.o: sets.c gcc -c -Wall sets.c node.o: node.c gcc -c -Wall node.c clean: rm -f *.o --------- ch17/sets/node.c :------------------------- CUT HERE ---- /*************************/ /* node.c */ /*************************/ #include <stdio.h> #include <stdlib.h> #include "node.h" void insert(Node **set, int elem) { Node *new_node; if ((*set) == NULL) /* the set is empty */ if (((*set) = malloc(sizeof(Node))) != NULL) { (*set)->elem = elem; (*set)->next = NULL; } else { printf("Error in malloc - Function insert\n"); exit(0); } else { /* The set's not empty */ new_node = *set; /* First we search for elem in the set */ while ((new_node->next != NULL) && (new_node->elem != elem)) new_node = new_node->next; if (new_node->elem != elem) { /* elem isn't in the set: add it */ if ((new_node->next = malloc(sizeof(Node))) != NULL) { /* New element successfully created */ new_node->next->elem = elem; new_node->next->next = NULL; } else { /* New element couldn't be created */ printf("Error in malloc - Function insert\n"); exit(0); } } } } void insert_prompt(Node **set, int n) { int elem; printf("\nElement you wish to add to set %1d: ", n); scanf("%d", &elem); insert(set, elem); printf("\nSet %1d is now:\n", n); print(*set); } void delete(Node **set, int n) { Node *previous, *current; int elem; printf("\nSet %1d is:\n", n); print(*set); printf("\nElement you wish to delete from set %1d: ", n); scanf("%d", &elem); if ((*set)->elem == elem) { /* The first element is being deleted */ current = *set; *set = (*set)->next; free(current); } else { /* Search the list */ previous = *set; current = previous->next; while (current != NULL && current->elem != elem) { /* Search for elem, or end of list */ previous = current; current = current->next; } if (current == NULL) return; /* never found it */ if (current->elem == elem) { /* found elem in current, so bypass it */ previous->next = current->next; free(current); } } printf("\nSet %1d now is:\n", n); print(*set); } void done(Node **set) { Node *current, *previous; current = *set; while (current != NULL) { /* Haven't reached the end of the list */ previous = current; current = current->next; free(previous); } *set = NULL; } Node *sunion(Node *set1, Node *set2) { Node *result, *current; result = NULL; current = set1; /* Insert all elements of set 1 */ while (current != NULL) { insert(&result, current->elem); current = current->next; } /* Insert all elements of set 2 */ current = set2; while (current != NULL) { insert(&result, current->elem); current = current->next; } return result; } void print(Node *set) { Node *current; if (set == NULL) printf("The set is empty.\n"); else { current = set; while (current != NULL) { printf("%d", current->elem); if (current->next != NULL) printf(", "); current = current->next; } printf("\n"); } } int cardinality(Node *set) { Node *current; int i; i = 0; current = set; while (current != NULL) { i++; current = current->next; } return i; } int locate(Node *set, int elem) { Node *current; current = set; while (current != NULL && current->elem != elem) current = current->next; return (current != NULL); } Node *intersection(Node *set1, Node *set2) { Node *result, *current; result = NULL; current = set1; while (current != NULL) { if (locate(set2, current->elem)) insert(&result, current->elem); current = current->next; } return result; } Node *get_set(int n) { int i, nelems; Node * set; printf("Reading Set %1d\n", n); set = NULL; printf("How many elements will the set have? "); scanf("%d", &nelems); for (i = 1; i <= nelems; i++) insert_prompt(&set, n); printf("\n"); return set; } --------- ch17/sets/node.h :------------------------- CUT HERE ---- /*************************/ /* node.h */ /*************************/ #ifndef NODE_H #define NODE_H struct node { int elem; struct node *next; }; typedef struct node Node; void insert_prompt(Node **set, int n); void insert(Node **set, int elem); void delete(Node **set, int elem); void done(Node **set); void print(Node *set); int cardinality(Node *set); int locate(Node *set, int elem); Node *sunion(Node *set1, Node *set2); Node *intersection(Node *set1, Node *set2); Node *get_set(int n); #endif --------- ch17/sets/sets.c :------------------------- CUT HERE ---- /*******************************************************************/ /* This program will implement sets, with the following operations:*/ /* union, intersection, and cardinality. Operations for */ /* creating, destroying, and printing the sets are also available. */ /* The sets are implemented as linked lists. */ /*******************************************************************/ #include <stdio.h> #include "node.h" main() { int choice; Node *set1, *set2; printf("SET MANIPULATION PROGRAM:\n"); printf("Insert, Delete, Union and Intersect two sets\n\n"); set1 = get_set(1); set2 = get_set(2); choice = 0; while (choice != 8) { printf("\nMENU:\n-----\n"); printf("1. Add an element to Set 1\n"); printf("2. Add an element to Set 2\n"); printf("3. Delete an element from Set 1\n"); printf("4. Delete an element form Set 2\n"); printf("5. View the cardinality of the sets\n"); printf("6. View the union of the sets\n"); printf("7. View the intersection of the sets\n"); printf("8. Exit\n\n"); printf("Please choose an option: "); scanf("%d", &choice); switch (choice) { case 1: insert_prompt(&set1, 1); break; case 2: insert_prompt(&set2, 2); break; case 3: delete(&set1, 1); break; case 4: delete(&set2, 2); break; case 5: printf("\nThe cardinality of Set 1 is %d.", cardinality(set1)); printf("\nThe cardinality of Set 2 is %d.\n", cardinality(set2)); break; case 6: printf("\nThe union of the sets is:\n"); print(sunion(set1, set2)); break; case 7: printf("\nThe intersection of the sets is:\n"); print(intersection(set1, set2)); break; case 8: printf("\nBye!\n\n"); break; default: printf("I'm sorry. That's not a valid option.\n"); choice = 0; } } done(&set1); done(&set2); return 0; } --------- ch17/integration/integration.c :------------------------- CUT HERE ---- #include <stdio.h> #include <stdlib.h> #include <math.h> float integrate(float func(float x), float low, float high, int n); float func0(float x); /* sine (x) */ float func1(float x); /* cosine x) */ float func2(float x); /* tan (x) */ float func3(float x); /* x*x */ float func4(float x); /* sqrt (x) */ main() { float high, low; int choice, npoints; float (*vec[5])(float); vec[0] = func0; vec[1] = func1; vec[2] = func2; vec[3] = func3; vec[4] = func4; printf("NUMERIC INTEGRATION PROGRAM\n\n"); choice = 0; while (choice != 6) { printf("1. Sine.\n"); printf("2. Cosine.\n"); printf("3. Tangent.\n"); printf("4. Square.\n"); printf("5. Square root.\n"); printf("6. Exit.\n\n"); printf("Please choose one: "); scanf("%d", &choice); if ((choice > 6) || (choice <= 0)) printf("\nSorry, that's not an option.\n"); else if (choice != 6) { printf("\nPlease enter the interval's lower limit: "); scanf("%f", &low); printf("\nPlease enter the interval's upper limit: "); scanf("%f", &high); npoints = -1; while (npoints < 0) { printf("\n\nHow many subintervals ? "); scanf("%d", &npoints); if (npoints < 0) printf("\nMust have a positive number !\n\n"); } printf("The result is : %f.\n\n", integrate(vec[choice-1], low, high, npoints)); } } printf("Bye!\n\n"); return 0; } float integrate (float func (float x), float low, float high, int n) { int i; float x, width, sum; sum = 0; width = (high - low) / n; x = low + width / 2; for (i = 0; i < n; i++) { sum = sum + func(x) * width; x = x + width; } return sum; } float func0(float x) { return sin(x); } float func1(float x) { return cos(x); } float func2(float x) { return sin(x) / cos(x); } float func3(float x) { return x * x; } float func4(float x) { return sqrt(x); } --------- ch18/sample1.c :------------------------- CUT HERE ---- #include <stdio.h> float func0(float p) { return p; } float func1(float p) { return p * 2.0; } float func2(float p) { return p * p; } float f_func0(int i, float (*func)(float)); float f_func1(int i, float (*func)(float)); float f_func2(int i, float (*func)(float)); main() { float (*vec[3])(float) = {func0, func1, func2}; float (*f_vec[3])(int, float (*func)(float)) = {f_func0, f_func1, f_func2}; printf("%5.2f\n", vec[0](3.0)); printf("%5.2f\n", f_vec[2](4, func1)); printf("%5.2f\n", f_vec[2](4, func2)); return 0; } float f_func0(int i, float (*func)(float)) { return func(i); } float f_func1(int i, float (*func)(float)) { return func(func(i)); } float f_func2(int i, float (*func)(float)) { return func(func(func(i))); } --------- ch18/sample2.c :------------------------- CUT HERE ---- #include <stdio.h> typedef float Func(float); typedef Func *Func_ptr; typedef Func_ptr Vec_func[3]; Func func0, func1, func2; typedef float F_func(int, Func_ptr); typedef F_func *F_func_ptr; typedef F_func_ptr Vec_f_func[3]; F_func f_func0, f_func1, f_func2; main() { Vec_func vec = {func0, func1, func2}; Vec_f_func f_vec = {f_func0, f_func1, f_func2}; printf("%5.2f\n", vec[0](3.0)); printf("%5.2f\n", f_vec[2](4, func1)); printf("%5.2f\n", f_vec[2](4, func2)); return 0; } float func0(float p) { return p; } float func1(float p) { return p * 2.0; } float func2(float p) { return p * p; } float f_func0(int i, float (*func)(float)) { return func(i); } float f_func1(int i, float (*func)(float)) { return func(func(i)); } float f_func2(int i, float (*func)(float)) { return func(func(func(i))); } --------- ch18/sample3.c :------------------------- CUT HERE ---- #include <stdio.h> typedef void Func(void); typedef Func *Func_ptr; typedef Func_ptr Vec_func[3]; Func func0, func1, func2; typedef void F_func(Vec_func v_func); typedef F_func *F_func_ptr; typedef F_func_ptr V_f_func[3]; F_func f_func0, f_func1, f_func2; main() { Vec_func vec = {func0, func1, func2}; V_f_func vec2 = {f_func0, f_func1, f_func2}; vec[0](); vec2[1](vec); return 0; } void func0() { printf("func0\n"); } void func1() { printf("func1\n"); } void func2() { printf("func2\n"); } void f_func0(Vec_func v_func) { v_func[0](); } void f_func1(Vec_func v_func) { v_func[0](); v_func[1](); } void f_func2(Vec_func v_func) { v_func[0](); v_func[1](); v_func[2](); } --------- ch19/point/Makefile :------------------------- CUT HERE ---- testpoint: testpoint.o point.o gcc -Wall testpoint.o point.o -o testpoint testpoint.o: testpoint.c gcc -c -Wall testpoint.c point.o: point.c gcc -c -Wall point.c clean: rm -f *.o testpoint --------- ch19/point/point.h :------------------------- CUT HERE ---- /****************/ /* point.h */ /****************/ #ifndef POINT_H #define POINT_H typedef struct { float x; float y; } Pointstruct; typedef Pointstruct *Point; Point create_point(); void set_x(Point p, float x); void set_y(Point p, float y); void print_point(Point p); #endif --------- ch19/point/testpoint.c :------------------------- CUT HERE ---- #include "point.h" main() { Point p; p = create_point(); set_x(p, 3.4); set_y(p, 5.6); print_point(p); return 0; } --------- ch19/point/point.c :------------------------- CUT HERE ---- /***************/ /* point.c */ /***************/ #include <stdio.h> #include <stdlib.h> #include "point.h" Point create_point() { return malloc(sizeof(Pointstruct)); } void set_x(Point p, float x) { p->x = x; } void set_y(Point p, float y) { p->y = y; } void print_point(Point p) { printf("Point p = (%f,%f)\n", p->x, p->y); } --------- ch19/complex/complex.cc :------------------------- CUT HERE ---- #include <stream.h> class Complex { private: float real; float imag; public: Complex(float x, float y); void print(); Complex operator+(Complex c); }; Complex::Complex(float x=0.0, float y=0.0) { real = x; imag = y; } void Complex::print() { cout << "(" << real << "+" << imag << "i)" << endl; } Complex Complex::operator+(Complex c) { Complex result; result.real = real + c.real; result.imag = imag + c.imag; return result; } main() { Complex a(1.2, 3.4), b(5.6), c; a.print(); b.print(); c = a + b; c.print(); return 0; } --------- ch19/stack/stack.c :------------------------- CUT HERE ---- #include <stdio.h> #define STACK_SIZE 10 struct stack { int items[STACK_SIZE]; int sp; }; typedef struct stack Stack; void initialize(Stack* s) { s->sp=-1; } void push(Stack* s, int i) { s->items[++s->sp]=i; } int pop(Stack *s) { return s->items[s->sp--]; } void print(const Stack* s) { int i; printf("Stack:\n"); for (i=0;i<=s->sp;i++) printf("%d ",s->items[i]); printf("\n"); } main() { Stack s; int i; initialize(&s); push(&s, 1); push(&s, 2); print(&s); i=pop(&s); print(&s); return 0; } --------- ch19/stack/stack.cc :------------------------- CUT HERE ---- #include <iostream.h> const int STACK_SIZE = 10; class Stack { private: int items[STACK_SIZE]; int sp; public: void print(void); Stack() { sp=-1; } void Stack::operator<<(int i) { items[++sp]=i; } void Stack::operator>>(int& i) { i=items[sp--]; } }; void Stack::print(void) { int i; cout << "Stack:\n"; for (i=0;i<=sp;i++) cout << items[i] << " "; cout << "\n"; }; main() { Stack s; int i; s << 1; s << 2; s.print(); s >> i; s.print(); return 0; } --------- ch19/car/Makefile :------------------------- CUT HERE ---- car: carmain.o car.o gcc -Wall carmain.o car.o -o car carmain.o: carmain.c car.h gcc -Wall -c carmain.c car.o: car.c car.h gcc -Wall -c car.c clean: rm -f *.o car --------- ch19/car/car.c :------------------------- CUT HERE ---- /*********************/ /* car.c */ /*********************/ #include <stdio.h> #include "car.h" void start_car(Car *c) { c->direction = 'N'; c->ignition_on = 1; } void forward(Car c) { printf("Going Forward. Heading %c.\n", c.direction); } void uturn(Car *c) { switch (c->direction) { case 'N': c->direction = 'S'; break; case 'S': c->direction = 'N'; break; case 'E': c->direction = 'W'; break; case 'W': c->direction = 'E'; break; } printf("Making U turn. Now heading %c.\n", c->direction); } void left(Car *c) { switch (c->direction) { case 'N': c->direction = 'W'; break; case 'S': c->direction = 'E'; break; case 'E': c->direction = 'N'; break; case 'W': c->direction = 'S'; break; } printf("Turning Left. Now heading %c.\n", c->direction); } void right(Car *c) { switch (c->direction) { case 'N': c->direction = 'E'; break; case 'S': c->direction = 'W'; break; case 'E': c->direction = 'S'; break; case 'W': c->direction = 'N'; break; } printf("Turning Right. Now heading %c.\n", c->direction); } int running(Car c) { return c.ignition_on; } void stop(Car *c) { printf("Car stopped.\n"); c->ignition_on = 0; } --------- ch19/car/car.h :------------------------- CUT HERE ---- /**********************/ /* car.h */ /**********************/ #ifndef CAR_H #define CAR_H typedef struct { char direction; /* 'N', 'S', 'E', 'W' */ int ignition_on; } Car; void start_car(Car *c); void forward(Car c); void uturn(Car *c); void left(Car *c); void right(Car *c); int running(Car c); void stop(Car *c); #endif --------- ch19/car/carmain.c :------------------------- CUT HERE ---- #include <stdio.h> #include "car.h" main() { char choice; Car c; start_car(&c); printf("Please type the correct key for each operation:\n"); printf("(f)orward, (u)turn, (l)eft, (r)ight, (s)top\n"); forward(c); while (running(c)){ scanf(" %c", &choice); switch (choice){ case 'r': right(&c); break; case 'l': left(&c); break; case 'f': forward(c); break; case 'u': uturn(&c); break; case 's': stop(&c); break; default : printf("Not an allowed operation.\n"); break; } } return 0; } --------- ch20/hamming.c :------------------------- CUT HERE ---- /**************************************************/ /* Implementation of Hamming codes: single error */ /* detection and correction in a transmitted word */ /**************************************************/ #include <stdio.h> #include <stdlib.h> #define BIT(word, i) (((word) & 1 << (i)) >> (i)) void gen_error(unsigned int *word); void encode(unsigned int *word); unsigned int decode(unsigned int *word); void print_bits(unsigned int word); main() { unsigned int word, error; char c; printf("HAMMING CODES PROGRAM\n"); while (1) { printf("Enter to continue, `q' to quit:"); scanf("%c", &c); if (c == 'q') break; word = rand() & 0x00ff; /* An 8-bit word */ printf("Data Word: "); print_bits(word); encode(&word); printf("Hamming encoded word: "); print_bits(word); gen_error(&word); printf("Word with random error: "); print_bits(word); error = decode(&word); if (!error) printf("No error!\n"); else { printf("Error at bit %u!\n", error); printf(" Corrected word: "); print_bits(word); } } return 0; } void gen_error(unsigned int *word) { /******************************/ /* produce the error */ /******************************/ unsigned int err, loc; err = rand() % 2; /* error bit */ loc = rand() % 12; err <<= loc; /* in random location */ *word ^= err; } void encode(unsigned int *word) { /*********************/ /* Hamming encoding */ /*********************/ unsigned int checkbit; checkbit = BIT(*word, 7) ^ BIT(*word, 6) ^ BIT(*word, 4) ^ BIT(*word, 3) ^ BIT(*word, 1); *word |= checkbit << 11; checkbit = BIT(*word, 7) ^ BIT(*word, 5) ^ BIT(*word, 4) ^ BIT(*word, 2) ^ BIT(*word, 1); *word |= checkbit << 10; checkbit = BIT(*word, 6) ^ BIT(*word, 5) ^ BIT(*word, 4) ^ BIT(*word, 0); *word |= checkbit << 9; checkbit = BIT(*word, 3) ^ BIT(*word, 2) ^ BIT(*word, 1) ^ BIT(*word, 0); *word |= checkbit << 8; } unsigned int decode(unsigned int *word) { unsigned int checkbit, error = 0; unsigned int permute[13] = {0,11,10,7,9,6,5,4,8,3,2,1,0}; checkbit = BIT(*word, 11) ^ BIT(*word, 7) ^ BIT(*word, 6) ^ BIT(*word, 4) ^ BIT(*word, 3) ^ BIT(*word, 1); error |= checkbit << 0; checkbit = BIT(*word, 10) ^ BIT(*word, 7) ^ BIT(*word, 5) ^ BIT(*word, 4) ^ BIT(*word, 2) ^ BIT(*word, 1); error |= checkbit << 1; checkbit = BIT(*word, 9) ^ BIT(*word, 6) ^ BIT(*word, 5) ^ BIT(*word, 4) ^ BIT(*word, 0); error |= checkbit << 2; checkbit = BIT(*word, 8) ^ BIT(*word, 3) ^ BIT(*word, 2) ^ BIT(*word, 1) ^ BIT(*word, 0); error |= checkbit << 3; error = permute[error]; if (error) *word ^= 1 << error; return error; } void print_bits(unsigned int word) { int j; printf("%4u: ", word); for (j = 11; j >= 0; j--) printf("%u", (word >> j) & 1 ); printf("\n"); } --------- ch21/offset.c :------------------------- CUT HERE ---- #include <stdio.h> #include <stddef.h> main() { struct s { char a; char *b[4]; float c; }; printf("Size of a: %lu. Offset of a: %lu.\n", (unsigned long) sizeof(char), (unsigned long) offsetof(struct s, a)); printf("Size of b: %lu. Offset of b: %lu.\n", (unsigned long) sizeof(char *[4]), (unsigned long) offsetof(struct s, b)); printf("Size of c: %lu. Offset of c: %lu.\n", (unsigned long) sizeof(float), (unsigned long) offsetof(struct s, c)); printf("Size of s: %lu.\n", (unsigned long) sizeof(struct s)); return 0; } --------- ch22/bank/account.c :------------------------- CUT HERE ---- /********************************/ /* account.c */ /********************************/ #include "account.h" void load_bank(const char *f_name, Account bank[], int max_accounts) { FILE *fp; int i; if ((fp = fopen(f_name, "r")) == NULL) /* If null, just clear the array */ for (i = 0; i < max_accounts; i++) bank[i].number = -1; /* -1 indicates an available cell */ else { /* Read the array from the file */ i = 0; while (1) { if (fscanf(fp, "%d", &bank[i].number)!=1) break; if (bank[i].number == -1) continue; if (fscanf(fp, "%d%f", &bank[i].type, &bank[i].balance)!=2) break; if (bank[i].type == SAVINGS) { if (fscanf(fp, "%d%f", &bank[i].item.s.interest, &bank[i].item.s.max_withdraw)!=2) break; } else { if (fscanf(fp, "%f%f%f", &bank[i].item.c.max_overdraw, &bank[i].item.c.overdraw, &bank[i].item.c.interest)!=3) break; } i++; } for (; i < max_accounts; i++) bank[i].number = -1; fclose(fp); } } void save_bank(const char *f_name, Account bank[], int max_accounts) { FILE *fp; int i = 0; if ((fp = fopen(f_name, "w")) == NULL) printf("Unable to open file for saving\n\n"); else { /* Write the array to the file */ while (i < max_accounts) { fprintf(fp, "%d\n", bank[i].number); if (bank[i].number != -1) { fprintf(fp, "%d %f ", bank[i].type, bank[i].balance); if (bank[i].type == SAVINGS) fprintf(fp, "%d %f\n", bank[i].item.s.interest, bank[i].item.s.max_withdraw); else /* checking account */ fprintf(fp, "%f %f %f\n", bank[i].item.c.max_overdraw, bank[i].item.c.overdraw, bank[i].item.c.interest); } i++; } fclose(fp); } } void display_account(Account bank[], int account) { if (bank[account].type == SAVINGS) printf("SAVINGS ACCOUNT #%d\n", bank[account].number); else printf("CHECKING ACCOUNT #%d\n", bank[account].number); printf("Balance: $%5.2f\n", bank[account].balance); if (bank[account].type == SAVINGS) { printf("Maximum daily withdrawal: $%5.2f\n", bank[account].item.s.max_withdraw); printf("Interest earned: %d\n", bank[account].item.s.interest); } else { /* CHECKING */ printf("Amount currently overdrawn: $%5.2f\n", bank[account].item.c.overdraw); if (bank[account].item.c.overdraw != bank[account].item.c.max_overdraw) printf("You can overdraw yourself by $%5.2f\n", bank[account].item.c.max_overdraw - bank[account].item.c.overdraw); printf("Interest charged for overdrawing: $%5.2f\n", bank[account].item.c.interest); } } void deposit(Account bank[], int account) { float amount; printf("Deposit Amount? "); scanf("%f", &amount); if (bank[account].type == SAVINGS) bank[account].balance += amount; else if (bank[account].item.c.overdraw == 0) bank[account].balance += amount; else if (amount > bank[account].item.c.overdraw) { bank[account].balance = amount - bank[account].item.c.overdraw; bank[account].item.c.overdraw = 0; } else bank[account].item.c.overdraw -= amount; } void withdraw(Account bank[], int account) { float amount; printf("Withdrawal amount ? "); scanf("%f", &amount); if (bank[account].type == SAVINGS) if ((bank[account].balance >= amount) && (bank[account].item.s.max_withdraw >= amount)) bank[account].balance -= amount; else printf("We cannot satisfy your request. " "Please check your balance.\n"); else /* CHECKING */ if (bank[account].item.c.overdraw == 0 && bank[account].balance > 0) if (amount <= bank[account].balance) bank[account].balance -= amount; else /* withdrawal will cause overdraw */ if (amount <= (bank[account].balance + (bank[account].item.c.max_overdraw - bank[account].item.c.overdraw))) { bank[account].item.c.overdraw = amount - bank[account].balance + bank[account].item.c.overdraw; bank[account].balance = 0; } else /* withdrawal exceeds max_overdraw */ printf("We cannot satisfy your request. " "Please check your balance\n"); else /* account already overdrawn */ if (amount <= (bank[account].item.c.max_overdraw - bank[account].item.c.overdraw)) /* withdrawal still covered under max_overdraw */ bank[account].item.c.overdraw += amount; else /* withdrawal exceeds max_overdraw */ printf("We cannot satisfy your request. " "Please check your balance\n"); } void transactions(Account bank[], int max_accounts) { int account, choice = 1; printf("Account number: "); scanf("%d", &account); if (account >= 0 && account < max_accounts) if (bank[account].number != -1) do { display_account(bank, account); printf("\n\n1. Make a deposit\n"); printf("2. Make a withdrawal\n"); printf("3. Close your account\n"); printf("4. Exit\n\n"); printf("Please choose an option: "); scanf("%d", &choice); switch (choice) { case 1: deposit(bank, account); break; case 2: withdraw(bank, account); break; case 3: bank[account].number = -1; printf("Your account has been terminated.\n"); printf(" We'll keep your balance as a fee " "for services rendered\n"); choice = 4; break; case 4: printf("Thanks for preferring us!\n\n"); break; default: printf("Sorry. That's not an option.\n\n"); } } while (choice != 4); else printf("Account not open.\n"); else printf("Invalid account number\n"); } void get_initial_deposit(Account bank[], int account) { float amount; printf("Initial deposit? "); scanf("%f", &amount); bank[account].balance = amount; } void open_savings(Account bank[], int account) { bank[account].type = SAVINGS; get_initial_deposit(bank, account); /* The initial deposit determines the interest */ if (bank[account].balance > 100000) { bank[account].item.s.interest = 30; bank[account].item.s.max_withdraw = bank[account].balance / 15; } else if (bank[account].balance > 50000) { bank[account].item.s.interest = 20; bank[account].item.s.max_withdraw = bank[account].balance / 10; } else { bank[account].item.s.interest = 10; bank[account].item.s.max_withdraw = bank[account].balance / 5; } } void open_checking(Account bank[], int account) { bank[account].type = CHECKING; bank[account].item.c.overdraw = 0; get_initial_deposit(bank, account); if (bank[account].balance > 100000) { bank[account].item.c.max_overdraw = bank[account].balance / 15; bank[account].item.c.interest = 23.5; } else if (bank[account].balance > 50000) { bank[account].item.c.max_overdraw = bank[account].balance / 10; bank[account].item.c.interest = 17.5; } else { bank[account].item.c.max_overdraw = bank[account].balance / 5; bank[account].item.c.interest = 8.5; } } void insert_account(Account bank[], int max_accounts) { int account, choice; /* Find first unoccupied account */ for (account = 0; bank[account].number != -1 && account < max_accounts; account++); if (account == max_accounts) printf("Sorry, we have our hands full at the moment!"); else { bank[account].number = account; printf("Your account number is: %d\n\n", account); printf("What kind of account do you wish?\n\n"); printf("1. Savings account\n"); printf("2. Checking account\n\n"); printf("Please choose an option: "); scanf("%d", &choice); switch (choice) { case 1: open_savings(bank, account); break; case 2: open_checking(bank, account); break; default: printf("Sorry. That's not a option\n"); } } } --------- ch22/bank/bank.c :------------------------- CUT HERE ---- /********************************/ /* bank.c */ /********************************/ #include <stdio.h> #include "account.h" #define MAX_ACCOUNTS 25 #define FILE_NAME "bank.dat" main() { int choice; Account bank[MAX_ACCOUNTS]; load_bank(FILE_NAME, bank, MAX_ACCOUNTS); printf(" ALMOST A BANK!\n\n"); printf("We'll keep your money safe\n"); printf(" (at least for a while)"); do { printf("\n\n1. Create a new account.\n"); printf("2. Transact on an existing account.\n"); printf("3. Exit.\n\n"); printf("Please choose an option: "); scanf("%d", &choice); switch (choice) { case 1: insert_account(bank, MAX_ACCOUNTS); break; case 2: transactions(bank, MAX_ACCOUNTS); break; case 3: printf("It has been a pleasure serving you!\n"); break; default: printf("Sorry. That's not an option\n"); } } while (choice != 3); save_bank(FILE_NAME, bank, MAX_ACCOUNTS); return 0; } --------- ch22/bank/Makefile :------------------------- CUT HERE ---- bank: bank.o account.o gcc -g -Wall bank.o account.o -o bank bank.o: bank.c gcc -g -c -Wall bank.c account.o: account.c gcc -g -c -Wall account.c clean: rm -f *.o bank --------- ch22/bank/account.h :------------------------- CUT HERE ---- /********************************/ /* account.h */ /********************************/ #ifndef ACCOUNT_H #define ACCOUNT_H #include <stdio.h> typedef enum {SAVINGS, CHECKING} Account_type; /* savings account */ struct saving { int interest; /* Interest paid. */ float max_withdraw; /* Maximum withdrawal */ }; /* checking account */ struct check { float max_overdraw; /* Maximum overdraw permitted */ float overdraw; /* Current overdraw */ float interest; /* Interest charged on overdrawn amount. */ }; typedef struct { int number; /* Account number */ Account_type type; /* Savings or checking */ float balance; /* Account balance */ union { struct saving s; /* savings acount, or */ struct check c; /* checking account */ } item; } Account; void load_bank(const char * f_name, Account bank[], int max_accounts); void save_bank(const char * f_name, Account bank[], int max_accounts); void insert_account(Account bank[], int max_accounts); void transactions(Account bank[], int max_accounts); #endif --------- ch22/parts/Makefile :------------------------- CUT HERE ---- all: invent invent: invent.o readline.o gcc -Wall invent.o readline.o -o invent invent.o: invent.c gcc -c -Wall invent.c readline.o: readline.c gcc -c -Wall readline.c clean: rm -f *.o invent --------- ch22/parts/invent.c :------------------------- CUT HERE ---- #include <stdio.h> #include "readline.h" #define NAME_LEN 25 #define FILE_NAME "parts.dat" struct part { int number; char name[NAME_LEN+1]; int on_hand; }; typedef struct part Part; int find_part(int number, Part* p); void insert(void); void search(void); void update(void); void print(void); /********************************************************** * main: Prompts the user to enter an operation code, * * then calls a function to perform the requested * * action. Repeats until the user enters the * * command 'q'. Prints an error message if the user * * enters an illegal code. * **********************************************************/ main() { char code; for (;;) { printf("Enter operation code: "); printf("(Insert, Search, Update, Print, or Quit): "); scanf(" %c", &code); while (getchar() != '\n') /* skips to end of line */ ; switch (code) { case 'i': case 'I': insert(); break; case 's': case 'S': search(); break; case 'u': case 'U': update(); break; case 'p': case 'P': print(); break; case 'q': case 'Q': return 0; default: printf("Illegal code\n"); } } printf("\n"); return 0; } /********************************************************** * find_part: Looks up a part number in the inventory * * file. If the part is found, stores the part * * in p, and returns the part's file position. * * If the part is not found, returns 0. * **********************************************************/ int find_part(int number, Part* p) { FILE *fp; long int file_position; if ((fp = fopen(FILE_NAME, "rb")) == NULL) return 0; while (fread(p, sizeof(*p), 1, fp) != 0) if (p->number == number) { file_position = ftell(fp); fclose(fp); return file_position; } fclose(fp); return 0; } /********************************************************** * insert: Prompts the user for information about a new * * part and then inserts the part into the * * database. Prints an error message and returns * * prematurely if the part already exists. * **********************************************************/ void insert(void) { FILE *fp; Part p; int number; printf("Enter part number: "); scanf("%d", &number); if (find_part(number, &p) > 0) { printf("Part %d already exists.\n", p.number); return; } p.number = number; printf("Enter part name: "); read_line(p.name, NAME_LEN); printf("Enter quantity on hand: "); scanf("%d", &p.on_hand); if ((fp = fopen(FILE_NAME, "ab")) == NULL) { printf("Can't open file !\n"); exit(1); } fwrite(&p, sizeof(p), 1, fp); fclose(fp); } /********************************************************** * search: Prompts the user to enter a part number, then * * looks up the part in the database. If the part * * exists, prints the name and quantity on hand; * * if not, prints an error message. * **********************************************************/ void search(void) { Part p; int number; printf("Enter part number: "); scanf("%d", &number); if (find_part(number, &p) > 0) { printf("Part name: %s\n", p.name); printf("Quantity on hand: %d\n", p.on_hand); } else printf("Part not found.\n"); } /********************************************************** * update: Prompts the user to enter a part number. * * Prints an error message if the part doesn't * * exist; otherwise, prompts the user to enter * * change in quantity on hand and updates the * * database. * **********************************************************/ void update(void) { FILE *fp; long file_position; Part p; int number, change; printf("Enter part number: "); scanf("%d", &number); if ((file_position = find_part(number, &p)) > 0) { printf("Enter change in quantity on hand: "); scanf("%d", &change); p.on_hand += change; if ((fp = fopen(FILE_NAME, "rb+")) == NULL) { printf("Can't open file !\n"); exit(1); } fseek(fp, file_position - sizeof(p), SEEK_SET); fwrite(&p, sizeof(p), 1, fp); fclose(fp); } else printf("Part not found.\n"); } /********************************************************** * print: Prints a listing of all parts in the database, * * showing the part number, part name, and * * quantity on hand. Parts are printed in the * * order in which they were entered into the * * database. * **********************************************************/ void print(void) { FILE *fp; Part p; if ((fp = fopen(FILE_NAME, "rb")) == NULL) { printf("Can't open file !\n"); return; } printf("Part Number Part Name " "Quantity on Hand\n"); while (fread(&p, sizeof(p), 1, fp) != 0) printf("%7d %-25s%11d\n", p.number, p.name, p.on_hand); fclose(fp); } --------- ch22/parts/readline.c :------------------------- CUT HERE ---- /********************************************************* * From C PROGRAMMING: A MODERN APPROACH, by K. N. King * * Copyright (c) 1996 W. W. Norton & Company, Inc. * * All rights reserved. * * This program may be freely distributed for class use, * * provided that this copyright notice is retained. * *********************************************************/ /* readline.c (Chapter 16, page 345) */ #include <ctype.h> #include <stdio.h> #include "readline.h" int read_line(char str[], int n) { int ch, i = 0; while (isspace(ch = getchar())) ; while (ch != '\n' && ch != EOF) { if (i < n) str[i++] = ch; ch = getchar(); } str[i] = '\0'; return i; } --------- ch22/parts/readline.h :------------------------- CUT HERE ---- /********************************************************* * From C PROGRAMMING: A MODERN APPROACH, by K. N. King * * Copyright (c) 1996 W. W. Norton & Company, Inc. * * All rights reserved. * * This program may be freely distributed for class use, * * provided that this copyright notice is retained. * *********************************************************/ /* readline.h (Chapter 16, page 345) */ #ifndef READLINE_H #define READLINE_H /********************************************************** * read_line: Skips leading white-space characters, then * * reads the remainder of the input line and * * stores it in str. Truncates the line if its * * length exceeds n. Returns the number of * * characters stored. * **********************************************************/ int read_line(char str[], int n); #endif --------- ch23/anagram.c :------------------------- CUT HERE ---- /*********************************************************/ /* */ /* This program takes two strings as parameters, removes */ /* duplicate characters from them, and determines if the */ /* second string is an anagram of the first. */ /* */ /*********************************************************/ #include <stdio.h> #include <stdlib.h> #include <string.h> char *repeat_off(char *str); int is_anagram(char *str1, char *str2); main(int argc, char *argv[]) { char *str1, *str2; if (argc != 3){ printf("ANAGRAM needs two strings as parameters.\n"); printf("Type: ANAGRAM word1 word2\n"); return 0; } str1 = repeat_off(argv[1]); str2 = repeat_off(argv[2]); if (strlen(str1) != strlen(str2)) printf("NO ANAGRAM.\n"); else if (is_anagram(str1, str2)) printf("YES, an ANAGRAM.\n"); else printf("NO ANAGRAM.\n"); return 0; } char *repeat_off(char *str) { char *str1, *str2; str1 = str; while (*str1) { str2 = str1 + 1; while (*str2) if (*str1 != *str2) str2++; else memmove(str2, str2 + 1, strlen(str2)); str1++; } return str; } int is_anagram(char *str1, char *str2) { while (*str2) { if (!strchr(str1, *str2)) return 0; str2++; } return 1; } --------- ch23/tokens.c :------------------------- CUT HERE ---- /***********************************************************/ /* */ /* This program reads a string from the input and prints */ /* the words in it, each on a separate line. The program */ /* uses the strtok function to delimit words. */ /* */ /***********************************************************/ #include <stdio.h> #include <string.h> #define MAXLENGTH 1000 main() { char string[MAXLENGTH+1]; char delims[] = " `~!@#$%^&*()_+|-=\\\"\t\n;:',./<>?"; int c, i = 0; char *p; while ((c = getchar()) != EOF) if (i < MAXLENGTH) string[i++] = c; string[i] = '\0'; p = strtok(string, delims); while (p) { puts(p); p = strtok(NULL, delims); } return 0; } --------- ch24/hash/Makefile :------------------------- CUT HERE ---- all: hash hash: hash.o table.o gcc -g -Wall hash.o table.o -o hash hash.o: hash.c gcc -c -g -Wall hash.c table.o: table.c gcc -c -g -Wall table.c clean: rm -f hash.o table.o hash --------- ch24/hash/table.c :------------------------- CUT HERE ---- /*************************************/ /* Implementation of ADT Hash Table */ /*************************************/ #include <stdlib.h> #include <stdio.h> #include <string.h> #include <assert.h> #include <errno.h> #include "table.h" static int hash(const char* str); void initialize(Table tab) { int i; for (i = 0; i < MAXBUCKET; i++) tab[i] = EMPTYBUCKET; } int hash(const char *str) { int res; for (res=0; *str != '\n'; str++) res ^= (unsigned char) *str; return res % MAXBUCKET; } void insert(FILE* fptr, Table tab, const char *str, long position) { char str2[MAXLINE+1]; int index; assert((index = hash(str)) >= 0); if (tab[index] == EMPTYBUCKET) { tab[index] = position; return; } do { errno = 0; if (fseek(fptr, tab[index], SEEK_SET)) { printf("File error 1, program quits.\n"); exit(1); } fgets(str2, MAXLINE, fptr); if (strcmp(str, str2) == 0) return; index = (index + 1) % MAXBUCKET; assert(index >= 0); } while (index != EMPTYBUCKET); tab[index] = position; } void retrieve(FILE* fptr, const Table tab, const char *str) { char str2[MAXLINE+1]; int index, comparisons = 0, found; assert((index = hash(str)) >= 0); do { if (tab[index] == EMPTYBUCKET) { found = 0; break; } errno = 0; if (fseek(fptr, tab[index], SEEK_SET)) { printf("File error 2, program quits.\n"); exit(1); } fgets(str2, MAXLINE, fptr); comparisons++; if ((found = (strcmp(str, str2) == 0))) break; index = (index + 1) % MAXBUCKET; } while (index != EMPTYBUCKET); if (found) printf(" String found. "); else printf(" String not found. "); printf("Needed %d comparison(s).\n", comparisons); } void print(FILE* fptr, const Table tab) { int i; char str[MAXLINE+1]; printf("\nHash Table:\n"); printf("Index FPOS String\n"); printf("-----------------------------\n"); for (i = 0; i < MAXBUCKET; i++) { printf("%4d %6ld: ", i, tab[i]); if (tab[i] == EMPTYBUCKET) printf("<EMPTY BUCKET>\n"); else { fseek(fptr, tab[i], SEEK_SET); fgets(str, MAXLINE, fptr); printf("%s", str); } } } --------- ch24/hash/hash.c :------------------------- CUT HERE ---- /*********************************************************/ /* This program stores the position of each string in */ /* the input file, in a hash table. Efficient retrieval */ /* of strings can then be performed. The program deals */ /* with some of the error conditions that may arise, */ /* using the <errno.h> and <assert.h> libraries. */ /*********************************************************/ #include <stdio.h> #include <stdlib.h> #include <assert.h> #include <errno.h> #include "table.h" main(int argc, char *argv[]) { FILE *fptr; Table tab; char str[MAXLINE+1]; long position, new_position; initialize(tab); if (argc < 2) { printf("Program requires name of data file.\n"); exit(1); } errno = 0; if ((fptr = fopen(argv[1], "r")) == NULL) { printf("File error 3: Cannot open file %s.\n", argv[1]); exit(1); } new_position = 0; printf("Reading strings from file '%s' ...\n", argv[1]); while (1) { position = new_position; fseek(fptr, position, SEEK_SET); if (fgets(str, MAXLINE, fptr) == NULL) break; new_position = ftell(fptr); insert(fptr, tab, str, position); } #ifndef NDEBUG print(fptr, tab); #endif while(1) { printf("Please enter a string: "); if (fgets(str, MAXLINE, stdin) == NULL) break; if (str[0] == '\n') break; retrieve(fptr, tab, str); } fclose(fptr); return 0; } --------- ch24/hash/table.h :------------------------- CUT HERE ---- /*************************************/ /* table.h -- ADT Hash Table */ /*************************************/ #ifndef TABLE_H #define TABLE_H #define MAXBUCKET 256 /* Max number of buckets */ #define MAXLINE 100 /* Max number of chars per line */ #define EMPTYBUCKET -1 typedef long Table[MAXBUCKET]; void initialize(Table tab); void insert(FILE* fptr, Table tab, const char *str, long position); void retrieve(FILE* fptr, const Table tab, const char *str); void print(FILE* fptr, const Table tab); #endif --------- ch24/file_printer.c :------------------------- CUT HERE ---- #include <stdio.h> #include <signal.h> #include <setjmp.h> #include <string.h> #define NAME_SIZE 128 jmp_buf env; FILE *fptr; void handler(int sig); void print_file(void); main() { char name[NAME_SIZE+1], *p; setjmp(env); while(1) { signal(SIGINT, SIG_IGN); printf("File: "); fgets(name, NAME_SIZE, stdin); if ((p = strchr(name, '\n')) != NULL) *p = '\0'; if (name[0] == '\0') break; if ((fptr = fopen(name, "r")) != NULL) { signal(SIGINT, handler); print_file(); } else fprintf(stderr, "Can't open file!\n"); } return 0; } void handler(int sig) { fprintf(stderr, "program interrupted !\n"); fprintf(stderr, "Closing file.\n"); fclose(fptr); longjmp(env, 1); } void print_file(void) { int c; while ((c = getc(fptr)) != EOF) putchar(c); } --------- ch25/locale.c :------------------------- CUT HERE ---- #include <locale.h> #include <stdio.h> #include <stdlib.h> #include <limits.h> #include <string.h> #define MAX_NAME 100 void printstring(const char *title, const char *str); void printchar(const char *title, char c); main() { struct lconv *p; char name[MAX_NAME+1]; char *temp; printf("Please enter name of locale: "); fgets(name, MAX_NAME, stdin); if ((temp = strchr(name, '\n')) != NULL) *temp = '\0'; printf("LOCALE is \"%s\"\n", name); temp = setlocale(LC_ALL, name); if (temp == NULL) { printf("That locale is not available.\n"); exit(1); } p = localeconv(); printstring("decimal_point ", p->decimal_point); printstring("thousands_sep ", p->thousands_sep); printstring("grouping ", p->grouping); printstring("int_curr_symbol ", p->int_curr_symbol); printstring("currency_symbol ", p->currency_symbol); printstring("mon_decimal_point", p->mon_decimal_point); printstring("mon_thousands_sep", p->mon_thousands_sep); printstring("mon_grouping ", p->mon_grouping); printstring("positive_sign ", p->positive_sign); printstring("negative_sign ", p->negative_sign); printchar("int_frac_digits ", p->int_frac_digits); printchar("frac_digits ", p->frac_digits); printchar("p_cs_precedes ", p->p_cs_precedes); printchar("p_sep_by_space ", p->p_sep_by_space); printchar("p_sign_posn ", p->p_sign_posn); printchar("n_cs_precedes ", p->n_cs_precedes); printchar("n_sep_by_space ", p->n_sep_by_space); printchar("n_sign_posn ", p->n_sign_posn); return 0; } void printstring(const char *title, const char *str) { printf("%s: \"%s\"\n", title, str); } void printchar(const char *title, char c) { printf("%s: ", title); if (c == CHAR_MAX) printf("UNAVAILABLE\n"); else printf("%d\n", c); } --------- ch26/sort.c :------------------------- CUT HERE ---- #include <stdio.h> #include <stdlib.h> #include <stdarg.h> #include <time.h> #include <string.h> #define MAX_STR_LEN 30 #define CONVERSION_BASE 10 #define NUMS_PER_LINE 10 #define DEBUG clock_t before, after; time_t start_time; int compare(const void *a, const void *b); void print_array(int a[], int array_size); void debug(const char *fname, const char *format, ...); void check_endptr(const char *endptr); void report_timing(void); main() { int i, *a, array_size, max_value; char s[MAX_STR_LEN+1]; char *endptr, *p; atexit(report_timing); start_time = time(NULL); printf("How many random values to sort? "); fgets(s, MAX_STR_LEN, stdin); if ((p = strchr(s, '\n')) != NULL) *p = '\0'; array_size = strtol(s, &endptr, CONVERSION_BASE); check_endptr(endptr); #ifdef DEBUG debug("main", "array_size is %d\n", array_size); #endif a = malloc(sizeof(int) * array_size); printf("Largest random value? "); fgets(s, MAX_STR_LEN, stdin); if ((p = strchr(s, '\n')) != NULL) *p = '\0'; max_value = strtol(s, &endptr, CONVERSION_BASE); check_endptr(endptr); #ifdef DEBUG debug("main", "max_value is %d\n", max_value); #endif srand((unsigned)time(NULL)); for (i = 0; i < array_size; i++) { a[i] = rand() % (max_value + 1); } print_array(a, array_size); #ifdef DEBUG debug("main", "begin sorting ...\n"); #endif before = clock(); qsort(a, array_size, sizeof(a[0]), compare); after = clock(); #ifdef DEBUG debug("main", "end sorting ...\n"); #endif print_array(a, array_size); return 0; } int compare(const void *a, const void *b) { int na = *(int *)a; int nb = *(int *)b; if (na < nb) return -1; if (na == nb) return 0; else return 1; } void print_array(int a[], int array_size) { int i; #ifdef DEBUG debug("print_array", "begin printing ...\n"); #endif for (i = 0; i < array_size; i++) { if (i % NUMS_PER_LINE == 0) printf("\n"); printf("%4d ", a[i]); } printf("\n"); #ifdef DEBUG debug("print_array", "end printing ...\n"); #endif } void debug(const char *fname, const char *format, ...) { va_list args; printf("DEBUGGING %s: ", fname); va_start(args, format); vprintf(format, args); va_end(args); } void check_endptr(const char *endptr) { if (*endptr != '\0') { debug("main", "input error: bad character is `%c`\n", *endptr); abort(); } } void report_timing(void) { clock_t elapsed; time_t t; elapsed = after - before; printf("Processor time = %6.2f ticks = %.2f seconds\n", (double)elapsed, (double)elapsed / CLOCKS_PER_SEC); t = time(NULL); printf("Elapsed time = %.2f seconds.\n", difftime(t, start_time)); printf("Program ends: %s", ctime(&t)); }