Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C pointers vs. Objective-C pointers

I'm coming from an Objective-C background and am trying to expand my knowledge in C. One thing has me confused, however, and that's the difference between pointers in C and Obj-C. As you can see in the examples below, things seem to behave a bit differently between both languages, and I was wondering if you could help explain why?

C code works fine:

void myFunction()
{
    int x, *pointerX; 
    pointerX = &x;
    *pointerX = 5;

    // Prints: "x is 5"
    printf("x is: %i", x);
}

Obj-C code fails:

- (void)myMethod
{
    NSString *string = @"Caramel coffee", *stringPointer;
    stringPointer = &string;                    // Warning:   Assignemnt from incompatible pointer type
    *stringPointer = @"Chocolate milkshake";    // Exception: Incompatible types in assignment

    NSLog(@"string is: %@", string);
}

Question: Why can't I assign stringPointer to the memory address of string (stringPointer = &string;), and why am I able to perform *pointerX = 5; under C, but I can't perform *stringPointer = @"Chocolate milkshake"; under Objective-C?

I realize that Obj-C deals with objects and C doesn't, but I can't seem to figure out the behind-the-scenes details as to why it doesn't work in Obj-C. Any help is greatly appreciated. Thanks! :)

like image 359
Dave Avatar asked Dec 07 '09 22:12

Dave


3 Answers

In your first example, x and pointerX have different types ((int) and (int *) respectively). In your second example, string and stringPointer have the same type (NSString *). Try instead:

NSString *string = @"Caramel coffee", **stringPointer;
like image 70
caf Avatar answered Sep 28 '22 08:09

caf


Your NSString *string is itself a pointer. Therefore, in order to point to it, you need to declare stringPointer as a pointer to a pointer. That is, declare stringPointer like this:

NSString **stringPointer;

Then everything should work. Note that the same pointer semantics apply in C and Objective-C.

like image 39
E.M. Avatar answered Sep 28 '22 08:09

E.M.


The thing is that when you create an object, you actually always manipulate it through a pointer assigned to it, hence (NSString *).

Try doing the same thing in C (working with a string), perhaps it becomes clearer:

void myFunction()
{
    char *string = "this is a C string!";
    char **ptr=&string;


    // Prints: "this is a c string"
    printf("ptr points to %s: \n",  *ptr);
}

As you can see, pointers work in exactly the same way as they do in objective-c. Bare in mind that there are very few primitives in objective-c (int is the most obvious one). Most of the time you are creating a pointer of type object X (say NSString), and then allocating a chunk of memory (through [[Object alloc] init]) and assigining the start address of that chunk to your pointer. Exactly the same as we've done in C with our string.

like image 39
theprole Avatar answered Sep 28 '22 08:09

theprole