use of pointers

Started by
19 comments, last by RaoulJWZ 9 years, 8 months ago

I also remember pointers clicking more in my mind when I thought them as addresses or directions for an object.

I thought about data types as e.g. boxes, and pointers as a paper with the directions to the box on it.

int myInt;

--> an int sized box with myInt written on it. int sized because it needs to be big enough to store whatever int I want to put in it.

int *myIntPointer = &myInt;

--> a piece of paper saying "the box in the kitchen on the top shelf".

Somewhat unrelated, hovering the "pointers" tag of this thread gives some fairly entertaining suggestions.

Hello to all my stalkers.

Advertisement


There are two reactions who helped the most: The one from Andy Gainey and rip-off.
For me these two reactions are clear and easy to understand, while english isn't my first language.

That is my normally preferred explanation as well:

Try to think of pointers as street addresses. Its a lot faster and more efficient to say I live at "101 binary street" than it would be to grab your actual house and say I live here.

You can either refer to the address, or you can chose that every time you refer to it you build a clone of the entire house, clone every item in the house, exactly duplicate the house in every aspect, then use the clone.

A pointer is just the address. It is a scrap of paper with an address. It can have a nonsense address, or even a blank address on the paper.

A reference is somebody saying "This is an object's home". It cannot be blank since that would make the object homeless. It cannot be modified, since the home will remain at that location.

To not understand the utility of pointers is to not understand the language. A much older and wiser engineer than myself once said something that I immediately understood and knew to be true: to be a real black-belt with any technological level, you must know the one beneath it.

To understand how to really use C or C++, you need some Assembly experience. Not a lot, you don't need to be a pro, but this will show you what the machine is doing and how, and you will suddenly understand everything in C and C++ intuitively--and you'll be damn good at it too!

The good thing in that all modern C/C++ compilers support inline assembly, so you don't need new tools, just google "x86 assembly tutorial" and spend an evening or two doing some ultra-low level coding :-)

A pointer is just 4 bytes (or 8 bytes in 64-bit), whereas the data it points to might be in the order of megabytes... Passing the pointer to the data around where it's needed is obviously faster than passing around the whole data.

Funny analogy: if you want to tell someone where you live, you don't just get a crane to lift your house and bring it to them to show them you live in that house... you just give them your address.

Thanks everyone for all those many reactions.

The only question i still have is: Is the whole explaination about the house

and the adress only of use with pointers to functions and arrays, or with normal int variables to?

(because a pointer to an int is 4 bytes and an int variable to)

thanks!

Thanks everyone for all those many reactions.

The only question i still have is: Is the whole explaination about the house

and the adress only of use with pointers to functions and arrays, or with normal int variables to?

(because a pointer to an int is 4 bytes and an int variable to)

thanks!

If you use that int as an address of some sort, then yes, the analogy of a house and address can be just as relevant to an int as it can to a pointer.

For example, if you have an array of 100 items, and an int that refers to the index in the array of the item most recently selected, then it is behaving like a reference to some other piece of data. It's as if you already know which street the house will be on (this is the array of 100 items), and now you simply need to know which of those 100 houses is the one you're interested in at the moment (this is the int index). There may be many other streets, but they serve other purposes. If you don't know which street contains the item you're looking for, then just having an array index won't help you. ("I'm looking for the fifth item, but the fifth item in which array?")

Pointers are sort of like global addresses, however, and don't care about which street a house is on. ("I'm looking for the seven hundred and sixteenth house in the world.") A basic array in C++ can in fact behave very much like a pointer. If an array is like a single street with multiple houses, using it like a pointer is like getting the global address of the very first house on the street. ("The first house on this street is the three hundredth house in the world.") If you want to access the very first house, you just use that address directly. If you want to access the fifth house on that street (which would be four houses down from the first house), you just take the address of the first house, and add four to it. That will give you the global address of the fifth house on that street: It is the three hundred and fourth house in the world. Something like this is in fact what your code is actually doing whenever you access an array using an int index.

There are other ways that an int could serve as a reference. If you research hash tables, you'll discover that an int can be used as a way to quickly find an item. It's typically referred to as a "key", but in this case it works very similarly to an address. It is a small piece of information that allows you to quickly find the full data to which it refers.

Hash tables pretty much only use some kind of int for their keys, but other data structures can use a wide variety of types as their keys. Strings can be used, pretty much in exactly the same way as you might look a word up in a dictionary. Two-dimensional vectors might be used as keys to look up which items are stored in a particular cell of a 2D grid, given an (x, y) location.

So the house/address analogy works for a lot of different situations. The curious aspect about pointers specifically is that the there is only one street in the entire world, it is very very long, and all the houses are only on one side of the street. The addresses theoretically start at 0, and increase by 1 until you reach the end of the street (the maximum amount of memory available)*. Other systems of houses and addresses might not be so simply organized. A dictionary can still be ordered alphabetically, but there may be large gaps between one word and the next. A hash table doesn't even have a well-defined concept of order; as you walk along its street, the addresses might go 3083, 95, 40382, 8593... There is a system that organizes it all, but it's not obvious to a casual human observer.

* Side note about pointers and the very long street: Modern operating systems and CPUs do a bunch of work that provide us with this rather simple view of memory. But it's not really a technically accurate view about what's actually going on in memory and in the hardware. In general, you shouldn't need to worry about this at all. But you might encounter patterns with pointer values that seem odd, or at some point you might need to delve into some more serious systems programming. In such cases, being aware that there is a deeper layer of complexity regarding pointers and addresses will help you avoid temporary confusion, and provide you a direction for research. "Virtual memory" would be the primary term to search for.

