
Learn C The Hard Way - mcantelon
http://learncodethehardway.org/
======
hp
Ohloh says I've changed at least half million lines of C code
(<https://www.ohloh.net/accounts/rhp/positions/total>) Play me a tiny violin
;-)

What kinda bugs me is that whenever people go to teach C, they make out like
it _has_ to be a low-level exercise, as if writing in C suddenly means you
can't use abstract data types or object-oriented style or name your functions
properly or have Unicode support.

For example, people teach libc string APIs like scanf() and strtok(), which
should almost never be used. (See <http://vsftpd.beasts.org/IMPLEMENTATION>
for one take.) Instead, use
<http://git.gnome.org/browse/glib/tree/glib/gstring.h> or write your own like
[http://cgit.freedesktop.org/dbus/dbus/tree/dbus/dbus-
string....](http://cgit.freedesktop.org/dbus/dbus/tree/dbus/dbus-string.h)

If you're going to display user-visible text, you are pretty much required to
link to GLib or another Unicode library, since libc doesn't have what you need
(unless you want to use the old pre-unicode multi-encoding insanity).

Don't use fgets() and other pain like that, use g_file_get_contents() perhaps,
or another library. (g_file_get_contents is in
[http://developer.gnome.org/glib/stable/glib-File-
Utilities.h...](http://developer.gnome.org/glib/stable/glib-File-
Utilities.html))

You need help from a library other than libc to deal with portability,
internationalization, security, and general sanity.

Maybe more importantly, a library will show you examples that in C you can
still use all the good design principles you'd use in a higher-level language.

I told someone to "use a string class" in C recently for example, and they
said "C doesn't have classes" - this is confusing syntax with concepts.

C requires more typing and more worrying about memory management, that's all.
It doesn't mean that all the best practices you know can be tossed.

There's a whole lot to be said about how to write large, maintainable
codebases in C, and it can even be done. It's not something I would or do
choose to do these days, but it can be done.

One other thought, two of the highest-profile C codebases, the Linux kernel
and the C library, have extremely weird requirements that simply do not apply
to most regular programs. However, a lot of people working in C or writing
about C have experience with those codebases, and it shows.

~~~
zedshaw
I'm glad you got so much about how my book is written from a few paragraphs in
an unfinished manuscript for it.

~~~
speckledjim
You should stop thinking everyone is attacking you. I think you'd be happier.

Really though, there's no content here. The fact it's been voted to #1 on
hackernews shows just how bad things are.

Items _should_ be upvoted on their merit, rather than who did them. Someone
writing _another_ book about programming C isn't newsworthy.

~~~
thebooktocome
I don't really understand your comment.

1\. The post is about Zed's draft; is it really so far of a leap to interpret
hp's remarks as a criticism of the book?

2\. Is this a fair paraphrase? "Everyone here isn't attacking you, also, your
draft sucks and shouldn't have been posted on HN."

~~~
baha_man
' Is this a fair paraphrase? "Everyone here isn't attacking you, also, your
draft sucks and shouldn't have been posted on HN."'

No, it's not. speckledjim is complaining that someone writing another book on
C is not news, he doesn't say anything about the draft sucking.

~~~
thebooktocome
Implied by "Really though, there's no content here." Maybe they meant the
comments, though.

~~~
TWAndrews
I think he's referring to this topic, rather than the draft.

------
nikcub
I always had an idea of a 'for programmers' series of books for those who know
how to program in one language (say, C++, Java or PHP) and wish to pick up a
new language

eg. 'python for programmers' would not need the first half of it dedicated to
explaining strings, loops etc. and could get straight into it from a
programmers perspective - a bit like K&R. You could then dedicate more content
to explaining philosophy, design decisions, internals, history, politics
(learn all the in-jokes ;)), etc.

this would also be a good format to learn new paradigms, eg. 'functional
programming in scheme, for programmers'

~~~
udoprog
Indeed, I currently get turned off by most books I pick up, simply because
they start out on a too basic general level.

