Question: ```
int array[10] = {1,2,3,4,5,6,7,8};
int *ptr = array;
std::cout<<*(ptr+ 2); => O/P = 3

int (*arr_ptr)[10] = &array;
std::cout<<*(*arr_ptr+2); => O/P = 3

```

Whats the difference between these 2. I know what they mean, but if they give same result why do we have 2 different notations?

Answer: 
The first case is the normal case: `ptr` is a pointer to the first element of the array `array`, and it is indexed (using `*(ptr+2)`, which is a synonym for `ptr[2]`) to access the third element of that array.

The second case is contrived: `arr_ptr` is a pointer to the (enitre) array `array`. It is first dereferenced (with `*arr_ptr`) to yield the array itself, which is then used as an argument to binary `+`, which causes it to get implicitly converted to a (nameless) pointer to its first element, which is then indexed in the same way `*(<nameless pointer>+2)` and gives the same result.

Making those implicit conversions explicit, you could write

```
int *ptr = &array[0];
std::cout<<*(ptr+ 2);

int (*arr_ptr)[10] = &array;
std::cout<<*( &(*arr_ptr)[0] + 2 );

```
They are not in fact the same to the compiler, and will result in different assembly language being generated.

Here is some good reference on the difference: <http://cplusplus.com/forum/articles/10/>