
The C Programming Language
I’m starting with the book The C Programming Language by Brian W. Kernighan and Dennis M. Ritchie. The legend, Dennis Ritchie is no longer with us but Brian Kernighan is still around and is 83 at the time of writing this. It’s interesting that Dennis Ritchie, the creator of C and one of the developers of Unix, died just one week after Steve Jobs but barely got a mention in the news. I think it says a lot about what our society currently values.

This book is a classic that sat on my bookshelf as a handy reference for many years. I plan to work on all the exercises from Chapter 1 to 8. It’s one of the first programming books I encountered all those years ago. I haven’t programmed in C for a very long time however many programming languages are either directly based on C, heavily inspired by its syntax and semantics or extend it in significant ways. Some of the C-like languages I’ve used in my career are C++, Objective-C, Java, JavaScript, Rust, Swift, Perl, Ruby and PHP.

Day 1
My first little brain teaser came in dealing with text streams because I’ve not had to do anything like that in so many years. It was tempting to search for the answer online but I resisted because this was not available to me when I was beginning. Copy/paste coding makes your brain rot. I did have to look up how to find out the EOF for macos terminal. It’s ^D at the start of a new line.
I heard the inner critic saying “You should know this. You’re a crappy programmer!” because I didn’t immediately get the correct result. If I went back to driving a manual car after years of driving an automatic I might also not be as smooth as I once was so I think it’s ok.
I decided to go with a counter solution but I could have saved the previous character to another variable and used that instead.
Exercise 1-9. Write a program to copy its input to its output,replacing each string of one or more blanks by a single blank.
#include <stdio.h>
int main()
{
int c, b;
b = 0;
while ((c = getchar()) != EOF) {
if (c == ' ') {
++b;
} else {
if (b >= 1) {
putchar(' ');
b = 0;
}
putchar(c);
}
}
return 0;
}
I’m in the habit of using curly brackets for loops and conditions rather than just the indent as seen in the K&R book. So most of the time I’ll use those in my examples even though it’s a bit longer.
Day 2
Just did section 1.6 Arrays today. I rediscovered the joy (and frustration) of working with characters and fixed length arrays. Back to basics really exercises the mind. I think my solution to Exercise 1-14 is ok but maybe a bit clumsy. I haven’t separated the code into any functions because the book hasn’t revealed those yet (next section). I am excluding whitespaces because I can’t be bothered dealing with them and I’m using ctype.h for the isspace()
function instead of checking each value.
Common Whitespace Characters in C
| Name | Character | Escape Code | ASCII Decimal | ASCII Hex |
| ------------------- | --------- | ----------- | ------------- | --------- |
| Space | `' '` | `' '` | 32 | 0x20 |
| Horizontal Tab | `\t` | `\t` | 9 | 0x09 |
| Newline (Line Feed) | `\n` | `\n` | 10 | 0x0A |
| Vertical Tab | `\v` | `\v` | 11 | 0x0B |
| Form Feed | `\f` | `\f` | 12 | 0x0C |
| Carriage Return | `\r` | `\r` | 13 | 0x0D |
I added some labels and prettified the chart a bit. It was really fun and satisfying to work on solving a non-productive puzzle. The focus on productivity and delivering on budget when working for somebody else kind of diminishes the joy of pure coding.
Exercise 1-14 Exercise 1-14. Write a program to print a histogram of the frequencies of different characters in its input.
#include <stdio.h>
#include <ctype.h>
int main()
{
int c, i, j, max, top;
max = 255; //valid character codes 0 - 255
int nc[max];
for (i = 0; i < max; ++i)
nc[i] = 0;
while ((c = getchar()) != EOF) {
// exclude whitespace characters
if (!isspace(c)) {
++nc[c];
}
}
top = 0;
for (i = 0; i < max; ++i) {
if (nc[i] > top) {
top = nc[i];
} else if (nc[i] == 0) {
nc[i] = -1; // flag so we can skip unused characters
}
}
printf("\n\n\n");
// top row of chart to bottom
for (i = 0; i < top; ++i) {
printf("%5d| ", top-i); // y axis key and line
for (j = 0; j < max; j++) {
if (nc[j] >= 0) {
if (nc[j] > 0 && nc[j] >= top-i) {
printf(" x ");
--nc[j];
} else {
printf(" ");
}
}
}
printf("\n");
}
// x axis line
printf(" ---");
for (i = 0; i < max; i++) {
if (nc[i] >= 0) {
printf("---");
}
}
// x axis key
printf("\n");
printf(" ");
for (i = 0; i < max; ++i) {
if (nc[i] >= 0) {
printf(" %c ", i);
}
}
// x axis label
printf("\n");
printf(" ");
for (i = 0; i < max; i++) {
if (nc[i] >= 0) {
printf(" ");
}
}
printf("char count\n\n\n\n");
return 0;
}
Input
a a a a a aa aaaaa
888 <<<<<<;
fff hh ;; n;X wJJJJJJJJJJJJJ;
Output
13| x
12| x x
11| x x
10| x x
9| x x
8| x x
7| x x
6| x x x
5| x x x x
4| x x x x
3| x x x x x x
2| x x x x x x x
1| x x x x x x x x x x
---------------------------------
8 ; < J X a f h n w
char count