does this line predate the while loop?
or boolean values in C?
does this line predate the while loop?
or boolean values in C?
It's the other way around. Very early C didn't have a for loop. It seems it was introduced in Unix V5: http://minnie.tuhs.org/cgi-bin/utree.pl?file=V5/usr/c/c00.c
And a for loop is basically just a while one, but they are sometimes used in different ways than the usual `for (size_t i = 0; i < len; ++i)`. One of my favorites is http://git.musl-libc.org/cgit/musl/tree/src/internal/floatsc....
>or boolean values in C?
1 and 0 are boolean values in C. But C didn't have a boolean type until C99 (called _Bool or bool after including <stdbool.h>).
c|32 will do a bitwise downcase of an ascii character so, "INFINITY", "infinity", "INfinITy" will all be accepted. In any of those cases i == 8 at the end of the loop and is still in scope, so the following if statement will ultimately return + or - Infinity.
> What does that loop even do?
for (i=0; i<8 && (c|32)=="infinity"[i]; i++)
if (i<7) c = shgetc(f);
It's a pattern matching loop. The 'c' variable is a character which is read from FILE * f. In this case, it's attempting to match the string "infinity" which has a length of 8. With ASCII, uppercase letters start from hex value 0x41 for the letter 'A'. Lowercase letters start from hex value 0x61 for the letter 'a'. Thus the difference between lowercase and uppercase is 0x20 which is 32 decimal or 100000 in binary. Thus, if you or the value of 'c' with 32 (0x20 or 00010000), you're setting the 2^5 bit of the character which converts uppercase to lowercase and leaves lowercase unchanged since all lowercase characters already have that bit set.I'm sure you can figure out the rest. As long as the character matches the corresponding index position in the character array "infinity", the for loop keeps matching characters. Eventually, a successful match results in a return value of sign * INFINITY from the function.
It's closer to an iterator over argv.
First, it sets the firsttime=1 flag, then it tries to open the first argument (file). After the first arg, it sets firsttime=0. It only breaks out of the loop once argv is exhausted.
firsttime=True
while (True) {
..
..
..
firsttime=False
}People educated in the Wirth way would say "that's not a for loop; there is no way to tell how often it will iterate when it is first entered" and write it as a while loop.
Old-school C programmers seem to think one iteration construct is enough for everybody and like to write any iteration as a for loop, ideally with a few commas and no actual statements, as in the classic strcpy:
char *strcpy(char *dst, CONST char *src)
{
char *save = dst;
for (; (*dst = *src) != '\0'; ++src, ++dst);
return save;
}
(from http://www.ethernut.de/api/strcpy_8c_source.html)Programmers with soe Wirth-style training do at least something like
char *
strcpy(char *s1, const char *s2)
{
char *s = s1;
while ((*s++ = *s2++) != 0)
;
return (s1);
}
(from http://www.opensource.apple.com/source/Libc/Libc-167/gen.sub...)[If you google, you can find way more variations on this. for example, http://fossies.org/dox/glibc-2.20/string_2strcpy_8c_source.h... does a do {...} while(....) that I am not even sure is legal C; it uses offsets into the source to write into the destination]
From your example I guess you are definitely in the Wirth (Pascalish) camp, beyond even that second state. Classic C programmers would either use 0 and 1 for booleans or #define macros FALSE and TRUE (modern C has true booleans, but that extra #include to get it increases compilation time, so why do it?
I am in te Pascal-ish camp. I like to say C doesn't have a for loop because its 'for' is just syntactic sugar for a while loop.
Also, as the other guy said, that code has while loops.
> while ((ch = getopt(argc, argv, "n:")) != -1) {
bool was introduced in C99