Pointers are one of the most useful and dangerous features of C. A pointer mishandled can corrupt data (or even code!) which may lie undiscovered for some time before causing unspecified and possibly unthinkable damage. This kind of problem is also very difficult to debug.
You cannot prohibit the use of pointers; they are too useful. You can, however, urge caution in their use.
Pointers and arrays in C are closely related and are sometimes used interchangeably. Their logical meaning, however, is different.
A pointer is dimensionless: it simply points to something. It has no 'home', and can be left pointing anywhere, even to nothing. Its additional flexibility means that it is often used in preference to arrays.
An array, on the other hand, has at least one dimension. It is finite, its bounds being included in its definition. It usually contains significant values.
In some implementations, pointers and integers are interchangeable. It is not, however, a very stylish or portable practice to interchange them.
The null pointer is a flag for saying, "This is not a valid pointer," and is useful for such as marking the end of a chain or as a function error return. Although NULL is not a part of the language, it is very commonly #define'd in stddef.h (ANSI) or stdio.h. It is more explicit to use NULL than zero. Of course, nothing should ever be put where a null pointer points to.
Beware of confusing NULL with NUL, which is the character '\0'. It may even be better to #define NUL as NUL_CHAR, in order to prevent accidents (see 5.5).
The simplest approach is to always cast, unless allocating the same type.