Two-dimensional array pointer manipulation in C ++

int main(){ int a[10][10]; int **ptr =(int **)a; cout<<a<<endl<<ptr<<endl; cout<<*a<<endl<<*ptr<<endl; return 0; } 

The output of this code on my computer

 0021FC20 0021FC20 0021FC20 CCCCCCCC 

Why is " a " equal to " * a "? why is not * equal to * ptr?

+4
source share
5 answers

Why is * a equal?

Since you cannot print an array, a implicitly converts from int[10][10] to int(*)[10] . What is actually printed instead of a is a pointer to the first line a .

*a - the first line of the array, which, in turn, is converted to a pointer to the first element .

Since the array has the same address as its first element, you get the same value twice.

+2
source

Why is a equal to *a ?

When used in a context that requires a pointer, the array will be converted to a pointer to its first element. a is an array of arrays; therefore, it will decay to a pointer to the first array. *a is the first array and will decompose into a pointer to the first integer in this array. Both of them exist in the same place, so the two pointers will have the same value.

why is not * equal to * ptr?

Since conversion from an array of arrays to a pointer to a pointer is not valid. You forced the conversion with cast - a dangerous C-style that in this case acts like reinterpret_cast - therefore *ptr will read the first few bytes of the array and interpret it as a pointer (perhaps the behavior here is undefined, so anything can happen in principle). There is no pointer to ptr in memory, so *ptr , of course, will not give you a valid pointer.

+4
source

Then I would suggest avoiding the static distribution of the stack of large matrices, instead choose dynamic allocation (on the heap) ...

+1
source

Warning. All the examples below should be correct, but not executed through the compiler to check for syntax errors.

The mechanisms of 2D arrays are actually simpler than they appear for the first time, but, as a rule, poorly understood. However, quick decryption of things requires a lot of experience, and even experienced developers sometimes have to stop and think for a moment (or two). Basically, when you see a 2D array, such as int a [5] [10] (I can resize your array to 5 to simplify it), you need to stop thinking of it as 2D. Think of it as 1D. The first index indicates the number of elements in this 1D array, like any other 1D array. When you index an array, for example [3], you get access to the object at index 3. This is no different from any other array. Suppose that a was specified instead:
 // Note: The size of the array, 5, can be omitted int a[5] = {5, 10, 15, 20, 25}; 

The subtask then gives the following:

 a[0] = 5 a[1] = 10 a[2] = 15 a[3] = 20 a[4] = 25 

It is easy and affordable. But if you do it now:

 // Note: Like above, the size of the array, 5, can be omitted int a[5][10] = {{ 5, 10, 15, 20, 25, 30, 35, 40, 45, 50}, { 55, 60, 65, 70, 75, 80, 85, 90, 95, 100}, {105, 110, 115, 120, 125, 130, 135, 140, 145, 150}, {155, 160, 165, 170, 175, 180, 185, 190, 195, 200}, {205, 210, 220, 225, 230, 235, 240, 245, 250, 255}}; 

You still have a 1D array, and you can index it in the same way as in the previous example, which gives the following (not real syntax, as you should think about it):

 a[0] = 5 10 15 20 25 30 35 40 45 50 a[1] = 55 60 65 70 75 80 85 90 95 100 a[2] = 105 110 115 120 125 130 135 140 145 150 a[3] = 155 160 165 170 175 180 185 190 195 200 a[4] = 205 210 220 225 230 235 240 245 250 255 

The only difference here is that instead of every element that is "int", as in the previous example, each element is an array instead (of 10 integers). Therefore, when you index it, as shown, each index (from 0 to 4) returns an array of 10 integers for this row. For example, [3] returns an array of 10 integers containing values ​​from 155 to 200. The element itself is "int [10]" and therefore you can relate to it this way. IOW, you return the equivalent of this:

 int b[10] = {155, 160, 165, 170, 175, 180, 185, 190, 195, 200}; 

And so, for example, the same as b [7] = 190, a [3] [7] = 190, since a [3] effectively returns the equivalent of b (an array of 10 integers), and the index [7] then captures an element at index 7 of this array, as does b [7]. Moreover, just as b is a pointer to the first element of the array (since all array names decay to a pointer to the first element of the array), which in this case is 155, [3] also does the same. What for? Since it returns the equivalent of b as described, and just like b, it splits into a pointer to its first element. IOW, how true this is:

 int *p = b; // "b" decays into a pointer to its first element (an "int") int val = *p; // Equals 155 

This is also true:

 int *p = a[3]; // a[3] returns the equivalent of "b", an int[10], and this decays into a pointer to its first element, just like "b" int val = *p; // Equals 155 

And finally, as FredOverflow mentioned, this is also true:

 int (*p)[10] = a; 

The syntax is addictive, but it makes sense. Since each array name decays to a pointer to its first element, as discussed, "a" therefore decays to a pointer to its first element. What is this element? Well, each element of "a" is an array of 10 integers, i.e. "Int [10]", so "a" must break into a pointer to the first of these "int [10]" elements. The syntax just above is how you declare this pointer. It defines p as a pointer to an array of 10 integers. (Pie) brackets are required due to C ++ priority rules. If you delete them, you will receive the following:

 int *p[10] = a; // Compiler error! 

Which declares p as an array of 10 elements, where each element is a pointer to an int. This is not the same IOW, so brackets are needed to change the priority (and therefore the value of this declaration). Using the correct syntax previously shown, "p" therefore points to the first element (an "int [10]" array containing elements 5 through 50), p + 1 points to a second element (an "int [10]" array containing elements from 55 to 100), etc. Bonus points: to do the following:

 (*(p + 3))[5] 

It returns 180, because (p + 3) returns a pointer to an array of 10 integers in "a [3]", and when dereferencing with the * operator, you get the actual array "int [10]" at that place, then the index [5] gives a value of 180 in this array.

No doubt it will still take a lot of practice to ponder this, but I hope this helps.

+1
source

A 2D array is not a pointer to a pointer. IT is effectively a pointer with rows * column elements.

 int main(){ int a[10][10]; int *ptr =(int *)a; cout<<a<<endl<<ptr<<endl; cout<<*a<<endl<<*ptr<<endl; return 0; } 

The above will give you what you need.

Although when de-linking a or ptr, you will find that you get the value undefined

if you set [4] [4] to say 5

Then you will find the value stored in

ptr [(line * 10) + column) will return this value, where row = 4 and column = 4.

0
source

Source: https://habr.com/ru/post/1399994/


All Articles