Pointers

Hi all,

I know this is the beginners forum, and so it should go without saying that I'm a beginner, but I will supplement that with the knowledge that I also have little background in computer terminology/functionality. I've been reading tutorials (both at this website and others) on C++ programming in general, and am struggling with the full application of pointers and passing by reference. I am hoping someone would be willing to dialogue with me on the topic so I can have that "aha!" epiphany moment.

I understand the basic principle of how pointers work. For example, I understand that if:

beth = *ted

beth will not equal the value of ted, but rather the value stored in the memory address that is equal to the value of ted. This is a rather simple concept. What I don't understand yet is how this works inversely, i.e.:

*ted = beth

Furthermore, I don't understand how it all works together within functions. For example, one I'm trying to understand from www.sdltutorials.com looks like this:

In CSurface.h we see:

1
2
3
4
5
6
7
class CSurface {
    public:
        CSurface();
 
    public:
        static SDL_Surface* OnLoad(char* File);
};


and in CSurface.cpp we see:

1
2
3
4
5
6
7
8
9
10
11
12
13
SDL_Surface* CSurface::OnLoad(char* File) {
    SDL_Surface* Surf_Temp = NULL;
    SDL_Surface* Surf_Return = NULL;
 
    if((Surf_Temp = SDL_LoadBMP(File)) == NULL) {
        return NULL;
    }
 
    Surf_Return = SDL_DisplayFormat(Surf_Temp);
    SDL_FreeSurface(Surf_Temp);
 
    return Surf_Return;
}


If someone could give me a step by step explanation (even over the things you think may be obtusely obvious), it would be greatly appreciated.

Daniel
Last edited on
Let's start with your more basic question:

You say you understand how it works in the first case, but not in the other, right? The idea behind something like

*pointer = value

