1
int s[4][2]={1,2,3,4,5,6,7,8};
printf("\n%u,%d",s+1,*(s+1));

Ans 2665496,2665496

In two dimensional array (s+1) gives the address of second row but why *(s+1) is not giving the value 3?

1
  • Didn't the compiler shout at you when you were trying to compile this? Commented May 22, 2013 at 20:38

4 Answers 4

6

As you say correctly s+1 is the address of the second row. So *(s+1) or more readable s[1] is a row, not a number. So it can't have "value 3".

Sign up to request clarification or add additional context in comments.

Comments

1

s has type int [4][2], i.e. it is an array of arrays.

Used in most expressions, it is implicitly converted to a pointer to its first argument, having type int (*)[2], i.e. pointer to array. So s+1 has type int (*)[2], pointer to array. This is the pointer to the second row (not an int, but an entire row).

*(s+1) is the dereference of that pointer to array. Hence, it has type int [2], i.e. an array of ints.

As with s above, by using it (an array) in most contexts (in this case as an argument to printf), it gets implicitly converted to a pointer to its first element, i.e. type int * a pointer to int. This is a pointer to the int that has value 3.

Since you are printing them pretending that they are integers, and both of them are pointers, they will both print addresses. The addresses will be the same, since the address of an array is the same as the address of its first element, even though the types of the pointers passed in were different.

You are kind of abusing the type system and passing in pointers of various types that are not compatible with the type you told printf. The reason this works is because C varargs are not type-checked.

5 Comments

so the above 2D array will create array of size 4 and puts the address (int (*)[2]) in each array element. Thus it creates a array of 4x2.So (s+1) will give the row address and *(s+1) will give the address of first element in that row.But both are same. Am i right? please help if my understanding is wrong
@user1762571: No, it's an array of size 4, and each element is an array. There are no pointers stored anywhere. s+1 gives the address of the second element of the array, which is a row (which is an array), and *(s+1) gives the row itself, i.e. an array.
Now i got it. s is the base address of the 2D array. By s+1 we are moving to the 2nd element of the array of size 4. Then *(s+1) gives the base address of second row. *(*(s+1)+0) gives the first element in second row. Please correct me for the last time.:)
@user1762571: s is not a "base address". The variable s is an array. When used in addition and most other places, it gets implicitly converted to a pointer to its first element, i.e. a pointer to the first row. So s+1 is a pointer to the second row. So *(s+1) (same as s[1]) is the second row (which is also an array). When used in most places, like passing it, this implicitly gets converted to a pointer to its first element, i.e. a pointer to the first element o the second row.
so (s+1) is of type int(*)[2] and *(s+1) is of type int[2].
0

Note that your array initialization results in a warning under gcc (got version 4.2.1):

main.c:3: warning: missing braces around initializer
main.c:3: warning: (near initialization for ‘s[0]’)

If you want to create an array of 2 rows / 4 columns, you've to do it this way:

int s[2][4] = {{1,2,3,4}, {5,6,7,8}};

You could then use printf as:

printf("%p,%d\n", s+1, **(s+1));

1 Comment

That warning is being moved from -Wall to -Wextra in newest versions of GCC. The warning is not very useful.
-1

Because s is effectively a pointer to a pointer, so if you dereference it, you get a pointer, not an int.

4 Comments

it is not a pointer to a pointer. it is a pointer to an array. try to print sizeof(*(s+1)).
I know that, hence "effectively", I was aiming for explanatory power over precision, here.
@PaulGriffiths Pointers and arrays aren't the same, not even inerchangeable.
As I said, I know that. The important thing is understanding why he's getting an address, and not the contents of one of his array elements. You can use pointers and arrays in similar enough ways that I think it's more helpful to explain it to someone who clearly lacks good knowledge of how the indirection is working to explain it in terms of pointers. I'm not saying that the distinction between arrays and pointers is not important, just that it obfuscates elucidation in this particular case, rather than aids it. The distinction adds nothing useful to the answer. You don't have to agree.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.