Averaging marks in C: two bugs and a skipped character
In a C practical, a student writes a function to average the marks of a class test. The array holds 40 marks, each between 0 and 100, and the function is declared int average(int m[], int n). The main function reads the number of students with scanf("%d", &n), then reads a section letter with scanf("%c", &sec). For marks 87, 92 and 78 the program prints 85, although the expected average is 85.67. The student changes the function to return float but the output still shows 85.000000, and the section letter is skipped. The teacher asks for a minimal correction rather than a rewrite, and warns that printf("%d", avg) is still in the code. The compiler reports no error.
1. Why does the program print 85, and why does changing only the return type to float still print 85.000000? Show the corrected return statement.
Read the worked answer
The sum is 87 + 92 + 78 = 257 and n = 3. In return sum / n; both operands are int, so C performs integer division and truncates 85.666... to 85 before the value is returned. The int return type then stores 85. Changing only the return type to float converts the already-truncated 85 to 85.0, so %f prints 85.000000. The fix is to force floating-point division, for example return (float)sum / n; or return sum / (float)n;, and to make the function return float. The cast must be on one operand; casting the result after division is too late. The compiler may not warn because the code is type-valid.
2. Explain why the section letter is skipped and give two minimal fixes.
Read the worked answer
scanf("%d", &n) stops at the newline after the number but leaves that newline in the input buffer. The next scanf("%c", &sec) sees the newline as a character and stores it in sec, so the letter typed by the user remains for the next read. Minimal fixes: use a leading space in the format, scanf(" %c", &sec);, which skips whitespace, or call getchar(); once after the numeric read to consume the newline. The leading-space fix is more robust because it also handles spaces and tabs. This is a buffering issue, not a data-type issue, so changing the function's return type cannot affect it.
3. The teacher warns that a diagnostic printf still uses %d with avg. What is the risk and what should be used instead?
Read the worked answer
Passing a float to printf with %d is undefined behaviour. In a variadic call the float is promoted to double, but %d tells printf to read an int; the bit patterns are different, so the output can be garbage or zero, and on some platforms it can crash. The correct conversion is %f, or %.2f for two decimal places. If an integer is genuinely wanted, cast explicitly with (int)avg and then use %d, accepting truncation. The safe habit is to enable compiler warnings (-Wall -Wextra) and match every format specifier to the promoted type; a silent compile is not evidence of correctness.