If you however dig a little deeper you can usually find stuff that isn't too
tutorialish. Like <http://www.c-faq.com/top.html> which has been an extremely
solid resource for me.

~~~
zedshaw
I'm hoping to make this book ramp up faster than LPTHW, since I'm assuming
people have either read that book or know one programming language already.
However, I'm also a big proponent of practicing the syntax even if you think
you're an expert already. It just makes things way easier later on.

~~~
nikcub
how about 'if you are proficient at another language, feel free to skip to
chapter x'? and put the generalized stuff at that point

~~~
zedshaw
If you really are that proficient, you should be able to figure out what you
can skip.

~~~
regularfry
I'm not so sure about that. The devil's in the details - you might think you
know something well enough to skip it, but get caught out later.

------
JoshTriplett
When I first learned C, I did so under DOS, an environment in which you could
declare a pointer to video memory, make a magic call, and start drawing
graphics. I found that a memorable way to learn pointers. Sadly, doing that in
the modern world requires quite a bit more setup.

~~~
angrycoder
You can do something similar now using SDL. In fact, unless you are blitting
bitmaps or using additional libraries, it is the only way to get stuff on
screen. SDL gives you a pointer that corresponds to the video memory and you
stick colors into it.

Here is a tutorial for using SDL for 'old school' graphics programming:

<http://sol.gfxile.net/gp/>

Of course this would require the student to install SDL and write a makefile
to link it all together. I feel that is something worth covering though, since
most books just do a bunch of hand waving when it comes to linking external
libraries.

~~~
JoshTriplett
When I said "quite a bit more setup", I had SDL in mind. :) Yes, you can get a
raw pointer to a graphics buffer via SDL, but in addition to the extra setup
to get a window, you have to make extra calls (such as SDL_Flip or
SDL_UpdateRect) to make your changes visible.

------
arkitaip
Zed, your level of productivity is truly inspiring. The best of luck to you.

~~~
mkramlich
I think the level of self-promotion and/or other-people-promoting-him is the
key factor. Not really the supposed productivity. I know many people who get a
lot done, both for day jobs, for contract work, as a hobby, as entreprenurial
ventures, etc. but 99.9% never hits the front page of HN on a regular basis
like Zed's activity seems to. Which doesn't lessen what he does and his
skills, but it does pull back the camera a bit to put it into a broader
context. Not everyone self-promotes to the same extent as Mr. Shaw, or has
other people promote them.

~~~
zedshaw
I personally have no idea why this stuff hits this site that often. Take this
for instance: It is a half-finished manuscript that I announced in a tweet to
people who follow me on twitter and asked for it. Already at the top of this
set of comments is a dickhead saying he's such a bad ass 'cause he's changed
"half a million lines of C code" and he thinks I'm not writing the book
correctly because I'm being too low level. He gets all of this from three
exercises and three paragraphs in the introduction.

Frankly, I consider hackernews kind of irritating and not useful as a
promotional tool. It amounts to about 5% of my traffic for 1 day at best, and
I only have to be here because if I'm not answering the petty little idiots
who troll here then the rumors spread through my professional circles.

In other words: I could live without this kind of promotion, so it's
definitely not "self-promotion".

~~~
llambda
Why is it that every comment I read by you is either you whining about being
treated unfairly or you attacking someone who supposedly "attacked" you? Are
you honestly that insecure? Do you read every comment as though it is in some
way attempting to degrade your image?

Here you denigrate the HN community, saying it doesn't generate a significant
amount of traffic for your site or whatever, and then go on to say you won't
respond to the petty "idiots". I see. You're too "professional" for that.
Obviously HN is so meaningless to you that you needn't bother with it. Yet
you're here, commenting, making an ass out of yourself.

Woe is poor Zed Shaw; always the victim.

~~~
bandushrew
A quick look through Zed's comment history tells me that the % of posts he has
made that could fit your description is roughly 1%.

So Im going to go with you having a selection bias.

