Lions and Tigers and Pointers, oh my!

Pages: 12
I’ve been spending time at SO again lately (dunno why) and I am again impressed by how confused people get by the idea of pointers.

It really doesn’t seem to me to be that exotic a concept, but it proves to be boundlessly confusing to a vast and unending mass of people.

So, I’m curious. Were they confusing to you at first? What was so confusing about them? What light-bulb moment got you past that?
At first pointers were, as most C/C++ concepts, confusing. For me looking at a pointer as a phone's speed dial entry helped make them less bewildering, and that was years ago. You don't need to remember the phone number you want to dial, just the speed dial entry. Along with knowing speed dial entries can be changed to a different number.

Having even a rudimentary idea of memory layout helps.

Pointers are really quite basic concepts, which is why so many people get befuddled. The simplicity seems to be hiding something more complicated (and possibly sinister) under the hood.
Once you understand it, it seems simple: a pointer is a variable like any other that holds a memory address. The pointer itself is a variable too, so it has its own memory address at which it holds that data.

However, this understanding requires you to understand so much more. What's a memory address? How is the value stored in there? How do I know which memory address I'm writing to (the pointer's or the one the pointer is holding)? When I write "ptr = 5" what am I doing??

...And what does it mean to "hold" a memory address anyway?

These are all questions a person can have and not even know it. It's like trying to figure out how a car works when you don't understand engines/transmissions. They may know those concepts enough to get by, but not enough to actually create meaningful connections about them later.

I often find this is what separates newbies from someone experienced in any field, how well they understand the basics. Once you understand them, you can problem solve your way to higher concepts. But if you don't understand them, you can't logic your way anywhere without tripping over your cracks in knowledge.

Then they are often introduced to double or even triple pointers when they still haven't understood pointers, blame professors for that one.
I think that for 99% of students, barring that 1/100 person who is either not the brightest bulb or is just easily confused**, I think its tied to two things: Bad books and bad teachers.

most try to dive into it all at once, throwing dynamic memory, accessors/iterator concepts, and data structures all into a giant bonfire of crap for the students to absorb, rather than taking a slow, methodical approach and a simple explanation of it all.

I have had a lot of luck talking about it as an array index. I just tell the kid that memory is like a very, very large array of bytes and a pointer is an integer that holds an index into that array. The rest is just syntax and dealing with the gotchas specific to C/C++ ... things like the double use of & (is this a pointer via address-of or a reference and what is the difference anyway?!) or understanding whether you have a constant pointer or a pointer to a constant and weirdness like [] vs * access, arithmetic (including negative indexing) and so on ... come to think of it, c and c++ syntax don't make it easy :)

** I am one of these. I get confused when bombarded by complicated crap that has no apparent use (which is about 40% of school stuff). For a long, long time I felt that way about most OOP, and still think that some of the more exotic stuff belongs only in a classroom. It probably makes me a heretic, but stuff like pimpl is overused and feels more like some egghead at lunch bragging about "look what I did" than anything necessary. (I know it has use cases, but I have seen it over and over where it added nothing but complexity and nerd points).
Last edited on
Ah, that all makes sense. I often say, “Nothing is obvious until it has been taught/learned”... and having bad or incomplete instruction is distressingly common.

I must be an unusual one. I learned it by reading an x86 assembly-language manual, lol.
I mean heck, it took me a quite a few times to really cement the syntax of a for loop in my head and to figure out whether it was running N or N+1 times.

I don't exactly remember how difficult pointers were for me to grasp. I probably had a bit of trouble but understood the basics of "okay, the pointer is initially pointing to the 'int a' variable, but now you're re-assigning it to point to the 'int b' variable, and indirectly modifying both variables.

The clearest analogy is probably the mailing address one, or the computer file one. Your address is not your house, and your address could become outdated if you move. A computer file is stored in a filesystem, but when you move a file locally within the same drive, you just need to move the handle -- which can happen in an instant -- not the actual 4 GB file.
And to be fair, a lot of people get into programming still in the mindset of what computers do is magic.

Most interactions with a computer involve the computer doing things in a useful, helpful way. But when it comes time to start programming, people really do need to recognize that computers are about as smart as a doorknob.
I don't remember ever having problems with learning pointers, I taught myself C back in 1988 by reading K&R's book (The ANSI edition), and doing my own code examples. I think that book explains it all rather well. Back then I never had Internet, and no one to ask either, but I did have use of a UNIX machine. I never did C or C++ at Uni, but it was during the 16 bit DOS assembly language course that I could see why things were that way in C. Later, teaching myself C++ with the help of many people on this forum, it wasn't hard1 to add on the idea of C++ references, and not be confused by the multiple meanings of & and *. Knowledge of pointers also helps with iterators.

1 Although there are some gotchas that need learning, like one can't have a std::vector of references, for example.

I came to c having first used assembly programming (PDP11, z80, 6502) and Pascal (which uses simple memory pointers) so the concept of memory and pointers to memory were nothing new. But when you get to the 3rd and 4th level pointer indirection............ I 'learnt' c from attending a Pascal to c conversion course (3 days) where the main thrust of the course was how to convert Pascal code to c. Then another conversion course from c to C++ (2 days). Nowadays in C++ you don't really need to use 'raw' pointers now that there are smart pointers. But if you do need/use 'raw' pointers then IMO reading up on Computer Architecture/Organisation would be useful.

Also, there are specific C books on using pointers (eg Understanding and Using C Pointers - https://www.amazon.co.uk/Understanding-Using-Pointers-Richard-Reese/dp/1449344186/ref=sr_1_1 )
Last edited on
I definitely was very confused. The books tried to use analogies and stuff to explain it was just confused me more when I was like "but how does &val turn into a random finger pointing at stuff?"

I feel like there were 3 things that always tripped up people learning to program:
* pointers
* threads
* and something I can't remember
I was much more confused by languages like Java or C#, where some types (e.g. booleans, integers and floats) happen to be "value" types that are always implicitly passed by-value, whereas other types (e.g. strings, objects, etc) happen to be "reference" types (effectively pointers) that are always implicitly passed by-reference – but without making this very important distinction explicit in the language at all.

Compared to that, the explicit distinction in C/C++ whether a variable/parameter is a value or whether it is a pointer (or reference) is much more logical/consistent and therefore is easier to understand. Granted, things get a little messy when it comes to arrays in C 😏

For example, in C, it makes sense that using the == operator with char* pointers will only evaluate to true, if they are actually pointing to the same memory location, whereas strcmp() is used to actually compare the string contents. Meanwhile, in Java, it can be quite surprising (certainly was for me!) that the == operator does not work with strings in the way you probably expect it work (because Java strings are in fact references, even though the language doesn't make that explicit), while == does work in the expected way with, e.g., integers.

____

Also: Some basic understanding of machine code (assembler language) and how calling conventions work, which I had before starting with C/C++, helps a lot to understand pointers. It helps you grasp what it actually means if we pass something "by-value" or "by-reference".
Last edited on
I personally do not like the design of Java, and do not understand how it became so popular.
how it became so popular


What were the alternatives?
Tcl/Tk, for one.
Smalltalk, too.

Delphi could easily have done it too (but Borland was too slow to recognize the need for bytecode and cross-platform libraries).

C++ could have too, but C++ is mired by about three bazillion chefs stirring the pot.

Pick just about any language. Sun et.al. marketed the hell out of Java, because ($money$).
I haven't come across Tcl/Tk before but it looks interesting.

Yes, could have been Delphi if Borland had got all their ducks in a row. Shame as I liked Delphi (and Pascal/Modula etc). There were compiler(s) that produced p-code so it was then easy-ish to get these programs to run on different systems.

C++ could have too, but C++ is mired by about three bazillion chefs stirring the pot.


Even with only a couple of cooks I doubt that C++ could have. Even now I don't see a long-term coherent road map for C++.....
Yeah, Pascal was actually had _the_ first bytecode system.
https://en.wikipedia.org/wiki/P-code_machine

It was simple and beautiful.

Fairly, Borland made their business targeting x86 DOS/Windows systems. Even today you cannot find a more powerful environment targeting Windows than Delphi. (Though Embarcadero won’t let you use it without promising an arm and maybe your firstborn, these days. I bought Delphi 5 for about $100 ages ago.)

As far as I am concerned, Embarcadero has made all the wrong decisions with Delphi once they bought out Borland. For example, the way they implemented operator overloading was about as stupid as possible, when it had already been done it beautifully by Wuppertal. But... it is what it is.

Of course, much of the fragmentation came from the so-called ISO/IEC Extended Pascal. The people who wrote that seemed to have had a bone to pick with Borland, going out of their way to make the language _more_ complicated and to do some of the same things Borland did in completely inane and incompatible ways...

There is a beautiful language trying to escape Object Pascal’s current state (and I don’t think it is Modula). As far as standards go, I think Free Pascal gets closest to making things right...


Even now I don't see a long-term coherent road map for C++

True, and sad. I think that it is the reason C++ is disliked by so many. It changes every few years, and not necessarily for the better.

To be fair, it does carry a lot of baggage, I guess. But to be fair-er, if it changes so significantly all the time, why not fix problems instead of pretending it is the same language?


While I’ve got my rant on, might as well mention that I’ve been playing with C a lot lately, and it always reminds me of one of the horrible design flaws with just the string functions, like strstr(), for example:

If strstr() fails, it returns NULL, when it would be so much better to just return a pointer to the end of the string! The failure test would be almost identical and the result would be so much more usable.

Alas for hindsight.
Last edited on
when java came out, it borrowed from C++ syntax which makes it fairly easy to learn, and its a small, simple language which helps too. Add the portability and all... its only drawback in the early days was poor performance. It was also the dawn of the pentium chip and people were starting to allow for performance loss if there were other things to be gained -- much like we see with python today.
Last edited on
ISO/IEC Extended Pascal


Wasn't this produced by 'academics' with little regard to the 'real world'? A Camel comes to mind.......

Even with C++, IMO Borland was 'better' than MS (I used both back then). Borland had OWL (now VCL) which IMO was way ahead of MFC in terms of use and functionality. C++ Builder and Delphi are both now available as free community versions.
I did meet pointers with C and Numerical Recipes for C. The latter had utility functions to allocate (multi-dimensional) arrays that "conveniently" did start indexing with 1, because someone else (than C) did so.

I don't recall having been confused (by pointers). What else have I forgotten?
keskiverto wrote:
What else have I forgotten?

Nothing. Pointers are easy.


Say, does anyone know any slick tricks to get the preprocessor to automatically determine if MSVC is compiling with /Os or not?

In GCC and Clang the __OPTIMIZE_SIZE__ macro gets #defined, but AFAICT there is no equivalent macro in MSVC. (Anything I can google agrees, quite rudely.)

I don’t currently have access to my Windows tools either, so I can’t really poke around very easily.

Or am I gonna be stuck requiring the user to specify a macro in addition to the compile flag?

For the curious, I have an optimized version of a routine that need not be included in the object code if compiling for size.
Pages: 12