The purpose of this is so that the execv function knows when to stop reading arguments.
After all, by passing arg you only pass a pointer to the first argument. The execv function will find all the arguments by incrementing this to find the next argument, until it finds a special sentinel value. According to the documentation of execv:
The array of pointers must be terminated by a NULL pointer.
(char *)0 is a null pointer of course.
So why did the person write (char *)0 instead of NULL?
They may have mixed up execv with execl which does require that specifically (char *)0 or equivalently (char *)NULL be passed.
This is because execl reads arguments via the varargs mechanism , so the actual argument must be specifically a char *. Passing NULL risks that NULL is a macro defined to the constant 0 of type int, which would break the varargs mechanism.