If you might need large values (above 32,767 or below -32,767), use long. Otherwise, if space is very important (i.e. if there are large arrays or many structures), use short. Otherwise, use int. If well-defined overflow characteristics are important and negative values are not, or if you want to steer clear of sign-extension problems when manipulating bits or bytes, use one of the corresponding unsigned types. (Beware when mixing signed and unsigned values in expressions, though)
Although character types (especially unsigned char) can be used as ``tiny’’ integers, doing so is sometimes more trouble than it’s worth. The compiler will have to emit extra code to convert between char and int (making the executable larger), and unexpected sign extension can be troublesome. (Using unsigned char can help)
A similar space/time tradeoff applies when deciding between float and double. (Many compilers still convert all float values to double during expression evaluation.) None of the above rules apply if pointers to the variable must have a particular type.
Variables referring to certain kinds of data, such as sizes of objects in memory, can and should used predefined abstract types such as size_t.
It’s often incorrectly assumed that C’s types are defined to have certain, exact sizes. In fact, what’s guaranteed is that:
type char can hold values up to 127; types short int and int can hold values up to 32,767; and type long int can hold values up to 2,147,483,647. something like the relation sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long) <= sizeof(long long)
From these values, it can be inferred that char is at least 8 bits, short int and int are at least 16 bits, and long int is at least 32 bits. (The signed and unsigned versions of each type are guaranteed to have the same size.) Under ANSI C, the maximum and minimum values for a particular machine can be found in the header file ; here is a summary:
Base type Minimum size (bits) Minimum value (signed) Maximum value (signed) Maximum value (unsigned)
char 8 -127 127 255
short 16 -32,767 32,767 65,535
int 16 -32,767 32,767 65,535
long 32 -2,147,483,647 2,147,483,647 4,294,967,295
(These values are the minimums guaranteed by the Standard. Many implementations allow larger values, but portable programs shouldn’t depend on it.)
If for some reason you need to declare something with an exact size (usually the only good reason for doing so is when attempting to conform to some externally-imposed storage layout, but see question 20.5), be sure to encapsulate the choice behind an appropriate typedef.
If you need to manipulate huge values, larger than the guaranteed range of C’s built-in types, you need an arbitrary-precision (or ``multiple precision’’) arithmetic library.
References: K&R1 Sec. 2.2 p. 34
K&R2 Sec. 2.2 p. 36, Sec. A4.2 pp. 195-6, Sec. B11 p. 257
ISO Sec. 220.127.116.11.1, Sec. 18.104.22.168
H&S Secs. 5.1,5.2 pp. 110-114