OTOH I do appreciate your vigorous defense of the HN community, too many
people just dont care about implied insults to their self identified tribal
group.

Go llambda!

~~~
llambda
You're probably right. I've only seen a couple of his recent comments in
threads related to his projects or site (and that thread about the GitHub
community). So I no doubt have a selection bias; I suppose it's worth noting
his reputation proceeds him, deserved or otherwise.

Nonetheless it's disheartening to see self-proclaimed "professionals" (I use
this term loosely for while a person may be employed professionally this is
not a guarantee a given individual will behave professionally: they are
distinct things) who are well known throughout the community, behave like
trolls. And even more so when they decide it's appropriate to take a shit on
this community.

Well I will always try my best to preserve what I value. It's in my nature I
guess. So thank you. :)

~~~
bandushrew
heh. His reputation appears to be a many faceted thing.

I, for instance, have been genuinely impressed with his productivity and his
output, his choice of projects and his code and am moved by that aspect of
myself that values quality to think very highly of him.

You, on the other hand, appear to feel that the most important aspect of his
output is the way he achieves the standards that you have set for him - judged
by how he expresses himself towards those who he feels are being disrespectful
or rude at him on the internet.

Just out of interest, do you believe that making a strongly negative personal
judgment based on a 'fact' that is clearly incorrect and could be easily
checked with just a few clicks is the act of a professional? do you meet your
own high standards?

~~~
llambda
First I will call out your blatant fallacy: tu quoque. Now let's review
things:

I readily admit I'm a hypocrite. But also note, I don't claim nor ever claimed
to be a professional; I'm not. I'm not at the helm of projects that are useful
to and used by many people. I haven't written books on the topic of computer
science. Nor have I given talks or do I run a website that receives a large
volume of traffic. Maybe that qualifies [him] as working in the domain of a
professional, yes?

Although he may have achieved great things, this doesn't give him a license to
troll HN and it doesn't excuse him of baseless personal attacks. The comments
he made that I replied to were no less than that, at best. At worst, they were
insight into his character. Certainly we can hope the latter is not true.
Nonetheless, there's no place for that kind of bullshit; it's inexcusable, I
don't care who you are. I made such a judgement because he clearly attacked
the user "hp" who had done nothing more than make an observation about texts
that introduce C in general. Zed's reaction was puerile, irrational, and even
paranoid. I hope you aren't standing up for such behavior?

~~~
bandushrew
"Maybe that qualifies [him] as working in the domain of a professional, yes?"

Either you think he is a professional, or you do not. You appear to be holding
up a standard, claiming that you believe he fits the criteria needed to be
judged by it, and then lambasting him for not living up to the standard you
have set. Overall, I find this somewhat confusing, but possibly I dont have
sufficient context to judge.

TBH Im not particularly motivated to 'stand up' for the behavior of anyone I
dont know.

I am interested in what makes you so interested in casting judgment on Zed, as
opposed to on yourself?

Whatever puerile, irrational and paranoid responses Zed may have produced, you
seem to be matching them with a self admitted hypocrisy, a large amount of
self righteous vitriol and a bewildering statement of tribal affiliation to an
anonymous internet discussion forum that apparently requires your outraged
protection lest it collapses completely under the weight of a misunderstanding
between Zed and another participant.

Zed has, to my knowledge, done you no harm of any kind. He certainly
represents absolutely no realistic threat to HN.

why do you feel justified abusing him in this fashion?

~~~
llambda
tu quoque. [1]

[1] <http://en.wikipedia.org/wiki/Tu_quoque>

~~~
bandushrew
dude, I heard you before.

It doesn't apply in this case. I will leave it as an exercise for the reader
to discern why.

------
gregjor
I'll be interested to see how this compares to K&R, which not only teaches the
C language but also C idioms and the reasons for using them. K&R is still one
of the very best programming books. Every other C book I've read is inferior.
Peter van der Linden's "Expert C Programming" is the only book on C besides
K&R that I've learned anything from.

