This post is more of a type of confirmation post rather than a particular question.
I read up some answers on this site and other places to clear up my confusion regarding pointers of type, ex- int(*)[size] which are pointers to an array. From what I've understood, there are some basic differences which I concluded on - 1) pointer arithmetic, 2) dereferencing . I wrote up this code to differentiate between int* and int(*)[size].
int arr1[5] {} ;
int (*ptr1) [5] = &arr1 ;
(*ptr1)[3] = 40 ;
cout << ptr1 << endl ;
cout << ptr1[3] << endl;
cout << ptr1 + 3 << endl ;
int arr2[5] {} ;
int* ptr2 = arr2 ;
ptr2[3] = 40 ;
cout << ptr2 << endl ;
cout << ptr2[3] <<endl ;
cout << ptr2 + 3 << endl ;
On observing the output of arithmetic on int(*)[size] its evident that when we add say i to it , it jumps over a block of 4*size*i memory whereas the int* jumps over a 4*i memory block. Also in int* the expression of the form ptr2[i] is equivalent to *(ptr2+i) but in pointers of type int(*)[size] this is not the case ptr1[i] is equivalent to (ptr1 + i) and to replicate the action of ptr2[i] we have to do (*ptr1)[i] in this case.
Are there anymore significant differences between the pointers of such type and which pointer amongst them should be preferred and why ? Please correct my analysis if I have gone wrong somewhere .

ptr1[3]has undefined behavior.ptr1[3]you're trying to access memory that is not meant to be accessed by you.