Part 2: The C Programming Language
The leftmost book was a first edition, and it beckoned me, sometime around 1984, from the shelves of Barnes & Nobles. Priced at $17.95, the book was a significant out-of-pocket expense for someone on their first job, but it would prove to be quite the investment.
Turning to the Introduction, I noticed it was denoted as Chapter 0. This was a delightful self-reference to the C language itself, where arrays started with an index of 0, instead of 1. Think of it as an elevator that marks the ground floor as "G" and the next floor up as "1."
C's array and pointer capabilities were what made the language especially powerful, compact, clear, and efficient, but it also took discipline to use them right. Pointers let you access memory, but sloppy use can take your pointer to bad places, leading to security holes, and ultimately crashing your program.
One technique I've used to corral stray pointers was to set them null after I was done with them. It was still wrong to read and write to these pointer locations, but the consequences of accidentally doing so would be less severe. I called this "parking your pointers" because it was analogous to engaging the parking brake after you've parked your car.
I was particularly fond of pointers to functions. They were typically used to guide sorting algorithms to a custom comparison function. I've used them to create a more flexible print() routine which could format for various devices such as a screen, a printer, or a file. Instead of having high-maintenance if-else sequences, or a slightly better switch() statement, you had 3 separate functions -- one of each device -- and passed in the desired function to the print() routine.
Initially, I encountered some resistance from teammates. Pointers to functions were not as obvious as if-else sequences, but after setting them up and using them, colleagues remarked how easy they were to use, and how clear they were for maintenance. Also, printing to a new device -- say, a network socket -- just meant writing a 4th function and passing it into the print() routine. Bonus: the existing production code for writing to a screen, printer, and file, would remain safely untouched.
C's pointers to functions can be considered a precursor to object-oriented polymorphism. Indeed, C++'s overloading and overriding of methods were formal language mechanisms for something very similar. For a language with about 30 keywords, C has proven itself to be pretty powerful.
To be concluded in part 3 ...
Turning to the Introduction, I noticed it was denoted as Chapter 0. This was a delightful self-reference to the C language itself, where arrays started with an index of 0, instead of 1. Think of it as an elevator that marks the ground floor as "G" and the next floor up as "1."
C's array and pointer capabilities were what made the language especially powerful, compact, clear, and efficient, but it also took discipline to use them right. Pointers let you access memory, but sloppy use can take your pointer to bad places, leading to security holes, and ultimately crashing your program.
One technique I've used to corral stray pointers was to set them null after I was done with them. It was still wrong to read and write to these pointer locations, but the consequences of accidentally doing so would be less severe. I called this "parking your pointers" because it was analogous to engaging the parking brake after you've parked your car.
I was particularly fond of pointers to functions. They were typically used to guide sorting algorithms to a custom comparison function. I've used them to create a more flexible print() routine which could format for various devices such as a screen, a printer, or a file. Instead of having high-maintenance if-else sequences, or a slightly better switch() statement, you had 3 separate functions -- one of each device -- and passed in the desired function to the print() routine.
Initially, I encountered some resistance from teammates. Pointers to functions were not as obvious as if-else sequences, but after setting them up and using them, colleagues remarked how easy they were to use, and how clear they were for maintenance. Also, printing to a new device -- say, a network socket -- just meant writing a 4th function and passing it into the print() routine. Bonus: the existing production code for writing to a screen, printer, and file, would remain safely untouched.
C's pointers to functions can be considered a precursor to object-oriented polymorphism. Indeed, C++'s overloading and overriding of methods were formal language mechanisms for something very similar. For a language with about 30 keywords, C has proven itself to be pretty powerful.
To be concluded in part 3 ...
Comments