├── README ├── ch1 ├── Makefile ├── ex_ch1_1.c ├── ex_ch1_2.c ├── ex_ch1_3.c ├── ex_ch1_4.c ├── ex_ch1_5.c └── ex_ch1_6.c ├── ch2 ├── ex1 │ ├── Makefile │ ├── increment.c │ ├── increment.h │ ├── main.c │ ├── negate.c │ └── negate.h └── ex2 │ ├── Makefile │ └── braces_paired.c ├── ch4 ├── ex1 │ ├── Makefile │ └── sqrt_approx.c ├── ex2 │ ├── Makefile │ └── naive_prime.c ├── ex3 │ ├── Makefile │ └── triangle.c ├── ex4 │ ├── Makefile │ └── copy_n.c ├── ex5 │ ├── Makefile │ └── print_dup_lines.c ├── ex6 │ ├── Makefile │ └── substr.c └── ex7 │ ├── Makefile │ └── deblank.c ├── ch5 ├── bit_array │ ├── Makefile │ ├── bit_array.c │ └── bit_array.h ├── encrypt │ ├── Makefile │ └── encrypt.c ├── expression │ ├── Makefile │ └── expression.c ├── reverse_bits │ ├── Makefile │ └── reverse_bits.c ├── store_bit_field │ ├── Makefile │ └── store_bit_field.c └── to_lower │ ├── Makefile │ └── to_lower.c ├── ch6 ├── del_substr │ ├── Makefile │ └── del_substr.c ├── find_char │ ├── Makefile │ └── find_char.c ├── reverse_string │ ├── Makefile │ └── reverse_string.c ├── sieve1 │ ├── Makefile │ └── sieve1.c └── sieve_bits │ ├── Makefile │ ├── bit_array.c │ ├── bit_array.h │ └── sieve_bits.c ├── ch7 ├── ascii_to_int │ ├── Makefile │ └── ascii_to_int.c ├── basic_printf │ ├── Makefile │ └── basic_printf.c ├── gcd │ ├── Makefile │ └── gcd.c ├── hermite │ ├── Makefile │ └── hermite.c ├── max_list │ ├── Makefile │ └── max_list.c └── written_amount │ ├── Makefile │ └── written_amount.c ├── ch8 ├── char_values │ ├── Makefile │ └── char_values.c ├── flat_indentity_matrix │ ├── Makefile │ └── flat_identity_matrix.c ├── identity_matrix │ ├── Makefile │ └── identity_matrix.c ├── matrix_multiply │ ├── Makefile │ └── matrix_multiply.c └── single_tax │ ├── Makefile │ └── single_tax.c └── ch9 ├── char_percent ├── Makefile └── char_percent.c ├── count_chars ├── Makefile └── count_chars.c ├── encryption ├── Makefile └── encryption.c ├── my_strcpy ├── Makefile └── my_strcpy.c ├── my_strcpy_end ├── Makefile └── my_strcpy_end.c ├── my_strncat ├── Makefile └── my_strncat.c ├── my_strnchr ├── Makefile └── my_strnchr.c ├── my_strnlen ├── Makefile └── my_strnlen.c ├── my_strrchr ├── Makefile └── my_strrchr.c ├── palindrome ├── Makefile └── palindrome.c └── the_count ├── Makefile └── the_count.c /README: -------------------------------------------------------------------------------- 1 | pointers-on-c 2 | 3 | My solutions for exercises in Kenneth Reek's book Pointers on C. 4 | -------------------------------------------------------------------------------- /ch1/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS=-Wall -g 2 | 3 | all: 4 | gcc -o ex_ch1_1 ex_ch1_1.c 5 | gcc -o ex_ch1_2 ex_ch1_2.c 6 | gcc -o ex_ch1_3 ex_ch1_3.c 7 | gcc -o ex_ch1_4 ex_ch1_4.c 8 | gcc -o ex_ch1_5 ex_ch1_5.c 9 | gcc -o ex_ch1_6 ex_ch1_6.c 10 | 11 | clean: 12 | rm -f ex_ch1_1 13 | rm -f ex_ch1_2 14 | rm -f ex_ch1_3 15 | rm -f ex_ch1_4 16 | rm -f ex_ch1_5 17 | rm -f ex_ch1_6 18 | -------------------------------------------------------------------------------- /ch1/ex_ch1_1.c: -------------------------------------------------------------------------------- 1 | /* 2 | Pointers on C - Chapter 1 - Exercise 1 3 | ex_ch1_1.c - Hello, world! 4 | 5 | author: nicolas steven miller 6 | */ 7 | 8 | #include 9 | 10 | int main(int argc, char* argv[]) 11 | { 12 | printf("Hello, world!\n"); 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /ch1/ex_ch1_2.c: -------------------------------------------------------------------------------- 1 | /* 2 | Pointers on C - Chapter 1 - Exercise 2 3 | ex_ch1_2.c - Input line echoer w/ line numbers 4 | 5 | author: nicolas steven miller 6 | */ 7 | 8 | #include 9 | 10 | int main(int argc, char* argv[]) 11 | { 12 | int character = 0; 13 | int line = 0; 14 | 15 | while(1) { 16 | int print_line_num = 1; 17 | while((character = getchar()) != EOF && character != '\n') { 18 | if(print_line_num) { 19 | printf("%d: ", line); 20 | print_line_num = 0; 21 | } 22 | putchar(character); 23 | } 24 | if(character == EOF) 25 | break; 26 | putchar('\n'); 27 | line++; 28 | } 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /ch1/ex_ch1_3.c: -------------------------------------------------------------------------------- 1 | /* 2 | Pointers on C - Chapter 1 - Exercise 3 3 | ex_ch1_3.c - Input line echoer w/ checksum (ignoring overflow) 4 | 5 | author: nicolas steven miller 6 | */ 7 | 8 | #include 9 | 10 | int main(int argc, char* argv[]) 11 | { 12 | int character = 0; 13 | char checksum = -1; 14 | while((character = getchar()) != EOF) { 15 | checksum += character; 16 | putchar(character); 17 | if(character == '\n') 18 | break; 19 | } 20 | printf("%d\n", checksum); 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /ch1/ex_ch1_4.c: -------------------------------------------------------------------------------- 1 | /* 2 | Pointers on C - Chapter 1 - Exercise 4 3 | ex_ch1_4.c - Read a series of input lines, compute length of each, print 4 | only the longest assuming 1000 character max line length (scary...) 5 | 6 | author: nicolas steven miller 7 | */ 8 | 9 | #include 10 | #include 11 | #define MAX_LINE_LENGTH 1000 12 | 13 | int main(int argc, char* argv[]) 14 | { 15 | char buf[MAX_LINE_LENGTH]; 16 | char max_buf[MAX_LINE_LENGTH]; 17 | int max_length = 0; 18 | int length = 0; 19 | int ch = 0; 20 | 21 | while((ch = getchar()) != EOF) { 22 | buf[length++] = ch; 23 | 24 | if(ch == '\n') { 25 | buf[length] = '\0'; 26 | if(length > max_length) { 27 | max_length = length; 28 | strncpy(max_buf, buf, length + 1); 29 | } 30 | 31 | length = 0; 32 | } 33 | } 34 | printf("%s", max_buf); 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /ch1/ex_ch1_5.c: -------------------------------------------------------------------------------- 1 | /* 2 | Pointers on C - Chapter 1 - Exercise 5 3 | ex_ch1_5.c - Modify rearrange function in chapter example for non-increasing order inputs 4 | 5 | author: nicolas steven miller 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #define MAX_COLS 20 13 | #define MAX_INPUT_LENGTH 1000 14 | 15 | int read_column_numbers(int columns[], int max); 16 | void rearrange(char* output, char const *input, int n_columns, int columns[]); 17 | void selection_sort(int columns[], int n_columns); 18 | void print_columns(int const columns[], int n_columns); 19 | 20 | int main(void) 21 | { 22 | int n_columns; 23 | int columns[MAX_COLS]; 24 | char input[MAX_INPUT_LENGTH]; 25 | char output[MAX_INPUT_LENGTH]; 26 | 27 | n_columns = read_column_numbers(columns, MAX_COLS); 28 | 29 | printf("unsorted columns: "); 30 | print_columns(columns, n_columns); 31 | selection_sort(columns, n_columns); // sort columns array in place 32 | printf("sorted columns: "); 33 | print_columns(columns, n_columns); 34 | 35 | while(gets(input) != NULL) { 36 | printf("Original input: %s\n", input); 37 | rearrange(output, input, n_columns, columns); 38 | printf("Rearranged line: %s\n", output); 39 | } 40 | 41 | return EXIT_SUCCESS; 42 | } 43 | 44 | int read_column_numbers(int columns[], int max) 45 | { 46 | int num = 0; 47 | int ch; 48 | 49 | while(num < max && scanf("%d", &columns[num]) == 1 50 | && columns[num] >= 0) 51 | num += 1; 52 | 53 | if(num % 2 != 0) { 54 | puts("Last column number is not paired."); 55 | exit(EXIT_FAILURE); 56 | } 57 | 58 | while((ch = getchar()) != EOF && ch != '\n'); 59 | 60 | return num; 61 | } 62 | 63 | int find_min_in_range(int start, int n_columns, int columns[]) 64 | { 65 | int current_min = INT_MAX; 66 | int min_index; 67 | int i; 68 | for(i = start; i < n_columns; i++) { 69 | if(columns[i] < current_min) { 70 | current_min = columns[i]; 71 | min_index = i; 72 | } 73 | } 74 | return min_index; 75 | } 76 | 77 | void selection_sort(int columns[], int n_columns) 78 | { 79 | int min_index; 80 | int temp; 81 | int i; 82 | 83 | for(i = 0; i < n_columns; i++) { 84 | min_index = find_min_in_range(i, n_columns, columns); 85 | temp = columns[i]; 86 | columns[i] = columns[min_index]; 87 | columns[min_index] = temp; 88 | } 89 | } 90 | 91 | void print_columns(int const columns[], int n_columns) 92 | { 93 | int i; 94 | for(i = 0; i < n_columns; i++) 95 | printf("%d ", columns[i]); 96 | 97 | printf("\n"); 98 | } 99 | 100 | void rearrange(char* output, char const *input, int n_columns, 101 | int columns[]) 102 | { 103 | int col; 104 | int output_col; 105 | int len; 106 | 107 | len = strlen(input); 108 | output_col = 0; 109 | 110 | for(col = 0; col < n_columns; col += 2) { 111 | int nchars = columns[col + 1] - columns[col] + 1; 112 | 113 | if(columns[col] >= len || 114 | output_col == MAX_INPUT_LENGTH - 1) 115 | break; 116 | 117 | if(output_col + nchars > MAX_INPUT_LENGTH - 1) 118 | nchars = MAX_INPUT_LENGTH - output_col - 1; 119 | 120 | strncpy(output + output_col, input + columns[col], nchars); 121 | output_col += nchars; 122 | } 123 | 124 | output[output_col] = '\0'; 125 | } 126 | 127 | -------------------------------------------------------------------------------- /ch1/ex_ch1_6.c: -------------------------------------------------------------------------------- 1 | /* 2 | Pointers on C - Chapter 1 - Exercise 6 3 | ex_ch1_6.c - Modify rearrange program to allow for odd number of column inputs 4 | last index copies from there to end of input 5 | 6 | author: nicolas steven miller 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #define MAX_COLS 20 14 | #define MAX_INPUT_LENGTH 1000 15 | 16 | int read_column_numbers(int columns[], int max); 17 | void rearrange(char* output, char const *input, int n_columns, int columns[]); 18 | void selection_sort(int columns[], int n_columns); 19 | void print_columns(int const columns[], int n_columns); 20 | 21 | int main(void) 22 | { 23 | int n_columns; 24 | int columns[MAX_COLS]; 25 | char input[MAX_INPUT_LENGTH]; 26 | char output[MAX_INPUT_LENGTH]; 27 | 28 | n_columns = read_column_numbers(columns, MAX_COLS); 29 | 30 | printf("unsorted columns: "); 31 | print_columns(columns, n_columns); 32 | selection_sort(columns, n_columns); // sort columns array in place 33 | printf("sorted columns: "); 34 | print_columns(columns, n_columns); 35 | 36 | while(gets(input) != NULL) { 37 | printf("Original input: %s\n", input); 38 | rearrange(output, input, n_columns, columns); 39 | printf("Rearranged line: %s\n", output); 40 | } 41 | 42 | return EXIT_SUCCESS; 43 | } 44 | 45 | int read_column_numbers(int columns[], int max) 46 | { 47 | int num = 0; 48 | int ch; 49 | 50 | while(num < max && scanf("%d", &columns[num]) == 1 51 | && columns[num] >= 0) 52 | num += 1; 53 | 54 | while((ch = getchar()) != EOF && ch != '\n'); 55 | 56 | return num; 57 | } 58 | 59 | int find_min_in_range(int start, int n_columns, int columns[]) 60 | { 61 | int current_min = INT_MAX; 62 | int min_index; 63 | int i; 64 | for(i = start; i < n_columns; i++) { 65 | if(columns[i] < current_min) { 66 | current_min = columns[i]; 67 | min_index = i; 68 | } 69 | } 70 | return min_index; 71 | } 72 | 73 | void selection_sort(int columns[], int n_columns) 74 | { 75 | int min_index; 76 | int temp; 77 | int i; 78 | 79 | for(i = 0; i < n_columns; i++) { 80 | min_index = find_min_in_range(i, n_columns, columns); 81 | temp = columns[i]; 82 | columns[i] = columns[min_index]; 83 | columns[min_index] = temp; 84 | } 85 | } 86 | 87 | void print_columns(int const columns[], int n_columns) 88 | { 89 | int i; 90 | for(i = 0; i < n_columns; i++) 91 | printf("%d ", columns[i]); 92 | 93 | printf("\n"); 94 | } 95 | 96 | void rearrange(char* output, char const *input, int n_columns, 97 | int columns[]) 98 | { 99 | int col; 100 | int output_col; 101 | int len; 102 | 103 | len = strlen(input); 104 | output_col = 0; 105 | 106 | for(col = 0; col < n_columns; col += 2) { 107 | int nchars; 108 | 109 | // if we've reached the last column index and it's not paired 110 | // copy to the end of the input line 111 | if(n_columns % 2 != 0 && col == n_columns - 1) { 112 | nchars = MAX_INPUT_LENGTH - columns[col] + 1; 113 | } 114 | else { 115 | nchars = columns[col + 1] - columns[col] + 1; 116 | } 117 | 118 | if(columns[col] >= len || 119 | output_col == MAX_INPUT_LENGTH - 1) 120 | break; 121 | 122 | if(output_col + nchars > MAX_INPUT_LENGTH - 1) 123 | nchars = MAX_INPUT_LENGTH - output_col - 1; 124 | 125 | strncpy(output + output_col, input + columns[col], nchars); 126 | output_col += nchars; 127 | } 128 | 129 | output[output_col] = '\0'; 130 | } 131 | 132 | -------------------------------------------------------------------------------- /ch2/ex1/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS=-Wall -g 2 | 3 | all: 4 | gcc -o test_inc_neg increment.c negate.c main.c 5 | 6 | clean: 7 | rm -f test_inc_neg 8 | 9 | -------------------------------------------------------------------------------- /ch2/ex1/increment.c: -------------------------------------------------------------------------------- 1 | /* 2 | Pointers on C - Chapter 2 - Exercise 1 3 | increment.c - increment function for ex1 4 | 5 | author: nicolas steven miller 6 | */ 7 | 8 | int increment(int i) 9 | { 10 | return i + 1; 11 | } 12 | -------------------------------------------------------------------------------- /ch2/ex1/increment.h: -------------------------------------------------------------------------------- 1 | int increment(int i); 2 | -------------------------------------------------------------------------------- /ch2/ex1/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | Pointers on C - Chapter 2 - Exercise 1 3 | main.c - main test function for increment and negate functions 4 | 5 | author: nicolas steven miller 6 | */ 7 | #include 8 | #include "increment.h" 9 | #include "negate.h" 10 | 11 | int main(int argc, char* argv[]) 12 | { 13 | printf("increment(10) : %d\n", increment(10)); 14 | printf("increment(0) : %d\n", increment(0)); 15 | printf("increment(-10) : %d\n", increment(-10)); 16 | printf("negate(10) : %d\n", negate(10)); 17 | printf("negate(0) : %d\n", negate(0)); 18 | printf("negate(-10) : %d\n", negate(-10)); 19 | return 1; 20 | } 21 | 22 | -------------------------------------------------------------------------------- /ch2/ex1/negate.c: -------------------------------------------------------------------------------- 1 | /* 2 | Pointers on C - Chapter 2 - Exercise 1 3 | increment.c - increment function for ex1 4 | 5 | author: nicolas steven miller 6 | */ 7 | 8 | int negate(int i) 9 | { 10 | return -1 * i; 11 | } 12 | -------------------------------------------------------------------------------- /ch2/ex1/negate.h: -------------------------------------------------------------------------------- 1 | int negate(int i); 2 | -------------------------------------------------------------------------------- /ch2/ex2/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS=-Wall -g 2 | 3 | wall: 4 | gcc -o braces_paired braces_paired.c 5 | clean: 6 | rm -f braces_paired 7 | -------------------------------------------------------------------------------- /ch2/ex2/braces_paired.c: -------------------------------------------------------------------------------- 1 | /* 2 | Pointers on Pointers on C - Chapter 2 - Exercise 2 3 | braces_paired.c - verifies that braces in a c source file are paired 4 | (without worrying about braces nested in comments and string or 5 | character literals 6 | 7 | author: nicolas steven miller 8 | */ 9 | #include 10 | 11 | int main(int argc, char* argv[]) 12 | { 13 | int braces = 0; 14 | int ch; 15 | 16 | while((ch = getchar()) != EOF) { 17 | if(ch == '{') 18 | braces++; 19 | else if(ch == '}') 20 | braces--; 21 | } 22 | 23 | if(braces == 0) 24 | printf("braces balanced\n"); 25 | else 26 | printf("braces unbalanced\n"); 27 | 28 | return 1; 29 | } 30 | -------------------------------------------------------------------------------- /ch4/ex1/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS=-Wall -g 2 | 3 | all: 4 | gcc -o sqrt_approx sqrt_approx.c 5 | 6 | clean: 7 | rm -f sqrt_approx 8 | -------------------------------------------------------------------------------- /ch4/ex1/sqrt_approx.c: -------------------------------------------------------------------------------- 1 | /* 2 | Pointers on C - Chapter 4 - Exercise 1 3 | sqrt_approx.c - sqrt approximation 4 | 5 | author: nicolas steven miller 6 | */ 7 | #include 8 | #define DEBUG 9 | 10 | float sqrt_approx(float n) 11 | { 12 | float approx = 1.0f; 13 | unsigned long int iterations = 0; 14 | while(1) { 15 | iterations++; 16 | float next_approx = (approx + (n / approx)) / 2; 17 | if(next_approx == approx) 18 | break; 19 | approx = next_approx; 20 | } 21 | 22 | #ifdef DEBUG 23 | printf("num iterations: %d\n", iterations); 24 | #endif 25 | 26 | return approx; 27 | } 28 | 29 | int main(int argc, char* argv[]) 30 | { 31 | printf("sqrt_approx(2.0): %f\n", sqrt_approx(2.0f)); 32 | printf("sqrt_approx(16.0): %f\n", sqrt_approx(16.0f)); 33 | printf("sqrt_approx(100.0): %f\n", sqrt_approx(100.0f)); 34 | printf("sqrt_approx(4.2): %f\n", sqrt_approx(4.2f)); 35 | return 1; 36 | } 37 | -------------------------------------------------------------------------------- /ch4/ex2/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS=-Wall -g 2 | 3 | all: 4 | gcc -o naive_prime naive_prime.c 5 | 6 | clean: 7 | rm -f naive_prime 8 | -------------------------------------------------------------------------------- /ch4/ex2/naive_prime.c: -------------------------------------------------------------------------------- 1 | /* 2 | Pointers on C - Chapter 4 - Exercise 2 3 | naive_prime.c - naive method for printing primes from 1-100 4 | 5 | author: nicolas steven miller 6 | */ 7 | #include 8 | 9 | int main(int argc, char* argv[]) 10 | { 11 | int i, j; 12 | int prime; 13 | for(i = 1; i < 100; i++) { 14 | prime = 1; 15 | for(j = 2; j < i; j++) { 16 | if(i % j == 0) 17 | prime = 0; 18 | } 19 | if(prime) 20 | printf("%d\n", i); 21 | } 22 | 23 | return 1; 24 | } 25 | -------------------------------------------------------------------------------- /ch4/ex3/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS=-Wall -g 2 | 3 | all: 4 | gcc -o triangle triangle.c 5 | 6 | clean: 7 | rm -f triangle 8 | -------------------------------------------------------------------------------- /ch4/ex3/triangle.c: -------------------------------------------------------------------------------- 1 | /* 2 | Pointers on C - Chapter 4 - Exercise 3 3 | triangle.c - determine type of triangle for integer side length inputs 4 | 5 | author: nicolas steven miller 6 | */ 7 | #include 8 | #include 9 | 10 | int main(int argc, char* argv[]) 11 | { 12 | char triangle[3]; 13 | printf("Enter 3 side lengths separate by spaces: "); 14 | if(scanf("%d %d %d", 15 | &triangle[0], 16 | &triangle[1], 17 | &triangle[2]) != 3) { 18 | printf("Invalid input.\n"); 19 | exit(1); 20 | } 21 | 22 | if(triangle[0] < 1 || 23 | triangle[1] < 1 || 24 | triangle[2] < 1) { 25 | printf("Bad side length.\n"); 26 | exit(1); 27 | } 28 | 29 | if(triangle[0] == triangle[1] && 30 | triangle[0] == triangle[2]) { 31 | printf("equalateral\n"); 32 | } 33 | else if(triangle[0] == triangle[1] || 34 | triangle[0] == triangle[2] || 35 | triangle[1] == triangle[2]) { 36 | printf("isosceles\n"); 37 | } 38 | else { 39 | printf("scalene\n"); 40 | } 41 | 42 | return 1; 43 | } 44 | -------------------------------------------------------------------------------- /ch4/ex4/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS=-Wall -g 2 | 3 | all: 4 | gcc -o copy_n copy_n.c 5 | 6 | clean: 7 | rm -f copy_n 8 | -------------------------------------------------------------------------------- /ch4/ex4/copy_n.c: -------------------------------------------------------------------------------- 1 | /* 2 | Pointers on C - Chapter 4 - Exercise 4 3 | copy_n.c - copy_n function and main test function 4 | 5 | author: nicolas steven miller 6 | */ 7 | #include 8 | #include 9 | 10 | void copy_n(char dst[], char src[], int n) { 11 | int len = strlen(src); 12 | int i; 13 | for(i = 0; i < n; i++) { 14 | if(i < len) 15 | dst[i] = src[i]; 16 | else 17 | dst[i] = '\0'; 18 | } 19 | } 20 | 21 | int main(int argc, char* argv[]) 22 | { 23 | char src[] = "foobar"; 24 | char dst[32]; 25 | copy_n(dst, src, 2); // n < len; not nul terminated 26 | dst[2] = '\0'; 27 | printf("%s\n", dst); 28 | copy_n(dst, src, 4); // n < len; not nul terminated 29 | dst[4] = '\0'; 30 | printf("%s\n", dst); 31 | copy_n(dst, src, 6); // n == len; not nul terminated 32 | dst[6] = '\0'; 33 | printf("%s\n", dst); 34 | copy_n(dst, src, 16); // n >= len; nul terminated 35 | printf("%s\n", dst); 36 | return 1; 37 | } 38 | -------------------------------------------------------------------------------- /ch4/ex5/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS=-Wall -g 2 | 3 | all: 4 | gcc -o print_dup_lines print_dup_lines.c 5 | 6 | clean: 7 | rm -f print_dup_lines 8 | -------------------------------------------------------------------------------- /ch4/ex5/print_dup_lines.c: -------------------------------------------------------------------------------- 1 | /* 2 | Pointers on C - Chapter 4 - Exercise 5 3 | print_dup_lines.c - prints one copy of each set of identical input lines 4 | assuming max line length of 128 5 | 6 | author: nicolas steven miller 7 | */ 8 | 9 | #include 10 | #include 11 | 12 | #define MAX_LINE_LENGTH 128 13 | 14 | int main(int argc, char* argv[]) 15 | { 16 | char past[MAX_LINE_LENGTH]; 17 | char input[MAX_LINE_LENGTH]; 18 | int should_print = 0; 19 | while(gets(input) != NULL) { 20 | if(strcmp(input, past) == 0) 21 | should_print = 1; 22 | else if(should_print) { 23 | printf("%s\n", past); 24 | should_print = 0; 25 | } 26 | strcpy(past, input); 27 | } 28 | 29 | return 1; 30 | } 31 | -------------------------------------------------------------------------------- /ch4/ex6/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS=-Wall -g 2 | 3 | all: 4 | gcc -o substr substr.c 5 | 6 | clean: 7 | rm -f substr 8 | -------------------------------------------------------------------------------- /ch4/ex6/substr.c: -------------------------------------------------------------------------------- 1 | /* 2 | Pointers on C - Chapter 4 - Exercise 6 3 | substr.c - substr function and main test function 4 | following req'ts given in ex writeup 5 | 6 | author: nicolas steven miller 7 | */ 8 | 9 | #include 10 | #include 11 | 12 | #define MAX_LINE_LENGTH 128 13 | 14 | int substr(char dst[], char src[], int start, int len) { 15 | int src_len = strlen(src); 16 | int i, j; 17 | 18 | if(start >= src_len || 19 | start < 0 || 20 | len < 0) { 21 | dst[0] = '\0'; 22 | return 0; 23 | } 24 | for(i = start, j = 0; i < start + len; i++, j++) 25 | dst[j] = src[i]; 26 | dst[j] = '\0'; 27 | return strlen(dst); 28 | } 29 | 30 | int main(int argc, char* argv[]) 31 | { 32 | char *str = "foobarbaz"; 33 | char dest1[16]; 34 | char dest2[16]; 35 | char dest3[16]; 36 | char dest4[16]; 37 | printf("%d\n", substr(dest1, str, 0, 5)); 38 | printf("%d\n", substr(dest2, str, 2, 3)); 39 | printf("%d\n", substr(dest3, str, 7, 2)); 40 | printf("%d\n", substr(dest4, str, 24, 5)); 41 | printf("dest1: %s\n", dest1); 42 | printf("dest2: %s\n", dest2); 43 | printf("dest3: %s\n", dest3); 44 | printf("dest4: %s\n", dest4); 45 | 46 | return 1; 47 | } 48 | -------------------------------------------------------------------------------- /ch4/ex7/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS=-Wall -g 2 | 3 | all: 4 | gcc -o deblank deblank.c 5 | 6 | clean: 7 | rm -f deblank 8 | -------------------------------------------------------------------------------- /ch4/ex7/deblank.c: -------------------------------------------------------------------------------- 1 | /* 2 | Pointers on C - Chapter 4 - Exercise 7 3 | deblank.c - deblank function, replace consecutive spaces 4 | with a single space and main test function 5 | 6 | author: nicolas steven miller 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #define MAX_LINE_LENGTH 128 14 | 15 | void deblank(char string[]) 16 | { 17 | int len = strlen(string); 18 | int i, j; 19 | char *buffer = (char *) malloc(len + 1); 20 | char last_char = 'q'; 21 | strcpy(buffer, string); 22 | for(i = 0, j = 0; i < len; i++) { 23 | if(buffer[i] == ' ' && last_char == ' ') 24 | continue; 25 | string[j] = buffer[i]; 26 | last_char = buffer[i]; 27 | j++; 28 | } 29 | string[j] = '\0'; 30 | free(buffer); 31 | } 32 | 33 | int main(int argc, char* argv[]) 34 | { 35 | char s1[] = " foo bar baz "; 36 | char s2[] = "foo bar baz "; 37 | char s3[] = "f oo"; 38 | deblank(s1); 39 | deblank(s2); 40 | deblank(s3); 41 | printf("%s\n", s1); 42 | printf("%s\n", s2); 43 | printf("%s\n", s3); 44 | 45 | return 1; 46 | } 47 | -------------------------------------------------------------------------------- /ch5/bit_array/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS=-Wall -g 2 | 3 | all: 4 | gcc -o bit_array bit_array.c 5 | 6 | clean: 7 | rm -f bit_array 8 | -------------------------------------------------------------------------------- /ch5/bit_array/bit_array.c: -------------------------------------------------------------------------------- 1 | /* 2 | Pointers on c - ch5, ex4 3 | bit_array.c - bit_array functions and main test function 4 | bit_numbers start from zero 5 | 6 | author: nicolas miller 7 | */ 8 | 9 | #include 10 | #include 11 | #include "bit_array.h" 12 | 13 | #define ARRAY_SIZE 32 14 | 15 | unsigned int array_index(unsigned int bit_number) 16 | { 17 | return bit_number / 8; 18 | } 19 | 20 | unsigned int bit_index(unsigned int bit_number) 21 | { 22 | return bit_number % 8; 23 | } 24 | 25 | void set_bit(char bit_array[], unsigned bit_number) 26 | { 27 | unsigned char mask = 1; 28 | mask <<= bit_index(bit_number); 29 | bit_array[array_index(bit_number)] |= mask; 30 | } 31 | 32 | void clear_bit(char bit_array[], unsigned bit_number) 33 | { 34 | unsigned char mask = 1; 35 | mask <<= bit_index(bit_number); 36 | mask = ~mask; 37 | bit_array[array_index(bit_number)] &= mask; 38 | } 39 | 40 | void assign_bit(char bit_array[], unsigned bit_number, int value) 41 | { 42 | if(value) { 43 | set_bit(bit_array, bit_number); 44 | } 45 | else { 46 | clear_bit(bit_array, bit_number); 47 | } 48 | } 49 | 50 | int test_bit(char bit_array[], unsigned bit_number) 51 | { 52 | unsigned char mask = 1; 53 | mask <<= bit_index(bit_number); 54 | return bit_array[array_index(bit_number)] & mask; 55 | } 56 | 57 | int main(int argc, char* argv[]) 58 | { 59 | char bit_array[ARRAY_SIZE]; 60 | int i; 61 | 62 | // clear all bits to start 63 | for(i = 0; i < ARRAY_SIZE * 8; i++) { 64 | clear_bit(bit_array, i); 65 | } 66 | 67 | set_bit(bit_array, 24); 68 | if(test_bit(bit_array, 24)) 69 | printf("bit 24 was set\n"); 70 | else { 71 | printf("failure\n"); 72 | exit(-1); 73 | } 74 | 75 | // verify no other bits were set 76 | for(i = 0; i < ARRAY_SIZE * 8; i++) { 77 | if(i == 24) 78 | continue; 79 | if(test_bit(bit_array, i)) { 80 | printf("another bit was set; failure\n"); 81 | exit(-1); 82 | } 83 | } 84 | 85 | clear_bit(bit_array, 24); 86 | for(i = 0; i < ARRAY_SIZE * 8; i++) { 87 | if(test_bit(bit_array, i)) { 88 | printf("all bits should be zero; failure\n"); 89 | exit(-1); 90 | } 91 | } 92 | 93 | assign_bit(bit_array, 13, 1); 94 | if(test_bit(bit_array, 13)) 95 | printf("bit 13 was set\n"); 96 | else { 97 | printf("failure\n"); 98 | exit(-1); 99 | } 100 | 101 | // verify no other bits were set 102 | for(i = 0; i < ARRAY_SIZE * 8; i++) { 103 | if(i == 13) 104 | continue; 105 | if(test_bit(bit_array, i)) { 106 | printf("another bit was set; failure\n"); 107 | exit(-1); 108 | } 109 | } 110 | 111 | assign_bit(bit_array, 13, 0); 112 | for(i = 0; i < ARRAY_SIZE * 8; i++) { 113 | if(test_bit(bit_array, i)) { 114 | printf("all bits should be zero; failure\n"); 115 | exit(-1); 116 | } 117 | } 118 | 119 | for(i = 0; i < ARRAY_SIZE * 8; i++) { 120 | set_bit(bit_array, i); 121 | } 122 | 123 | for(i = 0; i < ARRAY_SIZE * 8; i++) { 124 | if(!test_bit(bit_array, i)) { 125 | printf("all bits should be set; failure\n"); 126 | exit(-1); 127 | } 128 | } 129 | 130 | for(i = 0; i < ARRAY_SIZE * 8; i++) { 131 | clear_bit(bit_array, i); 132 | } 133 | 134 | for(i = 8; i < 16; i++) { 135 | set_bit(bit_array, i); 136 | printf("%d\n", bit_array[1]); 137 | clear_bit(bit_array, i); 138 | } 139 | 140 | for(i = 0; i < ARRAY_SIZE * 8; i++) { 141 | clear_bit(bit_array, i); 142 | } 143 | 144 | for(i = 0; i < 16; i++) { 145 | set_bit(bit_array, i); 146 | printf("0: %d\n", bit_array[0]); 147 | printf("1: %d\n", bit_array[1]); 148 | } 149 | 150 | return 1; 151 | } 152 | -------------------------------------------------------------------------------- /ch5/bit_array/bit_array.h: -------------------------------------------------------------------------------- 1 | void set_bit(char bit_array[], unsigned bit_number); 2 | void clear_bit(char bit_array[], unsigned bit_number); 3 | void assign_bit(char bit_array[], unsigned bit_number, int value); 4 | int test_bit(char bit_array[], unsigned bit_number); 5 | -------------------------------------------------------------------------------- /ch5/encrypt/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS=-Wall -g 2 | 3 | all: 4 | gcc -o encrypt encrypt.c 5 | 6 | clean: 7 | rm -f encrypt 8 | -------------------------------------------------------------------------------- /ch5/encrypt/encrypt.c: -------------------------------------------------------------------------------- 1 | /* 2 | Pointers on c - ch5, ex2 3 | encrypt.c - read chars and prints them out encrypting alphas 4 | per algorithm given in ex 5 | 6 | author: nicolas miller 7 | */ 8 | 9 | #include 10 | 11 | int encrypt(int ch) 12 | { 13 | if(ch >= 'a' && ch <= 'z') 14 | return 'a' + ((ch - 'a') + 13) % 26; 15 | else 16 | return 'A' + ((ch - 'A') + 13) % 26; 17 | } 18 | 19 | int main(int argc, char* argv[]) 20 | { 21 | int ch; 22 | while((ch = getchar()) && ch != EOF) { 23 | if((ch >= 'A' && ch <= 'Z') || 24 | (ch >= 'a' && ch <= 'z')) 25 | putchar(encrypt(ch)); 26 | else 27 | putchar(ch); 28 | } 29 | return 1; 30 | } 31 | -------------------------------------------------------------------------------- /ch5/expression/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS=-Wall -g 2 | 3 | all: 4 | gcc -o expression expression.c 5 | 6 | clean: 7 | rm -f expression 8 | -------------------------------------------------------------------------------- /ch5/expression/expression.c: -------------------------------------------------------------------------------- 1 | /* 2 | expression.c - expression evaluation ex test 3 | 4 | author: nicolas miller 5 | */ 6 | 7 | #include 8 | 9 | int main(int argc, char* argv[]) 10 | { 11 | int a = 10; 12 | int b = -25; 13 | int c = 0; 14 | int d = 3; 15 | int e = 20; 16 | 17 | printf("a: %d\n", a); // 10 18 | printf("b: %d\n", b); // -25 19 | printf("c: %d\n", c); // 0 20 | printf("b: %d\n", b); // 3 21 | printf("b++: %d\n", b++); // -25, b == -24 22 | b = -25; 23 | printf("--a: %d\n", --a); // 9, a == 9 24 | a++; 25 | printf("a / 6: %d\n", a / 6); // 1 26 | printf("a % 6: %d\n", a % 6); // 4 27 | printf("b % 10: %d\n", b % 10); // -5 28 | printf("a << 2: %d\n", a << 2); // 40 29 | printf("b >> 3: %d\n", b >> 3); // -4 30 | printf("a > b: %d\n", a > b); // 1 31 | printf("b = a: %d\n", b = a); // 10, b == 10 32 | b = -25; 33 | printf("b == a: %d\n", b == a); // 0 34 | printf("a & b: %d\n", a & b); // 2 35 | printf("a ^ b: %d\n", a ^ b); // -19 36 | printf("a | b: %d\n", a | b); // -17 37 | printf("~b: %d\n", ~b); // 24 38 | printf("c && a: %d\n", c && a); // 0 39 | printf("c || a: %d\n", c || a); // 1 40 | printf("b ? a : c: %d\n", b ? a : c); // 10 41 | printf("a += 2: %d\n", a += 2); // 12, a == 12 42 | a = 10; 43 | printf("a += 2: %d\n", a += 2); // 12, a == 12 44 | a = 10; 45 | printf("b &= 20: %d\n", b &= 20); // 4, b == 4 46 | b = -25; 47 | printf("b >>= 3: %d\n", b >>= 3); // -4, b == -4 48 | b = -25; 49 | printf("a %= 6: %d\n", a %= 6); // 4, a == 4 50 | a = 10; 51 | b = -25; 52 | d = 3; 53 | printf("a = b = c = d: %d\n", a = b = c = d); // 3 54 | a = 10; 55 | b = -25; 56 | c = 0; 57 | d = 3; 58 | printf("e = d + (c = a + b) + c: %d\n", e = d + (c = a + b) + c); // evil. ?? 59 | e = 20; 60 | printf("a + b * 3: %d\n", a + b * 3); // -65 61 | printf("b >> a - 4: %d\n", b >> a - 4); // -1 62 | printf("a != b != c: %d\n", a != b != c); // 1 63 | printf("a == b == c: %d\n", a == b == c); // 1 64 | printf("d < a < e: %d\n", d < a < e); // 1 65 | printf("e > a > d: %d\n", e > a > d); // 0 66 | printf("a - 10 > b + 10: %d\n", a - 10 > b + 10); // 1 67 | printf("a & 0x1 == b & 0x1: %d\n", a & 0x1 == b & 0x1); // 0 68 | printf("a | b << a & b: %d\n", a | b << a & b); // -25590 69 | printf("a > c || ++a > b: %d\n", a > c || ++a > b); // 1, no side fx 70 | printf("a > c && ++a > b: %d\n", a > c && ++a > b); // 1, a == 11 71 | printf("!~b++: %d\n", !~b); // 0, b == -24 72 | b = -25; 73 | printf("b++ & a <= 30: %d\n", b++ & a <= 30); 74 | printf("a - b, c += d, e - c: %d\n", a - b, c += d, e - c); 75 | c = 0; 76 | printf("a >>= 3 > 0: %d\n", a >>= 3 > 0); // 5, a == 5 77 | printf("a <<= d > 20 ? b && c++ : d--: %d\n", a <<= d > 20 ? b && c++ : d--); 78 | } 79 | -------------------------------------------------------------------------------- /ch5/reverse_bits/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS=-Wall -g 2 | 3 | all: 4 | gcc -o reverse_bits reverse_bits.c 5 | 6 | clean: 7 | rm -f reverse_bits 8 | -------------------------------------------------------------------------------- /ch5/reverse_bits/reverse_bits.c: -------------------------------------------------------------------------------- 1 | /* 2 | Pointers on c - ch5, ex3 3 | reverse_bits.c - function reverse_bits (independent of int width) and main test function 4 | 5 | author: nicolas miller 6 | */ 7 | 8 | #include 9 | 10 | unsigned int reverse_bits(unsigned int value) 11 | { 12 | unsigned int input_value = value; 13 | unsigned int output = 0; 14 | unsigned int current_bit; 15 | unsigned int input_width = 0; 16 | unsigned int int_width = 0; 17 | unsigned int output_copy; 18 | 19 | while(input_value != 0) { 20 | current_bit = 1 & input_value; 21 | output <<= 1; 22 | output |= current_bit; 23 | input_value >>= 1; 24 | input_width++; 25 | } 26 | 27 | output_copy = output; 28 | while(output_copy != 0) { 29 | output_copy <<= 1; 30 | int_width++; 31 | } 32 | 33 | return output <<= int_width - input_width; 34 | } 35 | 36 | int main(int argc, char* argv[]) 37 | { 38 | // book test case 39 | printf("%x\n", 25); // 0x19, 0b11001 40 | 41 | // yields 0x98000000 with 32-bit ints 42 | printf("%x\n", reverse_bits(25)); 43 | 44 | printf("%x\n", 1); 45 | printf("%x\n", reverse_bits(1)); 46 | return 1; 47 | } 48 | -------------------------------------------------------------------------------- /ch5/store_bit_field/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS=-Wall -g 2 | 3 | all: 4 | gcc -o store_bit_field store_bit_field.c 5 | 6 | clean: 7 | rm -f store_bit_field 8 | -------------------------------------------------------------------------------- /ch5/store_bit_field/store_bit_field.c: -------------------------------------------------------------------------------- 1 | /* 2 | Pointers on c - ch5, ex5 3 | store_bit_field.c - store_bit_field function and main test function 4 | 5 | author: nicolas miller 6 | */ 7 | 8 | #include 9 | 10 | int get_mask(unsigned int starting_bit, unsigned int ending_bit) 11 | { 12 | int width = (starting_bit - ending_bit) + 1; 13 | int mask = 1; 14 | int i; 15 | for(i = 1; i < width; i++) { 16 | mask <<= 1; 17 | mask |= 1; 18 | } 19 | 20 | for(i = 0; i < ending_bit; i++) { 21 | mask <<= 1; 22 | } 23 | 24 | return mask; 25 | } 26 | 27 | int store_bit_field(int original_value, int value_to_store, 28 | unsigned int starting_bit, unsigned int ending_bit) { 29 | int mask = get_mask(starting_bit, ending_bit); 30 | value_to_store <<= ending_bit; 31 | value_to_store &= mask; 32 | original_value &= ~mask; 33 | return original_value | value_to_store; 34 | } 35 | 36 | int main(int argc, char* argv[]) 37 | { 38 | /* test cases given in problem */ 39 | printf("%x\n", store_bit_field(0x0, 0x1, 4, 4)); /* 0x10 */ 40 | printf("%x\n", store_bit_field(0xffff, 0x123, 15, 4)); /* 0x123f */ 41 | printf("%x\n", store_bit_field(0xffff, 0x123, 13, 9)); /* 0xc7ff */ 42 | 43 | return 1; 44 | } 45 | -------------------------------------------------------------------------------- /ch5/to_lower/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS=-Wall -g 2 | 3 | all: 4 | gcc -o to_lower to_lower.c 5 | 6 | clean: 7 | rm -f to_lower 8 | -------------------------------------------------------------------------------- /ch5/to_lower/to_lower.c: -------------------------------------------------------------------------------- 1 | /* 2 | Pointers on c - ch5, ex1 3 | to_lower.c - read chars and prints them out converting upper to lower 4 | 5 | author: nicolas miller 6 | */ 7 | 8 | #include 9 | 10 | int main(int argc, char* argv[]) 11 | { 12 | int ch; 13 | while((ch = getchar()) && ch != EOF) { 14 | if(ch >= 'A' && ch <= 'Z') 15 | putchar(ch + 32); 16 | else 17 | putchar(ch); 18 | } 19 | return 1; 20 | } 21 | -------------------------------------------------------------------------------- /ch6/del_substr/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS=-Wall -g 2 | 3 | all: 4 | gcc -o del_substr del_substr.c 5 | 6 | clean: 7 | rm -f del_substr 8 | -------------------------------------------------------------------------------- /ch6/del_substr/del_substr.c: -------------------------------------------------------------------------------- 1 | /* 2 | Pointers on c - ch6, ex2 3 | del_substr.c - del_substr function and test cases as specified in text 4 | 5 | author: nicolas miller 6 | */ 7 | 8 | #include 9 | 10 | int matches_at_position(char *position, char const *substr) 11 | { 12 | while(*position != '\0' && *substr != '\0') { 13 | if(*position != *substr) 14 | return 0; 15 | position++; 16 | substr++; 17 | } 18 | 19 | /* got to the end of the substr and everything matched */ 20 | return *substr == '\0'; 21 | } 22 | 23 | /* not allowed to use std library funcs */ 24 | int my_naive_strlen(char const *str) { 25 | unsigned int length = 0; 26 | while(*str != '\0') { 27 | length++; 28 | str++; 29 | } 30 | return length; 31 | } 32 | 33 | char *substr_pos(char *str, char const *substr) 34 | { 35 | while(*str != '\0') { 36 | if(matches_at_position(str, substr)) 37 | return str; 38 | str++; 39 | } 40 | 41 | return NULL; 42 | } 43 | 44 | int del_substr(char *str, char const *substr) 45 | { 46 | char *substr_start = substr_pos(str, substr); 47 | if(substr_start == NULL) 48 | return 0; 49 | char *after_substr = substr_start + my_naive_strlen(substr); 50 | 51 | while(*after_substr != '\0') { 52 | *substr_start = *after_substr; 53 | substr_start++; 54 | after_substr++; 55 | } 56 | *substr_start = '\0'; 57 | 58 | return 1; 59 | } 60 | 61 | int main(int argc, char* argv[]) 62 | { 63 | char str1[] = "ABCDEFG"; 64 | char str2[] = "XXXXFOOBARXXXXXX"; 65 | char str3[] = "XXXXFOOBARXXXXXX"; 66 | char str4[] = "XXXXFOOBARXXXXXX"; 67 | char substr1[] = "FGH"; 68 | char substr2[] = "CDF"; 69 | char substr3[] = "XABC"; 70 | char substr4[] = "CDE"; 71 | char substr5[] = "FOOBAR"; 72 | char substr6[] = "FOO"; 73 | char substr7[] = "BAR"; 74 | 75 | 76 | printf("%d\n", my_naive_strlen(str1) == 7); 77 | printf("%d\n", my_naive_strlen(substr1) == 3); 78 | printf("%d\n", my_naive_strlen(substr2) == 3); 79 | printf("%d\n", my_naive_strlen(substr3) == 4); 80 | printf("%d\n", my_naive_strlen(substr4) == 3); 81 | 82 | printf("%d\n", del_substr(str1, substr1) == 0); 83 | printf("%s\n", str1); /* should be unchanged */ 84 | printf("%d\n", del_substr(str1, substr2) == 0); 85 | printf("%s\n", str1); /* should be unchanged */ 86 | printf("%d\n", del_substr(str1, substr3) == 0); 87 | printf("%s\n", str1); /* should be unchanged */ 88 | printf("%d\n", del_substr(str1, substr4) == 1); 89 | printf("%s\n", str1); /* should be ABFG */ 90 | printf("%d\n", del_substr(str2, substr5) == 1); 91 | printf("%s\n", str2); /* should be XXXXXXXXXX */ 92 | printf("%d\n", del_substr(str3, substr6) == 1); 93 | printf("%s\n", str3); /* should be XXXXBARXXXXXX */ 94 | printf("%d\n", del_substr(str4, substr7) == 1); 95 | printf("%s\n", str4); /* should be XXXXFOOXXXXXX */ 96 | 97 | return 1; 98 | } 99 | -------------------------------------------------------------------------------- /ch6/find_char/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS=-Wall -g 2 | 3 | all: 4 | gcc -o find_char find_char.c 5 | 6 | clean: 7 | rm -f find_char 8 | -------------------------------------------------------------------------------- /ch6/find_char/find_char.c: -------------------------------------------------------------------------------- 1 | /* 2 | Pointers on c - ch6, ex1 3 | find_char.c - find_char function as sepcified in text and main test function 4 | 5 | author: nicolas miller 6 | */ 7 | 8 | #include 9 | 10 | int matches(char const *target, char const *chars) 11 | { 12 | while(*chars != '\0') { 13 | if(*target == *chars) 14 | return 1; 15 | chars++; 16 | } 17 | return 0; 18 | } 19 | 20 | const char *find_char(char const *source, char const *chars) 21 | { 22 | if(source == NULL || chars == NULL 23 | || *source == '\0' || 24 | *chars == '\0') 25 | return NULL; 26 | 27 | while(*source != '\0') { 28 | if(matches(source, chars)) 29 | return source; 30 | source++; 31 | } 32 | return NULL; 33 | } 34 | 35 | int main(int argc, char* argv[]) 36 | { 37 | char *source1 = "ABCDEFG"; 38 | char *source2 = "QQQXQQQPRRRT"; 39 | char *chars1 = "XYZ"; 40 | char *chars2 = "JURY"; 41 | char *chars3 = "QQQQ"; 42 | char *chars4 = "XRCQEF"; 43 | char *chars5 = "EERP"; 44 | char *empty = ""; 45 | 46 | printf("%d\n", find_char(NULL, chars1) == NULL); 47 | printf("%d\n", find_char(source1, NULL) == NULL); 48 | printf("%d\n", find_char(NULL, NULL) == NULL); 49 | printf("%d\n", find_char(empty, chars1) == NULL); 50 | printf("%d\n", find_char(source1, empty) == NULL); 51 | 52 | printf("%d\n", find_char(source1, chars1) == NULL); 53 | printf("%d\n", find_char(source1, chars2) == NULL); 54 | printf("%d\n", find_char(source1, chars3) == NULL); 55 | printf("%d\n", *find_char(source1, chars4) == 'C'); 56 | printf("%d\n", *find_char(source2, chars5) == 'P'); 57 | 58 | return 1; 59 | } 60 | -------------------------------------------------------------------------------- /ch6/reverse_string/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS=-Wall -g 2 | 3 | all: 4 | gcc -o reverse_string reverse_string.c 5 | 6 | clean: 7 | rm -f reverse_string 8 | -------------------------------------------------------------------------------- /ch6/reverse_string/reverse_string.c: -------------------------------------------------------------------------------- 1 | /* 2 | Pointers on c - ch6, ex2 3 | reverse_string.c - reverse_string function and test cases 4 | 5 | author: nicolas miller 6 | */ 7 | 8 | #include 9 | 10 | char *last_char(char *string) { 11 | while(*string != '\0') 12 | string++; 13 | return --string; 14 | } 15 | 16 | void reverse_string(char *string) 17 | { 18 | if(string == NULL || *string == '\0') 19 | return; 20 | 21 | char *last_ch_ptr = last_char(string); 22 | 23 | while(string < last_ch_ptr) { 24 | char temp = *string; 25 | *string = *last_ch_ptr; 26 | *last_ch_ptr = temp; 27 | string++; 28 | last_ch_ptr--; 29 | } 30 | } 31 | 32 | int main(int argc, char* argv[]) 33 | { 34 | char str1[] = "ABCDEFG"; 35 | char str2[] = "ABCDEF"; 36 | char str3[] = "XXXXXXXXQQQNWNNNNDDJJJEFHHH"; 37 | 38 | 39 | printf("%s\n", str1); 40 | reverse_string(str1); 41 | printf("%s\n", str1); 42 | 43 | printf("%s\n", str2); 44 | reverse_string(str2); 45 | printf("%s\n", str2); 46 | 47 | printf("%s\n", str3); 48 | reverse_string(str3); 49 | printf("%s\n", str3); 50 | 51 | return 1; 52 | } 53 | -------------------------------------------------------------------------------- /ch6/sieve1/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS=-Wall -g 2 | 3 | all: 4 | gcc -o sieve1 sieve1.c 5 | 6 | clean: 7 | rm -f sieve1 8 | -------------------------------------------------------------------------------- /ch6/sieve1/sieve1.c: -------------------------------------------------------------------------------- 1 | /* 2 | Pointers on c - ch6, ex4 3 | sieve1.c - basic sieve of eratosthenes 4 | 5 | author: nicolas miller 6 | */ 7 | 8 | #include 9 | #define SIEVE_SIZE 100 10 | 11 | int main(int argc, char* argv[]) 12 | { 13 | char sieve_array[SIEVE_SIZE]; 14 | unsigned long long i; 15 | int step = 2; 16 | 17 | sieve_array[0] = 0; 18 | sieve_array[1] = 0; 19 | 20 | for(i = 2; i < SIEVE_SIZE; i++) { 21 | sieve_array[i] = 1; 22 | } 23 | 24 | while(step < SIEVE_SIZE) { 25 | if(!sieve_array[step]) { 26 | step++; 27 | continue; 28 | } 29 | for(i = 2 * step; i < SIEVE_SIZE; i += step) { 30 | sieve_array[i] = 0; 31 | } 32 | step++; 33 | } 34 | 35 | for(i = 0; i < SIEVE_SIZE; i++) { 36 | if(sieve_array[i]) 37 | printf("%lld: %d\n", i, sieve_array[i]); 38 | } 39 | return 1; 40 | } 41 | -------------------------------------------------------------------------------- /ch6/sieve_bits/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS=-Wall -g 2 | 3 | all: 4 | gcc -o sieve_bits sieve_bits.c bit_array.c -I. 5 | 6 | clean: 7 | rm -f sieve_bits 8 | -------------------------------------------------------------------------------- /ch6/sieve_bits/bit_array.c: -------------------------------------------------------------------------------- 1 | /* 2 | Pointers on c - ch5, ex4 3 | bit_array.c - bit_array functions and main test function 4 | bit_numbers start from zero 5 | 6 | author: nicolas miller 7 | */ 8 | 9 | #include 10 | #include 11 | #include "bit_array.h" 12 | 13 | unsigned int array_index(unsigned int bit_number) 14 | { 15 | return bit_number / 8; 16 | } 17 | 18 | unsigned int bit_index(unsigned int bit_number) 19 | { 20 | return bit_number % 8; 21 | } 22 | 23 | void set_bit(char bit_array[], unsigned bit_number) 24 | { 25 | unsigned char mask = 1; 26 | mask <<= bit_index(bit_number); 27 | bit_array[array_index(bit_number)] |= mask; 28 | } 29 | 30 | void clear_bit(char bit_array[], unsigned bit_number) 31 | { 32 | unsigned char mask = 1; 33 | mask <<= bit_index(bit_number); 34 | mask = ~mask; 35 | bit_array[array_index(bit_number)] &= mask; 36 | } 37 | 38 | void assign_bit(char bit_array[], unsigned bit_number, int value) 39 | { 40 | if(value) { 41 | set_bit(bit_array, bit_number); 42 | } 43 | else { 44 | clear_bit(bit_array, bit_number); 45 | } 46 | } 47 | 48 | int test_bit(char bit_array[], unsigned bit_number) 49 | { 50 | unsigned char mask = 1; 51 | mask <<= bit_index(bit_number); 52 | return bit_array[array_index(bit_number)] & mask; 53 | } 54 | -------------------------------------------------------------------------------- /ch6/sieve_bits/bit_array.h: -------------------------------------------------------------------------------- 1 | void set_bit(char bit_array[], unsigned bit_number); 2 | void clear_bit(char bit_array[], unsigned bit_number); 3 | void assign_bit(char bit_array[], unsigned bit_number, int value); 4 | int test_bit(char bit_array[], unsigned bit_number); 5 | -------------------------------------------------------------------------------- /ch6/sieve_bits/sieve_bits.c: -------------------------------------------------------------------------------- 1 | /* 2 | Pointers on c - ch6, ex5 3 | sieve_bits.c - more space efficient bit array sieve of eratosthenes 4 | 5 | author: nicolas miller 6 | */ 7 | 8 | #include 9 | #include "bit_array.h" 10 | 11 | #define SIEVE_SIZE 60000000 12 | 13 | int main(int argc, char* argv[]) 14 | { 15 | unsigned long long array_size = SIEVE_SIZE / 8; 16 | char sieve_array[array_size]; 17 | unsigned long long i; 18 | int step = 2; 19 | 20 | clear_bit(sieve_array, 0); 21 | clear_bit(sieve_array, 1); 22 | 23 | for(i = 2; i < SIEVE_SIZE; i++) { 24 | set_bit(sieve_array, i); 25 | } 26 | 27 | while(step < SIEVE_SIZE) { 28 | if(!test_bit(sieve_array, step)) { 29 | step++; 30 | continue; 31 | } 32 | for(i = 2 * step; i < SIEVE_SIZE; i += step) { 33 | clear_bit(sieve_array, i); 34 | } 35 | step++; 36 | } 37 | 38 | for(i = 0; i < SIEVE_SIZE; i++) { 39 | int is_prime = test_bit(sieve_array, i); 40 | if(is_prime) 41 | printf("%lld\n", i); 42 | } 43 | 44 | return 1; 45 | } 46 | -------------------------------------------------------------------------------- /ch7/ascii_to_int/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS=-Wall -g 2 | 3 | all: 4 | gcc -o ascii_to_int ascii_to_int.c 5 | 6 | clean: 7 | rm -f ascii_to_int 8 | -------------------------------------------------------------------------------- /ch7/ascii_to_int/ascii_to_int.c: -------------------------------------------------------------------------------- 1 | /* 2 | Pointers on c - ch7, ex3 3 | ascii_to_int.c - ascii_to_int function and test cases 4 | 5 | author: nicolas miller 6 | */ 7 | 8 | #include 9 | 10 | int ascii_to_int(char *string) 11 | { 12 | int return_val = 0; 13 | while(*string != '\0') { 14 | if(!(*string >= '0' && *string <= '9')) 15 | return 0; 16 | return_val *= 10; 17 | return_val += *string - '0'; 18 | string++; 19 | } 20 | return return_val; 21 | } 22 | 23 | int main(int argc, char* argv[]) 24 | { 25 | printf("%d\n", ascii_to_int("12345")); /* 12345 */ 26 | printf("%d\n", ascii_to_int("012345")); /* 12345 */ 27 | printf("%d\n", ascii_to_int("64512")); /* 64512 */ 28 | printf("%d\n", ascii_to_int("000")); /* 0 */ 29 | printf("%d\n", ascii_to_int("fqp000")); /* 0 */ 30 | printf("%d\n", ascii_to_int("4128733x")); /* 0 */ 31 | } 32 | -------------------------------------------------------------------------------- /ch7/basic_printf/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS=-Wall -g 2 | 3 | all: 4 | gcc -o basic_printf basic_printf.c 5 | 6 | clean: 7 | rm -f basic_printf 8 | -------------------------------------------------------------------------------- /ch7/basic_printf/basic_printf.c: -------------------------------------------------------------------------------- 1 | /* 2 | Pointers on c - ch7, ex5 3 | basic_printf.c - basic_printf function and test 4 | 5 | author: nicolas miller 6 | */ 7 | 8 | #include 9 | #include 10 | 11 | 12 | /* allowed to assume these print functions exist */ 13 | void print_integer(int i) { 14 | printf("%d", i); 15 | } 16 | 17 | void print_float(float f) { 18 | printf("%f", f); 19 | } 20 | 21 | void basic_printf(char *format, ...) 22 | { 23 | va_list args; 24 | va_start(args, format); 25 | while(*format != '\0') { 26 | if(*format == '%') { 27 | format++; 28 | if(*format == 'd') { 29 | print_integer(va_arg(args, int)); 30 | } 31 | else if(*format == 'f') { 32 | print_float(va_arg(args, double)); 33 | } 34 | else if(*format == 's') { 35 | char *string = va_arg(args, char *); 36 | while(*string != '\0') { 37 | putchar(*string); 38 | string++; 39 | } 40 | } 41 | else if(*format == 'c') { 42 | putchar(va_arg(args, int)); 43 | } 44 | } 45 | else { 46 | putchar(*format); 47 | } 48 | format++; 49 | } 50 | va_end(args); 51 | } 52 | 53 | int main(int argc, char* argv[]) 54 | { 55 | basic_printf("awesome string without any format codes\n"); 56 | basic_printf("%f %d %d %c\n", 3.1415, 72, 42, 'a'); 57 | basic_printf("%s %d %d %s\n", "here's a string to insert", 69, 69, "here's another string to insert"); 58 | return 1; 59 | } 60 | -------------------------------------------------------------------------------- /ch7/gcd/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS=-Wall -g 2 | 3 | all: 4 | gcc -o gcd gcd.c 5 | 6 | clean: 7 | rm -f gcd 8 | -------------------------------------------------------------------------------- /ch7/gcd/gcd.c: -------------------------------------------------------------------------------- 1 | /* 2 | Pointers on c - ch7, ex2 3 | gcd.c - gcd function and tests 4 | 5 | author: nicolas miller 6 | */ 7 | 8 | #include 9 | 10 | int gcd(int m, int n) 11 | { 12 | if(m < 0 || n < 0) 13 | return 0; 14 | if((m % n ) == 0) 15 | return n; 16 | else 17 | return gcd(n, m % n); 18 | } 19 | 20 | int main(int argc, char* argv[]) 21 | { 22 | printf("%d\n", gcd(-1, 2)); /* 0 */ 23 | printf("%d\n", gcd(1, -2)); /* 0 */ 24 | printf("%d\n", gcd(64, 2)); /* 2 */ 25 | printf("%d\n", gcd(54, 24)); /* 6 */ 26 | } 27 | -------------------------------------------------------------------------------- /ch7/hermite/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS=-Wall -g 2 | 3 | all: 4 | gcc -o hermite hermite.c 5 | 6 | clean: 7 | rm -f hermite 8 | -------------------------------------------------------------------------------- /ch7/hermite/hermite.c: -------------------------------------------------------------------------------- 1 | /* 2 | Pointers on c - ch7, ex1 3 | hermite.c - recursive function to compute value of hermite polynomials 4 | 5 | author: nicolas miller 6 | */ 7 | 8 | #include 9 | 10 | int hermite(int n, int x) 11 | { 12 | if(n <= 0) 13 | return 1; 14 | else if(n == 1) 15 | return 2 * x; 16 | else 17 | return 2 * x * hermite(n - 1, x) - 2 * (n - 1) * hermite(n - 2, x); 18 | } 19 | 20 | int main(int argc, char* argv[]) 21 | { 22 | printf("%d\n", hermite(3, 2)); /* 40 */ 23 | } 24 | -------------------------------------------------------------------------------- /ch7/max_list/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS=-Wall -g 2 | 3 | all: 4 | gcc -o max_list max_list.c 5 | 6 | clean: 7 | rm -f max_list 8 | -------------------------------------------------------------------------------- /ch7/max_list/max_list.c: -------------------------------------------------------------------------------- 1 | /* 2 | Pointers on c - ch7, ex4 3 | max_list.c - max_list function and test 4 | 5 | author: nicolas miller 6 | */ 7 | 8 | #include 9 | #include 10 | 11 | int max_list(int dummy, ...) 12 | { 13 | va_list args; 14 | int max = 0; 15 | int value; 16 | va_start(args, dummy); 17 | while((value = va_arg(args, int)) > 0) { 18 | if(value > max) 19 | max = value; 20 | } 21 | va_end(args); 22 | return max; 23 | } 24 | 25 | int main(int argc, char* argv[]) 26 | { 27 | printf("%d\n", max_list(42, 1, 71, 2, 42, 79, 20, -1)); /* 79 */ 28 | printf("%d\n", max_list(42, 79, 71, 2, 42, 79, 20, -1)); /* 79 */ 29 | printf("%d\n", max_list(42, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, -1)); /* 11 */ 30 | printf("%d\n", max_list(42, 1, -1)); /* 1 */ 31 | return 1; 32 | } 33 | -------------------------------------------------------------------------------- /ch7/written_amount/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS=-Wall -g 2 | 3 | all: 4 | gcc -o written_amount written_amount.c 5 | 6 | clean: 7 | rm -f written_amount 8 | -------------------------------------------------------------------------------- /ch7/written_amount/written_amount.c: -------------------------------------------------------------------------------- 1 | /* 2 | Pointers on c - ch7, ex6 3 | written_amount.c - written_amount function and test 4 | 5 | author: nicolas miller 6 | */ 7 | 8 | #include 9 | #define BUFFER_SIZE 1000 10 | 11 | const char *digit_to_string(int i) { 12 | const char *digit_strings[] = {"", "ONE ", "TWO ", "THREE ", "FOUR ", 13 | "FIVE ", "SIX ", "SEVEN ", "EIGHT ", "NINE "}; 14 | return digit_strings[i]; 15 | } 16 | 17 | const char *teen_to_string(int i) { 18 | const char *teen_strings[] = {"TEN ", "ELEVEN ", "TWLEVE ", "THIRTEEN ", 19 | "FOURTEEN ", "FIFTEEN ", "SIXTEEN ", 20 | "SEVENTEEN ", "EIGHTEEN ", "NINETEEN "}; 21 | return teen_strings[i % 10]; 22 | } 23 | 24 | const char *tens_to_string(int i) { 25 | const char *tens_strings[] = {"", "", "TWENTY ", "THIRTY ", "FORTY ", "FIFTY ", 26 | "SIXTY ", "SEVENTY ", "EIGHTY ", "NINETY "}; 27 | return tens_strings[i]; 28 | } 29 | 30 | char *copy_str(char *dest, const char *src) { 31 | while(*src != '\0') 32 | *dest++ = *src++; 33 | return dest; 34 | } 35 | 36 | void clear_buffer(char *buffer) { 37 | while(*buffer != '\0') 38 | *buffer++ = '\0'; 39 | } 40 | 41 | char *print_hundred(int i, char *buffer) { 42 | int hundreds = i / 100; 43 | int tens = (i % 100) / 10; 44 | int ones = i % 10; 45 | 46 | if(hundreds > 0) { 47 | buffer = copy_str(buffer, digit_to_string(hundreds)); 48 | buffer = copy_str(buffer, "HUNDRED "); 49 | } 50 | if(tens == 0) { 51 | buffer = copy_str(buffer, digit_to_string(ones)); 52 | } 53 | else if(tens == 1) { 54 | buffer = copy_str(buffer, teen_to_string(ones)); 55 | } 56 | else { 57 | buffer = copy_str(buffer, tens_to_string(tens)); 58 | buffer = copy_str(buffer, digit_to_string(ones)); 59 | } 60 | } 61 | 62 | void written_amount(unsigned int amount, char *buffer) 63 | { 64 | 65 | int billions = amount / 1000000000; 66 | if(billions > 0) { 67 | amount %= 1000000000; 68 | buffer = print_hundred(billions, buffer); 69 | buffer = copy_str(buffer, "BILLION "); 70 | } 71 | 72 | int millions = amount / 1000000; 73 | if(millions > 0) { 74 | amount %= 1000000; 75 | buffer = print_hundred(millions, buffer); 76 | buffer = copy_str(buffer, "MILLION "); 77 | } 78 | 79 | int thousands = amount / 1000; 80 | if(thousands > 0) { 81 | amount %= 1000; 82 | buffer = print_hundred(thousands, buffer); 83 | buffer = copy_str(buffer, "THOUSAND "); 84 | } 85 | buffer = print_hundred(amount, buffer); 86 | *buffer = '\0'; 87 | } 88 | 89 | int main(int argc, char* argv[]) 90 | { 91 | char buffer[BUFFER_SIZE]; 92 | int val = 65723; 93 | 94 | printf("%d\n", val); 95 | written_amount(val, buffer); 96 | printf("%s\n\n", buffer); 97 | clear_buffer(buffer); 98 | 99 | val = 789134; 100 | printf("%d\n", val); 101 | written_amount(val, buffer); 102 | printf("%s\n\n", buffer); 103 | clear_buffer(buffer); 104 | 105 | val = 9981235; 106 | printf("%d\n", val); 107 | written_amount(val, buffer); 108 | printf("%s\n\n", buffer); 109 | clear_buffer(buffer); 110 | 111 | val = 12345678; 112 | printf("%d\n", val); 113 | written_amount(val, buffer); 114 | printf("%s\n\n", buffer); 115 | clear_buffer(buffer); 116 | 117 | val = 123456780; 118 | printf("%d\n", val); 119 | written_amount(val, buffer); 120 | printf("%s\n\n", buffer); 121 | clear_buffer(buffer); 122 | 123 | val = 2147483647; 124 | printf("%d\n", val); 125 | written_amount(val, buffer); 126 | printf("%s\n\n", buffer); 127 | clear_buffer(buffer); 128 | 129 | return 1; 130 | } 131 | -------------------------------------------------------------------------------- /ch8/char_values/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS=-Wall -g 2 | 3 | all: 4 | gcc -o char_values char_values.c 5 | 6 | clean: 7 | rm -f char_values 8 | -------------------------------------------------------------------------------- /ch8/char_values/char_values.c: -------------------------------------------------------------------------------- 1 | /* 2 | Pointers on c - ch8, ex1 3 | char_values.c - char_values array static initialization 4 | 5 | author: nicolas miller 6 | */ 7 | 8 | #include 9 | 10 | 11 | int main(int argc, char* argv[]) 12 | { 13 | /* 3 x 6 x 4 x 5 */ 14 | char char_values[3][6][4][5] = { 15 | { 16 | }, 17 | { 18 | { 19 | }, 20 | { 21 | {} 22 | , 23 | {0,' ',0,0,0} 24 | }, 25 | { 26 | {} 27 | , 28 | {} 29 | , 30 | {0,0,0,'A',0}, 31 | {0,0,0,0, 'X'} 32 | 33 | }, 34 | { 35 | {} 36 | , 37 | {} 38 | , 39 | {0,0,0xf3,0,0} 40 | 41 | }, 42 | { 43 | {} 44 | , 45 | {} 46 | , 47 | {0,0,0,'\n',0} 48 | 49 | } 50 | }, 51 | { 52 | {} 53 | , 54 | { 55 | {0,0,0,0,0}, 56 | {0,0,0320,0,0} 57 | 58 | }, 59 | { 60 | {}, 61 | {0,'0',0,0,0}, 62 | {0,0,'\'',0,0}, 63 | {0,'\121',0,0,0} 64 | 65 | }, 66 | { 67 | }, 68 | { 69 | {}, 70 | {}, 71 | {}, 72 | {0,0,'3',3,0} 73 | 74 | } 75 | } 76 | }; 77 | 78 | printf("%c\n", char_values[1][2][2][3]); 79 | printf("%c\n", char_values[2][4][3][2]); 80 | printf("%c\n", char_values[2][4][3][3]); 81 | printf("%c\n", char_values[2][1][1][2]); 82 | printf("%c\n", char_values[1][1][1][1]); 83 | printf("%c\n", char_values[1][4][2][3]); 84 | printf("%c\n", char_values[2][5][3][4]); 85 | printf("%c\n", char_values[2][2][2][2]); 86 | printf("%c\n", char_values[1][3][2][2]); 87 | printf("%c\n", char_values[2][2][3][1]); 88 | printf("%c\n", char_values[1][2][3][4]); 89 | printf("%c\n", char_values[2][2][1][1]); 90 | 91 | return 1; 92 | } 93 | -------------------------------------------------------------------------------- /ch8/flat_indentity_matrix/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS=-Wall -g 2 | 3 | all: 4 | gcc -o flat_identity_matrix flat_identity_matrix.c 5 | 6 | clean: 7 | rm -f flat_identity_matrix 8 | -------------------------------------------------------------------------------- /ch8/flat_indentity_matrix/flat_identity_matrix.c: -------------------------------------------------------------------------------- 1 | /* 2 | Pointers on c - ch8, ex4 3 | flat_identity_matrix.c - version of identity matrix for arbirarily sized, flattened, square matrices 4 | 5 | author: nicolas miller 6 | */ 7 | 8 | #include 9 | 10 | int is_identity_matrix(int *matrix, int dimension) 11 | { 12 | int row, col; 13 | for(row = 0; row < dimension; row++) { 14 | for(col = 0; col < dimension; col++) { 15 | if(row == col) { 16 | if(*matrix != 1) 17 | return 0; 18 | } 19 | else { 20 | if(*matrix != 0) 21 | return 0; 22 | } 23 | matrix++; 24 | } 25 | } 26 | return 1; 27 | } 28 | 29 | int main(int argc, char* argv[]) 30 | { 31 | int matrix1[] = { 32 | 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33 | 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 34 | 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 35 | 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 36 | 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 37 | 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 38 | 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 39 | 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 40 | 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 41 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 42 | }; 43 | int matrix2[] = { 44 | 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45 | 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 46 | 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 47 | 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 48 | 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 49 | 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 50 | 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 51 | 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 52 | 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 53 | 0, 0, 0, 0, 7, 0, 0, 0, 0, 1 54 | }; 55 | int matrix3[] = { 56 | 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 57 | 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 58 | 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 59 | 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 60 | 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 61 | 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 62 | 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 63 | 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 64 | 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 65 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 66 | }; 67 | int matrix4[] = { 68 | 1, 0, 0, 0, 0, 69 | 0, 1, 0, 0, 0, 70 | 0, 0, 1, 0, 0, 71 | 0, 0, 0, 1, 0, 72 | 0, 0, 0, 0, 1 73 | }; 74 | int matrix5[] = { 75 | 1, 0, 0, 0, 72, 76 | 0, 1, 0, 0, 0, 77 | 0, 0, 1, 0, 0, 78 | 0, 0, 0, 1, 0, 79 | 0, 42, 0, 0, 1 80 | }; 81 | int matrix6[] = { 82 | 1, 0, 0, 0, 0, 83 | 0, 1, 0, 0, 0, 84 | 0, 0, 0, 0, 0, 85 | 0, 0, 0, 1, 0, 86 | 0, 0, 0, 0, 1 87 | }; 88 | 89 | printf("%d\n", is_identity_matrix(matrix1, 10)); 90 | printf("%d\n", is_identity_matrix(matrix2, 10)); 91 | printf("%d\n", is_identity_matrix(matrix3, 10)); 92 | printf("%d\n", is_identity_matrix(matrix4, 5)); 93 | printf("%d\n", is_identity_matrix(matrix5, 5)); 94 | printf("%d\n", is_identity_matrix(matrix6, 5)); 95 | 96 | return 1; 97 | } 98 | -------------------------------------------------------------------------------- /ch8/identity_matrix/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS=-Wall -g 2 | 3 | all: 4 | gcc -o identity_matrix identity_matrix.c 5 | 6 | clean: 7 | rm -f identity_matrix 8 | -------------------------------------------------------------------------------- /ch8/identity_matrix/identity_matrix.c: -------------------------------------------------------------------------------- 1 | /* 2 | Pointers on c - ch8, ex3 3 | identity_matrix.c - identity_matrix function and quick test 4 | 5 | author: nicolas miller 6 | */ 7 | 8 | #include 9 | 10 | int is_identity_matrix(int square_matrix[][10]) 11 | { 12 | int row, col; 13 | for(row = 0; row < 10; row++) { 14 | for(col = 0; col < 10; col++) { 15 | if(row == col) { 16 | if(square_matrix[row][col] != 1) 17 | return 0; 18 | } 19 | else { 20 | if(square_matrix[row][col] != 0) 21 | return 0; 22 | } 23 | } 24 | } 25 | return 1; 26 | } 27 | 28 | int main(int argc, char* argv[]) 29 | { 30 | int matrix4[10][10] = { 31 | {1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 32 | {0, 1, 0, 0, 0, 0, 0, 0, 0, 0}, 33 | {0, 0, 1, 0, 0, 0, 0, 0, 0, 0}, 34 | {0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, 35 | {0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, 36 | {0, 0, 0, 0, 0, 1, 0, 0, 0, 0}, 37 | {0, 0, 0, 0, 0, 0, 1, 0, 0, 0}, 38 | {0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, 39 | {0, 0, 0, 0, 0, 0, 0, 0, 1, 0}, 40 | {0, 0, 0, 0, 0, 0, 0, 0, 0, 1} 41 | }; 42 | int matrix5[10][10] = { 43 | {1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 44 | {0, 1, 0, 0, 0, 0, 0, 0, 0, 0}, 45 | {0, 0, 1, 0, 0, 0, 4, 0, 0, 0}, 46 | {0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, 47 | {0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, 48 | {0, 0, 0, 0, 0, 1, 0, 0, 0, 0}, 49 | {0, 0, 0, 0, 0, 0, 1, 0, 0, 0}, 50 | {0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, 51 | {0, 0, 0, 0, 0, 0, 0, 0, 1, 0}, 52 | {0, 0, 0, 0, 7, 0, 0, 0, 0, 1} 53 | }; 54 | int matrix6[10][10] = { 55 | {1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 56 | {0, 1, 0, 0, 0, 0, 0, 0, 0, 0}, 57 | {0, 0, 1, 0, 0, 0, 4, 0, 0, 0}, 58 | {0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, 59 | {0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, 60 | {0, 0, 0, 0, 0, 1, 0, 0, 0, 0}, 61 | {0, 0, 0, 0, 0, 0, 1, 0, 0, 0}, 62 | {0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, 63 | {0, 0, 0, 0, 0, 0, 0, 0, 1, 0}, 64 | {0, 0, 0, 0, 0, 0, 0, 0, 0, 0} 65 | }; 66 | 67 | printf("%d\n", is_identity_matrix(matrix4)); 68 | printf("%d\n", is_identity_matrix(matrix5)); 69 | printf("%d\n", is_identity_matrix(matrix6)); 70 | 71 | return 1; 72 | } 73 | -------------------------------------------------------------------------------- /ch8/matrix_multiply/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS=-Wall -g 2 | 3 | all: 4 | gcc -o matrix_multiply matrix_multiply.c 5 | 6 | clean: 7 | rm -f matrix_multiply 8 | -------------------------------------------------------------------------------- /ch8/matrix_multiply/matrix_multiply.c: -------------------------------------------------------------------------------- 1 | /* 2 | Pointers on c - ch8, ex5 3 | matrix_multiply.c - naive matrix_multiply function, utility funcs and quick test 4 | 5 | author: nicolas miller 6 | */ 7 | 8 | #include 9 | 10 | int get_val_at_ij(int *matrix, int i, int j, int cols) 11 | { 12 | return *(matrix + (cols * i + j)); 13 | } 14 | 15 | void set_val_at_ij(int *matrix, int i, int j, int cols, int val) 16 | { 17 | *(matrix + (cols * i + j)) = val; 18 | } 19 | 20 | int c_ij(int *m_a, int *m_b, int i, int j, int y, int z) 21 | { 22 | int c_ij = 0; 23 | int k = 0; 24 | for(; k < y; k++) { 25 | c_ij += get_val_at_ij(m_a, i, k, y) * get_val_at_ij(m_b, k, j, z); 26 | } 27 | 28 | return c_ij; 29 | } 30 | 31 | void matrix_multiply(int *m_a, int *m_b, int *result, int x, int y, int z) 32 | { 33 | int row; 34 | int col; 35 | for(row = 0; row < x; row++) { 36 | for(col = 0; col < z; col++) { 37 | set_val_at_ij(result, 38 | row, 39 | col, 40 | z, 41 | c_ij(m_a, m_b, row, col, y, z)); 42 | } 43 | } 44 | } 45 | 46 | void print_matrix(int *matrix, int rows, int cols) { 47 | int row; 48 | int col; 49 | for(row = 0; row < rows; row++) { 50 | for(col = 0; col < cols; col++) { 51 | printf("%d ", get_val_at_ij(matrix, row, col, cols)); 52 | } 53 | printf("\n"); 54 | } 55 | } 56 | 57 | int main(int argc, char* argv[]) 58 | { 59 | int x = 3; 60 | int y = 2; 61 | int z = 4; 62 | int i; 63 | 64 | int a[] = { 65 | 2, -6, 66 | 3, 5, 67 | 1, -1 68 | }; 69 | int b[] = { 70 | 4, -2, -4, -5, 71 | -7, -3, 6, 7 72 | }; 73 | int result[] = { 74 | 0, 0, 0, 0, 75 | 0, 0, 0, 0, 76 | 0, 0, 0, 0 77 | }; 78 | 79 | print_matrix(a, x, y); 80 | printf("\n"); 81 | print_matrix(b, y, z); 82 | printf("\n"); 83 | print_matrix(result, x, z); 84 | printf("\n"); 85 | 86 | matrix_multiply(a, b, result, x, y, z); 87 | 88 | print_matrix(result, x, z); 89 | printf("\n"); 90 | 91 | return 1; 92 | } 93 | -------------------------------------------------------------------------------- /ch8/single_tax/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS=-Wall -g 2 | 3 | all: 4 | gcc -o single_tax single_tax.c 5 | 6 | clean: 7 | rm -f single_tax 8 | -------------------------------------------------------------------------------- /ch8/single_tax/single_tax.c: -------------------------------------------------------------------------------- 1 | /* 2 | Pointers on c - ch8, ex2 3 | single_tax.c - single_tax function 4 | 5 | author: nicolas miller 6 | */ 7 | 8 | #include 9 | #include 10 | 11 | // yeah floats for money (what the book requires...) 12 | float single_tax(float income) 13 | { 14 | 15 | if(income < 0.0) { 16 | exit(-1); 17 | } 18 | else if(income < 23350.0) { 19 | return 0.15 * income; 20 | } 21 | else if(income > 23350.0 && income <= 56550.0) { 22 | return 3502.5 + (income - 23350) * 0.28; 23 | } 24 | else if(income > 56550.0 && income <= 117950.0) { 25 | return 12798.5 + (income - 56550.0) * 0.31; 26 | } 27 | else if(income > 117950.0 && income <= 256500.0) { 28 | return 31832.5 + (income - 117950.0) * 0.36; 29 | } 30 | else { 31 | return 81710.5 + (income - 256500.0) * 0.396; 32 | } 33 | } 34 | 35 | int main(int argc, char* argv[]) 36 | { 37 | printf("%f\n", single_tax(10000)); 38 | printf("%f\n", single_tax(20000)); 39 | printf("%f\n", single_tax(110000)); 40 | printf("%f\n", single_tax(210000)); 41 | printf("%f\n", single_tax(310000)); 42 | return 1; 43 | } 44 | -------------------------------------------------------------------------------- /ch9/char_percent/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS=-Wall -g 2 | 3 | all: 4 | gcc -o char_percent char_percent.c 5 | 6 | clean: 7 | rm -f char_percent 8 | -------------------------------------------------------------------------------- /ch9/char_percent/char_percent.c: -------------------------------------------------------------------------------- 1 | /* 2 | Pointers on c - ch9, ex1 3 | char_percent.c - computes distribution of character categories in std input 4 | 5 | author: nicolas miller 6 | */ 7 | 8 | #include 9 | #include 10 | 11 | int main(int argc, char* argv[]) 12 | { 13 | unsigned int num_chars = 0; 14 | 15 | unsigned int num_upper = 0; 16 | unsigned int num_lower = 0; 17 | unsigned int num_whitespace = 0; 18 | unsigned int num_digits = 0; 19 | unsigned int num_control = 0; 20 | unsigned int num_punct = 0; 21 | unsigned int num_non_print = 0; 22 | 23 | int c; 24 | 25 | while((c = getchar()) != EOF) { 26 | if(isupper(c)) 27 | num_upper++; 28 | else if(islower(c)) 29 | num_lower++; 30 | else if(isspace(c)) 31 | num_whitespace++; 32 | else if(isdigit(c)) 33 | num_digits++; 34 | else if(iscntrl(c)) 35 | num_control++; 36 | else if(ispunct(c)) 37 | num_punct++; 38 | else if(!isprint(c)) 39 | num_non_print++; 40 | num_chars++; 41 | } 42 | 43 | printf("num chars: %d\n", num_chars); 44 | printf("upper: %f%%\n", (float) num_upper / (float) num_chars * 100); 45 | printf("lower: %f%%\n", (float) num_lower / (float) num_chars * 100); 46 | printf("whitespace: %f%%\n", (float) num_whitespace / (float) num_chars * 100); 47 | printf("digits: %f%%\n", (float) num_digits / (float) num_chars * 100); 48 | printf("control: %f%%\n", (float) num_control / (float) num_chars * 100); 49 | printf("punct: %f%%\n", (float) num_punct / (float) num_chars * 100); 50 | printf("non-print: %f%%\n", (float) num_non_print / (float) num_chars * 100); 51 | 52 | return 1; 53 | } 54 | -------------------------------------------------------------------------------- /ch9/count_chars/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS=-Wall -g 2 | 3 | all: 4 | gcc -o count_chars count_chars.c 5 | 6 | clean: 7 | rm -f count_chars 8 | -------------------------------------------------------------------------------- /ch9/count_chars/count_chars.c: -------------------------------------------------------------------------------- 1 | /* 2 | Pointers on c - ch9, ex9 3 | count_chars.c - count chars in str that match any of set of chars 4 | 5 | author: nicolas miller 6 | */ 7 | 8 | #include 9 | 10 | int count_chars(char const *str, char const *chars) 11 | { 12 | int count = 0; 13 | char const *chars_ptr = chars; 14 | while(*str != '\0') { 15 | while(*chars_ptr != '\0') { 16 | if(*str == *chars_ptr) { 17 | count++; 18 | break; 19 | } 20 | chars_ptr++; 21 | } 22 | chars_ptr = chars; 23 | str++; 24 | } 25 | 26 | return count; 27 | } 28 | int main(int argc, char* argv[]) 29 | { 30 | char str1[] = "abcdefgabcdefg111"; 31 | char chars1[] = "abcdef"; 32 | char chars2[] = "abc"; 33 | char chars3[] = "1"; 34 | char chars4[] = "2"; 35 | char chars5[] = ""; 36 | 37 | printf("%d\n", count_chars(str1, chars1) == 12); 38 | printf("%d\n", count_chars(str1, chars2) == 6); 39 | printf("%d\n", count_chars(str1, chars3) == 3); 40 | printf("%d\n", count_chars(str1, chars4) == 0); 41 | printf("%d\n", count_chars(str1, chars5) == 0); 42 | 43 | printf("%d\n", count_chars(str1, chars1)); 44 | printf("%d\n", count_chars(str1, chars2)); 45 | printf("%d\n", count_chars(str1, chars3)); 46 | printf("%d\n", count_chars(str1, chars4)); 47 | printf("%d\n", count_chars(str1, chars5)); 48 | 49 | return 1; 50 | } 51 | -------------------------------------------------------------------------------- /ch9/encryption/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS=-Wall -g 2 | 3 | all: 4 | gcc -o encryption encryption.c 5 | 6 | clean: 7 | rm -f encryption 8 | -------------------------------------------------------------------------------- /ch9/encryption/encryption.c: -------------------------------------------------------------------------------- 1 | /* 2 | Pointers on c - ch9, ex12, ex13, ex14 3 | encryption.c - very basic encryption scheme and functions 4 | - assume key array is 27 chars long 5 | - ignore non-alpha, preserve case 6 | 7 | author: nicolas miller 8 | */ 9 | 10 | #include 11 | #include 12 | 13 | 14 | void kill_dups(char *key) { 15 | char *other; 16 | while(*key != '\0') { 17 | other = key + 1; 18 | while(*other != '\0') { 19 | if(*key == *other) { 20 | char *cpy = other + 1; 21 | while(*cpy != '\0') { 22 | *(cpy - 1) = *cpy; 23 | cpy++; 24 | } 25 | *(cpy - 1) = '\0'; 26 | continue; 27 | } 28 | 29 | other++; 30 | } 31 | key++; 32 | } 33 | } 34 | 35 | int contains(char *key, char ch) { 36 | while(*key != '\0') { 37 | if(*key == ch) 38 | return 1; 39 | key++; 40 | } 41 | return 0; 42 | } 43 | 44 | void fill_in_rest(char *key) { 45 | char *key_front = key; 46 | int i; 47 | while(*key != '\0') 48 | key++; 49 | char ch = 'a'; 50 | while(ch <= 'z') { 51 | if(!contains(key_front, ch)) { 52 | *key = ch; 53 | *(key + 1) = '\0'; 54 | key++; 55 | } 56 | ch++; 57 | } 58 | } 59 | 60 | int prepare_key(char *key) 61 | { 62 | char *ptr = key; 63 | if(*key == '\0') 64 | return 0; 65 | 66 | while(*ptr != '\0') { 67 | if(!isalpha(*ptr)) 68 | return 0; 69 | ptr++; 70 | } 71 | ptr = key; 72 | while(*ptr != '\0') { 73 | *ptr = tolower(*ptr); 74 | ptr++; 75 | } 76 | kill_dups(key); 77 | fill_in_rest(key); 78 | return 1; 79 | } 80 | 81 | void encrypt(char *data, char const *key) 82 | { 83 | while(*data != '\0') { 84 | if(isalpha(*data)) { 85 | int upper = isupper(*data); 86 | if(upper) 87 | *data = tolower(*data); 88 | *data = key[*data - 'a']; 89 | if(upper) 90 | *data = toupper(*data); 91 | } 92 | data++; 93 | } 94 | } 95 | 96 | void decrypt(char *data, char const *key) 97 | { 98 | while(*data != '\0') { 99 | if(isalpha(*data)) { 100 | int upper = isupper(*data); 101 | char const *key_ptr = key; 102 | if(upper) 103 | *data = tolower(*data); 104 | while(*data != *key_ptr) 105 | key_ptr++; 106 | *data = 'a' + (key_ptr - key); 107 | if(upper) 108 | *data = toupper(*data); 109 | } 110 | data++; 111 | } 112 | } 113 | 114 | int main(int argc, char* argv[]) 115 | { 116 | char test[27] = "abcdefg"; 117 | char test2[27] = "aabbcdabddbbadaefbagfffaqq"; 118 | char test3[27] = "aaabbb"; 119 | char test4[27] = "trailblazers"; 120 | char test4upper[27] = "TRAILBLAZERS"; 121 | char nonalpha[27] = "123213*(*@#$&*@&$"; 122 | char empty[27] = ""; 123 | 124 | char toencrypt[] = "abcdefg"; 125 | char toencrypt_upper[] = "ABCDEFG"; 126 | char toencrypt2[] = "abcdefg@*&#@*&#*@ABCDEFG"; 127 | 128 | /* 129 | kill_dups(test); 130 | printf("%s\n", test); 131 | kill_dups(test2); 132 | printf("%s\n", test2); 133 | kill_dups(test3); 134 | printf("%s\n", test3); 135 | kill_dups(test4); 136 | printf("%s\n", test4); 137 | 138 | printf("%d\n", contains(test, 'a')); 139 | printf("%d\n", contains(test, 'b')); 140 | printf("%d\n", contains(test, 'c')); 141 | printf("%d\n", contains(test, 'd')); 142 | printf("%d\n", contains(test, 'e')); 143 | printf("%d\n", contains(test, 'z')); 144 | printf("%d\n", contains(test, '1')); 145 | 146 | fill_in_rest(test); 147 | printf("%s\n", test); 148 | fill_in_rest(test2); 149 | printf("%s\n", test2); 150 | fill_in_rest(test3); 151 | printf("%s\n", test3); 152 | fill_in_rest(test4); 153 | printf("%s\n", test4); 154 | */ 155 | 156 | prepare_key(test); 157 | printf("%s\n", test); 158 | prepare_key(test2); 159 | printf("%s\n", test2); 160 | prepare_key(test3); 161 | printf("%s\n", test3); 162 | prepare_key(test4); 163 | printf("%s\n", test4); 164 | prepare_key(test4upper); 165 | printf("%s\n", test4upper); 166 | printf("%d\n", prepare_key(nonalpha) == 0); 167 | printf("%d\n", prepare_key(empty) == 0); 168 | 169 | encrypt(toencrypt, test4); 170 | printf("%s\n", toencrypt); 171 | encrypt(toencrypt_upper, test4); 172 | printf("%s\n", toencrypt_upper); 173 | encrypt(toencrypt2, test4); 174 | printf("%s\n", toencrypt2); 175 | 176 | decrypt(toencrypt, test4); 177 | printf("%s\n", toencrypt); 178 | decrypt(toencrypt_upper, test4); 179 | printf("%s\n", toencrypt_upper); 180 | decrypt(toencrypt2, test4); 181 | printf("%s\n", toencrypt2); 182 | return 1; 183 | } 184 | -------------------------------------------------------------------------------- /ch9/my_strcpy/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS=-Wall -g 2 | 3 | all: 4 | gcc -o my_strcpy my_strcpy.c 5 | 6 | clean: 7 | rm -f my_strcpy 8 | -------------------------------------------------------------------------------- /ch9/my_strcpy/my_strcpy.c: -------------------------------------------------------------------------------- 1 | /* 2 | Pointers on c - ch9, ex3 3 | my_strcpy.c - my_strcpy with dest_length param to avoid overflow and tests 4 | 5 | author: nicolas miller 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | char *my_strcpy(char *dest, const char *source, size_t dest_length) 13 | { 14 | char *front_of_dest = dest; 15 | 16 | size_t copied = 0; 17 | while((copied < dest_length) && (*source != '\0')) { 18 | *dest++ = *source++; 19 | copied++; 20 | } 21 | *dest = '\0'; 22 | 23 | return front_of_dest; 24 | } 25 | 26 | int main(int argc, char* argv[]) 27 | { 28 | char dest1[9]; 29 | char dest2[9]; 30 | char dest3[9]; 31 | 32 | char *src1 = "01234"; 33 | char *src2 = "123456789"; 34 | char *src3 = "123456789abcdf"; 35 | 36 | printf("%s\n", my_strcpy(dest1, src1, 9)); 37 | printf("%s\n", my_strcpy(dest2, src2, 9)); 38 | printf("%s\n", my_strcpy(dest3, src3, 9)); 39 | 40 | return 1; 41 | } 42 | -------------------------------------------------------------------------------- /ch9/my_strcpy_end/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS=-Wall -g 2 | 3 | all: 4 | gcc -o my_strcpy_end my_strcpy_end.c 5 | 6 | clean: 7 | rm -f my_strcpy_end 8 | -------------------------------------------------------------------------------- /ch9/my_strcpy_end/my_strcpy_end.c: -------------------------------------------------------------------------------- 1 | /* 2 | Pointers on c - ch9, ex6 3 | my_strcpy_end.c - my_strcpy_end with dest_length param to avoid overflow and tests 4 | returns pointer to end of string rather than beginning.. 5 | 6 | author: nicolas miller 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | char *my_strcpy_end(char *dest, const char *source, size_t dest_length) 14 | { 15 | size_t copied = 0; 16 | while((copied < dest_length) && (*source != '\0')) { 17 | *dest++ = *source++; 18 | copied++; 19 | } 20 | *dest = '\0'; 21 | 22 | return dest; 23 | } 24 | 25 | int main(int argc, char* argv[]) 26 | { 27 | char dest1[9]; 28 | char dest2[9]; 29 | char dest3[9]; 30 | 31 | char *src1 = "01234"; 32 | char *src2 = "123456789"; 33 | char *src3 = "123456789abcdf"; 34 | 35 | printf("%d\n", *my_strcpy_end(dest1, src1, 9) == '\0'); 36 | printf("%d\n", *my_strcpy_end(dest2, src2, 9) == '\0'); 37 | printf("%d\n", *my_strcpy_end(dest3, src3, 9) == '\0'); 38 | 39 | printf("%s\n", dest1); 40 | printf("%s\n", dest2); 41 | printf("%s\n", dest3); 42 | 43 | return 1; 44 | } 45 | -------------------------------------------------------------------------------- /ch9/my_strncat/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS=-Wall -g 2 | 3 | all: 4 | gcc -o my_strncat my_strncat.c 5 | 6 | clean: 7 | rm -f my_strncat 8 | -------------------------------------------------------------------------------- /ch9/my_strncat/my_strncat.c: -------------------------------------------------------------------------------- 1 | /* 2 | Pointers on c - ch9, ex3 3 | my_strcat.c - my_strcat with dest_length param to avoid overflow and tests 4 | 5 | author: nicolas miller 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | char *my_strcat(char *dest, const char *source, size_t dest_length) 13 | { 14 | char *dest_start = dest; 15 | size_t dest_position = 0; 16 | 17 | while(*dest++ != '\0') 18 | dest_position++; 19 | dest--; 20 | while(dest_position < dest_length && *source != '\0') { 21 | *dest++ = *source++; 22 | dest_position++; 23 | } 24 | *dest = '\0'; 25 | 26 | return dest_start; 27 | } 28 | 29 | int main(int argc, char* argv[]) 30 | { 31 | char dest1[10] = "01234"; 32 | char dest2[10] = "foobar"; 33 | char dest3[10] = ""; 34 | 35 | char *src1 = "56789"; 36 | char *src2 = "bazquux"; 37 | char *src3 = "Surely you're joking, Mr. Feynman"; 38 | 39 | printf("%s\n", my_strcat(dest1, src1, 10)); 40 | printf("%s\n", my_strcat(dest2, src2, 10)); 41 | printf("%s\n", my_strcat(dest3, src3, 10)); 42 | 43 | return 1; 44 | } 45 | -------------------------------------------------------------------------------- /ch9/my_strnchr/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS=-Wall -g 2 | 3 | all: 4 | gcc -o my_strnchr my_strnchr.c 5 | 6 | clean: 7 | rm -f my_strnchr 8 | -------------------------------------------------------------------------------- /ch9/my_strnchr/my_strnchr.c: -------------------------------------------------------------------------------- 1 | /* 2 | Pointers on c - ch9, ex8 3 | my_strnchr.c 4 | 5 | author: nicolas miller 6 | */ 7 | 8 | #include 9 | 10 | char *my_strnchr(char const *str, int ch, int which) 11 | { 12 | char *match = NULL; 13 | while(*str != '\0') { 14 | if(*str == ch && which-- > 0) 15 | match = str; 16 | str++; 17 | } 18 | 19 | return match; 20 | } 21 | 22 | int main(int argc, char* argv[]) 23 | { 24 | char str1[] = "foo foo2 foo3"; 25 | 26 | printf("%s\n", my_strnchr(str1, 'f', 1)); 27 | printf("%s\n", my_strnchr(str1, 'f', 2)); 28 | printf("%s\n", my_strnchr(str1, 'f', 3)); 29 | printf("%s\n", my_strnchr(str1, 'o', 1)); 30 | printf("%s\n", my_strnchr(str1, 'o', 2)); 31 | printf("%s\n", my_strnchr(str1, 'o', 3)); 32 | printf("%s\n", my_strnchr(str1, 'o', 4)); 33 | printf("%s\n", my_strnchr(str1, 'o', 5)); 34 | printf("%s\n", my_strnchr(str1, 'o', 6)); 35 | printf("%s\n", my_strnchr(str1, '3', 6)); 36 | printf("%s\n", my_strnchr(str1, '3', 72)); 37 | printf("%s\n", my_strnchr(str1, '3', 1)); 38 | 39 | return 1; 40 | } 41 | -------------------------------------------------------------------------------- /ch9/my_strnlen/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS=-Wall -g 2 | 3 | all: 4 | gcc -o my_strnlen my_strnlen.c 5 | 6 | clean: 7 | rm -f my_strnlen 8 | -------------------------------------------------------------------------------- /ch9/my_strnlen/my_strnlen.c: -------------------------------------------------------------------------------- 1 | /* 2 | Pointers on c - ch9, ex2 3 | my_strnlen.c - my_strnlen function and tests 4 | 5 | author: nicolas miller 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | size_t my_strnlen(const char *s, int size) 13 | { 14 | unsigned int length = 0; 15 | while(length < size && *s != '\0') { 16 | length++; 17 | s++; 18 | } 19 | 20 | return length; 21 | } 22 | 23 | int main(int argc, char* argv[]) 24 | { 25 | char *str1 = "here's a string sdfjkl"; 26 | char *str2 = "123456789"; 27 | char unterm[9] = "123456789"; 28 | 29 | printf("%zd\n", my_strnlen(str1, 50)); 30 | printf("%zd\n", my_strnlen(str2, 50)); 31 | printf("%zd\n", my_strnlen(unterm, 9)); 32 | 33 | return 1; 34 | } 35 | -------------------------------------------------------------------------------- /ch9/my_strrchr/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS=-Wall -g 2 | 3 | all: 4 | gcc -o my_strrchr my_strrchr.c 5 | 6 | clean: 7 | rm -f my_strrchr 8 | -------------------------------------------------------------------------------- /ch9/my_strrchr/my_strrchr.c: -------------------------------------------------------------------------------- 1 | /* 2 | Pointers on c - ch9, ex7 3 | my_strrchr.c - rightmost occurance of char 4 | 5 | author: nicolas miller 6 | */ 7 | 8 | #include 9 | 10 | char *my_strrchr(char const *str, int ch) 11 | { 12 | char *match = NULL; 13 | while(*str++ != '\0') 14 | if(*str == ch) 15 | match = str; 16 | 17 | return match; 18 | } 19 | 20 | int main(int argc, char* argv[]) 21 | { 22 | char str1[] = "f2f3333333333f34fff"; 23 | char str2[] = "349944848844847"; 24 | 25 | printf("%d\n", *my_strrchr(str1, 'f') == 'f'); 26 | printf("%d\n", *my_strrchr(str2, '7') == '7'); 27 | printf("%d\n", my_strrchr(str2, 'f') == NULL); 28 | 29 | return 1; 30 | } 31 | -------------------------------------------------------------------------------- /ch9/palindrome/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS=-Wall -g 2 | 3 | all: 4 | gcc -o palindrome palindrome.c 5 | 6 | clean: 7 | rm -f palindrome 8 | -------------------------------------------------------------------------------- /ch9/palindrome/palindrome.c: -------------------------------------------------------------------------------- 1 | /* 2 | Pointers on c - ch9, ex10 3 | palindrome.c - determine if string is palindrome 4 | 5 | author: nicolas miller 6 | */ 7 | 8 | #include 9 | 10 | int palindrome(char *str) 11 | { 12 | char *end = str; 13 | while(*end != '\0') 14 | end++; 15 | end--; 16 | 17 | while(str < end) { 18 | if(*str != *end) 19 | return 0; 20 | str++; 21 | end--; 22 | } 23 | 24 | return 1; 25 | } 26 | 27 | int main(int argc, char* argv[]) 28 | { 29 | char str1[] = "abcdefgabcdefg111"; 30 | char str2[] = "abcdefggfedcba"; 31 | char str3[] = "abcdefgfedcba"; 32 | char str4[] = "11111111"; 33 | char str5[] = "11111112"; 34 | char str6[] = "31111112"; 35 | char str7[] = "3"; 36 | char str8[] = ""; 37 | 38 | printf("%d\n", palindrome(str1)); 39 | printf("%d\n", palindrome(str2)); 40 | printf("%d\n", palindrome(str3)); 41 | printf("%d\n", palindrome(str4)); 42 | printf("%d\n", palindrome(str5)); 43 | printf("%d\n", palindrome(str6)); 44 | printf("%d\n", palindrome(str7)); 45 | printf("%d\n", palindrome(str8)); 46 | 47 | return 1; 48 | } 49 | -------------------------------------------------------------------------------- /ch9/the_count/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS=-Wall -g 2 | 3 | all: 4 | gcc -o the_count the_count.c 5 | 6 | clean: 7 | rm -f the_count 8 | -------------------------------------------------------------------------------- /ch9/the_count/the_count.c: -------------------------------------------------------------------------------- 1 | /* 2 | Pointers on c - ch9, ex11 3 | the_count.c - count occurances of 'the' on standard input assuming: 4 | -- words separated by one or more whitespace chars 5 | -- input lines less than 100 lines 6 | 7 | author: nicolas miller 8 | */ 9 | 10 | #include 11 | 12 | #define BUFFSIZE 100 13 | 14 | int matches(char *str, char *the) { 15 | while(*the != '\0') { 16 | if(*str != *the) 17 | return 0; 18 | str++; 19 | the++; 20 | } 21 | 22 | /* only match if bounded by space or null on right */ 23 | if(!isspace(*str) || *str == '\0') 24 | return 0; 25 | 26 | return 1; 27 | } 28 | 29 | int the_count(char *str) 30 | { 31 | int count = 0; 32 | while(*str != '\0') { 33 | if(matches(str, "the")) 34 | count++; 35 | 36 | while(!isspace(*str)) /* skip over rest of word */ 37 | str++; 38 | while(isspace(*str)) /* skip over space between words */ 39 | str++; 40 | 41 | } 42 | return count; 43 | } 44 | 45 | int main(int argc, char* argv[]) 46 | { 47 | char buffer[BUFFSIZE]; 48 | 49 | while(fgets(buffer, BUFFSIZE, stdin) != NULL) { 50 | printf("the_count: %d\n", the_count(buffer)); 51 | } 52 | 53 | return 1; 54 | } 55 | --------------------------------------------------------------------------------