
Ask HN: How do I learn C and C++ when I love high-level languages? - zuck9
I&#x27;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&#x2F;port, google the API and done.<p>C&#x2F;C++ is different, I&#x27;m afraid of pointers. I can&#x27;t think of anything that I will like to make in C&#x2F;C++ since it is so low-level. What I can do in one line in Ruby will take dozens.<p>I will really appreciate any pointers on how do I learn them. (no pun intended)
======
10098
First, just to clear things up, C and C++ are two different languages. Yes,
C++ is backwards compatible, but you'll do yourself a favor if you start
perceiving them as two completely separate laguages now.

Before you start, you need to answer yourself why you're doing it. Unless you
really have some inherent interest in the language, learning it just for the
sake of learning will be tough because there is no instant gratification.

A good book to start learning C++ is Stanley Lippman's "C++ primer". Make sure
you have the latest edition because it reflects the recent big changes in the
language.

The best thing you can do when dealing with lower-level languages like C and
C++ is understand that things like lists, strings, integers, floating point
numbers, objects, etc. do not actually exist. They are simply abstractions.
There are only the CPU and memory. You can think of the memory as a very very
long array of bytes.Pointers are simply indices for that byte array. Roughly
speaking, all that happens in a computer is the CPU fetches some bytes from
memory which contain instructions and then modifies the bytes in some other
region of the memory according to given instructions.

Once I realized the above things, a lot of other things immediately started
making sense to me, so I hope this helps you or others.

------
stormbrew
Stop being scared of pointers, they aren't magic and you've _been using them
all along_. In most high level languages you are using a pointer for any
variable that's not a number. Which is why when you assign one variable to
another and modify one it modifies it from the perspective of the other.
Because they _point_ to the same object.

Fundamentally, though, they're a value just like any other, just a number
that's an index into the giant array called memory. The language provides
convenient syntactic sugar to 'dereference' them, which just means evaluate
the address and index to it.

Basically:

    
    
        *blah
    

is equivalent to:

    
    
        all_of_memory[blah]
    

which, incidentally, is equivalent to:

    
    
        0[blah]
    

and back around again:

    
    
        blah[0]

~~~
hadoukenio
In all my years, I've never seen anyone describe it like this. Nice one.

