Q:

Can I omit const qualifiers in declaration for pointer types?

For a function definition which contains the declaration of type void foo(const int ) Both of the following declarations are valid.
void foo(const int); // valid
void foo(int); // valid, const can be omitted.

But if a function definition contains a declaration of type void foo(const int*) omitting const is ilegal:
void foo(const int *); // valid declaration
void foo(int *); // error: const cannot be omitted.

Why is const cannot be omitted in the function declaration if its parameter has pointer types? What makes the difference?

A:

const int x means that x is read-only inside the function.  The outside world doesn't care either way; the function is working with a copy of the argument.
However const int *p means that p points to something that is read-only.  The outside world does care about this; it's a promise that the pointee can't be modified.
The corollary of this is that the following two declarations are equivalent:
void foo(const int *);
void foo(const int * const);

A:

You can only omit the const specifier when it's applied directly to the parameter. In the pointer case, it's applied to the thing being pointed at, not the pointer itself, so there's an extra level of indirection between const and the parameter. You could omit it in this case:
void foo(int* const);
void foo(int*);

