Hello World in C, Dev Setup

As mentioned, I'm learning C, and I've achieved hello-world, plus recursive calculations of factorials and some data structures. Whee. :) For those playing along at home, I'll describe my dev setup.

But first, an unexpected discovery: Counter to my intuition, there's a beneficial synergy between learning a new editor and learning a new language at the same time. I had thought it would be too many new things to take on at once. I've wanted to learn Vim for its beautiful efficiency, but its formidable learning curve repels all comers. I couldn't gain traction. When writing in a language with which I am comfortable (C#, English), my thoughts would run too fast, too far ahead of my rudimentary editor skills, ideas slipping out of my grasp as I stumbled around the text with j, k, h, and l (and never the one I meant). But in C, where I am carefully picking my way over unfamiliar terrain, my lines of code have slowed down to match my fingers. Because I am trying to hang onto only one edit at a time, I can spare a second to check that A will switch me to insert mode at the end of the current line. I recommend it: learning a new language is a good time to learn a new text editor.

Sandbox


I use VirtualBox to run virtual machines. VMs are excellent for experiment-based learning; think of it: a nice clean server that you can start up, poke and abuse, throw away and start again. If you start with the right VM image—for example, one configured for Ruby on Rails—you can jump right into the experimentation without all the installation hoop-jumping.

For this endeavor I chose TurnKey Linux's Core appliance because it's just Linux and not much else, following their instructions for installing a TurnKey appliance.

To install a compiler (later), I needed my VM to connect to the internet. In VirtualBox Settings > Network, I set "Attached to" to "Bridged Adapter," meaning the VM could use my laptop's connection, and the adapter's "Name" to my wireless card. (The other choice in the dropdown list is a PCI-E Fast Ethernet Controller, and that... didn't work.) With that set, I powered up the VM, which starts the webmin console. I let it automatically configure DHCP, and I was internet-ready.

Editor


Vim is already installed on the Core VM image, so I just needed to type "vim helloworld.c" to start stumbling around my new code file. I'm relying on the TuXfiles Vim cheat sheet.

Compiler


I chose GCC, the GNU Compiler Collection for my C compiler, and I needed to download and install it. Following TurnKey's apt-get instructions:
  • apt-get update (to update apt's list of modules)
  • apt-cache search gcc (to find modules for the gcc compiler - gcc-4.1 looked right.)
  • apt-cache show gcc-4.1 (to get info about it)
  • apt-get install gcc-4.1 (to install it)
  • gcc-4.1 myfile.c -o myexename (to compile and generate myexename executable)
  • ./myexename (to run my program)


Hello World


I followed a video that creates and compiles a C program using the GCC compiler. "Hello, World!" A simple phrase, profoundly satisfying.

Dipping into C

I decided on Monday that I should learn C. Cultivate a nodding acquaintance, at any rate. Louis is always prodding me to become a better craftsman, to become more proficient with my tools. So I figured I should understand my roots.

I picked up O'Reilly's Mastering Algorithms with C at the library, and I'm already having fun. It will get into recursion, Big O notation, linked lists, quicksorts, encryption, and all that jazz, but right off the bat, it starts with pointers.

Immediately some aspects of C# become more clear, by understanding their precursors from C: the ideas behind reference types and passing parameters by reference, and the joys of automatic garbage collection and abstracted memory allocation.

The syntax of pointers in C involves a lot of punctuation—a subtle and nuanced application of asterisks and ampersands—which the book assumes I would already know. My favorite search engine (code-named Sweetie, as in, "Hey, Sweetie, can you find...") turned up an online edition of The C Book, containing this excellent explanation of pointers.

Here's my understanding so far. Please suggest corrections if I've gotten it sideways.
int *mypointer;mypointer's type is "pointer that can point to an integer"
mypointer = &myint;mypointer is pointing to the location where myint is stored
*mypointer = 7;the place where mypointer is pointing now contains a 7, so myint now equals 7
myotherint = myint;myotherint also equals 7 (but just a copy of 7, so changes to myint won't affect myotherint)

So what? So now I'm clearer about reference types in C#. In C, I can pass a pointer as a parameter to a function, instead of passing a value. That means I'm passing the function a reference to a location in memory. If the function uses the pointer to change the stuff in that location, when someone else accesses that location, they will receive the changed stuff. Contrast this with passing a value, such as an integer, to a function, which actually passes a copy of the value. Any changes to the value are scoped within the function and are not detectable from outside. It's something I've known for a while, but now I know why.

If you no longer need the piece of memory that a pointer points to but you fail to de-allocate that memory, it will stay held in reserve forever—voilà, a memory leak. Different data types take up different amounts of memory, so writing a data type into a pointer of a differently sized data type will overwrite other pieces of memory in unpredictable ways. I feel like I've been making peanut-butter sandwiches with a butter knife and just noticed that other people are wielding samurai swords: looks really powerful and flexible, but I'm scared I'd cut off a finger. Now I get what the big deal is about the CLR's garbage collector (and how in some contexts it would be too restrictive).

I'm having fun getting "closer to the metal" and realizing the reasons behind some things I've taken for granted. I can't wait to get into the chapters on algorithms.