3

I was asked this question as a class exercise:

int A[] = {1,3,5,7,9,0,2,4,6};

printf("%d\n", *(A+A[1]-*A));

I couldn't figure it out on paper, so went ahead to compiling a simple program and tested it and found that printf("%d",*A) always gives me 1 for the output.

But I still do not understand why this is the case, hence it would be great if someone can explain this.

3
  • @abelenky: the result 1 is from printf("%d\n", *A), which is what you'd expect, I believe. The original code would produce 5, though. The question is misleading. Commented Jun 1, 2016 at 4:37
  • 1
    @abelenky: Steve0101 is right, printf("%d\n", *A) will always print 1 for the given array. Commented Jun 1, 2016 at 4:38
  • Yeah, I misread it, and thought he was getting 1 for the output of the bigger expression. Sorry. Still, link to IDEOne, as a great way to share MVCE code Commented Jun 1, 2016 at 12:05

4 Answers 4

7

A is treated like a pointer to the first element of array of integers. A[1] is the value of the first element of that array, which is 3 (indexes are 0-based) *A is the value to which A points, which if the zeroth element of array, so 1. So

A[1] - *A == 3 - 1 == 2

Now we have

*(A + 2)

That's where pointer arithmetic kicks in. Since A is a pointer to integer, A+2 points to the second (0-based) item in that array and *(A+2) gets its value. So answer is 5.

Also please note for future reference that pointer to an integer and array of integers are somewhat different things in C, but for the purposes of this discussion they are the same thing.

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

8 Comments

Though it is automatically converted to a pointer in this expression, A is an array, not a pointer.
@MikeCAT yeah, as usual it is very tempting to lie and say that arrays are pointers. They almost are (for the purposes of this situation).
"value of first element".. no, second.
+ and - are left-right associative; it is (A + A[1]) - *A, not A + (A[1] - *A). In this case it happens those are equivalent but in general that may not be so.
Pointers and arrays are different, for all purposes ... this answer is better off without that last paragraph.
|
4

Break it down into its constituent parts:

A by itself is the memory address of the array, which is also equivalent to &A[0], the memory address of the first element of the array.

A[1] is the value stored in the second element of the array, which is 3.

*A dereferences the memory address of the array, which is equivilent to A[0], the value stored in the first element of the array, which is 1.

So, do some substitutions:

  *(A+A[1]-*A)
= *(A+(A[1])-(A[0]))
= *(A+3-1)
= *(A+2)

The notation *(Array+index) is the same as the notation Array[index]. Under the hood, they both take the starting address of the array, increment it by the number of bytes of the array element type (in this case, int) multiplied by the index, and then dereference the resulting address. So *(A+2) is the same as A[2], which is 5.

Comments

2
  • Arrays used in expressions are automatically converted into pointers pointing at the first elements of the arrays except for some exceptions such as operands of sizeof or unary & operators.
  • E1[E2] is defined to be equivalent to *((E1) + (E2))
  • + and - operator used to pointers will move the pointer forward and backward.

In this case, *A is equivalent to *(A + 0), which is equivalent to A[0] and it will give you the first element of the array.

The expression *(A+A[1]-*A) will

  1. Get the pointer to the first element, which points at 1, via A
  2. Move the pointer to A[1] (3) elements ahead via +A[1], so the pointer now points at 7
  3. Move the pointer to *A (1) element before what is pointed via -*A, so the pointer now points at 5
  4. Dereference the pointer via the unary * operator, so the expression is evaluated to 5

3 Comments

I know what your are thinking, but I guess what is confusing is the "Move the pointer.." phrase. Due to operator precedence the values inside the (...) are evaluated where A[1] (+3) and -*A (-1) are added to pointer A before being dereferenced. So the pointer doesn't move, you effectively add 2 to it before dereference. Or, is there another pointer being moved?
@DavidC.Rankin "the pointer" here is a rvalue, "move the pointer" means "make the pointer point to a different location"
Yes, that's what I understood it to be, but the verbiage still caused a double.. then tripple take, and a bit of head scratching to try a suss out the meaning. As it the earlier comment, it was clear Mike had no problem with understanding, but the wording seemed at odds with the good solution he posted.
0

An array variable in C is only the pointer to the initial memory location for the array. So if you derreference the array, you will always get the value for the first position.

If you sum up 1 to the original array value, like *(A+1) you will get the second position.

You can get any position from the array using the same method:

*(A) is the first position

*(A+1) is the second position

*(A+2) is the third position

and so on...

If you declare the int array as int* A and allocate the memory and attribute the values, it is usually easier to visualize how this works.

1 Comment

Arrays are automatically converted into pointers for dereferencing, but arrays are NOT pointers!

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.