Unfortunately, in the code I've seen both in the projects I worked on and in the internet, I've found it to be true. At the very least, almost all typecasts I've seen are unnecessary, in the sense that the variables involved were not defined as the correct type (e. g. using int instead of size_t when dealing with memory sizes), or are only necessary as a consequence of bad API design.
In the end, falling back to type casting undermines the built-in type safety of C++. For that reason alone you should avoid it.
Why do you say it's not useful? I'd say it is, especially since the second form you presented is wrong! The second form declares p as a pointer (or array of pointers) of pointers to int, and it will require additional memory to store the array of pointers it points to. The first form does not require additional memory to store pointers, because x is not the address to an array of pointers, instead it is the address of the first element! That's quite a difference, and the reason why your second form will likely cause your app to crash!
P.S.: type casting, especially C-style casts, are always bad, and almost almost always semantically wrong and will crash your app. If the compiler complains that types are incompatible you better believe it - it's built to detect this kind of thing, while most programmers aren't.