Good luck, I'm all for more programmers understanding C but I wonder if the
wonderful days of programming close to the hardware are ancient history.
"[P]eople are deathly afraid of C thanks to other language inventor's
excellent marketing against it." Maybe, but I think the _raison d'être_ for C
is not apparent to programmers who started with Java, Python, or Ruby.

~~~
irahul
K&R won't work for someone beginning programming. This book is specifically
targeted towards teaching programming to programming virgins.

The examples and exercises K&R uses will be very hard for beginners. When it
builds a recursive descent top down parser to read the declarations in
English(and vice-versa), that will be totally lost on the beginners.

K&R wasn't written for beginners and I doubt it will work well for a
programming beginner - should be fine for someone who already knows
programming in some other language.

~~~
zedshaw
Nope, this book isn't for total beginners. I mean, it might work, but I'm
actually telling the total newbs to go read
<http://learnpythonthehardway.org/> first. My thought is teaching
"computational thinking" is easier with a language like Python, so people
should start there.

------
rpearl
Do people really think C is some mysterious, inscrutable language?

"To many programmers, this makes C scary and evil."

Is this actually true for people? I find C code generally very easy and
straightforward to understand; there's not any magic behind the scenes, like
there is in any language that's more "high level" than C.

~~~
ramidarigaz
Many of the friends I made in my CS classes were terrible with pointers. I
never really understood why they didn't grasp pointers, but it was a major
stumbling block for them in C/C++

~~~
cturner

        I never really understood why they didn't grasp pointers
    

The root of the problem is the language designers' loose use of star. "star
something" is contained in a phrase that means one thing at declaration, "star
something" has a different meaning the rest of the time.

    
    
        #include <stdio.h>
        void eg(int i) {
            int *j = &i; // "huh? Put the address of i into *j?"
            *j = *j + 1;
            printf("%d\n", *j);
        }
        int main() {
            eg(4);
        }
    

With more detail. In the line..

    
    
        int *var = something;
    

.. the system assigns to the pointer. Yet in..

    
    
        *var = 6;
    

.. it assigns to the contents of the pointer.

Common usage creates further room for confusion:

    
    
        int *var; // <- this is what people write
        int* var; // <- instead of this
    

If they'd made the syntax ".int var", and then used * solely for
dereferencing, people wouldn't have these problems learning pointers. Consider

    
    
        #include <stdio.h>
        void eg(int i) {
            .int j = &i;
            *j = *j + 1;
            printf("%d\n", *j);
        }
        int main() {
            eg(4);
        }
    

Further confusion comes from (1) special arrangements around string
declaration and (2) printf use of %s to expect a string pointer when %d and %f
expects (non-pointer) simple int and simple float.

    
    
        char* something = "huh? so now this does goe into *something?";

~~~
roel_v
That's because of the (visually) 'wrong' use of * (wrong in the sense that
it's unintuitive). The key is that * is part of the _type_ of the declaration,
not of the variable; an int* is not an int. So

    
    
      int *j = &i;
    

is more correctly expressed and easier to understand when written like

    
    
       int* j = &i;
    

The only reason to put the * in front of the variable name is when declaring
several pointers in one line. So the solution is to only use it that context,
or not doing it at all.

~~~
alecbenzer
This bothers me so much about C/C++ syntax. int* a, b; should clearly declare
two int pointers, not one int pointer and one int.

Stroustrup wrote something somewhere where he explained that int* a; is more
appropriate for use in C++ because C++ is supposed to be more focused on
types, and int * a; is more appropriate for C because of something about C's
philosophy, but I can't remember what. I wish they would have changed the
syntax for C++, but I guess he couldn't have while still keeping C++ a
superset of C.

edit: found it: <http://www2.research.att.com/~bs/bs_faq2.html#whitespace>

"A ``typical C programmer'' writes ``int _p;'' and explains it ``_ p is what
is the int'' emphasizing syntax, and may point to the C (and C++) declaration
grammar to argue for the correctness of the style. Indeed, the * binds to the
name p in the grammar.