------
tathastu
I think to _learn_ C/C++ it's helpful to have a mindset of wanting to
understand the machine rather than build code. It's of course great fun to use
Python's built in maps etc (and C++ has equivalents) but what you can do in
C/C++ that you can't in Python is create the raw data structures down to the
exact memory locations where they'll be used. One of the ways to learn C++ is
make a relatively complex data structure (red-black tree, or bloom filter) and
then throw as much data as you can inside it, see when you cross a threshold
of memory usage -- then see if you can improve on that.

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](http://www.stroustrup.com/Tour.html)

------
brewt
Good C++ isn't that far from high-level languages. Look at the bullet points
here:

[http://msdn.microsoft.com/en-
us/library/hh279654.aspx](http://msdn.microsoft.com/en-
us/library/hh279654.aspx)

If you primarily use value and reference semantics, RAII, smart pointers, STL
containers and algorithms, etc, C++ looks a lot like a really powerful high-
level language, because that's what it is. Things only start to get ugly
and/or low-level when you are trying to heavily optimize things.

Stroustrop (mentioned in other comments) is a great way to get started, and
Effective C++ ([http://www.amazon.com/Effective-Specific-Improve-Programs-
De...](http://www.amazon.com/Effective-Specific-Improve-Programs-
Designs/dp/0321334876)) and its cousins will help you not shoot yourself in
the foot.

C is a whole different beast. If you've coded in Java, you have a basic idea
of how to do encapsulation in C++. Encapsulation in C is nearly impossible to
guarantee. Really, a lot of C programming relies heavily on negotiated
conventions and design by contract. Learning the C language is pretty easy
(read K&R some weekend), but learning to program well in C is a completely
different thing.

------
nostrademons
Take a job where you'll have access to senior C++ programmers who'll mentor
you. One good way to do this is to get a frontend/webdev job at a company that
also does some hardcore C++ backend development, then once you're in the
company, offer to start fixing bugs in the core product as long as you get
some mentoring/code reviews for them. Most devs don't turn down an offer to
help.

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

------
mden
Go to a code practice site like hackerrank or oj.leetcode (personal favorite
but I suggest using an external compiler for it) and solve problems. Start
from the simplest ones and make your way up. Once you solve a problem, go back
the following day or week and without using a reference solve it from scratch.
After solving a problem look at the solutions provided in the forums. A lot of
the time they will be a lot more elegant and contain things you haven't
considered or seen before.

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.

~~~
er0k
four halves, huh?

~~~
mden
What can I say, C++ isn't easy to learn :)

------
candu
Look into more recent language features:

[https://stackoverflow.com/questions/3016107/what-is-
tagged-s...](https://stackoverflow.com/questions/3016107/what-is-tagged-
structure-initialization-syntax)

[http://www.stroustrup.com/C++11FAQ.html](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++.

------
kristiandupont
I don't think that C/C++ is different, this is exactly how I learned those as
well. Be aware though, that C++ and C are very different languages and you
should choose one. If you want to do kernel-level stuff or embedded code, C is
probably a better choice than C++, whereas if you want to go into gaming or
complex desktop applications (think Photoshop), C++ might be the one to
choose.

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.

~~~
duaneb
C++ is also very applicable in kernel programming. See: Haiku, Darwin,
Windows. I would not write a C kernel now; Linux and *BSD only maintain
relative security and dearth of bugs through years of maintenance and rigorous
code guidelines. C++ (even as only a thin layer over the C code) can provide
ridiculous modularity and safety that C alone cannot—think RAII and parametric
allocators. From a software engineering perspective alone, I think C++ is the
win.

C is much better as glue code between languages than anything else.

------
dllthomas
Work your way through "A Book on C"? That's how I did it...

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.

------
AnthonBerg
C/C++ didn't truly click for me until I had learned assembler. (Helped my
understanding of every other language too.)

~~~
mden
Assembly didn't really click for me until I learned computer architecture :p

You can always go one level down, but I would hardly say you need assembly for
c or c++.

~~~
AnthonBerg
Haha :) True, so I propose adding computer architecture to the things to learn
about. Not because I think it is NEEDED but because It was a great benefit in
my experience. Just a little goes a long way.

------
hackerboos
Find a slow part of your Python/Ruby/Lua application that could use some
speeding up and then write an extension for it in C.

Some useful reading:

