This part is pretty easy, just skips to the first non-whitespace character:
for (i = 0; isspace(s[i]); i++) //skip whitespace
;
Now we check if the first non-whitespace character is a - to set it negative, then skip over the character whether its a - or a +:
sign = (s[i] == '-') ? -1 : 1;
if (s[i] == '+' || s[i] == '-')
i++;
Now it starts to get tricky. Let's use an example of 1234.5678. First we're going to handle the part before the decimal. Its handled by looking at each digit, adding it to val, then if the next digit is not a decimal, multiply val up to the point by 10 to left shift it and add the next digit. For example with 1234.5678, we first see digit 1, add it to val for a val of 1. The next digit is 2, so we multiple current val (1) by 10 to get 10 then add 2 to get 12. The next digit is 3, so we multiply the current val (12) by 10 to get 120, then add 3 to get 123. The next digit is 4, so we multiple the current val (123) by 10 to get 1230, then add 4 to get 1234. Then the '.' is not a digit, so we've finished the left side of the number.
for (val = 0.0; isdigit(s[i]); i++)
val = 10.0 * val + (s[i] - '0');
This part just moves past the dot.
if (s[i] == '.')
i++;
Now we do the same with the right side of the decimal as we did with the left, but we also track how many digits are past the decimal (with the power variable). In the example of 1234.5678, the first digit we see is 5. So we multiply the current val (1234) by 10 and add 5 for (12345). We also increase our power to 10.0. This continues until we get a val of 123456789 and a power of 10000.0.
for (power = 1.0; isdigit(s[i]); i++) {
val = 10.0 * val + (s[i] - '0');
power *= 10.0;
}
Finally, we divide by the power to get the decimal place in the correct spot (123456789 / 10000.0):
return sign * val / power;