Reputation: 6940
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
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
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
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