What the code is supposed to do
The function printSum takes an array of integers, nums, and should print the sum of all its elements once. The helper mainFunction calls it with [1, 2, 3], so the program should print a single line:
6
The code you start with prints three lines instead:
1
2
3
The starting code is:
func printSum(_ nums: [Int]) {
for num in nums {
var sum = 0
sum += num
print(sum)
}
}
// Do not change this code:
func mainFunction() {
printSum([1, 2, 3])
}
There are two mistakes. Leave mainFunction alone and fix printSum.
What goes wrong
Trace the loop by hand. Everything between the braces of for num in nums runs once per element, and that includes the declaration var sum = 0.
- For
num = 1: a newsumis created as 0, becomes 1, and1is printed. - For
num = 2: a brand-newsumis created as 0, becomes 2, and2is printed. - For
num = 3: the same happens again and3is printed.
That shows both bugs at once:
- The total is reset on every pass. A variable declared inside a loop body exists only for that one pass. Each pass starts with a fresh
sumof 0, so earlier numbers are never added in. - The print is inside the loop. Even with a correct running total,
print(sum)would run after every element and show the partial sums 1, 3 and 6. The total is complete only after the last element has been added.
Fixing it step by step
- Move the declaration above the loop. Put
var sum = 0beforefor num in nums. It now runs once, andsumstays alive for the whole loop. - Keep the addition in the loop.
sum += numstays where it is, adding each element to the running total. - Move the print below the loop. After the closing brace of the loop,
print(sum)runs one time with the finished total.
The fixed code in Swift
func printSum(_ nums: [Int]) {
var sum = 0
for num in nums {
sum += num
}
print(sum)
}
func mainFunction() {
printSum([1, 2, 3])
}
The details that matter here:
- Scope. A constant or variable lives from its declaration to the closing brace of the block that contains it. Declared inside the loop,
sumbelongs to a single pass. Declared above the loop, it belongs to the whole function body, and each pass updates the same variable. Asumdeclared inside the loop can't be read by aprintbelow the loop either: the compiler reports that it cannot findsumin scope. var, notlet. The total changes, so it must be avar. Withlet,sum += numis a compile error because the constant can't be mutated.- Overflow.
Intis 64 bits and an overflowing sum crashes the program instead of wrapping around. For this lesson the numbers are small. - An empty array.
printSum([])prints0, because the loop does nothing and the total is still its starting value.
Common mistakes
- Fixing only one of the two bugs. Moving only the declaration prints
1,3and6. Moving only the print leaves the total reset each time, so the program prints3, the last number. - Moving the print but not out of the loop's braces. A
printindented under the loop but before its closing brace is still inside the loop. - Starting the total at 1. That would make every sum one too large.
- Changing
mainFunction. The task says its code stays as it is.
