1

I'm currently studying C++. Not in school. Using books, tutorials and practice.

One thing that confuses me and I haven't been able to track down an answer is when to use the dereference operator (*) for pointers. For example, from C++ primer which I'm currently reading:

char *cp = get_string();
if (cp) /* ... */    // true if the pointer cp is not zero 

while (*cp) /*    ... */    // true if *cp is not the null character

I don't understand why in the if statement it is just cp without dereference operator and then in the while statement it uses the dereference operator. There is other examples like a mix of uses in a for loop but this is the latest example in the book that confuses me. Thanks in advance for your help.

Summary: when do you just use variable name of pointer without the dereference and when do you use it with dereference. And how to tell difference.

MKSnazzy
  • 71
  • 1
  • 1
  • 10
  • 4
    The answer is in your code comments .. – HazemGomaa Sep 30 '16 at 03:49
  • @HAG, I'm not in school, I'm trying to learn so I didn't understand fully what it meant, but thanks for downvoting a beginner because I didn't understand. I thought the purpose of posting here was if I needed help. It might have been easy for you to understand what those comments meant, but I'm sure when you first started out things were confusing too in some aspects. – MKSnazzy Sep 30 '16 at 04:23
  • I didn't downvote ! However, I do think that you can find an answer with simple online search .. there are tons of tutrial that can help you on what you asking for. That's probably why your question is downvoted ... – HazemGomaa Sep 30 '16 at 04:31
  • @HAG, well then I apologize. And I did google search. Tried for a while but couldn't find my specific ask. It was just questions about why use pointers and pointers over references. I don't know why I got downvoted for asking a question. – MKSnazzy Sep 30 '16 at 04:32
  • http://stackoverflow.com/questions/897366/how-do-pointer-to-pointers-work-in-c – HazemGomaa Sep 30 '16 at 04:33
  • http://www.cplusplus.com/doc/tutorial/pointers/ – HazemGomaa Sep 30 '16 at 04:34
  • http://stackoverflow.com/questions/4955198/what-does-dereferencing-a-pointer-mean – HazemGomaa Sep 30 '16 at 04:39
  • @HAG none answer my question. I knew what dereferencing was. What I didn't know was some of the cases where you didn't use that operator for different situations. Thanks though. – MKSnazzy Sep 30 '16 at 04:42

4 Answers4

2

A pointer is a variable whose value is the address of another variable or object. We say that the pointer "points to" that other object.

When writing an expression, cp means the pointer variable. *cp means the variable or object whose address the pointer variable holds.

Try to keep clear in your mind the distinction between "the pointer" and "the thing being pointed to". These are two distinct things, each with their own lifetimes and storage requirements.

So to address the code in your question, if (cp) is testing the pointer. It's short for if ( cp != nullptr ), i.e. has the pointer been set to point somewhere? (In other words, does the pointer currently hold the address of another object?)

if (*cp) means if (*cp != 0) , it is asking about the value of the object whose address is stored in the pointer (in other words, the value of the object being pointed to).

