I have just started learning C and a question has bugged me for a while now. If I write
int i = -1;
unsigned int j = 2;
unsigned int k = -2;
<
I would say it depends on the compiler and the architecture of the machine. Given 8 bits = 1 byte, the following table summarizes different Integer types with their required sizes for both (signed) int and unsigned int on 32 and 64-bit machines:
+------+------+---------+-------+--------+-------------+-----------+
|Type |char |short int|int |long int|long long int|int pointer|
+------+-------+--------+-------+--------+-------------+-----------+
|32-bit|8 bits|16 bits |32 bits|32 bits |64 bits |32 bits |
+------+------+---------+-------+--------+-------------+-----------+
|64-bit|8 bits|16 bits |32 bits|64 bits |64 bits |64 bits |
+------+------+---------+-------+--------+-------------+-----------+
As you may know, the biggest difference between (signed) int and unsigned int is that in (signed) int the Most Significant Bit (MSB) is reserved for the sign of the Integer and hence:
int having n bits can have a value between -(2^(n-1)) to (2^(n-1))-1unsigned int having n bits can have a value between 0 to (2^n)-1Now, we can calculate the range (possible values) of different (singed) int types as follows:
+------+---------+----------+----------+----------+-------------+-----------+
|Type |char |short int |int |long int |long long int|int pointer|
+------+---------+----------+----------+----------+-------------+-----------+
|32-bit|-(2^7) to|-(2^15) to|-(2^31) to|-(2^31) to|-(2^63) to |-(2^31) to |
| |+(2^7)-1 |+(2^15)-1 |+(2^31)-1 |+(2^31)-1 |+(2^63)-1 |+(2^31)-1 |
+------+---------+----------+----------+----------+-------------+-----------+
|64-bit|-(2^7) to|-(2^15) to|-(2^31) to|-(2^63) to|-(2^63) to |-(2^63) to |
| |+(2^7)-1 |+(2^15)-1 |+(2^31)-1 |+(2^63)-1 |+(2^63)-1 |+(2^63)-1 |
+------+---------+----------+----------+----------+-------------+-----------+
Furthermore, we can calculate the range (possible values) of different unsigned int types as follows:
+------+-------+----------+-------+--------+-------------+-----------+
|Type |char |short int|int |long int|long long int|int pointer|
+------+-------+---------+--------+--------+-------------+-----------+
|32-bit|0 to |0 to |0 to |0 to |0 to |0 to |
| |(2^8)-1|(2^16)-1 |(2^32)-1|(2^32)-1|(2^64)-1 |(2^32)-1 |
+------+-------+---------+--------+--------+-------------+-----------+
|64-bit|0 to |0 to |0 to |0 to |0 to |0 to |
| |(2^8)-1|(2^16)-1 |(2^32)-1|(2^64)-1|(2^64)-1 |(2^64)-1 |
+------+-------+---------+--------+--------+-------------+-----------+
Finally, to see how and why we store a long long int using 8 bytes (64 bits) on a 32-bit machine see this post.