Integer types can be declared as signed or unsigned. A signed integer can represent negative and positive values, while an unsigned integer represents only non-negative values.
#include <stdio.h>
int main()
{
signed int a = -10;
unsigned int b = 10;
printf("signed int = %d\n", a);
printf("unsigned int = %u\n", b);
return 0;
}
Example Output #
signed int = -10
unsigned int = 10
Explanation #
A signed integer can represent values on both sides of zero:
signed int a = -10;
An unsigned integer cannot represent negative values:
unsigned int b = 10;
For the same integer width, using unsigned provides a larger range of non-negative values because no bits are needed to represent a negative sign.
Signed and Unsigned Integer Types #
| Type | Typical 32-bit range |
|---|---|
signed char |
−128 to 127 |
unsigned char |
0 to 255 |
signed short |
−32,768 to 32,767 |
unsigned short |
0 to 65,535 |
signed int |
−2,147,483,648 to 2,147,483,647 |
unsigned int |
0 to 4,294,967,295 |
signed long long |
−9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 |
unsigned long long |
0 to 18,446,744,073,709,551,615 |
The exact ranges depend on the implementation. The table shows common ranges for the corresponding widths.
For integer types other than char, signed is the default when no signedness is specified:
int a;
signed int b;
Both declare signed integer types.
For char, whether a plain char behaves as signed or unsigned is implementation-defined. signed char and unsigned char explicitly specify the signedness.
Unsigned Integer Wraparound #
Unsigned arithmetic is performed modulo one more than the maximum representable value. For example, with an 8-bit unsigned type:
unsigned char value = 255;
value++;
printf("%u\n", (unsigned int)value);
The value wraps from 255 to 0.
Signed integer overflow, in contrast, is undefined behavior and should not be treated as ordinary wraparound.