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