> 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.
The whole function is trying to parse a float value, that loop is looking for the string "Infinity".
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.
It's not a while loop... well, maybe a "while 1 {}" loop.
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.
Depends on the person. There likely is a correlation on what century you learned programming, but certainly one whether you have experience with pascal-ish languages.
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:
[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.
That's probably the cleaner way to do it, but honestly, the hacked for-loop feels pretty clean too. And it ensures that your firsttime flag is properly set, regardless of how you break out of the loop (a 'continue' in the middle of your example would fail to set the flag properly).
That is not correct. In C99, _Bool (and the typedef bool) are special, because when any value is converted to _Bool, the result is 0 or 1 (!!x). Although the standard does not explicitly say that _Bool can only hold anything other than 0 and 1 (only that it is capable of representing these values), this seems to be the case, effectively.
It's a bit more, the bool type can only hold two values, 0 and 1. (6.3.1.2 Boolean type #1) "When any scalar value is converted to _Bool, the result is 0 if the value compares equal to 0; otherwise, the result is 1."
does this line predate the while loop?
or boolean values in C?