const char *p 和char * const p

把一个声明从右向左读。 
char * const cp; ( * 读成 pointer to ) 
cp is a const pointer to char :const是修饰指针,表明指针不能修改指向了
const char * p; 
p is a pointer to const char; :表明const是修饰一个只读变量,该内存位置是只读的,不可修改,p依旧可以指向别的地方


另外

#define是预处理指令,在编译预处理时进行简单的替换,不作正确性检查

typedef是在编译时处理的。它在自己的作用域内给一个已经存在的类型一个别名

typedef int * int_ptr;
#define int_ptr int *

nt_ptr a, b; //相当于int * a, b; 只是简单的宏替换
nt_ptr a, b; //a, b 都为指向int的指针,typedef为int* 引入了一个新的助记符

typedef int * pint ;
#define PINT int *

const pint p ;//p不可更改,但p指向的内容可更改
const PINT p ;//p可更改,但是p指向的内容不可更改。

const char *p 和char * const p