[http://www.swig.org/](http://www.swig.org/)

[http://dan.iel.fm/posts/python-c-extensions/](http://dan.iel.fm/posts/python-
c-extensions/)

[https://blog.jcoglan.com/2012/07/29/your-first-ruby-
native-e...](https://blog.jcoglan.com/2012/07/29/your-first-ruby-native-
extension-c/)

~~~
chaitanyav
I agree with @hackerboos, definitely write a c-extension. It will not only
enhance your knowledge of python but you will also learn C/C++ during the
development. I did something similar wrote a ruby c-extension
[https://github.com/chaitanyav/fibonacci](https://github.com/chaitanyav/fibonacci)
for fun. Also, checkout the CS107 videos on youtube which are C based (look
for cs107 stanford).

you can also try writing the core utils using your newly learned C/C++
skills.([https://github.com/chaitanyav/cprograms](https://github.com/chaitanyav/cprograms))

------
tdicola
Some advice I can offer, be very very careful of the quality of resources you
use to learn C and C++. In particular look at the year the book/tutorial/etc.
was written and try to get stuff that was written or updated recently. Both
languages have been around for many years and evolved quite a bit. Advice
about how to use C++ in 1990 is vastly different than how to use it in 2014
with modern C++ versions.

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](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](http://www.stroustrup.com/Tour.html))
Great small intro to modern C++ programming, by the creator of the language.

~~~
cammsaul
+1 on A Tour of C++. ~200 pages that do a fantastic job of introducing the
language.

------
wainstead
I researched this same question back in 2011. One of the most recommended
books is "Memory as a Programming Concept in C and C++":

[http://www.amazon.com/Memory-Programming-Concept-
Frantisek-F...](http://www.amazon.com/Memory-Programming-Concept-Frantisek-
Franek/dp/0521520436)

A rather expensive book but stellar reviews. I borrowed it from the library.
It's very concise too.

For C++ a lot of people still recommend "Accelerated C++":

[http://www.amazon.com/Accelerated-C-Practical-Programming-
Ex...](http://www.amazon.com/Accelerated-C-Practical-Programming-
Example/dp/020170353X/ref=sr_1_1)

because it teaches you "canonical" C++ instead teaching you "C with classes,"
which seems to be a common complaint among veteran C++ programmers. It's very
readable too.

I'm going to pick up "Writing Great Code":

[http://www.amazon.com/Write-Great-Code-Understanding-
Machine...](http://www.amazon.com/Write-Great-Code-Understanding-Machine-
ebook/dp/B0096FEJGQ/ref=sr_1_1)

because it explains computer architecture. Once you start programming in C/C++
you are much closer to the metal and having an understanding of the
architecture will lead to better choices.

------
glenjamin
I would usually think of myself as a high-level langauge developer. I've
recently been working my way through
[http://buildyourownlisp.com/](http://buildyourownlisp.com/) \- Which I'm
seriously enjoying.

It's doing a great job of teaching me C, while also reminding me how great
high level languages actually are!

------
falcolas
Don't be too afraid of pointers - you're already using them if you're using
Python when you work with mutable structures.

    
    
        >>> a = {'foo': 0}
        >>> b = a
        >>> b['foo'] = 1
        >>> a['foo']
        1
        >>> id(a)
        140428021358832
        >>> id(b)
        140428021358832
    

`a` and `b` are just pointers to the underlying structure. The only difference
is that Python is taking care of the dereferencing for you, whereas in C you
would have to explicitly dereference the pointer.

That's all there is to them. It's a reference to another location in memory,
which, when dereferenced, refers to that other location. In pseudocode:

    
    
        >>> b = 1
        >>> a = &b
        >>> b = 2
        >>> a*
        2
        >>> a* = 3
        >>> b
        3

------
fnordfnordfnord
Get yourself an Arduino or some other similar cheap hardware dev kit and build
some project for fun? It's a start.

~~~
zwieback
That's what I was going to say - you can really appreciate when pointers are
useful if you manipulate registers or memory-mapped I/O.

------
ilaksh
Take a look at Nim. It is extremely efficient (since it compiles to C) and
clean, and will allow you to incredibly easily interface with C or go down to
the low level.

[http://nim-lang.org/](http://nim-lang.org/)

Also, take a look at DCPU-16 stuff. Assembly might be more fun to play around
with. [http://www.dcpu-ide.com/](http://www.dcpu-ide.com/) Also x86 assembly.
Its exciting because you can get incredible performance and get insight into
how things work at the lowest levels. Google x86 assembly tutorial. Also the
DCPU-16 has awesome peripherals like the display and even a 3d vector display.

Then when you can come at it from the lowest level pointers are less of a big
deal. You can think about making your own OS, (look for a tutorial) and then
it will be a more natural progression to C (with pointers).

------
alain94040
_I can 't think of anything that I will like to make in C/C++_

Let me address the motivation issue.

C/C++ strength is speed. Write a simple piece of computation in your favorite
language (Ruby for instance). Write the same in C and measure the time it
takes.

Once you see how slow Ruby is, you may get excited by C enough to continue
exploring it.

~~~
lambdasquirrel
C/C++ can also produce data structures that are more compact than any managed
language could allow. For example, one of the oldest tricks in raytracing is
to stuff a few bits of information into the lower bits of a float, so that you
don't have to waste a whole byte encoding the metadata for a kd-tree node. But
even this is ultimately related to speed. It allows the programmer to squeeze
a whole lot into a cache line.

~~~
fleitz
There's also the advantage of sequential memory access, it's generally not
idiomatic in higher level languages to use contiguous arrays.

------
muchabi
The other answers sound like they're from people who aren't new to the idea of
pointers...

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.

------
vasquez
Why do you want to learn C or C++ if you can't think of something you'd like
to use them for? I've written a fair bit of assembler and occasionally still
do tiny projects in C or C++, but my language of choice (by far) is the
highest level general purpose one I've come across.

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.

~~~
zuck9
Because I don't want to get that feeling when I'm reading some C/C++ and have
absolutely no idea what's going on.

------
orr94
If you need an interesting project to motivate you, you could try to build
something with Arduino. It requires purchasing some hardware, of course, but
it's cheap enough to play around with.

------
wsc981
I'd say you just get the book "C Programming: A Modern Approach" by K.N. King.
At the end of every chapter there are some exercises & challenges.

It's an excellent book (see the ratings on Amazon) and also fun to read
through.

C should be much easier to learn than C++. The language is much more basic
feature-wise and the standard C library is very small indeed.

[0]: [http://www.amazon.com/Programming-Modern-Approach-2nd-
Editio...](http://www.amazon.com/Programming-Modern-Approach-2nd-
Edition/dp/0393979504)

------
canterburry
I have many timed tried to embark on this very journey and always gave up when
I realized I had none of the conveniences available to me as I do with the
Java platform.

I thought of all the conveniences of Spring injection, a bazillion java
libraries nicely managed by maven etc. The ecosystem available to me in Java
is what always made me give up. I guess I never needed to learn C/C++ badly
enough to justify the time investment.

------
deet
Telling us what type of personal projects you liked doing in the past would be
very helpful.

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.

------
cammsaul
You could try doing a cross-platform (iOS/Android) game with a C++ framework
like Cocos2d-x. I read through Cocos2d-x By Example
([http://www.amazon.com/Cocos2d-X-Example-Beginners-Guide-
Enge...](http://www.amazon.com/Cocos2d-X-Example-Beginners-Guide-
Engelbert/dp/178216734X)) last year and it was pretty good. Didn't assume a
prior knowledge of C++

------
niklasber
You don't necessarily have to do low level stuff with C/C++. Sure you'll still
be dealing with pointers etc, but my point is it doesn't have to be very low
level just because it's C/C++. Depending on what you want to implement it
might be a good idea to use a framework such as Qt. [http://qt-
project.org/](http://qt-project.org/)

------
blt
You need to understand how machines work if you want to be a good C/C++
programmer. I suggest Berkeley's CS 61C video lectures:
[https://www.youtube.com/playlist?list=PL58D76972AD4CB040](https://www.youtube.com/playlist?list=PL58D76972AD4CB040).

------
terminalcommand
Head First C is an excellent book. It introduces some concepts such as
variadic functions and function pointers too early. You might need some
supplements on them. I suggest reading through the head first c book and
watching youtube videos on topics, you don't quite get at the first time.

------
andrewflnr
I'd say just find a good tutorial type book. I got an adequate understanding
of pointers from reading _C++ for Dummies_. Anyway, don't be afraid. Pointers
require care to avoid various issues, but they're fundamentally a simple
concept. You'll be fine.

------
limdauto
I think you just need an incentive. Try to work on problem where performance
really matters such as physics engine or scientific simulator if you are not
into OS stuff. You will learn to hate automatic memory management soon enough
;)

------
sauere
Read the part on pointers in the "The C Programming Language" book. Or go to
your favorite coffee shop with a C-buddy, buy him some drinks and let him
explain ;)

------
Vektorweg
Do you really need to learn a another language, when you don't like its
features? All general-purpose programming languages can solve the same
problem.

~~~
dllthomas
_" All general-purpose programming languages can solve the same problem."_

That's not really true, in general. They can all compute the same things. Some
problems have constraints beyond "what is computed".

~~~
Vektorweg
I don't get it. What do you mean?

~~~
zuck9
Performance reasons

~~~
dllthomas
That's much of it. Another reason might be "no one has written a XYZ
interpreter for the target architecture", which may be due to performance or
just obscurity. Another problem constraint might be pedagogical - if the
problem you are trying to solve is "show how to do X in language Y" then of
course language Z can't be used - though that example could reasonably be
dismissed as trivially true. I'm sure we can come up with some more if we try.

------
bnejad
Build some system utilities. If you are on Linux/OSX try to program a subset
of the features of one of your favorite command line tools.

------
mamcx
Perhaps use GO or RUST?

Also, I think pascal is great (I use it professionally/Delphi) and the way how
pointer and raw code is used is not scary.

~~~
dbaupp
(Btw neither Go nor Rust have all-caps names.)

------
aosmith
Have you tried Go? Might make the transition a little easier. UDP hole
punching is always fun with C/C++.

~~~
zuck9
Yes, I did. Absolutely HATE the syntax. Not gonna use it anytime soon.

------
anon4
Download a Commodore 64 emulator and learn ROM BASIC. Write a game in it.
After that, try learning C again. You'll be infinitely thankful for such high-
level constructs as functions and structs. And you'll understand what they do
a bit better, probably.

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.

