-5

Here is the question: What is the output of the program?

#include<stdio.h>
int main()
{
int  A[2][10]={{1,2,3,4,5,6,7,8,9,10},{11,12,13,14,15,16,17,18,19,20}   };
int (*v)[10]=A;

printf("**v=%d\n",**v);
printf("**(v+1)=%d\n",**(v+1));
printf("*(*v+1)=%d\n",*(*v+1));
printf("*(v[0]+1)=%d\n",*(v[0]+1));
printf("*(v[1])=%d\n",*(v[1]));
}

Outputs:

**v=1
**(v+1)=11
*(*v+1)=2
*(v[0]+1)=2
*(v[1])=11

Especially, I'm not very clear about how did *v divide array A into 10 parts, and please tell me the reasons about each output. Thanks!

Mihai Maruseac
  • 20,967
  • 7
  • 57
  • 109
gfzhu
  • 23
  • 3

3 Answers3

8

There's a concept called array decay at work. Also, pass each definition through cdecl.

The second line is

declare v as pointer to array 10 of int

Thus it is a pointer to an array of 10 elements. This pointer is initialized with A -- the array it points to is the first row of A.

Then, v+1 is another pointer to an array of 10 elements, following the first one. Thus, it is the second row of A.

Community
  • 1
  • 1
Mihai Maruseac
  • 20,967
  • 7
  • 57
  • 109
3
  1. In the **v, *v will be replaced by value of v[0], which is an address, say X, therefore the outer * will be used to indicate the value of address X, which is 1.

  2. In the **(v+1), *(v+1) will become v[1], which is again an address, say Y, and the outer asterisk will give the value at address Y, which is 11.

  3. *(*v+1)=2 => *(v[0] + 1) => here pointer shifts to the next location, and this location is v[0][1], which is similar to *(*(v+0)+1). Value at v[0][1] is 2.

  4. *(v[0]+1)=2, same reason.

  5. *(v[1])=11, v[1] holds the base address of the second row, which is the starting address of second row's 0th column, and the value at that location is 11.

Mihai Maruseac
  • 20,967
  • 7
  • 57
  • 109
noNameYet
  • 635
  • 2
  • 10
  • 15
0

Okay, let's review first, how arrays decay and second, how declarations work.

A is declared as a 2D array. When A is used in any expression, it will "decay" to a pointer to its first element. In C, a 2D array is made up of two 1D arrays. So an element of a 2D array is a 1D array. So when A is used in any expression, it will decay to a pointer to the first row of A, which is an array of 10 ints.

int (*v) [10] means that v is a pointer to an array of 10 ints. The assignment

int (*v)[10] = A;

is an expression, so A there has decayed to a pointer to 10 ints as well, so the assignment is valid.

So now when you look at **v, you are dereferencing first, v, which means you are getting what v points at, which is the first row of your 2D array. Then you are dereferencing *v, which means you are getting the first element of that first row. That is 1, so your output is 1.

When you look at **(v + 1), you are first adding 1 to the pointer v. Since v points to a row, adding 1 gets you a pointer to the next row. Then you do the double dereferencing as above and you get the first element of the next row, which is 11.

When you look at *(*v + 1), you are first dereferencing v, which means you get the first row. Then you add 1 to that, which gets you a pointer to the next element of the row. Then you dereference that, which gets you the 2, the second element.

To summarize: v points to the whole first row. *v points to the first element of the first row. (v + 1) points to the whole second row. (*v + 1) points to the second element of the first row.

After this, figuring out the rest is probably quite easy.

verbose
  • 7,827
  • 1
  • 25
  • 40
  • Thank you very much, I think here assigning 10 elements to v makes me confused. In fact, int (*v)[2] is enough. – gfzhu Aug 05 '13 at 10:03
  • No, it won't be enough. `(*v)[2]` would be a pointer to an array of 2 ints. Each row in `A` is an array of 10 ints. You really need `(*v)[10]`. – verbose Aug 05 '13 at 10:05