M.M
  • 138,810
  • 21
  • 208
  • 365
  • So without dereference is seeing if it is actually pointed to an object and dereference is comparing the actual value of that object? – MKSnazzy Sep 30 '16 at 03:55
  • @Matt That is correct. – gowrath Sep 30 '16 at 03:58
  • 1
    @Matt well it depends what you do with the expression afterwards. The thing to understand is that `cp` refers to the pointer, `*cp` refers to the pointed-to object. (Both of those things are "actual values"). You could then go on to compare those against something, or assign to them, or do addition, or anything else – M.M Sep 30 '16 at 04:00
  • @gowrath Thanks a bunch. I've been struggling. But let me ask you this. Why write `auto pbeg = ia.begin();` instead of with the * – MKSnazzy Sep 30 '16 at 04:01
  • 1
    @Matt where would you put a `*` in that line ? – M.M Sep 30 '16 at 04:04
  • @M.M -- I seen the code snippet in the book, and it was initializing a pointer without the dereference operator, which i thought you had to do when initializing a pointer for first time – MKSnazzy Sep 30 '16 at 04:07
  • A pointer does not have to be a variable. It can be an object of another storage class, too. – Amin Negm-Awad Sep 30 '16 at 04:08
  • @Matt `pbeg` is not a pointer. – user253751 Sep 30 '16 at 04:09
  • 1
    @Matt I guess you mean `auto *pbeg = ia.begin();` ? If so, then there is no dereference operator in that line. Operators only occur in expressions, but `*pbeg` is a declarator. Symbols have different meanings in declarators than in expressions. Try to consult your learning materials for its section on declarations. Also look up how [`auto` deduction](http://en.cppreference.com/w/cpp/language/auto) works as it is different to other types in a declaration. – M.M Sep 30 '16 at 04:10
  • @immibis he went on to dereference it. here is full code: `auto pbeg = v.begin(); while (pbeg != v.end() && *pbeg >= 0) cout << *pbeg++ << endl;` – MKSnazzy Sep 30 '16 at 04:13
  • @Matt `auto` can deduce to a pointer type, as explained by the page I linked in my previous comment. (Although that is not what's happening in this code). This is far afield from your original question though. The stackoverflow comments section isn't for tutoring. It is meant to be one question per thread. I would recommend consulting your learning materials and if you cannot find an answer to a question, then post a new question. – M.M Sep 30 '16 at 04:15
  • @M.M -- I thought it should be `*pbeg` but it's not. i ran the code both way and it only compiled and ran without the declarator. – MKSnazzy Sep 30 '16 at 04:15
  • `v.begin()` does not return a pointer, so `auto pbeg` does not deduce a pointer – M.M Sep 30 '16 at 04:16
  • @M.M -- I did not intend to get tutoring, it was related I thought because I was asking when to use *, and this was an example where that object went on to be dereferenced but was declared as a pointer – MKSnazzy Sep 30 '16 at 04:16
  • You asked about when to use the dereference operator on a pointer, not when to use `*` in an `auto` declaration, those are completely separate questions – M.M Sep 30 '16 at 04:17
  • @M.M -- OK, well if it's not a pointer and it went on to be dereferenced in the loop, then I missed something somewhere. – MKSnazzy Sep 30 '16 at 04:17
  • Look up "overloaded operators" – M.M Sep 30 '16 at 04:18
  • @M.M Thanks for your help. – MKSnazzy Sep 30 '16 at 04:19
2

The difference is simple but takes practice to get used to. Essentially, the dereference operator is used when you want to deal with what the pointer is actually pointing to (i.e the thing that is actually at the end of the pointer).

So for example, if I have a char *cp = get_string();, then cp is a pointer that is pointing to the first character in an array of characters.

Checking something like if(cp) is checking whether the pointer is 0 (i.e. if the pointer is pointing to NULL). This is probably useful in this context in that get_string() returns a pointer to a string if it is successful, or a NULL if something went wrong.

In contrast, doing something like while(*cp) is saying, while the character currently pointed to by cp is not 0 (the null character \0), then continue looping. In this context, your while loop probably looks something like:

while(*cp) {
    // process letter currently pointed to by cp
    cp++; // advance cp to point to the next character.
}

This is a common idiom to iterate through a character array.

gowrath
  • 3,136
  • 2
  • 17
  • 32
1

This image explains the concept. enter image description here

A pointer variable always stores the address of another variable. In case of arrays, it stores the address of the first element in the array.

The dereference operator refers to the value in the address stored by the particular pointer variable. In the above example, the address stored in the pointer variable ptr is 1001. *(ptr) should give the value stored in address location 1001 which is the content of the variable var ie, 50.

In summary, When you want to check if the pointer variable is pointing to some address location, you use the variable without dereference operator and when you want to deal with the value stored in the address location stored in the pointer variable, use it with the dereference operator

In your example, First it checks if the pointer points to a string by the statement

if(cp)

Then it is checking if the content of the variable it the pointer is non null (May be to check the end of the string)by the statement

while(*cp)
Christina Jacob
  • 665
  • 5
  • 17
0

I don't think writing these two tests like this is good practice. For clarity (and this is the very question you ask) they should be:

if(cp == nullptr) // or `cp == NULL`
    ...
if(*cp == '\0')
    ...
n.caillou
  • 1,263
  • 11
  • 15
  • I'm just learning not trying to make a program. I'm trying to lunderstabd the fundamentals. – MKSnazzy Sep 30 '16 at 03:56
  • It is convention to avoid the redundancy of `if(cp == NULL)`. It's like writing `if(condition == True)`; it is considered excessive. – gowrath Sep 30 '16 at 03:56
  • @Matt What I mean is, the first case check for the nullity of _the pointer_, and the second for the nullity of _the pointed character_. And if you do `*cp` with a null pointer you'll cause a segmentation fault, because it is not a valid memory address. – n.caillou Sep 30 '16 at 03:59
  • 1
    @gowarth I think it depends on context and personal style. For beginners or pieces of code where it may not be obvious what is tested, it is still good practice, IMO. – n.caillou Sep 30 '16 at 04:01
  • @gowrath Indeed, it is redundant. But he wrote *for clarity*. Making things explicit can clarify them. – Amin Negm-Awad Sep 30 '16 at 04:06
  • @AminNegm-Awad I agree it is a good pedagogical tool. My issue is only that he said he "doesn't think this is good practice". That is not just for clarity, it is a claim that this is better standard practice. – gowrath Sep 30 '16 at 04:16
  • @n.caillou I agree for beginners this is a good tool for clarity; thank you for providing it. I just wouldn't encourage saying it is good practice. It is a good first example to show what is happening and then they should try using what is actually standard practice. – gowrath Sep 30 '16 at 04:17
  • I'll concede that, in a project with lots of pointers you definitely wouldn't want to have NULL's all over the place. – n.caillou Sep 30 '16 at 04:26