"We should have a great fewer disputes in the world if words were taken for what they are, the signs of our ideas only, and not for things themselves." - John Locke

Thanks everyone for all those many reactions.

The only question i still have is: Is the whole explaination about the house

and the adress only of use with pointers to functions and arrays, or with normal int variables to?

(because a pointer to an int is 4 bytes and an int variable to)

thanks!

Ints, arrays, and functions are all just data. They're meant to be interpreted differently, but they're all just data. This is particularly important when you're dealing with pointers. float* foo = bar; means "get the value of bar. I want to store that value in a variable named foo. I want you to pretend that value is an address to a block of memory, and I want you to pretend that block of memory is a float."

That block of memory could have been an int. bar itself could have been an int. C doesn't care, and it will try to do what you ask regardless.

To not understand the utility of pointers is to not understand the language. A much older and wiser engineer than myself once said something that I immediately understood and knew to be true: to be a real black-belt with any technological level, you must know the one beneath it.

To understand how to really use C or C++, you need some Assembly experience. Not a lot, you don't need to be a pro, but this will show you what the machine is doing and how, and you will suddenly understand everything in C and C++ intuitively--and you'll be damn good at it too!

The good thing in that all modern C/C++ compilers support inline assembly, so you don't need new tools, just google "x86 assembly tutorial" and spend an evening or two doing some ultra-low level coding :-)

Turtles all the way down. Does this mean you need to know micro-instructions in order to be good enough at assembly in order to be good enough at C? Do you then need to pick up Verilog in order to be able to synthesize the hardware?

There's other issues with this idea too. What's "below" python? Certainly, the reference implementation is written in C, but there's nothing fundamentally C-like about it. They could just as easily have written it in FORTRAN.

I didn't see where anyone mentioned Polymorphism yet.

You can use pointers to common base classes instead of instances of specific classes. For example: instead of your physics manager having a list of starships, missiles, asteroids, etc. You can create a PhysicsObject base class and then derive your Starships, Missiles, and Asteroids from them.

Now your physics manager class can have a list of PhysicsObject pointers and not care about which derived type each item is. Each of these derived items can be treated like a PhysicsObject so you have a list of them, and all your physics functions can take a PhysicsObject pointer.


// For this function, we could pass it a pointer to a Starship, a pointer to a missle, 
// or a pointer to anything that dervies from the base class PhysicsObject
void ApplyForce(PhysicsObject* physicsObject, float direction, float magnitude, float elapsedSeconds);

Do a search for C++ polymorphism for some more reading. This looked like a decent article.

http://www.codingunit.com/cplusplus-tutorial-polymorphism-and-abstract-base-class

- Eck

EckTech Games - Games and Unity Assets I'm working on
Still Flying - My GameDev journal
The Shilwulf Dynasty - Campaign notes for my Rogue Trader RPG


I didn't see where anyone mentioned Polymorphism yet.

Yes. That is another reason to understand them. If you are coming from Java or C#, you can just set references equal to base classes. But you need a reference or pointer in C++. No wonder beginners have trouble learning the language.

I think, therefore I am. I think? - "George Carlin"
My Website: Indie Game Programming

My Twitter: https://twitter.com/indieprogram

My Book: http://amzn.com/1305076532

Turtles all the way down. Does this mean you need to know micro-instructions in order to be good enough at assembly in order to be good enough at C? Do you then need to pick up Verilog in order to be able to synthesize the hardware?

There's other issues with this idea too. What's "below" python? Certainly, the reference implementation is written in C, but there's nothing fundamentally C-like about it. They could just as easily have written it in FORTRAN.

Each "level" of language provides an abstraction from the lower (and generally previous) one; new languages have most often been added to improve developer productivity (with many more recent exceptions existing merely for preference, to enforce some specific programming paradigm, or to provide platform agnosticism--such as Java).

C, for example, while it is a high level language, was intended to abstract away the ridiculous verbosity of ASM, because for the vast majority of programs you don't need to know how, for e.g., a loop works on the hardware (in actual instructions): you just need to know it will work. This has the side benefit that it makes better programmers, because heuristics learned by seasoned low-level geeks can be baked into the compiler and then the rest of us get them for free.

It is a bit silly to say "the more you know, the better you'll be..." even thought it's true. But I would argue that the incremental improvement for a Javascript developer to learn low-level CPU architecture details is very near zero. But this is not so for closer languages. If you want to really excel at C or C++, learning a bit of what the developers of those language were trying to abstract will really pay off.

In the context of your question, this means learning a bit of assembly. The term "pointer" is a somewhat language-specific one, whereas more generally (and when using ASM) the term "address" would be used. You can't miss how the CPU handles memory and what role addresses play in processing--both all the time, and also in the context of creating highly performant code. And you can't walk away from even a few simple "Hello world" type ASM apps without feeling quite at home using them.

And no, learning below that will not pay much. But, if you decide to become a driver optimization guru and do much of your work in ASM, you would be well served by learning all about instruction piplining, microcode and more.

That would be rather architecture-specific knowledge. Fortunately, the basic stuff you would learn from ASM and be able to apply to C/C++ would not.

I hope I explained myself a bit more clearly :-)

Oh, and I know very nearly nothing about Python, so I can't really comment. Find out who created it and what they used before and you'll have your answer.

This topic is closed to new replies.

Advertisement