Odisha CHSE +2 Vocational Computer Technique study materials
Odisha CHSE +2 Vocational Computer Technique study resources

The Bill That Always Prints Zero

Odisha CHSE +2 Vocational Computer Technique · Put your knowledge to work in context.

All case studies

The Bill That Always Prints Zero

A +2 vocational student writes a C program for the electricity bill project. The slab rules are: first 100 units at Rs 1.50, next 200 units at Rs 2.50, and any units above 300 at Rs 4.00. Her program is:

int main(){ int units; float bill; printf("Units: "); scanf("%d", units); if(units<=100) bill=units1.5; else if(units<=300) bill=1001.5+(units-100)2.5; else bill=1001.5+200*2.5+(units-300)*4; if(bill=0) printf("No charge"); printf("Bill=%d", bill); return 0; }

On the lab computer it prints Bill=0 whatever she types, and the compiler shows only warnings, not errors. Her teacher says the slab logic is correct and the fault is elsewhere. She has a viva in three days and must be able to explain and repair the program, and to test it with 0, 250 and 500 units.

1. Trace the program for 250 units and for 0 units. State what it should print and what it actually prints, and identify the cause of each error.

Read the worked answer

Expected for 250 units: 100×1.5 = 150, plus 150×2.5 = 375, total 525. Expected for 0 units: Bill = 0 and the message 'No charge'.

Actual behaviour: scanf('%d', units) passes the current value of units as if it were an address. That is undefined behaviour; the input is not stored where intended, and units may hold garbage or the program may crash. Whatever bill is computed, the statement if(bill=0) is an assignment, not a comparison. It sets bill to 0, and the condition is false, so 'No charge' is never printed. Finally, printf('%d', bill) prints a float through an integer conversion, which is also undefined. The visible result is Bill=0.

So three independent defects combine: missing & in scanf, = instead of ==, and the wrong format specifier. The slab arithmetic itself is correct, which is why the teacher says the logic is fine. The student should trace each line rather than assume the formula is at fault.

2. Rewrite the faulty lines and justify the data types and the slab boundaries at exactly 100 and 300 units.

Read the worked answer

Corrected lines: scanf("%d", &units); if(bill == 0.0) printf("No charge\n"); printf("Bill=%.2f\n", bill);

units should be int because electricity is billed in whole units. bill should be double (or float) because the rates 1.5 and 2.5 produce fractions; using int would truncate 1.5×1 to 1. A double is preferable for money, with %.2f for display. Better still, round once at the end rather than at every step.

The boundaries are correct with <=. At exactly 100 units the first branch runs: 150. At exactly 300 units the second branch runs: 150 + 200×2.5 = 650. At 301 the third branch runs: 150 + 500 + 1×4 = 654. Using < instead of <= at 100 would send 100 units into the second branch and produce 150 + 0 = 150 by accident, but at 300 it would produce 150 + 200×2.5 + 0 = 650 by accident too; the structure is nevertheless fragile and should be kept consistent.

Validation should also reject negative units, since a negative bill is meaningless.

3. Why does the compiler only warn? How would you catch this class of error before the viva, and what test cases would you use?

Read the worked answer

C is permissive by design. An assignment inside an if condition is legal and is sometimes written deliberately, so the compiler cannot treat it as an error. A mismatch between %d and a float argument, and a suspicious scanf argument, are diagnosed only as warnings, and only when warnings are enabled. Without -Wall the compiler may say nothing useful.

Practical checks: compile with gcc -Wall -Wextra and read every warning; consider -Werror during development; run a debugger or insert temporary printf statements to print units and bill immediately after input; test the boundaries rather than only a typical value.

Test table: 0 (expect 0, No charge), 100 (150), 101 (152.50), 250 (525), 300 (650), 301 (654), 500 (1450), and a negative value (rejected). Also test non-numeric input to see whether scanf fails. Judgement: warnings are evidence, not noise. A program that 'runs' is not the same as a program that is correct.