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: 
After editing your question, following are the differences:

```
(1) int *ptr = array;

```

`array` gets decayed to the pointer. `ptr` is ideally allowed to point to any `int[]` irrespective of its size

```
(2) int (*arr_ptr)[10] = &array;

```

`arr_ptr` is a pointer to an `int[10]`. It's very specific definition and you can never assign an array to `arr_ptr` which has size other than `10`.

```
int array_2[20];
arr_ptr = &array_2; // error

```
Use the notation that you understand and that fits the problem domain. If your app has an array, then use array notation. If you have to push pointers around for some other reason, then the second version is appropriate.