A ``typical C++ programmer'' writes ``int* p;'' and explains it ``p is a
pointer to an int'' emphasizing type. Indeed the type of p is int*. I clearly
prefer that emphasis and see it as important for using the more advanced parts
of C++ well."

------
briandoll
I'm very excited to see Zed working on this. This exercise-driven tutorial
format seems efficient and practical, but what makes this really stand out is
Zed's approach to the overall goal.

I greatly appreciate an 'opinionated' programming book. I've probably heard
more debates on formatting and style for C than any other language.

------
mikeocool
Oh man, totally looking forward to this. It seems like so many programmers are
kind of afraid of C because it's reputation and avoid learning it because
they're language of choice is 'more productive.' Which is really unfortunate,
I've found having a good amount of C is hugely beneficial to understanding
what's going on under the hood when you're using a higher level language, even
if you rarely actually program in C itself.

Plus even if you do primarily program in higher level languages, it's a great
tool to have in your belt when you need to fix a bug in a library whose
bindings you're using in higher level language, or when you legitimately do
need to eak a little more performance from a particular piece of code.

Also, love that the book starts by teaching you how to use make as well, so
many C books gloss over the tools.

------
newcguy
I know a fair amount of C. But I am still looking forward to this book as I
hear that LPTHW taught something to even intermediate level people. Besides
the exercises are usually good and would like to solve them.

------
rgrieselhuber
My wish came true. :-)

<http://apps.ycombinator.com/item?id=1727617>

------
raniskeet
How about having a webpage with recommended libs for newbies to use? Sort of
like NodeJS modules page.

------
ctdonath
I look forward to the content. As a beginning C++ instructor I find there is
something lacking between the truth of the language and the conventions for
presenting it. Nobody, AFAIK save for the truly hardcore student, has nailed
it.

~~~
zedshaw
Got any feedback on the things students get wrong? My experience is they fail
to grasp memory management, pointers, functions as pointers, linkers or just
how a program actually runs.

If you've got others I'd love to hear them.

~~~
rpearl
As a teaching assistant for a class (<http://www.cs.cmu.edu/~410/>) where
students write a whole lot of code in C, _please_ introduce the address-of (&)
operator and explain how to obtain pointers without using malloc(). Do this
before the concept of the heap is ever introduced at all.

Be careful when explaining the compiler and how a program actually runs. I've
found that a lot of student problems come from "the compiler is magic" when it
really isn't (maybe related to my other surprised comment below, about how
people "don't get C"--they attribute too much magic to the compiler.) Maybe
even emphasize that every piece of C code can be translated in a fairly easy
fashion to a pretty small amount of assembly.

For the preprocessor, emphasize that it is a solely textual replacement, with
no symbolic evaluation. Explain why:

    
    
        #define FOO BAR + BAZ

or

    
    
        #define MAX(x,y) (((x) < (y)) ?  (y) : (x))
    

will go horribly wrong (the first in 5*FOO, the second in MAX(x++, y++)).

~~~
sausagefeet
I find it is much more helpful, when teaching C, to avoid the word 'address',
and call (&) the pointer-to operator. Thinking of pointers as numbers (which
the address-analogy does) tends to be harmful for newer C programmers because
they want to treat them like numbers.

~~~
palish
They _are_ numbers (either 32-bit or 64-bit). Nothing more, nothing less. I
don't understand why you wouldn't want to think of them that way.

For example...

    
    
      const char* current = "ohai thar";
      const char* end     = current + strlen( current );
    
      assert( end >= current );
      size_t bytecount = (end - current);
    

(size_t is an unsigned type, so if 'end' is less than 'current', it will
overflow. If you want to allow for that, use ptrdiff_t.)

