Pointers?

Okay, I am relatively new to programming in C languages, and I am not stupid but I can't seem to wrap my head around this...

What is the point of pointers? Isn't an identifier really just a pointer to where it has allocated memory? So why use a pointer instead of using the original identifier? And further down the rabbit-hole, why use a pointer to point to a pointer? What is the *practical* use in doing so?

Last edited on
...
Last edited on
a pointer is a 4 byte memory location that holds an address to a block of memory.

When creating a variable in program space, the memory that is used is allocated (set aside memory) when the program is run, and destroyed when the program terminates. This means that you, as the programmer, need to know all the entities that the program needs to create at compilation time.

But lets sat that you are writing a program that tracks animal births. There is no way to determine how many animals are going to be born. So you need a way to allocate dynamically when the program is being run. This is a good time to use a pointer to memory created using new.

Another example is to pass by pointer. Remember that when you pass an object into a function you can pass it three ways: by value, by reference, and by pointer. When you pass by value, an entire copy of the object is made on the stack, and the program uses this to operate on, leaving the original unchanged. This is okay when using predefined types, because the size of the object is relatively small. But lets say that you are trying to pass a large object. It becomes easier to pass by reference or pointer, because the CPU doesn't make a copy of the entire object, it just uses the pointer to reference the original object.

Have you ever used a 2d array?
 
int array[2][2];


if you wanted to create this dynamically at run time you would need to use a pointer to a pointer:
 
int ** Array;


would be the same thing.
...
Last edited on
Thank you both. I knew that it was a direct access sort of thing, but I just needed to know some situations that it would be used in. Thanks again for the help.
@IWhisIKnew: you are misusing pointers.
If you want to limit the scope of a variable, then limit the scope of the variable.
Your code is ugly, error-prone, and inefficient.
delete new T

@OP: another example is relationships.
By instance a `vehicle' may have a pointer to its driver, so in case of a crash it can let him know that he's dead.
Whoa, whoa! ...Whoa...

First of all, the keyword new is used to allocate memory on the heap, not the stack. If you want to declare a large amount of memory on the stack and control when it is "deleted", use a "naked block." E.g.
1
2
3
4
5
6
7
8
9
10
Type x;

{   //this is a naked block
    BigType y;
    y.foo();
    y.bar(x);
}

//y is no longer in scope, therefor its destructor was called and the stack pointer was reset
// also, there is no "bad" pointer floating around, and the identifier "y" can be reused 


Second (and arguably less important), a pointer is only 4 bytes in a 32 bit program. (Get it? 4 bytes == 32 bits.)

Third. You do not need to use pointers to pointers to make a 2D array. Programmers only do that when they want their 2D array syntax to look like they are used to. E.g.
1
2
3
4
5
6
7
8
9
10
11
12
//these are not const, and can not be used to declare an array on the stack
int width = ...;
int height = ...;

T *array = new T[width * height];

//iterate through the "2D" array
for( int row = 0; row < height; row++ )
    for( int col = 0; col < width; col++ )
        do_something_with( array[row * height + col] ); //~ array[row][col]

delete[] array;

Note however that a dynamic array of arrays should (or could) be a pointer to a pointer if both the outer array's size and each inner array's size was determined at run time; and the inner arrays might not all be the same size. E.g. outer array of classes, inner sub-arrays are the rosters of those classes. Each class might have a different number of students, and the number of classes may be dynamic (or at least unknown at compile-time.)

----------------------------------------------------------------------------------------------------------------------------------
To answer the OP:

A pointer is an address. Just like everything else in a computer, these addresses are numbers (usually represented in hex, and whose size is dependent on your CPU and compiler. Yes a 64 bit program has larger pointers then a 32 bit one. This gives them more addresses to work with though. Think about this: if every house could only have a 4 digit address, you could only have 10000 houses. So although these 4 digit address would be easier/quicker to write then our current -- number street, city state, blah blah -- they would be impractical.) So why do we, as programers, care about these internal numbers. Let's say I need to hire a designer for my house (they would be represented as a function in our program, and our house would be a variable... a big variable.) Would it (a) be easier to tell him my address, or (b) build a copy of my house and send that to him?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//pass a copy (copied implicitly)
Design designer(House project) {
    do_stuff_with( project );
    ...
}

//pass only the address (no copying)
Design designer(House *project) {
    do_stuff_with( *project ); //need to dereference the pointer
    ...
}

int main() {
    House myHouse;
    desinger( myHouse ); //for (a) pass-by-copy
    designer( &myHouse ); //need to get address for (b) pass-by-pointer
    ...
    return 0;
}
(b) is clearly a faster and more efficient alternative to (a), if we trust the designer to not steel stuff from our house. Of course I'm joking, but not entirely. This is a real concern for the programmer. If we don't know who wrote the code for the designer function, and we don't/can't actually read through it, we might not want to pass our house to it, or our house might not come back the same as when it went in.

However, it's worth pointing out (bad pun intended) that C++ (not C) provides an alternative.
1
2
3
4
5
6
7
8
9
10
11
12
//pass a reference to the house (no copying)
Design designer(House &project) {
    do_stuff_with( project ); //no need to dereference any pointers
    ...
}

int main() {
    House myHouse;
    designer( myHouse ); //no need to get address
    ...
    return 0;
}
Here we get all the "benefits" of copying only the address and not copying the house, but we never need to explicitly get the address or dereference it. The only caveat is that a reference can not be NULL, i.e. it must actual point to something.

Another thing to note (in C++ only) is that in my above code, dealing with 2D arrays, I could have avoided the explicit new and delete operations by using a standard library like <vector>. These objects will allocate the memory need, and deallocate it when done, automatically. (This idea of hiding specific details of an algorithm is known as "encapsulation", and the C++ standard libraries make excellent use of it.)

----------------------------------------------------------------------------------------------------------------------------------
In short:

If you're using C++, you likely wont deal much with pointers. (Mainly only when you need NULL, are utilizing a C library, or are asked to for some school assignment.)

If you're using C, get used to them! They allow for faster programs, and allocation of data on the heap.
Ok. Let's say Im writing a game and I have a class table for my character's stats. (Don't worry about classes yet ,you'll run into them soon enough).

Say this table includes all his stats, agi, strength, charisma, dex, etc.. Say I got ten of these characters running around in my game, and I want to write a function that if they go to the gym and work out they get stronger.

Now I have my character john who I make an object of class characters. So lets say john.strength is his strength attribute. Now I write a function to make my character stronger.

Code:
void workout ()
{
john.strength = john.strength + 1;
}


Great, but what if I want to use that function for ALL my characters? For Johny, Cindy, Barry and Mr. Rouchefort? If I couldnt use pointers I'd have to do something ridiculous like

Code:
void workout (string name)
{
name.strength = name.strength +1;
}


And of course that wouldn't work, as it would assume I am calling a character called "name" instead of putting the string there like I want it. Ok so we have to use pointers..makes it so much easier.

Code:

characters* ch; /* This creates a pointer ch that points to class characters. Just go with me on this. */
ch = &john; /* The user wants to play as character john, so we set this pointer equal to the address of john in memory */

void workout (characters *ch)
{
ch->strength = ch->strength+1;
}


Now we have a funciton that works for any of our ten characters. BTW -> is the same thing as using the dereference operator *, but the syntax for object pointers is confusing so we use -> instead to dereference.

That help?
Topic archived. No new replies allowed.