What is the difference between an iteration and a loop? - c

I am doing Cs50 Harvard University online and I'm on week 3 but while watching the video I noticed that I iterations and loops seem the same, as they repeat things over and over. But there must be a difference or else they wouldn't have two names for the same thing. No matter how many times I re-watch the video I can't find a difference. Please help me understand.

"Loop" refers to language constructs that are used to repeatedly execute some code. (for loops, while loops, etc.)
"Loop" can also refer to code being executed repeatedly. (e.g. "It's stuck in a loop.")
Iterating is the process of doing something repeatedly. (e.g. "This loop iterates over the elements of the array.")
An iteration is a single pass of a loop. (e.g. "In the first iteration of that for loop, i will be 0.")

Usually "loop" refers to the code and "iteration" refers to the conceptual process of repeating some steps. In this case, they are more or less the same. Additionally, you could use "iteration" to refer to a single repetition within a loop which gives it a different meaning.
A case example for the first usage of "iteration" would be:
You can print a linked list either by using iteration or recursion. If you use iteration, simply create a while-loop that propagates a "current" node through the list and stops when it becomes NULL.
And an example refering to specific repetitions:
The following loop outputs numbers 1 to 10 in reverse order. At the k-th iteration, 10-k+1 is printed:
for (i=10; i>=1; i--){
printf("%d\n", i);
}

That's how I would define it:
"Loop" - A control flow statement that iterates the code in the loop's body dependent upon a provided loop condition. It is a language construct and in C we have three kinds of these constructs: for, while and do-while.
"Iteration" - One specific walkthrough of the code inside of the loop's body after the first walkthrough. In other words, a single repetition of the execution of the loop body's code.
When doing looping/iterating (as verb they can be seen equal indeed), you repeat over the code in the loop's body. Every single repetition is an iteration.
A loop's purpose is the capability to do iterations. Without being able to do iterations the loop construct is useless.
So, both terms are closely related, but not the same.

Related

Which is better between defining a variable near its context or avoid repeated allocation/initialisation?

My examples from Python, but I guess the concept applies to most languages. Suppose I have the following scenario
for element in big_list:
temp_var=something # This remains constant throughout the iterations
# Looping clause
Here, temp_var is a constant variable that is necessary within the loop. But if it remains constant, should I define it just before starting the for loop? The two conflicting principles here are
Variables should be defined with the smallest scope possible so as to not crowd the namespace. It is an argument for doing as above, which also keeps the variable closer to the context of usage.
But defining inside the loop requires repeated initialisation and allocation on each iteration. Or is it something the compiler/interpreter optimises so that I can turn a blind eye anyhow?
As the variable will not change inside the loop, I definitely choose to define it before the loop. Also, reason 1 is unuseful if variable it isn't unallocated before exiting the loop, I mean, it will remain alive after the loop. After exit the loop, you can unset the variable. So, my approach will be:
temp_var = something # This remains constant throughout the iterations
for element in big_list:
# Looping clause
# loop ended
del temp_var # If it's not needed anymore
I'm sorry I don't manage python, but I think this "code" is easily understood, and applicable to almost any language.

What do "single-entry" and "single-exit" mean for a statement?

From An Integrated Approach to Software Engineering
By Pankaj Jalote
Clearly, no meaningful program can be written as a sequence of simple
statements without any branching or repetition (which also involves
branching). So, how is the objective of linearizing the control flow
to be achieved? By making use of structured constructs. In
structured programming, a statement is not a simple assignment
statement, it is a structured statement. The key property of a
structured statement is that it has a single-entry and a
single-exit. That is, during execution, the execution of the (structured) statement starts from one defined point and the execution
terminates at one defined point. With single-entry and single-exit
statements, we can view a program as a sequence of (structured)
statements. And if all statements are structured statements, then
during execution, the sequence of execution of these statements will
be the same as the sequence in the program text. Hence, by using
single-entry and single-exit statements, the correspondence between
the static and dynamic structures can be obtained.
The most commonly used single-entry and single-exit statements are
Selection: if B then S1 else S2
if B then S1
Iteration: While B do S
repeat S until B
Sequencing: S1; S2; S3;...
What do "single-entry" and "single-exit" mean in a structured statement?
Why are statements listed at the end are single-entry and single-exit?
For example, in if B then S1 else S2, why is it single exit, given it can terminates at either S1 or S2?
Can you give a statement which is not single entry?
Can you given a statement which is not single exit?
In many languages, the only statements that do not have a single entry are those which happen to contain labels for use with goto or switch statements located outside them, and the only statements that do not have a single exit are those which contain a goto to an outside location, trigger an exception, or otherwise force stack unwinding. Note that for any particular call of a function, the only "normal" exit point will be the code immediately following that call.
The notion of single entry/single exit may be unclear to those who have never worked with code that didn't use such an approach. Examples of the latter may be found when writing code for the platforms like the Atari 2600 where RAM space is often at an absolute premium. If a piece of code will be invoked from the code that shows the title screen, or from within the game logic, and there one can't afford the two bytes of stack space necessary for a subroutine-call instruction, it would not be uncommon to jump to the code (rather than using a "JSR" [jump to subroutine] instruction), and have the code exit by checking whether a game is in progress and jumping back to the appropriate spot in the "show title screen" or "perform game logic" code. Such a design may be awkward to maintain if it becomes necessary to invoke it from more places in the code, but such techniques may be necessary if RAM is really tight (e.g. one only has 128 bytes total, as on the Atari 2600).

Require code to perform this loop in SPSS including looping variable names

I am looking for the spss code to perform the following:
I have three variables: ResponseID and Q1 and Q2 that needs to be copied throughout my data set, I have already included variables for them - it starts with VAR00002, VAR00003 and VAR00004 several times throughout my data set. I now want to populate them, I therefore have to include the name of the variable in the loop and it needs to carry on doing this for the first set of three, the second set (VAR00005,VAR00006 and VAR00007) etc. (depending on the condition included in the Do IF). Then there is also the Else IF (and another Do If) included afterwards.
Loop # = 1 to 27
Do IF (Q[#(23)+2]=2).
COMPUTE (VAR0000(#+1))=ResponseID.
COMPUTE (VAR0000(#+2))=Q1.
COMPUTE (VAR0000(#+3))=Q2.
End if.
Else If.
Do If.
Q[(#-1)*(23)+3])=2.
DELETE VARIABLES Q[#(23)+3] TO Q623.
End If.
End Else If.
I am not sure what you need to do, but take a look at DO REPEAT, which allows you to repeat a set of transformations in a loop.
Niether I understand exactly what you are trying to do, perhaps look into LOOP / VECTOR combination

time complexity is order of n or square of n if i use same variables for nested loops

for(i=0;i<n;i++)
{
for(;arr[i]!=' ';i++)
{
//required code
}
//required code
}
Suppose I want to do some operation like 'reversing each and every word of a sentence (but not sentence as a whole. Example:
Input: "This is a ball"
Output: "sihT si a llab"
'.
Then definitely inside the loop, I will look for a 'Space' character. I want to ask following things:
(1) The way, I have used two loops, why do people say that I am unnecessarily making the program more complex by making it O(n^2).
I know I could use 'if' inside the outer 'for' loop in place of inner 'for'. But, if I choose this way, how could this be O(n^2), as I think I am increasing the loops over same variable 'i', I think it is O(n).
(2)Why "what I have written" (inner for loop in place of 'if') is not considered a good practice? Does it have to do a lot with cache issues?
Your double loop has a time complexity of O(n), since the total number of iterations is n.
Modifing the loop variable of a for loop is considered bad practice. I would use while loops instead.
Note that the inner loop has a bug - it needs to check that it doesn't continue past the end of the buffer.

What are your tips for keeping track and avoiding bugs in loops?

I just found ... AGAIN ... a real time wastage bug as follows
for (int i = 0; i < length; i++)
{ //...Lots of code
for (int j = 0; i < length; j++)
{
//...Lots of code
}
}
Did you notice straight ahead the inner i which SHOULD BE j ? Neither did I. So from now on I am going to use:
for (int i = 0; i < length; i++)
{
for (int i1 = 0; i1 < length; i1++)
{
}
}
What are your tips for inner and outer while and for loops ?
Edit: Thanks for the valuable responses. Herewith short summary of the proposed tips:
use meaningful variables names for index variables ( instead i use SomeObjCollectionLength )
place the contents of the inner loop into a separate method and call that method from the outer loop
not manageable amount of lines of code between the outer and inner loop is a strong signal for code smell
avoid copy pasting and rushing , write the index vars with care
You might want to check the summary by LBushkin for the following
use foreach and iterators whenever possible
initialize the variables just before entering the loops
Make each loop perform only one function. Avoid mixing responsibilities in a single loop
When possible, make your loops short enough to view all at once
Don't use i & j (or any other single letter variable) as index names. Use proper names and you will not get into this type of problems.
One of the simplest and cleanest solutions is to place the contents of the inner loop into a method so it becomes:
for (int i = 0; i < length; i++)
{
DoSomething();
}
private void DoSomething(int outerValue)
{
for (int i = 0; i < length; i++)
{
// Do something else
}
}
For me, the 'code smell' here is 'lots of code'.
If the amount of code in the loops is particularly large, the distance between the inner and outer loops means that they're not as likely to be compared against each other for correctness.
Admittedly, looking at the start of the inner loop in isolation should bring the issue to your attention, but having the main structure in as small a section of code as possible gives your brain less to digest.
It may be possible to extract the 'lots of code' sections into separate functions/methods, in order to reduce the size of the main structure - but this may not alway be practical.
Also, I'd say that 'i1' isn't a particulary good choice of variable name, as that tends to encourage 'i2', 'i3' etc, which doesn't really lead to understandable code. Maybe replacing all of the loop variables with something more meaningful would help the clarity of the code, and reduce the chances of the original error.
My top advice (in no particular order) for writing better loop code (much of this is from the excellent book Code Complete):
Avoid multiple exit points for loops.
Use continue/break sparingly.
Refactor nested loops into separate routines, when possible.
Use meaningful variable names to make nested loops readable.
Use foreach() loops when possible, rather than for(i=...) loops.
Enter the loop from one location only. Don't jump into a loop with goto's. Ever.
Put initialization code immediately before the loop.
Keep loop initialization statements with the loop they are related to.
Avoid reusing variables between non-nested loops.
10.Limit the scope of loop-index variables to the loop itself.
Use while(true) for infinite loops, rather than for(;;)
In languages that provide block constructs (e.g. '{' and '}') use them rather than indenting to enclose the statements of a loop. Yes, even for single line loops.
Avoid empty loops.
Avoid placing housekeeping chores in the middle of a loop, place them at the beginning and/or end instead.
Make each loop perform only one function. Avoid mixing responsibilities in a single loop.
Make loop termination conditions obvious.
Don't monkey with the loop index variable of a for() loop to make it terminate.
Avoid code that depends on the loop indexer's final value.
Consider using safety counters in complex loops - they can be checked to make sure the loop doesn't execute too many, or too few times.
Use break statements, when possible, to terminate while loops.
When possible, make your loops short enough to view all at once.
That's a copy-paste mistake, avoid copy paste.
As for your solution, its not much better. The mistake can still slip between tons of code. I tend to use meaningful names even for loop temporary variables.
leverage your IDE, on VS, try to use this: http://msdn.microsoft.com/en-us/library/z4c5cc9b(VS.80).aspx
sample: type for, then press Tab Tab successively
I came here to be smart and say "I just write it right the first time". But then I saw your example and, well, I've done that too many times myself.
When you need nested loops like that, my only solution is to be alert and thinking when you write the code.
Where possible, using iterators and for each loops are nice.
Also, I can't see how your suggested solution is going to be any better. And it doesn't look as nice either.
First of all, reduce the loop body size, i.e. move stuff to separate functions. It is generally a bad idea to have functions longer than what can fit into the screen, so loops should be even smaller.
Secondly, use meaningful variable names in cases like this. I would only use i and j in simple loops with a few lines of code. For instance, if you are going through a two-dimensional array, "col" and "row" would make much more sense, make the code easier to read ("which was which?") and easier to spot mistakes like this.
You just have to take extra care of such issues, there's no magic bullet against this. Even with "better naming" you propose you will once in a while lose track of whether this is Nth or (N+M)th level of nested loop and make an error.
If nested loop is necessary write it carefully. If it can be avoided by extracting the outer loop body into a function that would be a good guard against indices misuse.
As in this as in many things, there's some excellent advice in Steve McConnell's Code Complete. It would be well worth your time to read what he's got to say about building good looping code. I don't have my copy of the book handy here but the whole book is worth your time.
I use 'ii' and 'jj' for transient loop counters if I really need them - they are easier to search for than 'i' and 'j' and also easier to spot in examples like the above. To go one better you can actually use a real variable name. If you're looping over a string then you can call it characterIndex or something. It's more typing, but it documents itself and saves time on debugging obscure problems later.
Better still would be to avoid numerical counters and use named iterators over a collection. They make the intent clearer, in my opinion.
Finally, if possible it's nice to do away with the loop entirely: Boost::Foreach is one way of doing this in C++, although I generally prefer to use languages such as Python which natively allow direct iteration over the contents of a container without a need for incrementing an index value or iterator.
Try to use more declarative loop constructs. For instance, if you don't really need indices (those is and js) and your programming environment allows for it, you can use a foreach construct to iterate over the collection.

Resources