~~~
sausagefeet
No, they aren't numbers. The standard is quite clear on this. Consider old DOS
architecture where you had a section and offset. Your code is also not well-
defined C. C only lets you perform subtraction between two pointers in the
same block, this code is at best implementation defined and worst undefined (I
can't remember).

------
pbreit
Has anyone actually used "Learn Python the Hard Way" in a beneficial way? I
started it several times but never got very far and just learned Python from
other sources. I didn't really care for the approach.

~~~
irahul
Was it your first book? If not, you weren't in the target audience from what I
make out of the contents of the book.

For people who already know programming, the official tutorial is the fastest
and the best way to start: <http://docs.python.org/tutorial/index.html>

------
getsat
Why is %d used to interpolate an integer into a format string? I don't recall
seeing this done for any reason before.

I hope Zed actually covers how dangerous format strings can be if not handled
properly. Format strings are still (hilariously) one of the major exploitation
vectors in C-based applications today.

Edit: According to Wikipedia, %i and %d are synonymous. Sorry for the
confusion.

~~~
zedshaw
It's not for the type, but for the output. The 'd' means "decimal" output. For
example, you can do %x to "hexadecimal" output, and %o for octal. Of course,
there's some complex interplay with what type you hand that function.

As for how "dangerous" it is, yeah it's not going to rape your family, it'll
just crash. So I'll be showing people how to prevent it.

~~~
getsat
It'll crash and potentially allow code execution if the rest of the args are
user coercible. Check out the first few chapters of The Shellcoder's Handbook
for examples.

Thanks for the explanation. I've never seen/had to use %d with integers. I've
only used it with %.Nd for floats/doubles.

~~~
zedshaw
code/ex3.c:6: warning: format ‘%d’ expects type ‘int’, but argument 2 has type
‘double’

You should probably read this book. :-)

~~~
getsat
Hmm, I don't recall MSVC++ ever warning about that! Unfortunately, I did use
Windows at one point in my career.

I'll pass on reading it since I don't intend to write C ever again, but I hope
the book works out well for you. :)

Edit: Just dug up some of my old C code. It is indeed %.2f that I was thinking
of. Sorry for the confusion once again.

------
seagaia
I hope this book will show lots of new C programmers the beauty of pointers in
hand-holdy detail ('cause that's the level needed, I feel). Maybe basic stuff
about VM, so all the pointer operations make sense (everything is a byte at
some offset etc.).

At least I didn't fully appreciate C until I understood some of the underlying
concepts.

Looking forward to reading this!

------
Sapient
Having read a fair bit of LPTHW (though I had no actual interest in the
language), I am really excited about this.

One of the best things about LPTHW was the context it was written in, and if
LCTHW is written in the same way, it should be a really awesome read!

~~~
zedshaw
That's the idea, although I'm going to assume you know how to use at least one
programming language, and probably redirect total newbies to LPTHW if they
don't. That should make it easier to ramp up in C and then do cool useful
stuff with it.

~~~
Sapient
That's awesome to hear. I actually know a bit of C, but it has been years
since I used it - so this book seems like a good one to read to 'reboot' my C
skills.

I'll definitely be waiting anxiously for you to finish.

Good luck!

------
emehrkay
I jokingly made this suggestion to him on twitter. He posted a few
"assignments" and we (I assume it was more than myself participating) posted
pics of our console output.

This guy loves to program

------
megamark16
I asked and Zed delivers:
<https://twitter.com/#!/megamark16/status/71183280287920128>

------
tomrod
Nice! Where's the rest?

