The <inttypes.h> file includes signed and unsigned integer types large enough to hold a pointer. These are given as intptr_t and uintptr_t. In addition, <inttypes.h> provides intmax_t and uintmax_t, which are the longest (in bits) signed and unsigned integer types available.
Use the uintptr_t type as the integral type for pointers instead of a fundamental type such as unsigned long. Even though an unsigned long is the same size as a pointer in both the ILP32 and LP64 data models, using uintptr_t means that only the definition of uintptr_t is effected if the data model changes. This makes your code portable to many other systems. It is also a more clear way to express your intentions in C.
The intptr_t and uintptr_t types are extremely useful for casting pointers when you want to perform address arithmetic. Use intptr_t and uintptr_t types instead of long or unsigned long for this purpose.