I am studying C++ and came across this Code
int a[] = {9,8,−5};
int∗ p = &a[2] ;
and was wondering what exactly that means? So a is an Array and p is a pointer. But what does the & before a[] mean?
and what does mean then?
std::cout << (p − a) << "\n";
edit:
so i have read some answeres but what i still dont understand is what the & is really for. Is there a difference between
int∗ p = &a[2] ;
and
int∗ p = a[2] ;
?
Thanks for your help.
This code
int∗ p = &a[2];
is equivalent to this:
int∗ p = a + 2;
so even mathematically you can see that p - a is equal to a + 2 - a so I think result should be obvious that it is equal to 2.
Note name of array can decay to a pointer to the first element but is not that pointer, as many may mistakenly say so. There is significant difference.
About your note, yes there is difference, first expression assigns address of third element to p, second is syntax error as you try to assign int to int * which are different types:
int a[] = { 1, 2, 3 };
int var = a[2]; // type of a[2] is int and value is 3
int *pointer = &a[2]; // type of &a[2] is int * and value is address of element that holds value 3
Subject of your question says that you think & means reference in this context. It only means reference when applied to types, when used in expression it means different things:
int i, j;
int &r = i; // refence when applied to types
&i; // address of in this context
i&j; // binary AND in this
In your case & is used to get the address to a value. So what will happen there is that p will contain the address of a[2], thus p will be a pointer to the third element of the array.
EDIT: Demo (with p-a included)
Related
i have 5 digits in 1 pointer
int* reversevec(int* ptr, unsigned int Ne){
int* ReverResult;
unsigned int rever=Ne, z;
ReverResult=(int*)malloc(Ne*sizeof(int));
for (int i = 0; i < Ne; ++i)
{
z=*(ptr+rever);
printf("%i ",z);//to be sure z starts from the last number on ptr to the fisrt
rever--;
}
return ReverResult;
}
example
Number of elements(Ne)=5
int* ptr have 5 numbers {1 2 3 4 5}
every time when z is printed i got {5 4 3 2 1}
but i cant save z into *ReverResult
ReverResult=(z+rever);
this line is what i tried to put into cicle for to save z and position into int pointer ReverResult but i cant convert int to int*;
There are many problems here
z is a local variable int.
its address will not be useful to return, because it will be out of scope.
returning an offset from its address is even worse, since that is a totally unrelated place in memory.
you also have an off-by-one error. imagine Number elements is one. You will then try to view ptr+1 instead of ptr+0.
you've also tagged this c++ but are writing c style code.
to answer your primary question, rather than writing ReverResult=(z+rever) one could write *(ReverResult + rever - 1) = *(ptr + i)
The other way round, you need to dereference your pointer to be able to assign. After all, you are easier off with pure pointer arithmetics:
int* result = malloc(sizeof(*ptr) * ne);
// let's just have to pointers running through the two arrays:
for(int* p = ptr + ne, *r = result; p-- != ptr; ++r)
{
*r = *p;
// ^ ^ this is the important part: dereference both pointers
}
If you still prefer indices you can use operator[]:
--ne; // so that we don't have to subtract within the loop again and again
for(size_t index = 0; index <= ne; ++index)
{
result[index] = ptr[ne - index];
// ^^^^^^^ again: dereferencing, this time with offset
}
array[index] is entirely equivalent to *(array + index) – and actually it, too, to index[array] (e. g. 7[array]), which is often used to fool the inexperienced...
#include <iostream>
using namespace std;
int main ()
{
int numbers[5];
int * p;
p = numbers; *p = 10;
p++; *p = 20;
p = &numbers[2]; *p = 30;
p = numbers + 3; *p = 40;
p = numbers; *(p+4) = 50;
for (int n=0; n<5; n++)
cout << numbers[n] << ", ";
return 0;
}
Fairly new coder here. This is an example taken from the pointers page on cplusplus.com. They talk about dereferencing, the address of operator, and then they talk about the relationship between arrays and pointers. I noticed if I simply printed out a declared array it spits out the address of the array. I'm really trying to understand exactly what some of these lines of code are doing and am having a hard time.
Everything makes sense up until *p=10. I read this as, "the value being pointed to by pointer p is equal to 10" but an array isn't just one value. In this case it's 5... So, whats the deal? Will the compiler just assume we are talking about the first element of the array?
Even more confusing for me is p++;. p right now is the address of the array. How do you do p=p+1 when p is an address?
I understand p= &numbers[2];. As well as the following *p = 30;.
p = numbers + 3; confuses me. Why are we able to take an address and just add 3 to it? And, what does that even mean?
Everything within the for loop makes sense. It's just printing out the array correct?
Thanks for your help in advance!
As Pointed out this due to pointer arithmetic.
So both array numbers and pointer p are int, so after assigning numbers's base address to pointer p and the *p=10 does numbers[0]=10
Now when you do p++ the address of p is incremented but not to the next numeric value as in normal arithmetic operation of ++ but to the address of the next index of numbers.
Let's assume a int is 4byte of memory and numbers's initial address is 1000.
So p++ makes address it to be incremented to 1004 which is numbers[1]
Basically it points to the next int variable position in memory.
So when *p = 20 is encountered the value 20 will be assigned to the next adjacent memory i.e. 1004 or numbers[1]=20.
After that the p directly assigned address of 3rd index numbers[2] i.e 1008 (next int var in memory). Now p is pointing to the 3rd index of numbers so *p=30 is again numbers[2]=30
p = numbers + 3; *p = 40; does similar thing that is assigns base address of numbers incremented by 3 indexes (1000 + 3*sizeof(int) =1012 ==> 1000 + 3*4 =1012) to p and assigns 40 to that. so it becomes equivalent to numbers[3]=40.
Then p = numbers; *(p+4) = 50; is assigning 1000 to p and the adding 4 to the address of p by using the () and assigns 50 to the value by using *() which is value of the address(1000+ 4*4 = 1016) inside the braces.
Using a pointer like this in C++: p = numbers makes p point to the first element of the array. So when you do p++ you are making p point to the second element.
Now, doing *p = 10 assigns 10 to whatever p is pointing to, as in your case p is pointing to the first element of the array, then *p = 10 is the same as numbers[0] = 10.
In case you see this later: *(p + i) = 20, this is pointer arithmetic and is the same as p[i] = 20. That's why p[0] = 10 is equivalent to *(p + 0) = 10 and equivalent to *p = 10.
And about your question: How do you do p=p+1 when p is an address?: as arrays in C++ are stored sequentially in memory, if the element p is pointing at memory address 6400010 then p++ points at 6400014 assuming each element pointed by p occupies 4 bytes. If you wonder why p++ is 6400014 instead of 6400011, the reason is a little magic C++ does: when increasing a pointer, it doesn't increase by 1 byte but by 1 element so if you are pointing to integers, each one occupying 4 bytes, then p will be increased by 4 instead of 1.
Let's break it down:
int numbers[5];
int * p;
Assigning the array variable to a pointer means that the pointer will be pointing to the first element:
p = numbers; // p points to the 1st element
*p = 10; // 1st element will be 10
p++; // go to next location i.e. 2nd element
*p = 20; // 2nd element will be 20
You can do pointer arithmetic and it works according to the type. Incrementing an int pointer on a 32-bit machine will do a jump of 4 bytes in memory. On a 64-bit machine, that will be 8 bytes. Keep in mind that you cannot do this with a void pointer.
p = &numbers[2]; // assign the address of 3rd element
*p = 30; // 3rd element will be 30
p = numbers + 3; // numbers + 3 means the address of 4th element
*p = 40; // 4th element will be 40
p = numbers; // p points to the 1st element
*(p + 4) = 50; // p + 4 means the address of 5th element
// dereference 5th location and assign 50
// 5th element will be 50
There are a lot of pages on the web on how pointers work. But there are a couple things to quickly point out.
int* p;
The above line mean p is a pointer to an int. Assigning something to it doesn't change what it is. It is a pointer to an int, not an array of int.
int number[5];
p = number;
This assignment takes the address where the array is stored, and assigns it to p. p now points to the beginning of that array.
p++;
p now points to the 2nd int in the array. Pointers are incremented by the size of the object they point to. So the actual address may increase by 4 or 8, but it goes to the next address of an int.
*p = 30;
This is an assignment, not a comparison. It doesn't say that what p points to is 30, it copies 30 into the address pointed to by p. Saying "equals" is generally confusing in programming terms, so use either "assign" or "compare" to be clear.
1> p=numbers;
pointer p now points to the start of the array, i.e first element.
2> *p=10;
first element now becomes 10, as p is pointing to the first element.
3> p++;
this moves the pointer to the next element of the array, i.e second element
So, again *p=20; will make second element=20
4> p = &numbers[2];
this statement means that p now points to 3rd element of the array.
So, *p = 30; will make 3rd element=30
5> p = numbers + 3;
Wen we do p=numbers+1; it points to second element, so p=numbers+3; will now point to 4th element of array. *p = 40; make the fourth element=40
6> p = numbers;
Again p points to first element of array
*(p+4) = 50; will now make 5th element=50
Why do you have to specify an index number when assigning a value to the first element in an array?
Let's say we had this array:
int childer[] = {10, 30, 50};
then both childer and childer[0] would be accessing the first element of the array, so why can't you dochilder = 15;?
Arrays are similar to pointers. For example an array decays to a pointer when passed to a function, or even when the operators [] and the unary * are applied to them (Thanks StoryTeller). So
childer[0]
is equivalent to
*childer
and you can do
*childer = 15;
to set the first element to 15.
childer
on the other hand is the same as
&childer[0]
childer[0] and childer have two different meanings. childer[0] is the first element of the array while childer is a pointer to the first element. In order to get the first element using the pointer, you have to use *childer.
so,
*childer = 15;
can be used for assignment.
you could dereference the name of the array, but just trying to do
childer = -999;
is completely wrong...
see the example below:
int main() {
int childer[] = { 10, 30, 50 };
cout << childer[0] << endl;
cout << *childer << endl;
//now write
childer[0] = 200;
cout << childer[0] << endl;
cout << *childer << endl;
//now write again
*childer = -999;
cout << childer[0] << endl;
cout << *childer << endl;
return 0;
}
First of all
int childer[] = { 10, 20, 30 };
...
childer = ....; <--- THIS WILL NOT COMPILE, as childer is not an lvalue.
you cannot say childer = 20;, you can say childer[0] = 20; or *childer = 20;, or even more *(childer + 1) = 20; (to access other elements than the first), but you cannot use childer as the whole array in an assignment. Simply, neither C nor C++ allow this.
Arrays and pointers are very different things. What confuses you, is that neither C, nor C++ have a way to reference the array as a whole, and the array identifier, by itself, means the address of the first element (and not a pointer but a reference). What I mean by a reference, and I don't use the word pointer for just now, is that a pointer normally refers to a variable of pointer type, and as a variable, can be modified (mainly because the array position cannot be changed at runtime). You cannot write something like array = something_else;, when array is an array. Array names cannot be used by themselves as lvalues, only as rvalues. This can be done with pointers, like
int childer[] = { 10, 20, 30, };
int *pointer = childer;
and then
pointer = some_other_place_to_point_to;
because pointer is a pointer and childer isn't.
The meaning that both languages attribute to the array name is just a pointer rvalue pointing to the address of the first element (and typed as the cell type, continue reading for an explanation on this). And this is not the same as the address of the array (both are different things, demonstrated below) as the first (the array name is a pointer to cell type, while the array address &childer is a pointer to the whole array type). This can be illustrated with the next program, which tries to show you the difference in sizes for the array element, the whole array, the array pointer and the cell pointer:
#include <stdio.h>
#include <sys/types.h>
#define D(x) __FILE__":%d:%s: " x, __LINE__, __func__
#define P(fmt, exp) do { \
printf(D(#exp " == " fmt "\n"), (exp)); \
} while(0)
#define TR(sent) \
sent; \
printf(D(#sent ";\n"))
int main()
{
int i = 1;
TR(double a[10]);
P("%p", a);
P("%p", &a);
P("%d", sizeof a);
P("%d", sizeof &a);
P("%d", sizeof *a);
P("%d", sizeof *&a);
return 0;
}
which executes into (I selected double as the type of cell to make evident the differences while trying to be more architecture independent):
$ pru
pru.c:16:main: double a[10]; <-- array of ten double's (a double is 8 bytes in many architectures)
pru.c:18:main: a == 0xbfbfe798 <-- address values are
pru.c:19:main: &a == 0xbfbfe798 <-- equal for both.
pru.c:20:main: sizeof a == 80 <-- size of whole array.
pru.c:21:main: sizeof &a == 4 <-- size of array address (that's a pointer to array)
pru.c:22:main: sizeof *a == 8 <-- size of pointed cell (first array element)
pru.c:23:main: sizeof *&a == 80 <-- size of pointed array.
But you are wrong when saying that you cannot use an expression to access the other elements, as you can, use array + 1 to mean the address of the second element, and array + n to access the address of the n + 1 element. Evidently array + 0 is the same as array (the 0 number is also neutral in pointer addition), so you can get on it easily. Some people like to write it for fun also as 0+array (to abuse of the commutativity of the + operator) and go further, to write something like 0[array], to refer to the first element of the array (this time the access being to the element, and not to its address) I don't know if this continues to be valid with the new standards, but I'm afraid it continues, perhaps, to allow for legacy code to be compilable (adding to the controversy of what should be conserved and what can be eliminated on standard revisions)
c++
p is pointing to specific place
int * p
When I try p=p[1] it says can't convert int to int (using devcpp).
While p=&p[1] works fine
Why do I need to do the second method?
p[1] is an address. So the first method should work?
Can you explain me about this error?
p[1] is the same as *(p + 1).
You want the address of this element, which is simply (p + 1). C++ also allows &p[1], as you noticed.
p[1] is equivalent to *(p + 1) so it's a value, not an address. p = p + 1 or just p++ would be what you want.
While p is anint*, p[1] is an element from that array, therefore p[1] is int.
You can do p = &p[1] in other ways, for instance, p = p + 1, or p++. Both will set p to the same final value.
Notice when doing such arithmetic operations with pointers, it will not not increment the address by 1, its incrementing it by 1 times the size of one element, so its really the same thing.
This was a question in our old C++ exam. This code is driving me crazy, could anyone explain what it does and - especially - why?
int arr[3]={10,20,30};
int *arrp = new int;
(*(arr+1)+=3)+=5;
(arrp=&arr[0])++;
std::cout<<*arrp;
This statement writes to the object *(arr+1) twice without an intervening sequence point so has undefined behavior.
(*(arr+1)+=3)+=5;
This statement writes to the object arrp twice without an intervening sequence point so has undefined behavior.
(arrp=&arr[0])++;
The code could result in anything happening.
Reference: ISO/IEC 14882:2003 5 [expr]/4: "Between the previous and next sequence point a scalar object shall have its stored value modified at most once by the evaluation of an expression."
(*(arr+1)+=3)+=5;
arr + 1 - element with index 1
*(arr + 1) - value of this element
(arr + 1) += 3 - increase by 3
((arr+1)+=3)+=5 - increase by 5;
so arr[1] == 28
(arrp=&arr[0])++;
arr[0] - value of element 0
&arr[0] - address of element 0
arrp=&arr[0] - setting arrp to point to elem 0
(arrp=&arr[0])++ - set arr to point to elem 1
result: 28
This line:
(*(arr+1)+=3)+=5;
produces the same result as this (see footnote):
arr[1] += 3;
arr[1] += 5;
This line:
(arrp=&arr[0])++;
produces the same result as this (see footnote):
int* arrp = arr+1;
So this line:
std::cout<<*arrp
prints out 28.
But this code leaks memory because int *arrp = new int; allocates a new int on the heap which will be lost on assignment by (arrp=&arr[0])++;
Footnote: Of course I'm assuming an absence of weirdness.
Edit: Apparently some of the lines in fact lead to undefined behavior, due to C++ Standard 5/4. So this really is a crappy exam question.
int arr[3]={10,20,30}; // obvious?
int *arrp = new int; // allocated memory for an int
(*(arr+1)+=3)+=5; // (1)
(arrp=&arr[0])++; // (2)
std::cout<<*arrp; // (3)
(1)
*(arr+1) is the same as arr[1], which means that *(arr+1)+=3 will increase arr[1] by 3, so arr[1] == 23 now.
(*(arr+1)+=3)+=5 means arr[1] is increased by another 5, so it will be 28 now.
(2)
arrp will pont to the address of the first element of arr (arr[0]). The pointer arrp will then be incremented, thus it will point to the second element after the entire statement is executed.
(3)
Prints what arrp points to: the second element of arr, meaning 28.
Well, remember that arrays can be interpreted as pointers
int arr[3]={10,20,30};
int *arrp = new int;
creates an array arr of three integers and an int pointer that gets assigned with a freshly allocated value.
Since assignment operators return a reference to the value that has been assigned in order to allow multi-assignment,
(*(arr+1)+=3)+=5;
is equivalent to
*(arr+1)+=3;
*(arr+1)+=5;
*(arr + 1) refers to the first element of the array arr, therefore arr[1] is effectively increased by eight.
(arrp=&arr[0])++; assigns the address of the first array element to arrp and afterward increments this pointer which now points to the second element (arr[1] again).
By dereferencing it in std::cout<<*arrp, you output arr[1] which now holds the value 20 + 3 + 5 = 28.
So the code prints 28 (and furthermore creates a memory-leak since the new int initially assigned to arrp never gets deleted)
I'll try to answer you by rewriting the code in a simpler way.
int arr[3]={10,20,30};
int *arrp = new int;
(*(arr+1)+=3)+=5;
(arrp=&arr[0])++;
std::cout<<*arrp;
=== equals ===
int arr[3]={10,20,30};//create array of 3 elements and assign them
int *arrp = new int;//create an integer pointer and allocate an int to it(useless)
//(*(arr+1)+=3)+=5;
arr[1] = arr[1] + 3;//arr[1] == arr+1 because it is incrementing the arr[0] pointer
arr[1] = arr[1] + 5;
//(arrp=&arr[0])++;
arrp = &arr[0];//point the integer pointer to the first element in arr[]
arrp++;//increment the array pointer, so this really is now pointing to arr[1]
std::cout<<*arrp;//just print out the value, which is arr[1]
I am assuming you understand pointers and basic c.