
Ask HN: Improve C language skills after K&R? - SoftwarePatent
I&#x27;ve already read and understood K&amp;R. At work I write rails code and deal with challenges like large databases and scaling large codebases. I was thinking about doing Project Euler problems or cryptopals.com in C. Any other ideas?<p>My objective is to better understand how computers work, how ruby works, and generally to be a better software engineer.
======
seibelj
You could try to make a non-trivial application in C, such as something using
IPC / sockets. You could try to make a game. You could try to make a UI
application using GTK or similar UI framework. You could start contributing to
an open source project (there are so many official GNU C projects). You could
try to write a server that implements a simple protocol from the RFC (such as
socks5)[0].

Also look into C build systems like cmake or autotools.

[0]
[https://www.ietf.org/rfc/rfc1928.txt](https://www.ietf.org/rfc/rfc1928.txt)

------
616c
I would love feedback on this. I wanna take a secure software design course
and my C is lacking. Everyone recommends Learn C the Hard Way.

[http://c.learncodethehardway.org](http://c.learncodethehardway.org)

tptacek, who is obviously hot stuff here on HN for his infosec knowledge,
recommends this book on Amazon favorably on his recommended InfoSec reading
list.

C Interfaces and Implementations: Techniques for Creating Reusable Software

[https://www.amazon.com/review/RMXKDJNH8UOPU/ref=cm_cr_dp_tit...](https://www.amazon.com/review/RMXKDJNH8UOPU/ref=cm_cr_dp_title?ie=UTF8&ASIN=0201498413&channel=detail-
glance&nodeID=283155&store=books)

He said it is the most advanced C book in existence. If only I had enough time
to not only read but understand it all! Haha.

~~~
hatsunearu
How is this?

Some random guy suggested this to me to take my C to the next level: Expert C
Programming: Deep C Secrets

[https://www.amazon.com/Expert-Programming-Peter-van-
Linden/d...](https://www.amazon.com/Expert-Programming-Peter-van-
Linden/dp/0131774298/)

~~~
616c
I mean I laughed. But yes, tptacek worship, even from wannabes like me, is
annoying (perhaps even to him).

My point was can someone steer us to good materials. I proferred what I heard
hoping others would correct me and other posters.

I like the premise of LCTHW. Why not show me small projects that are simple to
compile, but sucky and basic, and ask me to gradually fix him.

I went through a few chapters, and it is good. I am just lazy. But the
projects are small. If somene fleshed this out into something more thorough,
it would help sucky learners like me everywhere!

~~~
tptacek
Yeah, it's pretty weird.

CII is a great, great C book though.

------
GregBuchholz
The Peter van Linden book: _Expert C Programming_ is old but nice:

[https://www.google.com/search?q=expert+c+programming+deep+c+...](https://www.google.com/search?q=expert+c+programming+deep+c+secrets+pdf)

...you may also enjoy:

[http://www.gowrikumar.com/c/index.php](http://www.gowrikumar.com/c/index.php)

[http://blog.regehr.org/archives/213](http://blog.regehr.org/archives/213)

...and learn to use a memory error debugging tool like:

[http://elinux.org/Electric_Fence](http://elinux.org/Electric_Fence)

[http://valgrind.org/](http://valgrind.org/)

...Besides C, other ways of expanding your horizons would be to learn things
like: Prolog, Lisp, Haskell, and/or Verilog.

~~~
hatsunearu
First link doesn't seem to work?

~~~
GregBuchholz
Replaced it.

------
tacostakohashi
Make sure you have a good understanding of the standard library - in C, this
should _not_ be thought of as a black box (because, unlike in some languages,
it is written in the language itself, and also it's rather small and minimal).

You should familiarize yourself with the source for a C standard library (not
necessarily the one your're using, maybe uclibc, something simple), and work
towards being able to implement the functions yourself. For some functions
like malloc(), printf(), etc, understanding the implementation tradeoffs will
help you understand problems with your own code.

~~~
meekins
As someone who has only casually dabbled in C I found "C: A Reference Manual"
[1] a great companion to the "Expert C Programming" book. The typography is
dull but the content is excellent - all the details about the language
standard and libraries are there while remaining concise enough to serve as a
reference book.

[1] [http://careferencemanual.com/](http://careferencemanual.com/)

------
xavierJohnson
Start learning 8086 or more commonly known a x86 Assembly... That will get you
much closer to the hardware and will give you entirely new sets of problems to
solve and an immense knowledge of how computers work.

Guaranteed to make you a better software engineer.

~~~
tacostakohashi
That sounds like more of a way to learn x86 assembly than a way to learn C.
For all we know, this guy is writing his C for an ARM or a m68k - who knows?

~~~
xavierJohnson
the OP says "My objective is to better understand how computers work, how ruby
works, and generally to be a better software engineer." I just gave him
options.

------
juliangoldsmith
Personally, I've always enjoyed doing low-level programming. You may consider
looking at writing homebrew games for older consoles, or OS development. Both
of those would require you to expand your C skills, and would give you an
intimate understanding of how computers work.

------
sn9
My recommendation would be to work through _Computer Systems: A Programmer 's
Perspective_ [0] if you're comfortable with K&R.

David Hanson's _C Interfaces and Implementations_ is also excellent.

[0] [http://csapp.cs.cmu.edu/](http://csapp.cs.cmu.edu/)

------
kristianp
Implementing some dynamic data structures should give you a good understanding
of how pointers work and allocating and freeing memory. Start with linked
lists, then binary trees, then B-trees if you have time. Priority queues
(heaps) are fun too.

~~~
colanderman
Exactly this. Implementing low-level algorithms focuses on C's strengths:
arrays (memory layout) and manual memory allocation. They will be your biggest
blind spots coming from a dynamic language, and they are the primary reason
one would use C.

After that I would move on to implementing something like a telnet or simple
HTTP server, focusing on using sockets and processes _correctly_ : handling
all error cases, ensuring no deadlock, etc. That is C's other strength: it is
the language of Unix.

------
eu90h
I'd recommend Ben Klemens' excellent book "21st Century C - Tips from the New
School" [0]. This book teaches you modern C techniques and, most importantly,
the tooling that modern C programmers use (git, autotools, valgrind, etc.) It
also covers commonly used libraries to help you from reinventing the wheel
(GLib, POSIX standard, SQLite, libxml, & cURL.)

As mentioned in another post, David Hanson's "C Interfaces and Implementations
- Techniques for Creating Reusable Software" [1] is a great book, stressing
the design of good APIs. This book in particular might help you in your goal
to become a better engineer.

On the free side, there's an excellent PDF by Jens Gustedt, "Modern C" [2].
I've not read the whole thing but it seems like an in-depth look at C11.

John Regehr's blog "Embedded in Academia" [3] is a good resource for C
programming. You'll learn a lot about weird edge cases and undefined behavior.
He also has a recent post about teaching C, with suggestions for resources
[4].

[0] [https://www.amazon.com/21st-Century-Tips-New-
School/dp/14919...](https://www.amazon.com/21st-Century-Tips-New-
School/dp/1491903899/ref=sr_1_1?ie=UTF8&qid=1469742724&sr=8-1&keywords=21st+century+c)

[1] [https://www.amazon.com/Interfaces-Implementations-
Techniques...](https://www.amazon.com/Interfaces-Implementations-Techniques-
Creating-
Reusable/dp/0201498413/ref=pd_sim_14_4?ie=UTF8&dpID=51ICZM63B2L&dpSrc=sims&preST=_AC_UL160_SR125%2C160_&psc=1&refRID=WGSMXGVZT36WNBD0MTY6)

[2] [http://icube-icps.unistra.fr/img_auth.php/d/db/ModernC.pdf](http://icube-
icps.unistra.fr/img_auth.php/d/db/ModernC.pdf)

[3] [http://blog.regehr.org/](http://blog.regehr.org/)

[4]
[http://blog.regehr.org/archives/1393](http://blog.regehr.org/archives/1393)

------
leksak
Write a chat server capable of handling concurrent clients, and write a front-
end client in Ruby.

You'll need a thread-safe FIFO datastructure, such as a queue, handle sockets,
define a communications protocol (or borrow one, I'd recommend IRC).

Bonus: This will also teach you more about the Internet protocol suite
([https://en.wikipedia.org/wiki/Internet_protocol_suite](https://en.wikipedia.org/wiki/Internet_protocol_suite)),
particularly the Application/Transport layer.

Side-note: Project Euler and cryptopals problems are not well-suited for C,
use the right tool for the job.

------
dalewelch
The book: Expert C Programming: Deep C Secrets by Peter Van der Linden

This book is great, full of good code and even better writing.

~~~
SloopJon
Seconded. I also recommend _C Traps and Pitfalls_ and _The C Puzzle Book_ to
improve your understanding of this subtly complex language.

------
dmunoz
> My objective is to better understand how computers work, how ruby works...

Check out Pat Shaughnessy's Ruby Under a Microscope [0].

It gives a nice overview of the internals of MRI. It doesn't cover a who lot
of the C code, but references plenty of it and where it can be found in the
source code of MRI. Grab the book, the source for MRI, and do some digging.

[0] [https://www.amazon.com/Ruby-Under-Microscope-Illustrated-
Int...](https://www.amazon.com/Ruby-Under-Microscope-Illustrated-
Internals/dp/1593275277/)

~~~
616c
Agreed. I was at a Hackerspace years ago that worked on this principle, and
wanted to start lower than that.

[http://nand2tetris.org/course.php](http://nand2tetris.org/course.php)

Alas, I left before I could really get into it, and never had the peer
pressure to understand a lot of core CS way over my head.

------
lj3
handmade hero[0]! Casey Muratori records many hour long sessions where he goes
through the steps of making a video game from scratch in C. Practical, hands
on experience from a guy who knows his stuff.

[0]: [https://handmadehero.org/](https://handmadehero.org/)

------
hatsunearu
Learn secure coding. I think 80% of secure coding is making sure good coding
practice are done, and the rest are spotting algorithm/procedural issues (for
example, bad crypto isn't exactly "coding practice", but more of a conceptual
fault)

------
superuser2
Do the Pintos projects. You will learn a bit about operating systems too.

That was certainly the moment in my education where I went from shaky to
moderately confident about C.

Pintos is nice because there's an extremely thorough test suite already
written before you. It's easy to measure your progress (and know when you are
done) by the test report. Like TDD, without the pain of you personally having
to write the tests upfront.

[https://web.stanford.edu/class/cs140/projects/pintos/pintos_...](https://web.stanford.edu/class/cs140/projects/pintos/pintos_1.html)

~~~
tonysdg
It's worth noting this will help you greatly with your ability to use C, but
it will _not_ be immediately useful if your goal is learning to use C within
the context of Unix-like systems. That is, you won't have access to a
significant portion of the libraries most people expect. This _will_ teach you
how those libraries - and the system software/OS itself - are built.

------
pjungwir
I agree with the recommendation here to read _Expert C Programming: Deep C
Secrets_ by Peter Van der Linden.

As for practice: the challenge in learning new tech is always to find a small-
scale project that motivates you to build something. As a mostly-Rails
developer like you I've found a couple opportunities to write C by building
Postgres extensions. Here are my two:

[https://github.com/pjungwir/aggs_for_arrays/](https://github.com/pjungwir/aggs_for_arrays/)

[https://github.com/pjungwir/inetrange](https://github.com/pjungwir/inetrange)

Both of those are used in production systems and had good justification for
dropping down to C.

Or here is a tiny patch to the Postgres btree_gist extension that I am hoping
to get merged:

[https://commitfest.postgresql.org/10/332/](https://commitfest.postgresql.org/10/332/)

The JSON support in Postgres is still pretty new. Maybe you could write some
worthwhile additions for dealing with json or jsonb data? I would just look at
underscore.js for inspiration.

Also if you have a collection of personal shell utilities, you could try
rewriting them in C. Here is one of mine:

[https://github.com/pjungwir/range](https://github.com/pjungwir/range)

It is for printing a range of numbers like `1, 2, 3`. It is surprising how
many features you can add to a tool like that! (It is a bit of a joke, and I
have since learned bash gives you `{1..10}`. But something similar could still
make a good learning project.)

Perhaps you could also write a ruby gem that wraps some C library. For
instance I'm fond of the jsmn JSON parser [1]. Maybe a gem built around that
could give performance benefits? Or maybe some way to easily use Protocol
Buffers instead of JSON for Rails web requests?

[1] [http://zserge.com/jsmn.html](http://zserge.com/jsmn.html)

------
mveety
Really it all comes down to reading and practice. Instead of writing your
personal duct tape code in ruby why not try it in C? Sure it will be harder at
first but it will make you a better programmer all around. Also reading OS
code (like plan9/9front, *bsd, or xv6) will help you learn both how it works,
but also how to write better. I don't really do programming problems because
they don't give me anything useful at the end other than the knowledge. If I
want to practice I'm more inclined to try solving a problem I have in a new
way.

------
tjr
Help somebody else learn C.

------
Koshkin
You may find the linked note on learning how computers work useful. Basically,
I think that the value of knowing C in this respect is rather limited and that
there are much better ways to do that. Not to say that C is not worth
learning, of course, for its own merit.
[https://news.ycombinator.com/item?id=12118980](https://news.ycombinator.com/item?id=12118980).

------
thevibesman
These discussions may be useful:

"How to C (in 2016)":
[https://news.ycombinator.com/item?id=10864176](https://news.ycombinator.com/item?id=10864176)

"Critique of 'How to C (in 2016)'":
[https://news.ycombinator.com/item?id=10908217](https://news.ycombinator.com/item?id=10908217)

EDIT: Fixed formatting error

------
vikasr111
Do online courses form coursera and edx,and try to complete all the
assignments..this helps a lot

------
samblr
Learn writing code that uses IPC -> multi-threading -> linux OS -> Kernel

------
hga
In the bad old days, when, from memory and comparison with vast improvements
in the later editions of K&R's chapter on pointers etc., the _Lions '
Commentary on UNIX 6th Edition, with Source Code_
([https://en.wikipedia.org/wiki/Lions%27_Commentary_on_UNIX_6t...](https://en.wikipedia.org/wiki/Lions%27_Commentary_on_UNIX_6th_Edition,_with_Source_Code))
was held by many in equal or greater esteem than K&R. The code has bee
implemented as xc6
([https://en.wikipedia.org/wiki/Xv6](https://en.wikipedia.org/wiki/Xv6)), but
I haven't looked at it.

