一段简单的小程序看不懂求大家帮帮忙解释一下

时间:2023-02-10 19:58:39
  #include <ctype.h>
   /* atof:  convert string s to double */
   double atof(char s[])
   {
       double val, power;
       int i, sign;
       for (i = 0; isspace(s[i]); i++)  /* skip white space */
           ;
       sign = (s[i] == '-') ? -1 : 1;
       if (s[i] == '+' || s[i] == '-')
           i++;
       for (val = 0.0; isdigit(s[i]); i++)
           val = 10.0 * val + (s[i] - '0');
       if (s[i] == '.')
           i++;
       for (power = 1.0; isdigit(s[i]); i++) {
           val = 10.0 * val + (s[i] - '0');
           power *= 10;
       }
       return sign * val / power;
   }

前面的跳过空白符的for无法理解
找到小数点后的操作也无法理解
???

10 个解决方案

#1


把语句一条条拆开就容易理解,比如:

for (i = 0; isspace(s[i]); i++)  /* skip white space */
    ;

可以拆解为:

i = 0;
while(isspace(s[i])
{
    i++;
}

#2


       for (i = 0; isspace(s[i]); i++)  /* skip white space */
           ;
跳过空白符,唯一操作就是i++,所以为空白符的s[i]都被跳过了,接下来的s[i]是第一个非空字符。
而至于求小数部分操作:
       for (power = 1.0; isdigit(s[i]); i++) {
           val = 10.0 * val + (s[i] - '0');
           power *= 10;
这个循环计算结束之后,val是个整数值。power是val要除的数。
例如,小数0.456经过计算之后,val是456,power是1000。456/1000=0/456。

#3


Quote: 引用 1 楼 walkiz 的回复:

把语句一条条拆开就容易理解,比如:

for (i = 0; isspace(s[i]); i++)  /* skip white space */
    ;

可以拆解为:

i = 0;
]while(isspace(s[i])
{
    i++;
}
[/quote

它是跳过所有空格还是只跳过一个第一个呢?
这个while执行了多少次

#4


引用 2 楼 u012033027 的回复:
       for (i = 0; isspace(s[i]); i++)  /* skip white space */
           ;
跳过空白符,唯一操作就是i++,所以为空白符的s[i]都被跳过了,接下来的s[i]是第一个非空字符。
而至于求小数部分操作:
       for (power = 1.0; isdigit(s[i]); i++) {
           val = 10.0 * val + (s[i] - '0');
           power *= 10;
这个循环计算结束之后,val是个整数值。power是val要除的数。
例如,小数0.456经过计算之后,val是456,power是1000。456/1000=0/456。


它不是从小数点后面开始算的吗?
它前面在碰到小数点之前不也是计算了一个val了吗?
然后又在计算一次?就是这里好乱

#5



#include <ctype.h>
   /* atof:  convert string s to double */
   double atof(char s[])
   {
       double val, power;
       int i, sign;
       for (i = 0; isspace(s[i]); i++)  /* skip white space */
           ;
       sign = (s[i] == '-') ? -1 : 1; //取符号
       if (s[i] == '+' || s[i] == '-')
           i++;  
       for (val = 0.0; isdigit(s[i]); i++)
           val = 10.0 * val + (s[i] - '0'); //这边的val是整数部分
       if (s[i] == '.') //跳过小数点
           i++;
       for (power = 1.0; isdigit(s[i]); i++) {
           val = 10.0 * val + (s[i] - '0');//小数部分
           power *= 10;//多一位小数就多乘一次10为最后的除法作准备
       }
       return sign * val / power;
   }

#6


本新手,推算一下代码思路,不对勿拍

它的思路大约是这样,
123.456,以字符串形式输入,
进入函数后检查字符串,前面是否有空格,和符号,有则跳过符号,把字符串转换成
123456,另外找个变量记算一下有几个位的小数,这里是3位,于是123456/1000=123.456

#7


引用 6 楼 yajuie的回复:
本新手,推算一下代码思路,不对勿拍

它的思路大约是这样,
123.456,以字符串形式输入,
进入函数后检查字符串,前面是否有空格,和符号,有则跳过符号,把字符串转换成
123456,另外找个变量记算一下有几个位的小数,这里是3位,于是123456/1000=123.456

本新手,推算一下代码思路,不对勿拍

它的思路大约是这样,
123.456,以字符串形式输入,
进入函数后检查字符串,前面是否有空格,和符号,有则跳过符号,把字符串转换成
123456,另外找个变量记算一下有几个位的小数,这里是3位,于是123456/1000=123.456
本新手,推算一下代码思路,不对勿拍

它的思路大约是这样,
123.456,以字符串形式输入,
进入函数后检查字符串,前面是否有空格,和符号,有则跳过符号,把字符串转换成
123456,另外找个变量记算一下有几个位的小数,这里是3位,于是123456/1000=123.456
前面还有个变量记录了符号是+还是-
最后的结果
123.456*-1=-123.456
或者
123.456*1=123.456

#8


我觉得如果看不过来的时候,可以GDB跟踪
或者加打印看,这样就清楚了

#9


引用 4 楼 czwxp 的回复:
Quote: 引用 2 楼 u012033027 的回复:

       for (i = 0; isspace(s[i]); i++)  /* skip white space */
           ;
跳过空白符,唯一操作就是i++,所以为空白符的s[i]都被跳过了,接下来的s[i]是第一个非空字符。
而至于求小数部分操作:
       for (power = 1.0; isdigit(s[i]); i++) {
           val = 10.0 * val + (s[i] - '0');
           power *= 10;
这个循环计算结束之后,val是个整数值。power是val要除的数。
例如,小数0.456经过计算之后,val是456,power是1000。456/1000=0/456。


它不是从小数点后面开始算的吗?
它前面在碰到小数点之前不也是计算了一个val了吗?
然后又在计算一次?就是这里好乱


只有一个val,小数点之后才算完。如果是123.456,那么val=123456,power=1000

#10


引用 9 楼 u012033027 的回复:
Quote: 引用 4 楼 czwxp 的回复:

Quote: 引用 2 楼 u012033027 的回复:

       for (i = 0; isspace(s[i]); i++)  /* skip white space */
           ;
跳过空白符,唯一操作就是i++,所以为空白符的s[i]都被跳过了,接下来的s[i]是第一个非空字符。
而至于求小数部分操作:
       for (power = 1.0; isdigit(s[i]); i++) {
           val = 10.0 * val + (s[i] - '0');
           power *= 10;
这个循环计算结束之后,val是个整数值。power是val要除的数。
例如,小数0.456经过计算之后,val是456,power是1000。456/1000=0/456。


它不是从小数点后面开始算的吗?
它前面在碰到小数点之前不也是计算了一个val了吗?
然后又在计算一次?就是这里好乱


只有一个val,小数点之后才算完。如果是123.456,那么val=123456,power=1000


谢谢了

#1


把语句一条条拆开就容易理解,比如:

for (i = 0; isspace(s[i]); i++)  /* skip white space */
    ;

可以拆解为:

i = 0;
while(isspace(s[i])
{
    i++;
}

#2


       for (i = 0; isspace(s[i]); i++)  /* skip white space */
           ;
跳过空白符,唯一操作就是i++,所以为空白符的s[i]都被跳过了,接下来的s[i]是第一个非空字符。
而至于求小数部分操作:
       for (power = 1.0; isdigit(s[i]); i++) {
           val = 10.0 * val + (s[i] - '0');
           power *= 10;
这个循环计算结束之后,val是个整数值。power是val要除的数。
例如,小数0.456经过计算之后,val是456,power是1000。456/1000=0/456。

#3


Quote: 引用 1 楼 walkiz 的回复:

把语句一条条拆开就容易理解,比如:

for (i = 0; isspace(s[i]); i++)  /* skip white space */
    ;

可以拆解为:

i = 0;
]while(isspace(s[i])
{
    i++;
}
[/quote

它是跳过所有空格还是只跳过一个第一个呢?
这个while执行了多少次

#4


引用 2 楼 u012033027 的回复:
       for (i = 0; isspace(s[i]); i++)  /* skip white space */
           ;
跳过空白符,唯一操作就是i++,所以为空白符的s[i]都被跳过了,接下来的s[i]是第一个非空字符。
而至于求小数部分操作:
       for (power = 1.0; isdigit(s[i]); i++) {
           val = 10.0 * val + (s[i] - '0');
           power *= 10;
这个循环计算结束之后,val是个整数值。power是val要除的数。
例如,小数0.456经过计算之后,val是456,power是1000。456/1000=0/456。


它不是从小数点后面开始算的吗?
它前面在碰到小数点之前不也是计算了一个val了吗?
然后又在计算一次?就是这里好乱

#5



#include <ctype.h>
   /* atof:  convert string s to double */
   double atof(char s[])
   {
       double val, power;
       int i, sign;
       for (i = 0; isspace(s[i]); i++)  /* skip white space */
           ;
       sign = (s[i] == '-') ? -1 : 1; //取符号
       if (s[i] == '+' || s[i] == '-')
           i++;  
       for (val = 0.0; isdigit(s[i]); i++)
           val = 10.0 * val + (s[i] - '0'); //这边的val是整数部分
       if (s[i] == '.') //跳过小数点
           i++;
       for (power = 1.0; isdigit(s[i]); i++) {
           val = 10.0 * val + (s[i] - '0');//小数部分
           power *= 10;//多一位小数就多乘一次10为最后的除法作准备
       }
       return sign * val / power;
   }

#6


本新手,推算一下代码思路,不对勿拍

它的思路大约是这样,
123.456,以字符串形式输入,
进入函数后检查字符串,前面是否有空格,和符号,有则跳过符号,把字符串转换成
123456,另外找个变量记算一下有几个位的小数,这里是3位,于是123456/1000=123.456

#7


引用 6 楼 yajuie的回复:
本新手,推算一下代码思路,不对勿拍

它的思路大约是这样,
123.456,以字符串形式输入,
进入函数后检查字符串,前面是否有空格,和符号,有则跳过符号,把字符串转换成
123456,另外找个变量记算一下有几个位的小数,这里是3位,于是123456/1000=123.456

本新手,推算一下代码思路,不对勿拍

它的思路大约是这样,
123.456,以字符串形式输入,
进入函数后检查字符串,前面是否有空格,和符号,有则跳过符号,把字符串转换成
123456,另外找个变量记算一下有几个位的小数,这里是3位,于是123456/1000=123.456
本新手,推算一下代码思路,不对勿拍

它的思路大约是这样,
123.456,以字符串形式输入,
进入函数后检查字符串,前面是否有空格,和符号,有则跳过符号,把字符串转换成
123456,另外找个变量记算一下有几个位的小数,这里是3位,于是123456/1000=123.456
前面还有个变量记录了符号是+还是-
最后的结果
123.456*-1=-123.456
或者
123.456*1=123.456

#8


我觉得如果看不过来的时候,可以GDB跟踪
或者加打印看,这样就清楚了

#9


引用 4 楼 czwxp 的回复:
Quote: 引用 2 楼 u012033027 的回复:

       for (i = 0; isspace(s[i]); i++)  /* skip white space */
           ;
跳过空白符,唯一操作就是i++,所以为空白符的s[i]都被跳过了,接下来的s[i]是第一个非空字符。
而至于求小数部分操作:
       for (power = 1.0; isdigit(s[i]); i++) {
           val = 10.0 * val + (s[i] - '0');
           power *= 10;
这个循环计算结束之后,val是个整数值。power是val要除的数。
例如,小数0.456经过计算之后,val是456,power是1000。456/1000=0/456。


它不是从小数点后面开始算的吗?
它前面在碰到小数点之前不也是计算了一个val了吗?
然后又在计算一次?就是这里好乱


只有一个val,小数点之后才算完。如果是123.456,那么val=123456,power=1000

#10


引用 9 楼 u012033027 的回复:
Quote: 引用 4 楼 czwxp 的回复:

Quote: 引用 2 楼 u012033027 的回复:

       for (i = 0; isspace(s[i]); i++)  /* skip white space */
           ;
跳过空白符,唯一操作就是i++,所以为空白符的s[i]都被跳过了,接下来的s[i]是第一个非空字符。
而至于求小数部分操作:
       for (power = 1.0; isdigit(s[i]); i++) {
           val = 10.0 * val + (s[i] - '0');
           power *= 10;
这个循环计算结束之后,val是个整数值。power是val要除的数。
例如,小数0.456经过计算之后,val是456,power是1000。456/1000=0/456。


它不是从小数点后面开始算的吗?
它前面在碰到小数点之前不也是计算了一个val了吗?
然后又在计算一次?就是这里好乱


只有一个val,小数点之后才算完。如果是123.456,那么val=123456,power=1000


谢谢了