Hey everyone (especially Narue!),

I've ventured over to the C++ board again. I've been reading my C++ book (Data Structures and Algorithms in C++) again and want to fully grasp the concept of pointers. In the back of each chapter, a couple of exercises are available and I'm attempting to do them.

For the very first question, it's simply asking to figure out which assignment would cause compilation errors but unfortunately I can't find the solutions in the back of the book or online. :(

Q: If i is an integer and p and q are pointers to integers, which of the following assignments cause a compilation error?

a. p = &i; No error as p is assigned the address of i
b. p = *&i; Error as p is assigned the contents at the address of i
c. p = &*i; Error as p is assigned the address of the value at i
d. i = *&*p; No error as i is assigned the contents of the address containing the contents of p
e. i = *&p; No error as i is assigned the contents at the address of p
f. i = &*p; Error as i is assigned the address of the contents at p
g. p = &*&i; No error as p is assigned the address of the contents held at the address of i
h. q = *&*p; Error as q is assigned the contents at the address holding the contents of p
i. q = **&p; Error as q is assigned the contents holding the contents at the address of p
j. q = *&p; Error as q is assigned the contents at the address of p
k. q = &*p; No error as q is assigned the address holding the contents of p

I realize I could just test this by writing some code, but when I tested this a year ago in a lab, I was able to compile with some of those that actually should have caused a compilation error (and thus earned less than 100% on the problem). More importantly, I want to know if I properly described the assignments that were taking place.

Hey everyone (especially Narue!),

I've ventured over to the C++ board again. I've been reading my C++ book (Data Structures and Algorithms in C++) again and want to fully grasp the concept of pointers. In the back of each chapter, a couple of exercises are available and I'm attempting to do them.

For the very first question, it's simply asking to figure out which assignment would cause compilation errors but unfortunately I can't find the solutions in the back of the book or online. :(

Q: If i is an integer and p and q are pointers to integers, which of the following assignments cause a compilation error?

a. p = &i; No error as p is assigned the address of i
b. p = *&i; Error as p is assigned the contents at the address of i
c. p = &*i; Error as p is assigned the address of the value at i
d. i = *&*p; No error as i is assigned the contents of the address containing the contents of p
e. i = *&p; No error as i is assigned the contents at the address of p
f. i = &*p; Error as i is assigned the address of the contents at p
g. p = &*&i; No error as p is assigned the address of the contents held at the address of i
h. q = *&*p; Error as q is assigned the contents at the address holding the contents of p
i. q = **&p; Error as q is assigned the contents holding the contents at the address of p
j. q = *&p; Error as q is assigned the contents at the address of p
k. q = &*p; No error as q is assigned the address holding the contents of p

I realize I could just test this by writing some code, but when I tested this a year ago in a lab, I was able to compile with some of those that actually should have caused a compilation error (and thus earned less than 100% on the problem). More importantly, I want to know if I properly described the assignments that were taking place.

<< c. p = &*i; Error as p is assigned the address of the value at i >>

On this one, what is wrong with assigning the address of a value to a pointer? I think the problem here is that you are using the de-reference operator on a value, which isn't applicable. Or is i supposed to be a pointer? If so, then there should be no error, as you are just getting the address of a value: &(*i).

#define NULL 0

int main()
{
    int i = 5;
    int* p = NULL;
    int* q = NULL;

    p = &i; //No error as p is assigned the address of i
    p = *&i; //Error as p is assigned the contents at the address of i
    p = &*i; //Error as p is assigned the address of the value at i
    i = *&*p; //No error as i is assigned the contents of the address containing the contents of p
    i = *&p; //No error as i is assigned the contents at the address of p
    i = &*p; //Error as i is assigned the address of the contents at p
    p = &*&i; //No error as p is assigned the address of the contents held at the address of i
    q = *&*p; //Error as q is assigned the contents at the address holding the contents of p
    q = **&p; //Error as q is assigned the contents holding the contents at the address of p
    q = *&p; //Error as q is assigned the contents at the address of p
    q = &*p; //No error as q is assigned the address holding the contents of p

    return 0;
}

// results
dani.cpp: In function `int main()':
dani.cpp:10: error: invalid conversion from `int' to `int*'
dani.cpp:11: error: invalid type argument of `unary *'
dani.cpp:13: error: invalid conversion from `int*' to `int'
dani.cpp:14: error: invalid conversion from `int*' to `int'
dani.cpp:16: error: invalid conversion from `int' to `int*'
dani.cpp:17: error: invalid conversion from `int' to `int*'


Not sure what you mean about not being able to compile and get the errors. See above.

Line 13 is an error.

For line 18, the comment is wrong. This isn't an error. See program below.

#include <iostream>
int main()
{
    int i = 5;
    int* p = &i;
    int* q;
    q = *&p;
    std::cout << i << '\t' << &i << std::endl;
    std::cout << *p << '\t' << p << std::endl;
    std::cout << *q << '\t' << q << std::endl;
    return 0;
}

// results
5 0x23ff74
5 0x23ff74
5 0x23ff74

Comments
Thanks a lot! floatingDivs

OK, so why is 13 an error and why is 18 not an error? I see the code and realize that pointers p and q point to the same location, but WHY? Is q not being assigned the CONTENT at the address of p? If so, wouldn't outputting (cout << p) print out 5? Then, *p would also be 5?

Let's say int i is allocated the address 1080. Then, pointer p is allocated the address 1084 and pointer q is allocated the address of 1088.

The value (contents) of p is set to 1080 (meaning it points to int i and dereferences the value 5). Is the address of pointer q not assigned the contents at the address of p?

val(address)[value]
-------------------
i(1080)[5]
p(1084)[1080]
q(1088)[5]

Or am I missing something?

Edited 4 Years Ago by floatingDivs: n/a

13 is an error because the levels of dereferencing are wrong.

Since i is an int and p is a pointer to an int, no matter what else you do, you have to have exactly one more * than &. Just count them first. Don't worry about the order of the * and the &. If a * in front a p turns a p into an int, then if you throw in a &, that puts it back to a pointer. The other side of the equation is i, which an int, so you have an int on one side and a pointer on the other. Hence error.

18 has a q and a p. They're both the same "level" of address (a pointer to an int). You have a & and a *, or in other words equal numbers of them. Hence no error. All of this is without even looking at the order of operations of which operator does what first, which frankly I can't remember what that is. The point is that I didn't have to on this one. cout << p should print out 0x1080 in your example. cout << *p would print out 5.


As far as q goes, address 0x1088 will contain 0x1080, just as address 0x1084 will contain 0x1080.

*q means take the value stored at 0x1080, which would be 5.
&q would be the address of q, which is 0x1088.
q would be 0x1080, which is what is stored at 0x1088.

So depending on whether you have it as *& or &*, you either go from 0x1080 to 5, then back to 0x1080, or you go from 0x1080 to 0x1088, then back to 0x1080. Either way you end up at 0x1080. *q would be 5, as is *p.


>> The value (contents) of p is set to 1080.

Yep.

>> meaning it points to int i

Yep.

>> and dereferences the value 5

This may or may not be anal-retentive as far as grammar goes, but it also may be the crux of the matter. You can't "dereference" a VALUE. You can "dereference" an ADDRESS TO a VALUE.

>> Is the address of pointer q not assigned the contents at the address of p?

More grammar clarification. The CONTENTS of 0x1088 will be assigned the CONTENTS of 0x1084. They will both contain 0x1080. The only address anywhere that will contain 5 is 0x1080. You can't "assign" an address.

Wanna have some fun? Look at #17, not #18, and add a typecast...

#include <iostream>
int main()
{
    int i = 5;
    int* p = &i;
    int* q;
    q = (int*) **&p; // line 17, not 18
    std::cout << i << '\t' << &i << std::endl;
    std::cout << *p << '\t' << p << std::endl;
    std::cout << q << std::endl;
    return 0;
}

Now when you print out q, you'll get 5! But don't even dream of trying to print out *q! Well, you should try and then find out what happens. But this program above is PRECISELY what you are describing in your chart. Note that there is one more * than &. You need the typecast to make it compile. You try not to do this stuff without a really good reason though.

13 is an error because the levels of dereferencing are wrong.

Since i is an int and p is a pointer to an int, no matter what else you do, you have to have exactly one more * than &. Just count them first. Don't worry about the order of the * and the &. If a * in front a p turns a p into an int, then if you throw in a &, that puts it back to a pointer. The other side of the equation is i, which an int, so you have an int on one side and a pointer on the other. Hence error.

18 has a q and a p. They're both the same "level" of address (a pointer to an int). You have a & and a *, or in other words equal numbers of them. Hence no error. All of this is without even looking at the order of operations of which operator does what first, which frankly I can't remember what that is. The point is that I didn't have to on this one. cout << p should print out 0x1080 in your example. cout << *p would print out 5.


As far as q goes, address 0x1088 will contain 0x1080, just as address 0x1084 will contain 0x1080.

*q means take the value stored at 0x1080, which would be 5.
&q would be the address of q, which is 0x1088.
q would be 0x1080, which is what is stored at 0x1088.

So depending on whether you have it as *& or &*, you either go from 0x1080 to 5, then back to 0x1080, or you go from 0x1080 to 0x1088, then back to 0x1080. Either way you end up at 0x1080. *q would be 5, as is *p.


>> The value (contents) of p is set to 1080.

Yep.

>> meaning it points to int i

Yep.

>> and dereferences the value 5

This may or may not be anal-retentive as far as grammar goes, but it also may be the crux of the matter. You can't "dereference" a VALUE. You can "dereference" an ADDRESS TO a VALUE.

>> Is the address of pointer q not assigned the contents at the address of p?

More grammar clarification. The CONTENTS of 0x1088 will be assigned the CONTENTS of 0x1084. They will both contain 0x1080. The only address anywhere that will contain 5 is 0x1080. You can't "assign" an address.

Wanna have some fun? Look at #17, not #18, and add a typecast...

#include <iostream>
int main()
{
    int i = 5;
    int* p = &i;
    int* q;
    q = (int*) **&p; // line 17, not 18
    std::cout << i << '\t' << &i << std::endl;
    std::cout << *p << '\t' << p << std::endl;
    std::cout << q << std::endl;
    return 0;
}

Now when you print out q, you'll get 5! But don't even dream of trying to print out *q! Well, you should try and then find out what happens. But this program above is PRECISELY what you are describing in your chart. Note that there is one more * than &. You need the typecast to make it compile. You try not to do this stuff without a really good reason though.

VernonDozier,

Thank you so much for the explanation above. I've "got it" now and have been messing around with pointers today as well as just trying to read and make sure I understand 100% what you've just said, which I think I do.

Thread = solved, +rep to you good sir!

Jeez, pointer confusion = totally gone.

This question has already been answered. Start a new discussion instead.