is that dereferencing the pointer and assigning to it assigns to the memory location the pointer is pointing to. Dereferencing a pointer returns what is called an "l-value", which is (simply) something that can actually be assigned to (it's on the left side of the assignment operator). This is in contrast to "r-values" which cannot be assigned to; things like the "3" or "a+b".

As for your second question, I'd like to know what exactly about the function is confusing to you. I could explain what each line does, but that isn't anything you couldn't already see from the code itself (e.g. "line 2 creates a pointer to an SDL_Surface called Surf_Temp and initializes it to NULL").
Zhuge,

I'm a math junkie, so the whole pointer concept throws me based on what is on the left side and right side of the equal sign. I see what you're saying about l-values and r-values. So, the explanation for my two examples would be as follows:

beth = *ted assigning a value to beth that is equal to the value contained in a memory cell with an address equal to a value of ted

*ted = beth assigning a value equal to beth to the memory cell with an address equal to the value of ted

Would these be accurate descriptions?

As for the second question... I get confused because there are multiple pointers going on, so my only partial grasp on the topic gets muddled in trying to understand the whole thing. As you can see from my OP, the initial declaration of the function in CSurface.h included two pointers: OnLoad, pointing back to SDL_Surface and File, which I presume is the returned pointer?

In CSurface.cpp, we call the pointer function OnLoad (although it's confusing that they also include the class CSurface after the pointer declaration of the typedef struct SDL_Surface... maybe there's a nuance there I'm not understanding also?). After the function itself finishes and it returns Surf_Return, what is it actually returning? And to where?

Daniel
Yes, it sounds like you are describing the concepts correctly.

The declaration of the OnLoad() method says that it returns to pointer to an SDL_Surface and takes a pointer to a char as an argument. Something to note is that a char* represents a C-style string; it points to the first of many characters of a string. You should really think of it not as a pointer, but just a normal string/text in this context.

Just from looking at the class declaration, I would imagine (and it seems to be the case) the the OnLoad() function takes a C-string representing a file name and uses that to load up a surface and returns a pointer to that surface.

On line 5 of the method I would imagine SDL_LoadBMP() is loading a bitmap file specified by the filename given (this is the C-string "File"). That function returns a pointer to the surface that represents that just-loaded bitmap. That pointer is assigned to assigned to Surf_Temp so we can use it later.

The next part of the if statement condition checks if the surface pointer we have is NULL. I would imagine this is in the case of an error - e.g. the file didn't exist, there was a problem loading the bitmap, etc.

Line 9 seems to take the Surf_Temp we just loaded up and format it in some way (I'm not familiar with SDL at all so I couldn't tell you the specifics), returning a new pointer to this formatted surface. This, I would guess, is the final result surface we were looking for, so we put it in Surf_Return.

Finally, we call a function to free the temporary surface (the one we loaded into Surf_Temp and now now longer need as we have a formatted version) memory before returning the pointer to the formatted surface.

I hope this kind of explanation is helpful.

Now to your actual comments (some were answered above).

As you can see from my OP, the initial declaration of the function in CSurface.h included two pointers: OnLoad, pointing back to SDL_Surface and File, which I presume is the returned pointer?

I don't think this understanding is exactly right. See my description of the function definition above; OnLoad() takes a pointer to a char as a parameter and returns a pointer to an SDL_Surace.

In CSurface.cpp, we call the pointer function OnLoad

We are not calling anything in CSurface.cpp. This is just the function implementation. A call would probably look like this: SDL_Surface* somefile_surface = CSurace::OnLoad("somefile.bmp");

[quote(although it's confusing that they also include the class CSurface after the pointer declaration of the typedef struct SDL_Surface... maybe there's a nuance there I'm not understanding also?).[/quote]
What do you mean? I don't understand what you're saying about "including the class CSurface" as there are no #include statements and I don't see the typedef to which you are referring.

[quote]After the function itself finishes and it returns Surf_Return, what is it actually returning? And to where?[/quote]
It is returning the pointer to the formatted surface we loaded from the file given as a parameter. See my description of the implementation above. And it returns to whatever has called it; note again what I said above: this code is the implementation of the function, not a call.
One of the things you said, please clarify for me. You said:

Something to note is that a char* represents a C-style string; it points to the first of many characters of a string. You should really think of it not as a pointer, but just a normal string/text in this context.


If this is the case, then what's the point (ha!) in making it (char* File) and not just (char File)? Or is this a nuance of the SDL function OnLoad?

For my question you said you didn't understand, I used the word "include" not as #include but rather as the English word that it was a part of their function declaration. I also used the word "call" incorrectly, apparently...

My confusion stems from CSurface.h, where they have the line:

static SDL_Surface* OnLoad(char* File)

Why was CSurface:: not written before OnLoad(char* File) as it was in CSurface.cpp? That's not related to pointers, but it's confusing nonetheless.

Daniel
Ok, so I've decided to mess around a little with pointers in CodeBlocks to see if I could get somewhere with it, and I think it's just confused me more. I'm trying to understand the concept of passing by reference, namely, how it is usable. Here's what I've got:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
using namespace std;

int returning(int* ted, int nancy)
{
    nancy = *ted;
    return(nancy);
}

int main()
{
    int sarah = 50;
    int claire = 60;
    int* dude = &claire;
    cout << returning(dude, sarah) << endl;
    cout << sarah << endl;
    return 0;
}

When I run the program, I get 60 and 50. What I don't understand is why the value of sarah wasn't permanently modified. If I wanted sarah's value to be permanently modified (using a pointer, not just in general), how would I need to set it up differently?

Daniel
Last edited on
The easiest way is to change the function to accept a reference instead of passing by value. Passing by value doesn't change the content of the original value passed into the function which is why u still had a 50 for sarah.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
using namespace std;

int returning(int* ted, int &nancy)    //reference operator &
{
    nancy = *ted;
    return(nancy);
}

int main()
{
    int sarah = 50;
    int claire = 60;
    int* dude = &claire;
    cout << returning(dude, sarah) << endl;
    cout << sarah << endl;
    getchar();
    return 0;
}


As u'r asking for pointers it's a little trickier. U could do it like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int returning(int* pted, int *pnancy)  //accepts a pointer in 2nd param
{
    *pnancy = *pted;   //note the *      //pnancy = pted; will only copy the address and not the value stored at the address
	int nancy = *pnancy; //since we're returning an int we need copy the value at *pnancy into nancy
    return(nancy);
}

int main()
{
int sarah = 50;
    int claire = 60;
    int* pdude = &claire;
    cout << returning(pdude, &sarah) << endl;  //send the address of the int sarah
    cout << sarah << endl;

getchar();
return 0;
}


output:
60
60

Also, note that it's common practice to prefix pointers with 'p' to make code easier to read.
Last edited on
Topic archived. No new replies allowed.