I am busy with pointers at the moment and specifically pointers pointing to different elements in an array when I increment.
When I incremented using ++ everything is fine, but when I incremented using +2 things turned out differently to what I expected.
Let me explain.
In the first instance I set p2 = p1++;. The result I got there was what I expected, ie. p2 gives the value 2 and p1 gives the value 3. This is obviously since the initial value of p1 is assigned to p2 and afterwards p1 is incremented by 1, giving a new value for p1. No problem with that.
However; in the second instance I setp2 = p1+2. The result I got was not what I expected. The result was p1 gives value of 2 and p2 gives value of 4. How can this be? Shouldn't, like in the first instance, the initial value of p1 have been assigned to p2 , and then afterwards p1 incremented by 2 and given a new value of 4?
Then I got thinking a bit. Maybe +2 and ++ have different characteristics. What I mean with this is that when using ++, in this case, the code is saying (in layman's terms): "Make p2 point to the same address as p1 did at the start, and then let p1 point to the address of the next element". But when using +2 the code is saying: "Go to the element two "blocks" down from p1 and let p2 point to the address of that specific element; BUT DON'T CHANGE THE ADDRESS p1 IS POINTING TO WHILE DOING SO!". And this is what I mean with "they show different characteristics". They don't act in the same manner.
Is my assumption correct?
Also, how do you increment by two(or three or four, etc.) in this instance whilst maintaining the same characteristics as the ++ operator?
Here are some links to sites I researched which dealt with increments. But none of them really address my problem properly. Nor do any other sites. Also, most of them suggest using something like a +=2 to increment by two, which is fine, but that also does not tackle my specific problem.
Link1
Link2 SO
Could you please explain in the simplest terms possible since I am still new to C++.
Instance One
#include <iostream>
int main()
{
int a[5] = {1,2,3,4,5};
int *p1, *p2;
p1 = &a[1];
p2 = p1++;
std::cout << "Value1: " << *p1 << "\n" << "Value2: " << *p2;
return 0;
}
Output result of instance one (What I expected)
Value1: 3
Value2: 2
Instance Two
#include <iostream>
int main()
{
int a[5] = {1,2,3,4,5};
int *p1, *p2;
p1 = &a[1];
p2 = p1+2;
std::cout << "Value1: " << *p1 << "\n" << "Value2: " << *p2;
return 0;
}
Output result of instance two (NOT what I expected)
Value1: 2
Value2: 4
p2 = p1+2; does not modify the value of p1. It just assigns the result of p1+2 to p2.
p2 = p1++; does modify the value of p1. It first assigns p1 to p2, then increments p1 by one.
The output is exactly what is expected. When you perform this assignment:
p2 = p1 + 2;
You just ask to assign the value p1 + 2 to p2, that's it. There is no reason for p1 being updated. You seem to confuse the + operator with the post-increment/pre-increment ++ operator.
A little reminder might help.
Related
I can't understand what happens after line *p1=10, what happens with *p2 variable, and in the end how does secondvalue variable gets 20.
#include <iostream>
using namespace std;
int main ()
{
int firstvalue = 5, secondvalue = 15;
int * p1, * p2;
p1 = &firstvalue;
p2 = &secondvalue;
*p1 = 10;
*p2 = *p1;
p1 = p2;
*p1 = 20;
cout << "firstvalue is " << firstvalue << '\n';
cout << "secondvalue is " << secondvalue << '\n';
return 0;
}
Output of command
firstvalue is 10
secondvalue is 20
I can't understand how the secondvalue variable gets a value of 20.
If we assigned *p2=*p1 mustn't secondvalue variable get 10?
Lets see this step by step:
int firstvalue = 5, secondvalue = 15;
This initializes two 4 byte integers.
---------------------------------------
| | |
| firstvalue (5) | secondvalue (15) |
| | |
---------------------------------------
Initializes int pointers and sets their values
int * p1, * p2;
p1 = &firstvalue;
p2 = &secondvalue;
p1 now stores the address of firstvalue, and p2 stores the address of secondvalue
---------------------------------------
| (*p1) | (*p2) |
| firstvalue (5) | secondvalue (15) |
| | |
---------------------------------------
p1 p2
Now you assign 10 to *p1. What this does is that it modifies the value at the memory address which was stored in p1:
*p1 = 10;
---------------------------------------
| (*p1) | (*p2) |
| firstvalue (10) | secondvalue (15) |
| ^^ | |
---------------------------------------
p1 p2
Now you assign *p1 to the memory address stored in p2. *p1 dereferences the pointer p1 and returns you the value it is pointing to.
*p2 = *p1;
---------------------------------------
| (*p1) | (*p2) |
| firstvalue (10) | secondvalue (10) |
| | ^^ |
---------------------------------------
p1 p2
Now you change the memory address p1 is pointing to. Now p1 and p2 points to the same variable
p1 = p2;
---------------------------------------
| | (*p1) (*p2) |
| firstvalue (10) | secondvalue (10) |
| | |
---------------------------------------
p1 p2
Finally, you modify the value at the memory address stored by p1, (that is also p2).
*p1 = 20;
---------------------------------------
| | (*p1) (*p2) |
| firstvalue (10) | secondvalue (20) |
| | ^^ |
---------------------------------------
p1 p2
p1 = p2;
This doesn't copy the value pointers point to, just "address" the p2 points to. Thus at this point both p1 and p2 point to the secondvalue, and changing either of them applies changes to the secondvalue
If we assigned *p2=*p1 mustn't secondvalue variable get 10?
It sure does. And if that was the last assignment, then that what would happen. But perhaps you've noticed that there are more assignments, that follow this one:
p1 = p2;
p1 is now pointing to the same value that p2 is pointing to. p2 is pointing to secondvalue, so p1 is now pointing to secondvalue, too.
*p1 = 20;
The value that p1 points to gets assigned 20. And that's how secondvalue gets assigned 20.
Yeah, but when you p1 = p2; you make so p1 now stores the reference to second value, and in the line below you assing *p1 (this is secondvalue) to 20.
So in your code flow firstvalue is assigned to 10 on *p1 = 10; and secondvalue is assigned to 20 on *p1 = 20;
So, pointers and references (and de-referencing, oh my!)
Alas, this is where vocabulary makes a difference, and people love this particular selection of vocabulary. So here it is, explained in all its glory.
Values
A value is something that exists somewhere in memory (like a variable, though not necessarily). To be useful, we programmers like to give values both a type and a name.
int x = 74;
double pi = 3.141592;
string name = "Hannah";
References
A direct reference is an alias, another name, if you will, for a value.
int x = 7; // type:int, name:x, value:7
int& z = x; // z = another name for x
z = 12; // x = 12;
Using aliases is something we do in normal life.
I call my father “Dad”.
Dad’s friends call him “Bill”.
My friends call him “Mr. Greer”.
Different names. Same person.
Now, some C++ purists will tell you these are just plain references. Well, yes... and no. Yes, as far as the C++ Language is concerned. No, as far as understanding things is concerned. Just remember that when talking to C++ people, the word “reference”, unless otherwise qualified with some adjective, always means direct reference, or alias.
Pointers
Before C++ introduced “references” as part of the language abstraction, we had indirect references — also called pointers.
It is indirect because a pointer is not itself a reference. But you can get a reference from a pointer’s value by dereferencing it using the * operator.
The term is a bit wonky (because it looks like you are “un”-referencing it), but the opposite is true: you are taking that indirect reference (the pointer value) and effectively converting it into an (unnamed) direct reference, an alias for the “pointed-to” (or “referenced”) value.
int x = 7;
int* px = &x; // type=(pointer to int) name=“px” value=(address of x)
*px = 12; // (direct reference to x) = 12
In other words px is a pointer with an indirect reference to — i.e. address of — x.
Thus when we dereference px with the * operator, we transform the expression into a direct reference to x — at which point we have access to read or modify x’s value just as if we had x in hand to begin with.
I suspect the term “dereference” came about because we are “un”-indirect referencing a pointer value to obtain a direct reference, but all the people who created the term are dead now and I don’t know of any place they felt the need to explain it.
WHAT YOU MEANT TO ASK
So, a dereferenced pointer is an alias for the target object. You want to know what happens if you don’t dereference the pointers, which would be:
“What happens if we assign an un-dereferenced pointer to another un-dereferenced pointer?”
... and un-dereferenced means not dereferenced, so you are basically asking:
What happens when we assign one pointer to another?
The answer at this point should not be a surprise: the same thing that happens whenever we assign any variable’s value to another.
int x = 7;
int* p1 = &x; // p1 now “points to” x
int* p2 = p1; // and now p2 also “points to” x
Remember, the value of a pointer is the address of another object in memory, and you can copy values around however you like.
*p2 = 42; // x = The Answer
Got this piece of code from an homework assignment. I should figure out, what the value of &y[0] == &x.a. Btw sorry for not formatting properly, I tried my best.
So my approach was; y[0] = 1, and &y[0] means the address of 1, which is 0 in the array?
x.a confused me the most. Does it mean element a of the struct x? So x.a == 1 ? And its address would also be 0? So the boolean would come out as true(1), because 0 == 0. But the solution says it's false, but why?
struct my_struct {
int a;
double b;
int c;
};
my_struct x = { 1, 2, 3 };
int y[] = { 1, 2, 3 };
I expected the output 1 but apparently it's 0, but why?
&y[0] means the address of 1, which is 0 in the array
Almost, but not quite. The addresses given to you by the address-of operator are absolute values, not ones relative to the "container". So &y[0] is effectively the same as y, and &x.a is effectively the same as &x.
y is a value that can be converted to a pointer to the first element. This must and will be distinct (numerically) from &x which occupies a different part of memory.
| x.a | <- &x points here
| x.b |
| x.c |
| y[0]| <- y points here
| y[1]|
[ y[2]|
All of the above skims over the fact that those pointers might have different types. This matters to the compiler when checking the correctness of your code, but is ultimately discarded afterwards, as all addresses effectively become numerical values.
This expression
&y[0] == &x.a
compares addresses (pointers) of two different objects. The first one belongs to the array y (that is y[0] is the first element of the array) while the second one belongs to an object of the type my_struct (a is a data member of the object x).
The objects occupy different extents of memory.
So the expression yields false that is the addresses of the different objects are not equal each other.
I can provide an example when comparing two different pointers (that is pointers of different types) yields true.
Consider the following example
struct my_struct {
int a;
double b;
int c;
};
my_struct x = { 1, 2, 3 };
then ( void * )&x == ( void * )&x.a evaluates to 1.
Note: the casting is required because the operands have different types and there is no implicit conversion from one type to another.
One more example
#include <iostream>
#include <iomanip>
int main()
{
int y[] = { 1, 2, 3 };
std::cout << std::boolalpha
<< ( ( ( void * )&y == ( void * )y ) && ( ( void * )&y == ( void * )&y[0] ) && ( y == &y[0] ) )
<<'\n';
}
The program output is
true
All three expressions &y, y, and &y[0] have the same value (address). (An array used in an expression with rare exceptions is converted to pointer to its first element.)
The address of two separate declared variables are almost never equal (==).
Here, my_struct x = { 1, 2, 3 }; is declared separately from int y[] = { 1, 2, 3 };. When they're declared, they're given their own space in memory to occupy, so they're in two different spaces in memory. Even though the values stored by struct my_struct x and array int y[] are the same, they're stored in their own memory spaces.
If you want to see the actual memory locations, you can do this with a simple cout print statement:
cout << "&y[0]: " << &y[0] << endl;
cout << "&x.a: " << &x.a << endl;
&y[0] and &x.a are different addresses. If you are trying to check if they are the same, you can write a simple programm. And you will see the result.
struct my_struct {
int a;
double b;
int c;
};
int main()
{
my_struct x = { 1, 2, 3 };
int y[] = { 1, 2, 3 };
std::cout << "&y[0] = " << &y[0] << "\n&x.a = " << &x.a << "\n&y[0]==&x.a = " << (&y[0]==&x.a);
}
The output is:
&y[0] = 0x72261501a440
&x.a = 0x72261501a450
&y[0]==&x.a = 0
So we can see different values of &y[0] and &x.a. They are not the same. and also &y[0]==&x.a = 0 and it means false
The & will return memory address (depending on your target platform that is usually 16 to 64 bit number, either representing physical memory address, or virtual logical address mapped to physical memory by OS (on modern OS like linux or MacOS, the user process doesn't see true physical addresses by default)).
So this part of source:
my_struct x = { 1, 2, 3 };
int y[] = { 1, 2, 3 };
will instantiate both the structure and array in the memory as global variables, i.e. they will have memory addresses like 0x12345678, etc... and they will not overlap, if size of my_struct is for example 20 bytes, and x address is 0x1000, the array y will be in memory somewhere beyond it (address of y is also address of first element, in C/C++ the arrays are zero-cost abstraction, i.e. where the array starts, there's the first element already stored, and the rest of elements follow on consecutive memory addresses).
So your original expression &y[0] == &x.a is comparing one (absolute) address of particular element of the array with (absolute) address of structure member, and because they are instantiated in different regions of memory, the addresses will surely differ (as long as the index into array is within bounds) = false. You don't even need to check details which addresses precisely are compared.
But for completeness, the y[0] is the first element of array y, and address of that is identical to y itself. If there would be &y[1], that's address of second array element, with type int that means the &y[1] is equal to y+1 and/or to ((void*)y) + sizeof(int) ... in CPU machine code terms, that means if array starts at memory at address 0x2000, and int is 64 bits on your target platform, the second element starts at address 0x2008 (+8 bytes (64 bits) away from the start of array).
The &x.a is similarly full address where the actual value of member a resides in memory, so if the structure instance x starts at address 0x1000, the address of x.a will be also 0x1000 in this case (again zero cost of abstraction and it's simple struct type, if it would be class-like, having virtual functions, the member a would be probably a bit offset after the implicit virtual table pointer which is usually put at beginning of class/struct instance ... but this is implementation/platform specific, i.e. depends how particular compiler implements virtual functions/calls). For example the address of &x.b would be then 0x1008 (again I assume 64 bit int type, and I assume there's no extra padding applied in the my_struct, with different assumptions/conditions the offset of b from start of structure may be different than +8).
& gives you the address of an object.
&y gives you the address of the array y.
&y[0] gives you the address of the first element in array y which is equal to &y.
&x gives you the address of the struct x
&x.a gives you the address of the first member of the struct x which is equal to &x.
Since x and y are at different locations the addresses differ.
I am new to C++. With the following minimal program:
#include <iostream>
int main()
{
int i, &ri =i;
i = 5; ri = 10;
std::cout << i << " " << ri << std::endl;
}
I observe the output to be
10 10
where I expected it to be
5 10
My line of reasonning is:
&ri refers to i, so the initial value of ri is equal to i (whatever that is).
Now, when I assign the value 5 to i, then the value of ri changes to 5.
Now, when I change the value of ri to 10, then the reference of ri to i is removed and it now occupies a unique space with the value 10 and is no longer linked to i.
Therefore, now when I std::cout << i and << ri, the result should display 5 10.
Instead it seems that i is referring to ri (I checked by changing the values that I assign to ri).
Can you please let me know what I am thinking incorrectly?
C++ is not java. You cannot reassign a reference.
ri = 10; does not create another integer for ri to bind to. It is actually changing the value of what ri is bound to, which is i.
As suggested in the comments, you really should go for a good C++ book.
r and ri simply are two names for the same thing. You first assign 5 to that thing and later 10. After that, of course that one thing is 10 and referring to it with any of the names will give you that common value.
Reference means that you are assigning a variable &i to have the same memory address as the variable you are setting it equal to -- i. Thus, changing something about the information at that address changes any variable that is looking at that address for it's value (i.e. a reference or pointer variable).
ri is a reference to i. References work like pointers. ri and i are the same memory. If you type
std::cout << &i << " " << &ri << std::endl;
both will be the same. Setting ri to 10 doesn't give it new memory but sets current.
I have been asked to describe what these lines of code are doing for a college assignment
int main() {
int t1[] = {0,0,1,1,1}, t2[] = {0,0,1,1,1};
int *p1 = t1, *p2 = t2;
while (!*p1++ || !*p2++);
cout << (p1-t1) << endl;
cout << (p2-t2) << endl;
}
My take on it is, 2 arrays of type int are created and filled with values, 2 pointers are created and pointed at each array, then I start to have trouble.
while (!*p1++ || !*p2++);
To me this is saying while 0 move the position of *p1one place or while 0 move the position of *p2 one place, I'm really not confident in that assumption?
cout << (p1-t1) << endl;
So then we move onto the cout, now my take on this is, I'm subtracting the position of p1 from the position of t1, where p1 was positioned by the while and t1 points to the first position in the array.
again I could be completely wrong I'm only learning about pointers so please bear this in mind if I'm wrong in my assumptions.
The while loop is actually quite horrid. I've never seen code like this in real life, and would declare any programmer doing it in real life as mad. We need to go through this step by step:
while (condition);
We have here a while statement with an empty statement (the ";" alone is an empty statement). The condition is evaluated, and if it is true, then the statement is executed (which does nothing because it is an empty statement) and we start all over again. In other words, the condition is evaluated repeatedly until it is false.
condition1 || condition2
This is an "or" statement. The first condition is evaluated. If it is true, then the second condition is not evaluated and the result is "true". If it is false, then the second condition is evaluated, and the result is "true" or "false" accordingly.
while (condition1 || condition2);
This evaluates the first condition. If it's true we start all over. If it is false, we evaluate the second condition. If that is true, we start all over. If both are false, we exit the loop. Note that the second condition is only evaluated if the first one is false. Now we look at the conditions:
!*p1++
!*p2++
This is the same as *(p1++) == 0 and *(p2++) == 0. Each condition increases p1 or p2 after it has been evaluated, no matter what the outcome. Each condition is true if *p1 or *p2 was zero and false otherwise. Now we check what happens at each iteration:
p1 = &t1 [0], p2 = &t2 [0]
*p1++ == 0 is true, *p2++ == 0 is never evaluated, p1 = &t1 [1], p2 = &t2 [0].
*p1++ == 0 is true, *p2++ == 0 is never evaluated, p1 = &t1 [2], p2 = &t2 [0].
*p1++ == 0 is false, *p2++ == 0 is true, p1 = &t1 [3], p2 = &t2 [1].
*p1++ == 0 is false, *p2++ == 0 is true, p1 = &t1 [4], p2 = &t2 [2].
*p1++ == 0 is false, *p2++ == 0 is false, p1 = &t1 [5], p2 = &t2 [3].
t1 is the same as &t1 [0]. p1 - t1 == &t1 [5] - &t1 [0] == 5.
t2 is the same as &t2 [0]. p2 - t2 == &t2 [3] - &t2 [0] == 3.
You are correct in you assessment of t1, t2, p1, and p2.
while (!*p1++ || !*p2++);
I don't like this coding style, as it is easy to assume the programmer placed the semi-colon there by mistake. To indicate that an empty body is truly intended, the empty body should be distinguished in some way (like with a comment, placed on a separate line, or use curly braces instead).
The while enters the body so long as the condition is true. Since this is a logical-or expression, both !*p1++ and !*p2++ must be false before the while loop terminates. This happens when both *p1++ and *p2++ become non-zero. Because logical-or short circuits (the second expression is not evaluated if the first one is true), the progression of the p1 and p2 take on the following at the start of each iteration:
iter p1 *p1 p2 *p2 condition
---- -- --- -- --- ---------
0 &t1[0] 0 &t2[0] 0 !*p1++ is true, !*p2++ not evaluated
1 &t1[1] 0 &t2[0] 0 !*p1++ is true, !*p2++ not evaluated
2 &t1[2] 1 &t2[0] 0 !*p1++ is false, !*p2++ is true
3 &t1[3] 1 &t2[1] 0 !*p1++ is false, !*p2++ is true
4 &t1[4] 1 &t2[2] 1 !*p1++ is false, !*p2++ is false
Since each iteration uses post-increment, p1 ends with the value &t1[5], and p2 ends with the value &t2[3].
Pointer subtraction within the same array measures the distance between the two pointers in terms of number of array elements. An array name used in most expressions will decay to the value equal to the pointer to its first element. So t1 decays to &t1[0], and t2 decays to &t2[0].
Thus:
p1 - t1 => 5
p2 - t2 => 3
The key thing to note here is how the expression (a || b) is evaluated. First, the expression a is evaluated. If a returns true, b is not evaluated since OR of anything with True is True. This is called short-circuiting.
It helps to augment the code in the following manner -
int main(void){
int t1[] = {0,0,1,1,1}, t2[] = {0,0,1,1,1};
int *p1 = t1, *p2 = t2;
cout << *p1 << " " << *p2 << endl;
cout << p1 << " " << p2 << endl;
while (!*p1++ || !*p2++) {
cout << *p1 << " " << *p2 << endl;
cout << p1 << " " << p2 << endl;
}
cout << (p1-t1) << endl;
cout << (p2-t2) << endl;
return 0;
}
Output:
0 0
0x7fff550709d0 0x7fff550709f0
0 0
0x7fff550709d4 0x7fff550709f0
1 0
0x7fff550709d8 0x7fff550709f0
1 0
0x7fff550709dc 0x7fff550709f4
1 1
0x7fff550709e0 0x7fff550709f8
5 // Final p1 - t1
3 // Final p2 - t2
!*p1++ is equivalent to (!(*(p1++)). This is the post-increment operator. It increments the pointer but returns the old value (before the increment).
The expression in the loop is evaluated 5 times.
In the first iteration, p1 is incremented. Since the current value of *p1 (before incrementing) is 0, a ! of 0 returns 1. Due to short-circuiting, the rest of the expression is not evaluated. Thus only p1 gets incremented.
Same thing happens in the next loop.
Now, we have p1 = t1 + 2 indices, and p2 = t2.
In the third iteration, current value of *p1 is no longer 0. Thus both p1 and p2 are incremented.
Same thing happens in the fourth iteration.
Note that in the first four iterations, either p1 or p2 points to a 0 - so the not of either the left side or the right side is True and hence the while loop continues.
In the fifth iteration, both p1 and p2 are incremented, but since neither points to a 0 value, the loop exits.
Thus p1 is incremented 5 times, and p2 is incremented 3 times.
Summarizing - p1 - t1 will contain 1 + the number of 0s appearing continuously in the beginning of t1 and t2 (2 + 2 + 1). p2 - t2 will evaluate to 1 + number of 0s appearing continuously in the beginning of t2 (2 + 1).
First:
while (!*p1++ || !*p2++);
That means while the contents of p1 is 0 keep looping adding 1 to p1 each time until it becomes non-zero. Thereafter while the contents of p2 is 0 keep looping adding 1 to both p1 and p2 each time. If at any time the content of p1 become 0 again the logic repeats (I know this is confusing).
Basically in a while(first || second) style test the second part is only tested if the first part fails. And the pointer gets incremented regardless if the test passes or fails.
Your assumption about (p1-t1) is correct. That calculation gives you the number of integers between t1 and p1 (because they are int pointers). Because t1 is the beginning of the array the calculation actually gives you the index (offset) into the array that p1 is pointing at.
NOTE #1: If p1 and t1 were char pointers then subtracting them would give you the number of characters between them. If they were float pointers then subtracting them would give you the number of floats etc... Pointer arithmetic adds and subtracts in units of the data type they are pointing to.
NOTE #2: Strictly speaking t1 is an array type. It collapses to a pointer when you use it in a pointer context. For example in pointer arithmetic or when you assign it to a pointer variable. If that confuses you, don't worry, mostly it just works as a pointer because the compiler makes the conversion automatically whenever it is implied by the context.
As far as question is what would this print on console , answer is 0 0 before you removes ; at the end of while loop.
What's the significance of this loop?
First you are using OR that means if either value pointed to by p1 or p2 is 0 block would be executed. So, till p1 points to 3rd element (p1-t1) will give you number of elements crossed in t1 while (p2-t2) will be 0 as (p1-t1) will return true so second condition will not be checked. When p1 points to 1 then it will start incrementing p2 till it points to 3rd element of t2 and there's the end.
This is all this assignment has for you I believe.
This relation can help you better understand the conditions within the while loop:
arr[ i ] == * ( arr + i )
When doing pointer subtraction (if pointers are of the same type), the result is the distance (in array elements) between the two elements.
Assume that p1 and p2 are both pointers of type T*. Then, the value computed is:
( p2 - p1 ) == ( addr( p2 ) - addr( p1 ) ) / sizeof( T )
Edit: This question should be considered abandoned. I have flagged this question for deletion as i do not know how to even proceed any more at this point. I thank all of you for your willingness and taking the time out of your day to help me.
I am reading and following the documentation at cplusplus on data structures. I have been trying to figure out why the compiler will not accept " *pfruit.weight; " on my own for hours. It am sure it is something simple that i am missing.
error C2228: left of '.weight' must have class/struct/union
1> type is 'product *'
1> did you intend to use '->' instead?
"The operand to the left of the period (.) is not a class, structure, or union."
So how do i correctly access the value pointed by a pointer member?(Not access a reference)
#include <iostream>
using namespace std;
struct product
{
int weight;
float price;
} ;
int main ()
{
product afruit;
product * pfruit;
pfruit = &afruit;
pfruit->weight;
//Access a member of an object to which we have a reference
//equivalent to: (*pfruit).weight
*pfruit.weight; //<------ I am so sorry, i meant This is the problem, i am using a reworded line of code from an example and it isn't compiling and returning the error.
//Access the value pointed by a pointer member called weight;
//equivalent to: *(pfruit.weight)
system("pause");
return 0;
}
This code
struct product
{
int weight;
float price;
} ;
int main ()
{
product * pfruit;
*pfruit.weight;
is an operator precedence error. The rules of C++ are that . has higher precedence than *. *pfruit.weight would be correct if pfruit was a struct and weight was a pointer, but in your code it's the other way around, pfruit is the pointer and weight is just an int. So you need to add brackets to apply the operators the right way around
(*pfruit).weight;
You may use the following statement :
(*pfruit).weight;
Instead of :
*pfruit.weight;
which evaluates at compile-time to the following because of operator precedence :
*(pfruit.weight)
This is wrong because you are dereferencing a non-pointer value and trying
to dereference a pointer with the . operator instead of ->.
EDIT :
Here's some piece of response and informations about pointers and to your question as I understood it.
#include <iostream>
using namespace std;
struct product
{
int *weight;
float price;
};
int main()
{
product afruit;
product *pfruit;
pfruit = &afruit;
// Allocating 10 * sizeof(int) bytes of memory. ptr will now point to the first sizeof(int) bytes
// of the memory pointed by the weight pointer.
pfruit->weight = new int[10];
// The first sizeof(int) bytes of the memory pointed by ptr (equivalent to *ptr) equals now the value 4.
pfruit->weight[0] = 4;
// The second sizeof(int) bytes of memory pointed by ptr (or (*ptr + 1)) equals now 42.
pfruit->weight[1] = 42;
// Dereferencing pfruit AND the pointer to the weight, thus returning the VALUE of the first sizeof(int) bytes of weight (4)
// instead of the value of the pointer to weight (0x8b4e008 for instance).
int value = *(pfruit->weight);
std::cout << "Value of pfruit->weight[0] = " << pfruit->weight[0] << std::endl
<< "Value of pfruit->weight[1] = " << pfruit->weight[1] << std::endl
<< "Value of *(pfruit->weight) = " << *(pfruit->weight) << std::endl
<< "Value of *(pfruit->weight + 1) = " << *(pfruit->weight + 1) << std::endl
<< "Value of ptr = " << std::hex << pfruit->weight << std::endl;
// Prints :
// Value of pfruit->weight[0] = 4
// Value of pfruit->weight[1] = 42
// Value of *(pfruit->weight) = 4
// Value of *(pfruit->weight + 1) = 42
// Value of ptr = 0x8b4e008
//
// Note that ptr[0] == *ptr and ptr[1] == (*ptr + 1)
return (0);
}
once try this u may get it this can be written as pfruit->weight or (*pfruit).weight
(*pfruit).weight;
product afruit;
product * pfruit;
pfruit = &afruit;
pfruit->weight;
pfruit is a pointer and has the address of the struct afruit.
We use pfruit->weight when we access struct members using a pointer .
When you use a struct name you use . operator.
Now, pfruit is the pointer . Therefore, the struct itself is *pfruit
*pfruit.weight;
This is interpreted as *(pfruit.weight), because .has higher precedence than *. and you can't use . operator with a pointer on LHS
You have to clearly show that you mean (*pfruit).weight
Bit late to the party, but try this:
It sounds like you are expecting values like 'int weight' to be stored as pointers to data somewhere else in the same way that the product is being referred to via pfruit. Some languages do do this, but in C++ simple data members like your weight and price are going to be stored actually in the product data structure. So, if afruit happens to exist at address 1000 in memory, then pfruit will have the value 1000:
... 1000 1001 1002 1003 ...
--+-----+-----+-----+-----+--
| afruit... | | |
--+-----+-----+-----+-----+--
^
|
pfruit = 1000
This means that your weight (int) and price (float) data members will be stored here, one after the other. (and since an int and float are typically 32 bits in size, i.e. 4 bytes, the memory looks like this:
... 1000 1001 1002 1003 1004 1005 1006 1007 ...
--+-----+-----+-----+-----+-----+-----+-----+-----+--
| afruit... |
| <------ weight -----> | <------ price ------> |
--+-----+-----+-----+-----+-----+-----+-----+-----+--
^
|
pfruit = 1000
Consequently, pfruit also happens to point at the weight data (because it's first in the structure), but the price data is 4 bytes further along.
So, when you say you want to get to the data 'pointed to by weight' it doesn't make sense because it actually turns out that you don't need to because when you access the weight member you are already referring to the weight value. It's right there, in the memory occupied by afruit.
If you ARE trying to get a pointer TO the weight (or cost) data itself (instead of afruit, or actually from pfruit) you can do something like this:
int* pweight = &afruit.weight; //from an actual product object
float* pcost = &pfruit->cost; //via a pointer to a product object
There are now various ways to access the members of the product structure afruit:
afruit.weight = 20; //directly access the structure member
pfruit->weight = 10; //follow the structure pointer
*pweight = 15; //derefernce the int pointer
I hope this helps someone, at least a little bit.
Sam