Hacker News new | past | comments | ask | show | jobs | submit login
Ask HN: Improve C language skills after K&R?
70 points by SoftwarePatent on July 28, 2016 | hide | past | favorite | 39 comments
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.




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


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

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.


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...


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!


Yeah, it's pretty weird.

CII is a great, great C book though.


I've seen that book recommended a lot. Check online for the errata if your book doesn't have an errata insert.

21st Century C is another good one.


That is some high praise coming from someone who's opinions I respect. I may have to pick that book up - thanks for mentioning his review.


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

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.


I also strongly recommend Expert C Programming. In addition to giving a newbie lots of good info on C, it's also a lot of fun to read.


First link doesn't seem to work?


Replaced it.


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.


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/


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.


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?


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.


> Guaranteed 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.


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.


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/


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.


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.


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...

[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


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), 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.


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.


Seconded. I also recommend C Traps and Pitfalls and The C Puzzle Book to improve your understanding of this subtly complex language.


> 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...


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

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.


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/


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)


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_...


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.


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/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


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.


Help somebody else learn C.


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.


These discussions may be useful:

"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


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


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


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...) 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), but I haven't looked at it.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: