A loop is a control-flow structure that executes the same block of code repeatedly, either while a condition remains true or once for each element of a sequence. In programming fundamentals, it is the basic tool for iteration: processing every item in a list, retrying an operation, reading input until it ends or running a program until it is told to stop.
Each pass through the loop body is called an iteration. Every loop needs a way to begin, a body to repeat and a termination condition that eventually ends it; if that condition is never met, the result is an infinite loop. Loops are the iterative counterpart of recursion, which achieves repetition through a function calling itself.
How a loop executes
A loop executes as a cycle of test, body and update. The program evaluates a condition; if it holds, the body runs, the loop state changes, and control jumps back to the test. When the condition fails, execution continues with the first statement after the loop.
The parts of this cycle have conventional names. Getting each part right is what separates a correct loop from one that skips an element, processes one too many or never stops.
| Part | Role | Example in a counting loop |
|---|---|---|
| Initialization | Sets the starting state | i = 0 |
| Condition | Decides whether another iteration runs | i < n |
| Body | The repeated work | Process element i |
| Update | Moves the state toward termination | i = i + 1 |
| Loop variable | Tracks progress across iterations | The counter i |
Two statements alter the normal cycle. break leaves the loop immediately, and continue skips the rest of the current body and starts the next iteration. Both are useful, but heavy use makes the termination logic harder to follow.
Types of loops
Programming languages provide several loop forms, and choosing the one that matches the intent makes code shorter and safer. The main distinction is whether the number of iterations is known in advance and whether the condition is tested before or after the body.
| Loop form | Condition tested | Typical use |
|---|---|---|
| Counted for loop | Before each iteration | Known number of repetitions or index ranges |
| For-each loop | Implicitly, by the iterator | Every element of a list, set or map |
| While loop | Before each iteration | Repeat until an external condition changes |
| Do-while loop | After each iteration | Body must run at least once, such as input prompts |
| Infinite loop with exit | Inside the body | Event loops, servers and game loops |
Languages differ in which forms they offer. Python has for-each and while but no classic counted loop or do-while; Go uses a single for keyword for all forms; C, Java and JavaScript provide all of them. Modern code increasingly prefers for-each loops because they remove index errors entirely.
Loops compared with recursion and higher-order functions
Loops are one of three common ways to express repetition, alongside recursion and higher-order functions such as map, filter and reduce. All three can solve the same problems, but they differ in readability, memory use and how naturally they fit the data.
| Approach | Strength | Weakness |
|---|---|---|
| Loop | Direct, efficient, constant stack use | Mutable state can hide errors |
| Recursion | Natural for trees and divide-and-conquer | Stack depth limits, often a few thousand calls |
| Higher-order functions | Declarative, no manual index | Less suited to early exit or complex state |
A practical rule is to use loops for linear processing with possible early exit, recursion for hierarchical data, and higher-order functions for straightforward transformations of whole collections. Many compilers turn simple recursive and functional forms into loops internally, so performance differences are often smaller than expected.
Performance and complexity of loops
The cost of a loop is the cost of the body multiplied by the number of iterations, and nesting multiplies again. A single loop over n items is linear, a loop inside a loop over the same items is quadratic, and three levels are cubic.
Quadratic loops are a frequent hidden bottleneck. Checking whether each of 10,000 items appears in a list of 10,000 others takes up to 100 million comparisons, while building a hash-based set first reduces the work to roughly 20,000 operations. Moving invariant work out of the loop, such as computing a length or compiling a pattern once, is the next most common improvement.
| Structure | Complexity | Iterations for 1,000 items |
|---|---|---|
| Single loop | O(n) | 1,000 |
| Two nested loops | O(n²) | 1,000,000 |
| Three nested loops | O(n³) | 1,000,000,000 |
| Loop halving the range | O(log n) | About 10 |
Common loop errors
Loop errors are among the most common defects in beginner and professional code alike, because small boundary mistakes are easy to make and hard to see. Most fall into a few recognizable categories.
- Off-by-one errors come from using
<=instead of<, or starting at 1 instead of 0, and process one element too many or too few. - Infinite loops occur when the update never moves the state toward the condition, for example when a counter is not incremented.
- Modifying a collection while iterating over it skips elements or raises an exception in many languages.
- Floating-point counters accumulate rounding error, so a loop stepping by 0.1 may run one time more or less than expected.
- Shadowed or reused loop variables in nested loops cause the outer loop to end early or behave unpredictably.
A disciplined way to avoid these errors is to state the loop invariant, a property that holds before and after every iteration. If the invariant holds and each iteration makes measurable progress, the loop is both correct and guaranteed to terminate.
Understanding it simply
A loop tells a computer to do the same thing again and again until a job is finished. Instead of writing the same instruction a thousand times, a programmer writes it once and says how often or how long to repeat it.
It is like a recipe step such as stirring until the sauce thickens. The cook does not count the stirs in advance; the cook checks the sauce and stops when the condition is met. A loop works the same way, which is why it must always have a clear stopping point.
Applied in practice
A small online shop stores about 50,000 orders and needs a nightly report of customers who placed an order but never received a confirmation email. The first version used two nested loops, comparing every order with every sent email, and the job ran for more than 40 minutes.
A developer rewrote it with a single for-each loop over orders and a set of confirmed order numbers built in advance. The loop checks each order against the set and adds unmatched orders to the report, with a continue statement that skips canceled orders. The report now finishes in under two seconds and produces the same results, verified against the old output for a full week.