------
DannoHung
The biggest problem with C is not the language C, for it is a small and mostly
simple language with a few warts (I'm looking at you, pointer syntax), it is
the ecosystem into which you are thrust when you first use it.

That is, the ecosystem of, "What can I include without dicking around with
compiler and linker settings, which I do not care to learn very well because I
am just starting?", and the ecosystem of, "Why are all these standard
libraries full of functions that all the documentation tells me not to use?",
and most importantly, the ecosystem of, "Oh, this looks like a nice library
that would make my life easy, (and later), wait, why isn't my program working
on this other machine? I copied the binary over? Wait, what's this about a
missing so? Oh, that's the library I installed, wait, how do I put it the same
directory? Oh my god so many configuration settings! Wait, why can it still
not find the library? It's right there now! What's LD_LIBRARY_PATH?
LD_LIBRARY_PATH is bad? Why doesn't -R work? Oh, that's only for Solaris?
What's the equivalent for friggin' Linux?! Ah, rpath, wait... it's trying to
find the ABSOLUTE path? UGGARRHGHGHAAHHHH! Okay, finally, $ORIGIN... now let
me just put that in the make file like they said I should....
_AHGHGHGHGHGHGHHHHHHHHHHHHHHH!!!!!!!_ "

Which is to say, the ecosystem of fucking ratholes that have built up over 40
years of poor tool design that cannot be corrected now due to historical
precedent.

~~~
orp
C++ has the same issues.

To add another example, binary only distributions (e.g. some commercial
software) bring their dependencies with them, meaning that you have to use
roughly the same environment (compiler version, stl) to use them.

Libraries work a lot better in VM languages.

~~~
exDM69
It doesn't take a VM language or an interpreted lanugage to get libraries
working well. Take a look at Haskell's Cabal system and Hackage package
library. It works pretty good and doesn't use a VM.

With C and C++, you'll have to use your operating system's package management
to get all the important libraries (or build them by hand from Git sources,
etc), then have a build system that configures the build environment and
searches for all the libraries and other dependencies. It's not as nice as
using a dedicated tool for this, like Gem and Bundler in Ruby but usually you
get the job done - unless you work on Windows and don't have a package
manager.

------
alnayyir
I have the "learncthehardway.com" domain, waiting for Zed to stop being so
insanely busy so that I can do the hand-off. :)

------
leon_
I'm skeptical that it will be an alternative to K&R 2nd ed but nonetheless I'm
interested in the result.

------
derleth
Isn't "C For Programmers" essentially "HOWTO Use Pointers"? Is there another
really complicated idea that C has which most of its heirs do not have?

~~~
palish
Strings, and why strlen(s) != the number of letters in a string (UTF-8).

Why a string must end with a 0 byte.

Binary shifting numbers, especially signed numbers.

Memory management; it's fun for the whole family, and more than just knowing
how to allocate memory and store a pointer to it.

Some other points that I'm sure I'm missing.

~~~
Jach
> Why a string must end with a 0 byte.

Unless it's a pstring or you're working with assembly, other language, etc.

But yes there is a lot to learn with C you don't necessarily get with higher
level languages in most cases.

------
drivebyacct2
It should say "Learn C and make the hard way".

~~~
zedshaw
Oh, there's a _lot_ more tools on the way. C is one language that you could
spend whole books on just the tools.

~~~
irahul
May be a good idea to mention some of them. `valgrind` and `lint` comes to
mind. On second thoughts, `lint` can be dropped; compiler warnings are good
enough for a beginner(in fact, good enough for experienced programmers;
subjective).

~~~
JoshTriplett
The original lint tools seem entirely superseded by modern compiler warnings.
On the other hand, a whole new class of static analysis tools exist now, such
as Sparse, Coccinelle, Frama-C, and in the proprietary world Coverity.

------
swindsor
The problem with C isn't C. It's shitty C programmers.

Learn how the language works, follow good patterns, and expect some bumps in
the road.

Most of the time, though, you can use a different higher level language, and
be a happier and less stressed programmer

------
auston
Go Zed! I'll buy this when it's ready for payment!

------
helwr
I learned C the hard way by taking this course, motherfucker
<http://www.cs.columbia.edu/~jae/cs3157/2009-1/syllabus.html>
[http://www.cs.columbia.edu/~jae/papers/3157-paper-v2.2-camer...](http://www.cs.columbia.edu/~jae/papers/3157-paper-v2.2-camera-
final.pdf)

~~~
anonymous742
Actually, that looks like a pretty easy way to learn C; a whole semester on
it, beginning with things like using ssh? With instructors and TAs?

But ooh, Columbia, so you know it's hardkore.

