Evgeniy Kleban
Evgeniy Kleban

Reputation: 6940

Pointer difference

I'm studying pointers in Obj-C. Consider following code:

char c = 'Q';
char *charPtr;
charPtr = &c;

In the second line, we create a pointer variable of type char and name it charPtr. In my understanding, that is just pointer to memory address that contain some value of type char.

In the third line, we assign charPtr value (memory address) to another memory address that contain value c.

My question is, what is the difference between charPtr and *charPtr?

When I wrote *charPtr = &c there is an "yellow" warning - Incompatible pointer to integer conversion assigning to 'char' from 'char *'; remove &

App crash if launched (exc_bad_access)

When I wrote **charPtr = &c; compiler warn me with error : Indirection requires pointer operand ('int' invalid)

Summary, I want to know difference between charPtr and *charPtr, and what is **charPtr (2 asterisks).

Upvotes: 0

Views: 87

Answers (3)

Henri Normak
Henri Normak

Reputation: 4725

Simply put, *charPtr refers to the value pointed to by charPtr. However, as StackOverflow answers need to be a bit longer than a single sentence I shall try to give you an analogy.

As you are aware, a pointer is sort of like an road sign, saying "the thing you are looking for is at A/B/C whatever". The pointer can be used in several ways.

First and foremost you can point the sign to some other place, which is equivalent to charPtr = &c, saying "instead of A/B/C whatever, now use c as the destination".

Second, you can also use the pointer to change whatever it is pointing to, which would be equivalent to *charPtr = 'Q', which doesn't really change the pointer itself, but changes the contents of the field it is pointing to. Keeping with the road sign analogy, it is as if the sign is capable of changing the name of the city (that is the contents of var c)

Finally, pointers themselves can also be pointed to, sort of like a sign pointing to the next sign. For example char **cc = &charPtr would be a sign pointing to the original sign, in which case **cc can be used to access the actual value, while *cc is contents of the first sign (the address of the actual value). This can be extended as far as the eye can see, or at least as far as it is practically desirable.

Upvotes: 3

Amnon Shochot
Amnon Shochot

Reputation: 9376

  • char *charPtr; - you're declaring a variable named charPtr of type char *, i.e. "pointer to char"
  • charPtr = &c; - you are assigning the charPtr variable the address of variable c
  • *charPtr - in this case the '*' character is the indirection operator which means get the value in the address pointed by charPtr. The type of *charPtr in this case would be char (and NOT char*)

Now, per the above in the statement *charPtr = &c you're trying to assign the address of variable c (&c) to a char (*charPtr) which is why you get the warning Incompatible pointer to integer conversion assigning to 'char' from 'char *'; remove &.

When you're running the application you'll be trying to assign an address (of size 4 or 8 bytes) to a variable of type char (usually 1 or 2 bytes) which is why your application would crash on exc_bad_access

Upvotes: 1

Ken Thomases
Ken Thomases

Reputation: 90601

charPtr is a variable which holds a pointer to a value of type char. After line 2, it holds the address of the variable c.

*charPtr is an expression which dereferences the pointer and accesses the value at the pointed-to address. Because charPtr points to a value of type char, the expression *charPtr has type char. If you read from it, like char foo = *charPtr;, you get the char at the pointed-to location. In this case, you get the value of c, which is 'Q'. If you write to it, like *charPtr = 'A';, you store a new value at the pointed-to location. In this case, you change the contents of c.

**charPtr is a syntax error because charPtr is not a pointer-to-pointer type. The expression has the form of a double dereference: the first dereference is *charPtr, just like above. Applying the * operator to it again attempts to dereference it again, but the type of *charPtr is char. It's not a pointer, so it can't be dereferenced.

You might have a variable like this:

char **charPtrPtr = &charPtr;

Now, charPtrPtr is a variable which holds the address of the charPtr variable. Its type is char**.

*charPtrPtr dereferences the pointer it holds and gets the value that it was pointing to. This is the value of charPtr, which is, in turn, a pointer to c.

**charPtrPtr is a double dereference. It's the application of the unary * operator to *charPtrPtr. Since *charPtrPtr is effectively the same as charPtr, **charPtrPtr is effectively the same as *charPtr, which is the same as c.

Upvotes: 3

Related Questions