Synopsis: The sixth chapter in Stephen Prata’s C Primer Plus.
Loop with precondition:
for (initialization; examination; update)
operator
Initializing expression → test expression → corrective expression
Loop with postcondition:
do
operator
while (expression)
The operational part is repeated until the expression becomes false (false), i.e. equal to zero.
Contents:
Greek philosopher Zeno and the for loop
The Greek philosopher Zeno claimed that an arrow would never hit its target. At first, he said, the arrow flies halfway to the target. Then she flies half of the remaining path, then – half of the path that remains, and so on ad infinitum.
Since the entire arrow is broken into an infinite number of parts, Zeno argued, it would take an infinite amount of time for the arrow to reach the end of the path. However, we doubt that Zeno would have voluntarily agreed to become a living target in order to prove his case.
In this program, I first realized how important it is to give good, useful names to variables. Otherwise, the program turns into a real mess – with all these n, x, y, and so on. My version of Zeno’s aporia differs from the book version, it considers the situation of an arrow flying on the server for some infinitely divisible tick on the server:
#include <stdio.h>
int main (void)
{
int tick, limit;
double arrow, distance;
printf("Enter number of server ticks\n");
scanf("%d", &limit);
for (tick=1, arrow=1; tick <= limit; tick++, arrow=arrow/2)
{
distance = 1 - arrow;
printf("For %d tick arror would move %.6f distance\n",tick,distance);
}
getchar();getchar();
return 0;
}
Whereas the book presents rather an exercise with fractions.
…suppose the arrow takes one second to travel the first half of its path. It then takes 1/2 second to fly half the distance left, another 1/4 second to cover half the distance left after that, and so on. The total time of flight of the arrow can be represented as the following infinite sequence:
1 + 1/2 + 1/4 + 1/8 + 1/16 + …
Thus, the program proposes to use the ‘increment’ of multiplying the denominator (English denominator) of a fraction by 2. Like this (I replaced the seconds with ticks, this is somehow more correct):
#include <stdio.h>
int main (void)
{
int tick, limit;
double denominator, distance;
printf("Enter number of server ticks\n");
scanf("%d", &limit);
for (distance=0, tick=1, denominator=1; tick <= limit; tick++, denominator*=2)
{
distance+=1/denominator;
printf("For %d tick arror would make %.6f distance\n",tick,distance);
}
getchar();getchar();
return 0;
}
In general, the use of fractions here gave me problems when compiling the program (as I wrote earlier, I try not to peep into the book). In my first version, everything is somehow much clearer. Well, from a textbook point of view, causing problems is good, we’re learning 🙂 Actually, the purpose of this program was to show that more than one comma operation can be used.
Program “guess the number” – loop with postcondition (do while)
#include <stdio.h>
int main (void)
{
int n;
do
{
printf("Guess my favorite number!\n");
scanf("%d", &n);
} while (n != 13);
printf("Yay! It's 13!\n");
getchar();getchar();
return 0;
}
Cycle example. using the return value of a function
I pored over this program for quite a long time because of jambs with data types, then the results did not converge because of < instead of <= 🙂
// power.c - program to power up number #include <stdio.h> double power (double a, int b); int main (void) { double a; // number which we want to power int b; // power value double result; // result of calculation printf("Enter number and power or 'q' to quit:\n"); while (scanf("%lf%d", &a, &b) == 2) { result = power (a, b); printf("%.3f powered by %d is %.3f\n", a, b, result); printf("Enter another number and power or 'q' to quit):\n"); } getchar();getchar(); return 0; } double power (double a, int b) { int count; // counter to get to power value double pow = 1.0; // power calculation (sum of multiplications) for (count = 1; count <= b; count++) pow *= a; return pow; }
Programs with a more complex structure begin, so I will publish them with indents (I will have to move comments because of this, but what can I do …).
The program from control questions (#5), where it was necessary to find errors; here’s the corrected version:
#include <stdio.h> int main(void) { int i, j, list[10]; for (i = 0; i <= 9; i++) { list[i] = 2*i + 3; for (j = 0; j <= i; j++) printf(" %d", list[j]); printf("\n"); } getchar(); getchar(); return 0; }
Output:
3 3 5 3 5 7 3 5 7 9 3 5 7 9 11 3 5 7 9 11 13 3 5 7 9 11 13 15 3 5 7 9 11 13 15 17 3 5 7 9 11 13 15 17 19 3 5 7 9 11 13 15 17 19 21
In this program, I ran into the fact that you need to “reversely” understand what the program should do. The “step by step” mode of the compiler helped me figure it out (in Borland it’s called Step Over, hotkey F8), everything fell into place in it 🙂
The sixth program from the control questions – with nested loops. While reading about nested loops, it seems that it is quite complicated. In fact, the little one is not so scary; at least if the task is relatively simple, as here, to draw a golden square:
$$$$$$$$ $$$$$$$$ $$$$$$$$ $$$$$$$$
Output like this:
#include <stdio.h> int main(void) { int col, row; for (row = 1; row <= 4; row++) { for (col = 1; col <= 8; col++) printf("$"); printf("\n"); } getchar(); return 0; }
When doing security question #5, I realized that I was confused about the do while loop, because it seemed to me that in the example indicated there, you need to print an extra “Bye!”:
#include <stdio.h> int main(void) { int i = 0; while (++i < 4) printf("Hi! "); do printf("Bye! "); while (i++ < 8); return 0; }
Output:
Hi! Hi! Hi! Bye! Bye! Bye! Bye! Bye!
To understand, I changed the loop and in the “step by step” mode of the compiler I saw how it works, I recommend:
#include <stdio.h> int main(void) { int i = 1; do printf("%d ", i); while (i++ < 4); getchar(); return 0; }
In general, do while is a dangerous thing. For authentication, it is great, of course, but it’s quite easy to get confused. Perhaps it’s a matter of habit, you need to fill your hand 🙂
I wrote a separate next article about the eighth problem – the problem was painfully rewarding (don’t mess with scanf!).
Further, I was covered with a stupor regarding the sequence of increments. Here is a case, I decided to experiment:
#include <stdio.h> int main(void) { char letter; letter = 'a'; printf("%c is %d\n\n", letter, letter); printf("%c is %d... now a++: %c is %d\n", letter, letter, (letter)++, (letter)++); getchar(); getchar(); return 0; }
Output:
a is 97
c is 99... now a++: b is 97
Whaaat? I started smoking and remembered that at first these increments all work, and then everything is printed (and not one at a time, as it seemed to me) 🙂 Well, fir-trees. This is what it means to “practice a little” (MYTH). But why the hell is c is 99… now a++: b is 97) ? Apparently this is some kind of recursion, which is taken from where the hell knows where .. I’m afraid to imagine what can be done with such crooked expressions: D Pah-pah-pah, mind me!
I will also put the programming exercises for this chapter in a separate next post, because. there is already a decent test, and there are as many as 18 tasks in the exercises and many of them are not easy.