ReviseAlgo Logo

Control Flow

For Loops

Traditional and range-based for loops

Interview: Essential for iteration

For Loops

The for loop is the workhorse of iteration in C++. It packs initialization, condition checking, and increment into a single compact line. C++11's range-based for loop further simplifies iteration over containers by eliminating manual index management.

Traditional For Loop

The traditional for loop has three components: init; condition; update. Any or all of these can be omitted (creating infinite loops or custom control flows).

Range-Based For (C++11)

Range-based for iterates over any container that provides begin() and end() iterators. Using auto& avoids copies for non-trivial types. Using const auto& for read-only access.

Index-Based vs Range-Based Trade-offs

Use index-based when you need the index itself (e.g., for comparing adjacent elements or bidirectional traversal). Use range-based for readability and safety when you only need element values.

Interview Corner

Q: What is the difference between for(auto x : v) and for(auto& x : v)?

A: auto x creates a copy of each element — modifications don't affect the container and copying is expensive for large objects. auto& x creates a reference to the actual element — modifications affect the container and no copy is made. Use const auto& for efficient read-only access.

Q: Why should you avoid calling size() in a loop condition for a container?

A: While most STL containers have O(1) size(), it's still a function call evaluated every iteration. More critically, comparing a signed int index against an unsigned size_t result can trigger implicit signed/unsigned comparison warnings and potential bugs. Cache the size: const auto n = v.size();

Common Pitfalls

  • Off-by-one errors: Using i <= size instead of i < size leads to out-of-bounds access.
  • Modifying container in range-based for: Adding/removing elements while iterating with a range-based for invalidates iterators and causes undefined behavior.

Best Practices

  • Prefer range-based for loops for containers when index is not needed — they are safer and more expressive.
  • Use std::size_t or ptrdiff_t for loop indices over containers to avoid signed/unsigned mismatch.
  • Consider standard algorithms like std::for_each or std::transform for more expressive and parallelizable iteration patterns.