After switching to Java, Python and eventually Ruby, I honestly, honestly thought I’d never see another pointer again in my life. I’m still traumatized by the 4000 lines of X/Motif code I wrote as part of my undergraduate thesis many years ago. Nonetheless, it appears that he who wants to code on the IPhone must take a refresher, so here it is.
Pointers
Variable, meet pointer, who is nothing more than a memory address with your address in it.
#import <Foundation/Foundation.h> int main (int argc, const char * argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; int count = 1; int *ptr; // ptr is equal to the address of count ptr = &count; NSLog(@"c = %i, p = %i", count, *ptr); // contents of ptr is equal to the contents of count count = 2; *ptr = count; NSLog(@"c = %i, p = %i", count, *ptr); // ptr is actually a memory address NSLog(@"p == %i", ptr); [pool drain]; return 0; }
Gives us:
07:07:26.919 Pointers[1958:903] c = 1, p = 1 07:07:26.922 Pointers[1958:903] c = 2, p = 2 07:07:26.923 Pointers[1958:903] p == 1606414028
Structs
Pointer, meet struct. You two shall become very familiar. In fact, theres even some funky shorthand you can use together.
int main (int argc, const char * argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; struct date { int month; int day; int year; }; struct date today; struct date *ptr; today.month = 2; today.day = 19; today.year = 2010; // ptr points to today ptr = &today; // ptr is actually a memory address NSLog(@"t == %i", ptr); // we can still access the elements of thr struct NSLog(@"t == %i", (*ptr).month); // but we also get this cool shorthand NSLog(@"t == %i", ptr->year); [pool drain]; return 0; }
The product of your union (fnar, fnar):
07:16:58.706 Pointers[2360:903] t = 1606413984 07:16:58.709 Pointers[2360:903] t = 2 07:16:58.709 Pointers[2360:903] t = 2010
Methods and Functions
We have two options here – passing the address of a variable (&) is the same as declaring and passing a pointer.
#import <Foundation/Foundation.h> // we're accepting pointers here void exchange(int *p1, int *p2) { int temp; temp = *p1; *p1 = *p2; *p2 = temp; } int main (int argc, const char * argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; int x = 1, y = 2; // before exchange NSLog(@"x, y == %i, %i", x, y); // we can pass in the address of x, y exchange(&x, &y); NSLog(@"x, y == %i, %i", x, y); // or we can declare a pointer and pass that in instead int *p1, *p2; p1 = &x; p2 = &y; exchange(p1, p2); NSLog(@"x, y == %i, %i", *p1, *p2); [pool drain]; return 0; }
Mon cheri:
07:44:36.137 Pointers[2892:903] x, y == 1, 2 07:44:36.141 Pointers[2892:903] x, y == 2, 1 07:44:36.141 Pointers[2892:903] x, y == 1, 2
Arrays
And this, at last, is where the fun begins.
#import <Foundation/Foundation.h> int main (int argc, const char * argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; int *ptr; int myArray[] = {1, 2, 3}; // we can point at the start of the array like this ptr = &myArray[0]; NSLog(@"ptr == %i", *ptr); // or use the shorter version, the compiler treats the // occurence of an array name with subscript as pointer // to first element of the array ptr = myArray; NSLog(@"ptr == %i", *ptr); // then we can access directly ptr[1] = 5; NSLog(@"ptr == %i", myArray[1]); // or this way. they key point here is that the compiler // will look after the size of the inc/decrement depending // on what the array objects are *(ptr + 1) = 6; NSLog(@"ptr == %i", myArray[1]); // or increment/decrement *(++ptr) = 7; NSLog(@"ptr == %i", myArray[1]); [pool drain]; return 0; }
Gives us:
08:10:13.356 Pointers[3588:903] ptr == 1 08:10:13.359 Pointers[3588:903] ptr == 1 08:10:13.359 Pointers[3588:903] ptr == 5 08:10:13.360 Pointers[3588:903] ptr == 6 08:10:13.360 Pointers[3588:903] ptr == 7
Functions
Finally, its worth noting that you can declare a pointer to a function.
#import <Foundation/Foundation.h> void myfunc(int *a, int *b) { int temp; temp = *a; *a = *b; *b = temp; } int main (int argc, const char * argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; int a = 1, b = 2; // before function NSLog(@"a, b == %i, %i", a, b); // vanilla myfunc(&a, &b); NSLog(@"a, b == %i, %i", a, b); // we can declare a pointer to a function // note the parentheses around the function name void (*ptr) (int *a, int *b); ptr = myfunc; // using the ptr ptr(&a, &b); NSLog(@"a, b == %i, %i", a, b); [pool drain]; return 0; }
Point to my function baby.
08:12:16.534 Pointers[3608:903] a, b == 1, 2 08:12:16.536 Pointers[3608:903] a, b == 2, 1 08:12:16.537 Pointers[3608:903] a, b == 1, 2