(1)typedef has a strict type checking whereas macros are just copy-paste.
typedef int * int_ptr;
OR
#define int_ptr int *
int a=0,b=0;
int_ptr k1,k2;
// In case of #define int * k1,k2; where k1 is a pointer to integer, k2 is integer.
// In case of typedef both are pointer to integer.
k1 = &a; k2=&b;
(2) typedef cannot be applied with other types whereas macros can as they are blind copy-paste
typedef int integer;
OR
#define integer int
unsigned integer k = 0;
//works fine for macros but illegal in C when typedef is used for integer.
typedef int * int_ptr;
OR
#define int_ptr int *
int a=0,b=0;
int_ptr k1,k2;
// In case of #define int * k1,k2; where k1 is a pointer to integer, k2 is integer.
// In case of typedef both are pointer to integer.
k1 = &a; k2=&b;
(2) typedef cannot be applied with other types whereas macros can as they are blind copy-paste
typedef int integer;
OR
#define integer int
unsigned integer k = 0;
//works fine for macros but illegal in C when typedef is used for integer.