5.1.2 · D5C Programming
Question bank — Data types — char, short, int, long, float, double, size_t
True or false — justify
Each item is a claim. Answer true or false, then give the reason.
sizeof(int) is always 4 bytes on every C compiler.
False — the standard only guarantees
int holds at least 16 bits; 2-byte int was common on old 16-bit systems. Only sizeof(char) == 1 is fixed. See sizeof Operator.sizeof(char) is always 1.
True — the standard defines a byte as the size of a
char, so sizeof(char) == 1 by definition on every conforming compiler.A char is always able to store all values from 0 to 255.
False — plain
char may be signed or unsigned (implementation-defined). If signed, its range is and it cannot hold 200 correctly.float can represent more distinct numbers than int because it covers a bigger range.
False — both are 32-bit, so both have exactly patterns.
float spreads those patterns over a huge range, so it trades precision for reach; see IEEE-754 Floating Point.Two double values that print the same on screen are guaranteed bit-for-bit equal.
False — printing rounds to a few digits, so distinct bit patterns can print identically. Only a bitwise comparison proves equality.
unsigned int and int occupy the same number of bytes.
True — the signed/unsigned distinction changes interpretation of bits, not the byte count; both are typically 4 bytes.
Adding 1 to INT_MAX in a signed int gives INT_MIN.
False in principle — signed overflow is undefined behaviour, not a guaranteed wrap. Compilers may assume it never happens; see Integer Overflow and Undefined Behaviour.
Adding 1 to UINT_MAX in an unsigned int gives 0.
True — unsigned arithmetic is defined as modulo , so it wraps cleanly to 0 with no undefined behaviour.
size_t is just a fancy alias for int.
False —
size_t is unsigned and sized to hold the largest object (64-bit on a 64-bit machine), whereas int is signed and often narrower.Spot the error
Find the bug and explain the underlying type rule.
for (size_t i = strlen(s) - 1; i >= 0; i--) — what breaks?
i >= 0 is always true for an unsigned type, so the loop never ends; when i is 0, i-- wraps to a huge number instead of going negative.if (0.1 + 0.2 == 0.3) ... — why does this branch not run?
0.1 and 0.2 have no finite binary form and are rounded, so the sum is 0.30000000000000004, which is not equal to the rounded 0.3.char c = 200; printf("%d", c); printing -56 — what happened?
On a signed
char, 200 = 11001000 has the top bit set, so it is read as . The value simply doesn't fit in .printf("%d", my_size) where my_size is size_t — why is this wrong?
%d expects a signed int; a size_t argument mismatches the format, giving undefined behaviour. Use %zu.unsigned int n = -1; — is this an error?
Not a syntax error:
-1 converts to UINT_MAX by modulo- wrapping, so n becomes the largest unsigned value. Legal but surprising.if (strlen(a) - strlen(b) < 0) to test which string is shorter — why does it fail?
strlen returns size_t (unsigned), so the subtraction can never be negative; a smaller-minus-larger wraps to a huge positive value. Compare with < directly instead.float x = 16777217; then x prints as 16777216 — bug or expected?
Expected:
float has only 24 mantissa bits, so it cannot distinguish consecutive integers past ; rounds down.long total = a * b; where a, b are int and the product overflows — does widening to long save you?
No —
a * b is computed in int first (both operands are int), overflowing before the result is assigned. Cast one operand to long first. See Type Conversion and Promotion.Why questions
Answer with the mechanism, not just a restatement.
Why is the signed range asymmetric — one more negative than positive?
The pattern
1000…0 is reserved for the most-negative value, and 0 occupies a slot on the non-negative side, so there are negatives but only positives. See Two's Complement Representation.Why does the C standard bother giving minimum sizes instead of exact ones?
To let C run on wildly different hardware (8-bit, 16-bit, 64-bit) while still guaranteeing programs enough range to be portable.
Why does float give only ~7 decimal digits despite covering huge magnitudes?
Precision comes from mantissa bits (24), and digits; the exponent extends range, not precision.
Why store floats in scientific-notation form rather than as scaled integers?
To make precision relative — a fixed number of significant digits works for both atomic and astronomical sizes without wasting bits on leading zeros.
Why does IEEE-754 use an implicit leading 1 in the mantissa?
Normalizing to makes the leading bit always 1, so it need not be stored — a free extra bit of precision.
Why does size_t scale with the machine's address size?
A size must be able to describe the largest addressable object, which is bounded by how much memory the machine can address; see Pointers and Addresses.
Why is signed overflow undefined but unsigned overflow defined?
Unsigned is specified as modulo arithmetic, giving a fixed result; signed representations were historically not uniform, so the standard left the behaviour undefined for optimization freedom.
Edge cases
Boundary and degenerate inputs.
What does unsigned char u = 0; u = u - 1; produce?
It wraps to
255 — unsigned subtraction below 0 is modulo , so becomes .Is 0.0 == -0.0 true in IEEE-754?
True by the equality rule — positive and negative zero compare equal, even though their bit patterns differ by the sign bit.
What is the value of a float set exactly to INT_MAX (2147483647)?
It cannot be represented exactly (needs 31 mantissa bits,
float has 24), so it rounds to 2147483648.0 — one more than INT_MAX.What happens when you assign -1 to a size_t?
It becomes the maximum
size_t value (all bits 1) via unsigned wraparound, a common source of "impossibly huge" size bugs.Does char guarantee the range ?
No — plain
char may be unsigned, giving . Only signed char guarantees at least , and two's complement makes it .What is sizeof('A') in C (not C++)?
4 — a character constant in C has type int, not char, so sizeof('A') == sizeof(int). The mismatch surprises many.Recall One-line self-test
- Which type's
sizeofis fixed? →char(== 1) - Signed overflow verdict? → undefined behaviour
- Unsigned overflow verdict? → defined modulo
- Why can't
size_t i >= 0end a loop? → unsigned is never negative - Type of
'A'in C? →int