Ask HN: Improve C language skills after K&R?
I've already read and understood K&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?
My objective is to better understand how computers work, how ruby works, and generally to be a better software engineer.
39 comments
[ 4.6 ms ] story [ 84.1 ms ] threadGuaranteed to make you a better software engineer.
I wouldn't say it's a "Guaranteed" way to make you a better software engineer, but it does offer a lot of perspective that is invaluable to the fundamentals of microprocessors and how we interface with them.
Also look into C build systems like cmake or autotools.
[0] https://www.ietf.org/rfc/rfc1928.txt
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...
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.
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...
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!
CII is a great, great C book though.
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.
[1] http://careferencemanual.com/
This book is great, full of good code and even better writing.
[0]: https://handmadehero.org/
https://www.google.com/search?q=expert+c+programming+deep+c+...
...you may also enjoy:
http://www.gowrikumar.com/c/index.php
http://blog.regehr.org/archives/213
...and learn to use a memory error debugging tool like:
http://elinux.org/Electric_Fence
http://valgrind.org/
...Besides C, other ways of expanding your horizons would be to learn things like: Prolog, Lisp, Haskell, and/or Verilog.
"How to C (in 2016)": https://news.ycombinator.com/item?id=10864176
"Critique of 'How to C (in 2016)'": https://news.ycombinator.com/item?id=10908217
EDIT: Fixed formatting error
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...
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.
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...
[1] https://www.amazon.com/Interfaces-Implementations-Techniques...
[2] http://icube-icps.unistra.fr/img_auth.php/d/db/ModernC.pdf
[3] http://blog.regehr.org/
[4] http://blog.regehr.org/archives/1393
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.
David Hanson's C Interfaces and Implementations is also excellent.
[0] http://csapp.cs.cmu.edu/
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_...
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/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/
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
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
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), 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.