synkro
0xdeadbeef
So, I hope this help anyone. The next will be more game or grafic related, I swear!
Code:
/*
* GP32 Tutorial 04 "Pointers!"
*
* Intro
* -----
* Finally we have to talk about pointers. Many people fear this topic and
* they say you can handle C without pointers at all. That's right, but like
* all things in life there is a ugly and a elegant way to do things.
*
* Point me in the right direction!
* --------------------------------
* we can allocate space for an array of elements at compile time with fixed
* dimension sizes of any data type, even functions and structs. A variable
* is defined by position(address), size, name and content. For example:
*
* +--------------------+--------------------+
* | 0x1000000000000000 | x | address | name
* +--------------------+--------------------+
* | 33 | value
* +-----------------------------------------+
*
* This is the var named 'x' at the address 0x1000000000000000 with the value
* 33. whenever we use that var in our code, the program knows that 'x' is at
* that address and substitutes the var with the stored value. A variable's
* name stands for its content. (this is not an actual GP32 address but an
* example)
* To find out the address of a var you can use the address operator '&'.
* '&x' will give us the address of the var x and not its value. Now, it
* would be nice if we could store this address. A variable containing an
* address is called pointer!
*
* int *z;
* This defines a pointer containing an address of an integer. We store the
* address of 'x' in 'z' with this line: z = &x;
* +--------------------+--------------------+
* | 0xDEADBEEF00000000 | z | address | name
* +--------------------+--------------------+
* | 0x1000000000000000 | stored address
* +-----------------------------------------+
*
* Once we stored the address of x in z we can change the value of x with the
* address stored in z. *z = 20; does not change the stored address in z but
* the value of the variable x. '*' is an indirection via a pointer.
* This is not fancy at all, because you can manipulate that variable
* directly, so there is no use for the pointer. The main usage of pointers
* is to give them as parameters to functions. Because you don't have to move
* the complete data but its address to work with it.
*
* The parameter of the function doubleMe() is a pointer of type int. Because
* of the '*' the values will be doubled not the addresses. Functions can
* also return pointers. This is useful for larger data elements like
* structs or arrays. It is even possible to declare pointers for functions,
* you won't need that. If you want to do something like that I suggest that
* you learn C++ instead of wasting your time with those weird pointers.
*
* That's it??
* -----------
* No, it's not! The ugly part is coming now. We declare a pointer to point
* at another pointer. int **ptrptr; This is a pointer pointer. We point
* ptrptr at z (z is still pointing at x) so ptrptr is poiting at x.
* I know you want to ask me: "why do we need that sh**?" In one of the next
* tutorials I will handle abstract data types like double linked list. Those
* are helpful managing large numbers of data elements like sprites. Look at
* the following example code. Maybe, next time when you are coding you will
* find a way to use pointer in your own program to lighten stuff up.
* Good Luck!
*
* Disclaimer
* ----------
* This Tutorial is based on Mr. Mirko's SDK (mirko@mirkoroller.de)
* download it at: http://home.t-online.de/home/mirkoroller/gp32/
* THIS TUTORIAL IS NOT WRITTEN BY MR. MIRKO!
*
* SDK by Mr. Mirko mirko@mirkoroller.de
* Tutorial by synkro synkro@gmx.net
* 26.04.2004 13:59:52
*/
#include <gp32.h>
unsigned short *framebuffer; // A framebuffer pointer
void doubleMe(int *value);
void main(void)
{
framebuffer = (unsigned short*) FRAMEBUFFER;
gp_SetScreen(framebuffer, 16);
int i;
for (i=0; i<320*240; i++) framebuffer[i]=0xFFFF;
gp_SetCpuSpeed(66);
char string[33];
int x;
x = 33;
int *z;
z = &x;
// Pointing at x
int **ptrptr;
ptrptr = &z;
// we point at a pointer (z)
sprintf(string, "Address of x(%i) is: %p ",x ,&x);
// Sometimes you have to print out formated strings to show values or
// addresses of vars. The format sign '%i' is for ints. This sign will
// be replayced with the first var's value. As you maybe guessed '%p' is
// for addresses.
int x_pos = 5;
int y_pos = 40;
int length = 30;
int color = 0xF000;
gp_SetFont8(x_pos, y_pos, length, string, color, framebuffer);
sprintf(string, "Value of z is: %p ", z);
y_pos += 20;
gp_SetFont8(x_pos, y_pos, length, string, color, framebuffer);
*z = 20;
// we change x via the address stored in z
sprintf(string, "Value of x is: %i ",x);
y_pos += 20;
gp_SetFont8(x_pos, y_pos, length, string, color, framebuffer);
doubleMe(&x);
// we double x
sprintf(string, "Value of x is: %i ",x);
y_pos += 20;
gp_SetFont8(x_pos, y_pos, length, string, color, framebuffer);
**ptrptr = 666;
// we are not changing the address stored in 'ptrptr' nor the address
// stored in 'z' where 'ptrptr' is pointing at but the value of the var
// where 'z' points at. That's x!
sprintf(string, "Value of x is: %i ",x);
y_pos += 20;
gp_SetFont8(x_pos, y_pos, length, string, color, framebuffer);
sprintf(string, "Value of **ptrptr is: %i ",**ptrptr);
y_pos += 20;
gp_SetFont8(x_pos, y_pos, length, string, color, framebuffer);
while (1)
{
}
}
void doubleMe (int *value)
{
*value = *value + *value;
}