+ 5
Can you explain please ( i am confused in **q =p).
#include <iostream> using namespace std; int main() { int a[]={10,20,30,40,50}; int *p[]={a,a+1,a+2,a+3,a+4}; int **q=p; **q++; cout <<*a<<" "<<**p<<" "<<**q<<endl; q=p; ++**q; cout <<*a<<" "<<**p<<" "<<**q<<endl; return 0; }
5 Antworten
+ 2
**q is a double pointer (or pointer to pointer). p is an array of pointers. q = p means q is assigned the address of p[0].
To clarify:
a[0] is *p[0] and *q[0].
Note that *p[0] is always as same as *q[0] because q is assigned p. However a[0] might not as same as p or q. if *p[] = {a+1,a+2,a+3,a+4,a}, then:
a[0] is *p[4] and *q[4]
a[1] is *p[0] and *q[0]
+ 2
a" is an array of 5 integers. 'p' is an array of 5 pointers to integers initialized from the the addresses of the elements in the array "a". "q" is a pointer to a pointer to int. so int** q = p; means: "p" can be treated as a pointer to its first element (&p[0]) (array decay to pointer: an array name can be used in many situations as a constant pointer to its first element). so "p" is looked as a constant pointer to its first element *const and the type of "p" is array of pointers to int. so putting all together "p" is treated as int* *const p; p++;// error p is const. (*p)++; // ok increment the object in p not p itself. the const in p is top-level thus it is discarded when used as an initializer or in an assignment. so int** q = p; // is OK discarding the top-level const.
**q++; // here you have two operators: the de-reference operator * and the post-increment operator ++. The latter has precedence higher than the former so it is as if you wrote: **(q++);
+ 2
//so increment first the pointer q to pint to the second element in the array p then de-reference it. here de-referencing it without using its value has no meaning. and a good compiler will warn you about that: Warning: value computed is not used [-Wunused-value].
cout <<*a<<" "<<**p<<" "<<**q<<endl; // 10 10 20
because de-referencing an array name (here "a"0 yields the value in its first element. so *a is equivalent to cout << a[0]; or cout << *&a[0];
cout << **p;// 10 because as I've already said p is an array to pointers initialized from the addresses of the elements in the array "a". so *p yields the value in the first element in p which is the address of the first element in "a". **p; means de-referencing the pointer element in the arrays p of pointers which yields the value in the first element in a (10). it is as if you wrote: cout << *(&a[0]);
cout << **q; // 20
because in the previous statement you've incremented q to point to the second element in p which holds the address of the second
+ 1
element in p which holds the address of the second element in "a": &a[1]; so a[1] = 20; and **q = 20;
q = p; // putting back pointer q to point to the first element in array p.
++**q; // here there are two operators: the pre-increment operator ++ and the de-reference operator: They are of he same precedence level. so we apply Operator Associativity, they are Right-To-Left operators. so it is evaluated this way: ++(**q); // **q evaluates first
which yields de-referencing q which yields the value 10 (you've reset q to point to the address q points: q = p; in the previous statement). Then increment that value to 11 (10 + 1) so cout << a[0];// 11; and cout << **p;// 11; cout << **q; // 11
cout <<*a<<" "<<**p<<" "<<**q<<endl;
*a: 11
**p: 11
**q: 11