Learning code by comparison

Recently I’ve slowly been learning C. Learning C has been on my agenda for years since I started using IRC. I’ve always wanted to give back to the IRC community through contributions to the software I use; most of which are in C.

Usually when I learn a new language I try to compare it with language I already know. This probably isn’t a new concept.

So in this, I wanted to share my train of thought for figuring out how to deal with what I would usually know as “objects”, with C.

To guide myself, I start with a simple Ruby script:


class Person
  attr_accessor :name, :age

  def initialize(name, age)
    self.name = name
    self.age  = age
  end
end

person = Person.new('James Newton', 21)

person.name #=> "James Newton"
person.age  #=> 21
      

Since C does not have classes like Ruby, we use struct:


#include <stdio.h>

typedef struct {
    char *name;
    int  age;
} Person;

int main(int argc, const char *argv[])
{
    Person person = {"James Newton", 21};

    printf("%s\n", person.name);
    printf("%i\n", person.age);

    return 0;
}
      

A couple of things to point out here is

  1. C does not have a string type, so name is a pointer. This gives us the freedom to make name anything we want. It could also be something like char name[100] to just allow up to 100 characters as the name value.
  2. main must be an int type.

Then doing a quick and simple compile we get:


$ gcc test.c
$ ./a.out
James Newton
21
      

Now I’d like to make a function that will handle outputting the information about a Person.

In Ruby:


class Person
  # ...

  def info
    puts "#{self.name}, #{self.age}"
  end
end

person = Person.new('James Newton', 21)
person.info #=> "James Newton, 21"
      

Since struct can’t include functions, we write a function that works specifically with a Person.

Right below our Person struct:


void person_info(Person person)
{
    printf("%s, %i\n", person.name, person.age);
}
      

You’ll notice that we have Person person as the parameter. This means the value being passed will need to be a Person.

Next we’ll modify our main and take out the original printf calls and replace them with the function:


int main(int argc, const char *argv[])
{
    Person person = {"James Newton", 21};

    person_info(person);

    return 0;
}
      

After compiling and running we’d get the expected result:


$ gcc test.c
$ ./a.out
James Newton, 21
      

I’ll stop here because I’ve covered the gist of what I wanted to accomplish in this post. C in general is way more complicated than Ruby. You often don’t really realize how much work higher level languages like Ruby do for you, like memory management; which wasn’t touched on in this.

What little C I’ve learned so far I’ve learned by reading through Learn C The Hard Way. It’s a good place to start for anyone looking to jump into C.

I may write more as I progress through C, but until then!

Full code samples.