One of big myths in software industry was perpetuated by Joel Spolsky in his 2006 classic The Guerilla Guide to Interviewing
. I love and respect Joel, and fully agree with the article, except the following paragraph.
I’ve come to realize that understanding pointers in C is not a skill, it’s an aptitude.
In first year computer science classes, there are always about 200 kids at the beginning of the semester, all of whom wrote complex adventure games in BASIC for their PCs when they were 4 years old. They are having a good ol’ time learning C or Pascal in college, until one day the professor introduces pointers, and suddenly, they don’t get it. They just don’t understand anything any more. 90% of the class goes off and becomes Political Science majors, then they tell their friends that there weren’t enough good looking members of the appropriate sex in their CompSci classes, that’s why they switched.
For a long time, I believed this. Whenever I tried learning pointers in C, I'd struggle for a while, remember the above words and finally give up thinking pointers are not just not my cup of tea.
Then I started learning Go
One of the things that make Go syntax beautiful is how variables are declared. In most C-based languages, you write the type of the variable first, then the name of the variable. When reading a sentence, you have to read it from right to left. For example,
int x, y; // x and y are integers
int *p; // p is a pointer to an integer
However, in Go, the name comes first, followed by a type. So you read it from left to right. For example,
var x, y int; // variables x and y are integers
var p *int; // variable p is a pointer to an integer
That brings me back to the subject of pointers and why I don't agree with the above paragraph, especially the line understanding pointers in C is not a skill, it’s an aptitude.
When you are learning a new concept, especially a hard one like pointers, it matters a lot how it's being presented to you. When the concept doesn't make sense at first, it's easy to blame yourself and give up, rather than try to find a new teacher, tackling it from another angle, or learn it using a different approach.
That's what happened with me when learning pointers in C. Often I'd start on solid grounds, understanding what is a pointer, and how it points to another object in memory, by containing the actual memory address of the location where that object resides. The trouble came when de-referencing that pointer to get the underlying value of that object. I'd always get confused between the meaning of * of de-reference and the * of declaration.
In C, you'd do this:
int x, y;
p = &x // so far so good.
y = *p // ???
In Go, you do it as shown below. Notice the second line, where we are defining p (not *p) as a pointer to an integer. This is not confusing (for me, at least) as it looks different from the pointer declaration. There's a clear distinction between a pointer and a de-reference from a pointer.
var x, y int
var p *int
p = &x
y = *p // de-reference p to get the value at the memory address it's pointing to
Agreed, you can do this in C:
But this is not the same:
int* p, q // p is a pointer to an int, q is an int
In Go, this is how you declare two pointer to integers:
var p, q *int
It was not until I started learning Go, that I finally understood how pointers work. That opened new doors into how computer memory works, why strings are immutable in C#, the difference between Value Types and Reference Types in C#, and much more, which would have been next to impossible without learning pointers.
So if you are a new developer, and struggling with pointers in C, I'd recommend learn them in Go
first. Once you understand the basic idea, you can go back to C and the pointers start to make sense. But don't think, for a moment, that you are born without the part of the brain that understands pointers,
just because Joel said so.