Ask HN: How do I learn C and C++ when I love high-level languages?
I've been developing using languages like Python, Java and the like with automatic memory management for the past few years. The way I learned these languages was - read their language definition from learnxinyminutes.com, think of personal projects I wanted to make/port, google the API and done.
C/C++ is different, I'm afraid of pointers. I can't think of anything that I will like to make in C/C++ since it is so low-level. What I can do in one line in Ruby will take dozens.
I will really appreciate any pointers on how do I learn them. (no pun intended)
61 comments
[ 3.2 ms ] story [ 120 ms ] threadSome useful reading:
http://www.swig.org/
http://dan.iel.fm/posts/python-c-extensions/
https://blog.jcoglan.com/2012/07/29/your-first-ruby-native-e...
you can also try writing the core utils using your newly learned C/C++ skills.(https://github.com/chaitanyav/cprograms)
You can always go one level down, but I would hardly say you need assembly for c or c++.
For instance, in assembly you push/pop from stack, or you move things into the registers and from memory, you will have to deal with memory address, etc..
So he will learn the most important background about thinking in C, like stack vs. memory allocation, and what pointers really are under the hood (the memory address of a thing)
Try simple data structures first. Having linked list nodes that actually uses minimal memory (pointer to next node, a data field) is actually pretty exciting. Implement all the operations (get index i, remove index i, etc) because that's where a lot of the insight will come from. Then you can move onto binary search trees and other more complex stuff.
One of the most useful insights I've read was from "Effective C++", which said (paraphrasing) "C++ is a federation / family of languages which work together". Learn the C subset of it first so you're not overwhelmed with available features, and then you can get back to using templates / STL / the other languages later.
Pointers may be scary but they are just a concept that you need to grasp, like recursion. You first read about it and kind of get it, then you apply it over and over until suddenly you realize that you have developed a true understanding that allows you to build new abstractions on top.
You will hear people telling you to start with C first because C++ is a superset of C, but I always advice against this. Memory management is "manual" in both, but the idioms you apply are very different between the two. Unless you are looking to truly spend years perfecting both, pick one and go with it.
C is much better as glue code between languages than anything else.
It's doing a great job of teaching me C, while also reminding me how great high level languages actually are!
You really want to work with people who have done C++ before, because there are a number of tricks (RAII, ownership conventions, using const references and references to signal ownership conventions, smart pointers, unique_ptr, etc.) that are common industry practice but aren't all that well-documented on the web. C++ differs from Java or Python in that often the hard part isn't figuring out how to do something, but figuring out what not to do.
This is only half of it. The second half is to choose a mid size project, write yourself something that resembles a spec, and code it up from scratch. It could be some sys util or perhaps a video game (this will require you to learn library linking).
The third half is to read online articles and tutorials while you do the two things above.
The fourth and final half is to get yourself a book once you have a grasp on the language(s) and learn some of their more complicated idioms and pitfalls.
Also as a side note, at this point in time I don't think the "C/C++" conglomerate make much sense any more as modern C++ looks very different from C. Unless you explicitly need C, I would suggest learning C++ first as it's higher level (and also much larger). Though, idk, maybe learning C first is better as it's the foundation for C++... I guess either is fine, just not both simultaneously.
Pick something fun to write (to you) that is normally written in a lower level language.
For me C and C++ were fun to learn by writing graphics applications (ray tracers are great for this) and physics simulations (a solar system simulation maybe). Optimizing these to be as fast as possible is a great way to learn about pointers and manual memory management.
Having said that, C++ has come a long way, despite what haters say. I program primarily in C++ and very rarely have to use pointers. C++11/14 has excellent features (lambdas, initialization lists etc) which can make programming almost seem like writing a Python or Ruby script.
You may also have some luck with Bjarne's smallish "Tour of C++" book -- http://www.stroustrup.com/Tour.html
https://stackoverflow.com/questions/3016107/what-is-tagged-s...
http://www.stroustrup.com/C++11FAQ.html
Also, the Boost library is worth a look. C++ is fairly expressive if you wield it properly, and it offers several ways to minimize the pain of memory management. I would hesitate to call C++ "low-level". (C is another story.)
Other than that - C/C++ are used to solve different problems from Python, Ruby, etc. It is a common problem that people used to a particular toolset have difficulty identifying tasks that are suited to other tools. The suggestions to write C extensions or ports of command line tools are good ones - these will give you a taste for where C/C++ shine on a much more gradual learning curve than trying to write device drivers or kernel extensions.
Another example of practical C++ usage: in the past, I've often prototyped algorithms in Python, then rewritten them in C++ once the major bugs are ironed out. YMMV, but I found this to be faster than writing directly in C++.
That's not really true, in general. They can all compute the same things. Some problems have constraints beyond "what is computed".
Actually, I think the best approach would be to pick a project for which you can construct a believable (by you) reason why it should be in C. Some possible reasons:
1) You need precise control of hardware
2) You're running in an environment where higher level languages are not available
3) You need precise control of latencies
4) You need the absolute maximum possible performance
There are various projects with these requirements of various difficulties. I would say that it might be hard to simultaneously convince yourself that a project needs the maximum possible performance and also that it is tractable for you as a newbie C developer.
A simple kernel module might not be a bad thing, if you can do your development in a VM to recover from the inevitable crashes. The reason for C will be quite clear, but tooling will suffer.
Targeting microcontrollers will be similarly well motivated at a higher degree of awkwardness.
Edit: I'm sorry if this sounds condescending, but I really mean it. Basic is about one step above assembler - you get variables and nice access to some basic IO, but it's much closer to the metal than C. It really doesn't even have functions, you have to do GOSUB/RET yourself. It's also an extremely simple language. But it will give you an idea on how computers work at a basic level. After that you should have a much easier time grokking C.
IMO you don't need to know either C or asm to be a great programmer. Read a book on operating systems instead and you'll know all you need to about hardware. Add a thorough coverage of algorithms and data structures, and you're in a better position to write effective software than many I've worked with.
Also read some reviews of the book before you spend any time reading it. The mid 90's were a really bad time for C++ in my opinion since it was kind of a new language and being pushed heavily as the default 'learn computer programming' language (which Java later usurped). This means there are tons of very badly written and confusing resources that do more harm trying to teach C++ than actual good. Stuff like Deitel's C++ How To Program, etc.
For C++ in particular I can recommend:
Thinking in C++ (http://mindview.net/Books/TICPP/ThinkingInCPP2e.html) Although it's getting a little old, I think this is a great resource for someone just picking up the language.
A Tour of C++ (http://www.stroustrup.com/Tour.html) Great small intro to modern C++ programming, by the creator of the language.