Problems with 2 D Arrays

I wrote the following code in C:

#include<stdio.h> int main() { int a[10][10]={1}; //------------------------ printf("%d\n",&a); printf("%d\n",a); printf("%d\n",*a); //------------------------- printf("%d",**a); return 0; } 

With the above 3 printf outputs, I got the same value. On my machine it is 2686384. But with the last statement, I got 1.

Is that not so? These expressions mean:

  • Address a - 2686384
  • The value stored in a is 2686384
  • the value that is stored at the address of the variable indicated by the symbol a (i.e. at 2686384) is 2686384.

This means that a should be something like a variable pointing to itself ...

Then why the conclusion *(*a) 1? Why is it not evaluated as *(*a)=*(2686384)=2686384 ?

+4
source share
7 answers
 #include<stdio.h> int main() { // a[row][col] int a[2][2]={ {9, 2}, {3, 4} }; // in C, multidimensional arrays are really one dimensional, but // syntax alows us to access it as a two dimensional (like here). //------------------------ printf("&a = %d\n",&a); printf("a = %d\n",a); printf("*a = %d\n",*a); //------------------------- // Thing to have in mind here, that may be confusing is: // since we can access array values through 2 dimensions, // we need 2 stars(asterisk), right? Right. // So as a consistency in this aproach, // even if we are asking for first value, // we have to use 2 dimensional (we have a 2D array) // access syntax - 2 stars. printf("**a = %d\n", **a ); // this says a[0][0] or *(*(a+0)+0) printf("**(a+1) = %d\n", **(a+1) ); // a[1][0] or *(*(a+1)+0) printf("*(*(a+1)+1) = %d\n", *(*(a+1)+1) ); // a[1][1] or *(*(a+1)+1) // a[1] gives us the value on that position, // since that value is pointer, &a[i] returns a pointer value printf("&a[1] = %d\n", &a[1]); // When we add int to a pointer (eg. a+1), // really we are adding the lenth of a type // to which pointer is directing - here we go to the next element in an array. // In C, you can manipulate array variables practically like pointers. // Example: littleFunction(int [] arr) accepts pointers to int, and it works vice versa, // littleFunction(int* arr) accepts array of int. int b = 8; printf("b = %d\n", *&b); return 0; } 
+2
source

An expression consisting of the name of the array can decay to a pointer to the first element of the array. So even if a is of type int[10][10] , it can fade out to int(*)[10] .

Now this decay occurs in the expression *a . Therefore, the expression is of type int[10] . Repeating the same logic, this again splits into int* , and therefore **a is int , which, in addition, is the first element of the first element of the array a , i.e. 1 .

The other three print statements print out the address of the array, the first element of the array, and the first element of the first element of the array (which, of course, has the same address, only different types).

+1
source

First, the word on arrays ...

_Alignof it is the operand of 0 sizeof , _Alignof or unary & operators, or is a string literal used to initialize another array in the declaration, an expression of type "N-element array" from T "will be converted (" decay ") to expression type "pointer to T ", and the value of the expression will be the address of the first element in the array.

The &a expression is of type "pointer to a 10-element array from a 10-element array int " or int (*)[10][10] . The expression a is of the type "10-element array of a 10-element int array", which, according to the rule above, splits into a "pointer to a 10-element array int " or int (*)[10] . And finally, the expression *a (equivalent to a[0] ) has the type "10-element int array", which again, according to the rule above, splits into a "pointer to int ".

All three expressions have the same value, because the address of the array and the address of its first element are the same: &a[0][0] == a[0] == *a == a == &a , However, the types of expressions are different, which matters when doing pointer arithmetic. For example, if I have the following declarations:

 int (*ap0)[10][10] = &a; int (*ap1)[10] = a; int *ip = *a; 

then ap0++ will advance ap0 to point to the next 10x10 int array, ap1++ will advance ap1 to a pointer to the next array of 10 int elements (or a[1] ), and ip++ will advance ip to point to the next int ( &a[0][1] ).

**a equivalent to *a[0] , which is equivalent to a[0][0] . which is the value of the first element a and has type int and value 1 (note that only a[0][0] initialized to 1 , all other elements are initialized to 0 ).

Note that you must use %p to print pointer values:

 printf("&a = %p\n", &a); printf(" a = %p\n", a); printf("*a = %p\n", *a); 
+1
source

First of all, if you want to print pointer values, use %p - if you are on an 64-bit machine int almost certainly less than a pointer.

**a is the double dereferencing of what is int** efficient, so you get what the first element of the first submatrix is: 1.

0
source

If you define a as T a[10] (where T is some typedef), then a simple undecorated a means the address of the beginning of the array, the same as &a[0] . They both have type T* .

&a also the address of the beginning of the array, but it is of type T** .

Things get more complicated with multidimensional arrays. To see what happens, it's easier to break things into smaller pieces using typedefs. So, you have effectively written

 typedef int array10[10]; array10 a[10]; 

[Reader Exercise: What is Type a ? (this is not int** )]

**a correctly evaluates the first int in array a .

0
source

From C99 Std

Consider the array object defined by the declaration

 int x[3][5]; 

Here x is an array 3 × 5 from int; more precisely, x is an array of three element elements, each of which is an array of five integers. In the expression x [i], which is equivalent to (* ((x) + (i))), x is first converted to a pointer to an initial array of five ints . Then I am configured in accordance with the type x, which conceptually entails multiplying I by the size of the object pointed to by the pointer, namely an array of five int objects. Results are added and indirection is applied to get an array of five integers. When used in the expression x [i] [j], this array, in turn, is converted to a pointer to the first of int, so x [i] [j] gives int.

So,

The initial array will be only x [0] [0].

all x, & x and * x will point to x [0] [0].

0
source

No, there is nothing wrong with the code. Just the way you think about it ... The more I think about it, the more difficult it is for me to understand this explanation, so before I get into this, consider these points:

  • arrays are not pointers ; don't think of them that way; they are different.
  • [] is the operator. This is a shift and alert operator, so when I write printf("%d",array[3]); I move and put off

Thus, the array (allowing you to think about 1 dimension to start with) is somewhere in memory:

 int arr[10] = {1}; //Some where in memory---> 0x80001f23 [1][1][1][1][1][1][1][1][1][1] 

So, if I say:

 *arr; //this gives the value 1 

Why? because it is the same as arr[0] , it gives us the value at the address, which is the beginning of the array. It means that:

 arr; // this is the address of the start of the array 

So what does this give us?

 &arr; //this will give us the address of the array. //which IS the address of the start of the array //this is where arrays and pointers really show some difference 

So arr == &arr; . The "job" of the array is to store data; the array will not "point" to anything else, because it contains its own data. Period. The pointer, on the other hand, has the task of pointing to something else:

 int *z; //the pointer holds the address of someone else values z = arr; //the pointer holds the address of the array z != &z; //the pointer address is a unique value telling us where the pointer resides //the pointer value is the address of the array 

EDIT: Another way to think about this:

 int b; //this is integer type &b; //this is the address of the int b, right? int c[]; //this is the array of ints &c; //this would be the address of the array, right? 

So this is pretty clear how about this:

 *c; //that the first element in the array 

What does this line of code tell you? if I feel c , I get int. This means that plain c is the address. Since this is the beginning of the array, this is the address of the array, thus:

 c == &c; 
0
source

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


All Articles