ENGGEN 131 Chap.7 C Types, Operators and Standard I/O
C Types, Operators and Standard I/O
This chapter makes C evaluation rules explicit through declarations, operand types, integer division, conversions, precedence and formatted input-output. It distinguishes casting before an operation from converting an already completed result and treats input return values as part of the algorithm. Original traces show why printed decimals do not prove floating arithmetic occurred.
What this chapter covers
- 01
Integer, floating and character types
- 02
Integer division and mixed expressions
- 03
Cast placement and conversion order
- 04
Assignment, equality and precedence
- 05
Format specifiers, addresses and conversion counts
Worked example · free
Repair an average calculation
- 1The first division uses integer operands and produces 3.
- 1That result converts to 3.0 for storage in a.
- 1Casting before division makes b equal 3.5.
Key terms
- Integer division
- Division between integer operands with the fractional part discarded.
- Cast
- An explicit conversion of a value to another type.
- Format specifier
- A conversion description used by formatted input or output.
C Types, Operators and Standard I/O FAQ
Why did storing in double not preserve the fraction?
If integer division happened first, the fraction was discarded before assignment. The destination type converts only the completed integer result. Rehearse this distinction with a fresh type and conversion trace before relying on program output.
Why check an input function's return value?
It reports how many requested fields were converted, preventing the program from treating an unchanged destination as new valid input. Test the claim on a boundary case where the type and conversion assumptions become visible.
How do I avoid precedence mistakes?
Annotate the operations in execution order and add parentheses when the intended grouping would not be obvious to a reader. Write the expected type and conversion state first, then compare it carefully with execution.
Exam move
Start every expression trace with declared types. Mark operator precedence and associativity, then evaluate one operation at a time, recording the operand types, conversion applied, intermediate type and intermediate value. Only after the right-hand side is complete should assignment conversion be considered.
This prevents the common belief that a floating destination can recover a fractional part already discarded by integer division. Place a cast on an operand when the arithmetic itself must become floating; casting the completed quotient is too late. Practise mixed expressions with values that reveal truncation and grouping. Compare 7/2, 7.0/2, a cast before division and a cast after division.
Include negative values only after stating the language rule expected by the course context. Annotate prefix and postfix increment by separating the expression value from the later stored value, and prefer a separate update in authored code when compact syntax obscures sequence. Distinguish equality from assignment and explain how an assignment in a condition can both change state and yield a truth value.
Treat formatted input as a contract among a conversion specifier, destination type and destination address. Before the call, list the objects that may be written. After the call, check the number of successful conversions and use only destinations established by that result. If two integers were requested but one converted, the second object does not hold new input. Decide whether to retry, report failure or terminate.
Continuing with a prior value creates a logic defect that may survive ordinary tests. For output, pair each format specifier with the actual argument type and distinguish stored value from displayed representation. A decimal-looking printout does not prove floating arithmetic occurred before formatting, and limited displayed precision does not prove the stored value lacks further precision.
Predict the exact displayed field for a few examples, including width and precision only where relevant. Use formatting to communicate an already correct result, never as evidence that conversions and arithmetic were correct. Add a range audit to numerical traces. Estimate the largest intermediate value, because overflow can occur before a final assignment to a wider type.
Note signedness before comparisons, especially when negative signed values can be converted in an unsigned context. Choose types from the engineering meaning: counts and discrete states usually require integers, measurements often require floating values, and character data have their own representations. State why the range and precision are adequate rather than choosing types by habit.
Finish with a paper program that reads two values, validates conversion count, performs a calculation requiring floating division and prints a labelled result. Trace one valid input, one partial conversion and one value near a relevant range boundary. For each defect found, classify it as type choice, precedence, conversion timing, input contract, range or formatting.
Mastery means predicting both stored state and visible output while explaining the precise point at which each conversion takes place. Complete a final input-to-output trace for a program that reads two whole-number measurements, validates both conversions, computes a fractional ratio and prints a labelled result.
Annotate the address supplied to each input conversion, its return count, operand types at division, cast position, intermediate value, destination type and format argument. Test valid data, one successful conversion, a zero denominator and values large enough to challenge the chosen integer range. Predict stored state and displayed text before execution.
Repair failures at the earliest violated contract: input validation, domain check, conversion timing, range or format match. This end-to-end exercise demonstrates that correct numerical output depends on a chain of type and I/O decisions, not on the final printf line alone.