Control Flow II: Loops & Range-based for
লুপ ও range-based for
1. Three Classical Loop Forms
#include <iostream>
int main() {
// while: test before
int i = 0;
while (i < 3) { std::cout << "w" << i++; }
std::cout << "\n";
// do-while: test after (always runs once)
int j = 0;
do { std::cout << "d" << j++; } while (j < 3);
std::cout << "\n";
// for: combines init/condition/update
for (int k = 0; k < 3; ++k) std::cout << "f" << k;
std::cout << "\n";
}
2. Range-based for (C++11) — The Modern Way
The cleanest way to iterate over any container or array:
#include <iostream>
#include <vector>
int main() {
std::vector<int> v = {10, 20, 30, 40};
// Read-only iteration
for (const auto& x : v) std::cout << x << " ";
std::cout << "\n";
// Modify in place
for (auto& x : v) x *= 2;
for (int x : v) std::cout << x << " ";
std::cout << "\n";
}
| Form | Behavior | When to use |
|---|---|---|
for (auto x : v) | Copy each element | Small types (int, char) |
for (const auto& x : v) | Read-only reference | Read-only — default choice |
for (auto& x : v) | Mutable reference | Modify in place |
3. break, continue, and (rarely) goto
break— exit the innermost loop or switch.continue— skip to the next iteration.goto— almost never. The one valid use: jumping out of nested loops.
4. Loop Invariants — Proof of Correctness
An invariant is a statement that's true before and after each iteration. It proves the loop is correct.
int sum = 0;
for (int i = 1; i <= n; ++i) sum += i;
Invariant: Before iteration i, sum = 1 + 2 + ... + (i-1).
Initial: Before i=1, sum = 0 (empty sum). ✓
Maintain: If invariant holds before i, after
sum += i it holds for i+1. ✓
Termination: Loop ends at i=n+1, so sum = 1+...+n. ✓
5. Nested Loops & Time Complexity
#include <iostream>
int main() {
for (int i = 1; i <= 5; ++i) {
for (int j = 1; j <= i; ++j) {
std::cout << "*";
}
std::cout << "\n";
}
}
Two nested loops over n elements = O(n²) work. Triple nested = O(n³).
6. Practice Problems
- Print 1 to 100.
✨ Show Answer
for (int i = 1; i <= 100; ++i) std::cout << i << " "; - Compute n! for n=10 using a for loop.
✨ Show Answer
fact.cpp#include <iostream> int main() { long long f = 1; for (int i = 2; i <= 10; ++i) f *= i; std::cout << f << "\n"; } - Sum of even numbers 1..100.
✨ Show Answer
int s = 0; for (int i = 2; i <= 100; i += 2) s += i; // 2550 - Print a multiplication table for 7.
✨ Show Answer
for (int i = 1; i <= 10; ++i) std::cout << 7 << " x " << i << " = " << 7*i << "\n"; - Use range-for to compute the sum of
{1,2,3,4,5}.✨ Show Answer
std::vector<int> v = {1,2,3,4,5}; int s = 0; for (int x : v) s += x; - Print stars in a right triangle of height 5.
✨ Show Answer
See section 5 above. Output:
*
**
***
****
***** - Find the largest divisor of 100 less than 100.
✨ Show Answer
for (int d = 99; d >= 1; --d) if (100 % d == 0) { std::cout << d; break; } // 50 - Print all primes below 30.
✨ Show Answer
primes.cpp#include <iostream> int main() { for (int n = 2; n < 30; ++n) { bool isp = true; for (int d = 2; d * d <= n; ++d) if (n % d == 0) { isp = false; break; } if (isp) std::cout << n << " "; } } - Difference between
++iandi++?✨ Show Answer
Both increment
i.++ireturns the new value;i++returns the old. For loops, prefer++i— it can be faster for non-trivial types (no temp copy). For ints, identical. - Reverse a string with a loop.
✨ Show Answer
std::string s = "hello"; for (int i = 0, j = s.size()-1; i < j; ++i, --j) std::swap(s[i], s[j]); - Use
continueto skip multiples of 3 when printing 1..20.✨ Show Answer
for (int i = 1; i <= 20; ++i) { if (i % 3 == 0) continue; std::cout << i << " "; } - Why prefer
const auto&in range-for overauto?✨ Show Answer
Avoids unnecessary copy of each element. Plus the compiler enforces that you don't accidentally modify it. Default to
const auto&; switch toauto&only when you intend to modify. - Print Fibonacci numbers up to F(15) iteratively.
✨ Show Answer
int a = 0, b = 1; for (int i = 0; i < 15; ++i) { std::cout << a << " "; int next = a + b; a = b; b = next; } - When would you use
do-whileinstead ofwhile?✨ Show Answer
When you need the loop body to run at least once before the test. Common: menu-driven programs.
- Loop invariant for binary-counting bits in n:
int c=0; while(n){ c+= n&1; n>>=1;}✨ Show Answer
Invariant:
c= number of 1-bits processed so far. After the loop, n=0 (all bits processed) andc= total bit count.
Summary
while tests first, do-while tests last, for bundles init/cond/update.
Range-based for is the modern default for any container. Use const auto&
unless you need to modify. State your loop invariant — it is the proof of correctness.