有人可以解释为什么这个程序可以计算小数点后的位数

Can somebody explain why this program can count the number of digits after decimal point?

本文关键字:小数点 计算 解释 为什么 程序      更新时间:2023-10-16

显然,该程序可以计算小数点后的位数。它有效,但我很难理解它。

布尔在这里到底做了什么? 如果(ch=='.'( f=true;在这里实现?

#include <iostream>
#include <cstdio>
using namespace std;
int main()
{
    char ch;
    bool f=false;
    int num=0;
    while((ch=getchar())!='n')
    {
        if(f)
            if(ch>='0' && ch<='9')
                num++;
            else
                break;
        if(ch=='.')
            f=true;
    }
    if(num>0)
        cout<<num<<endl;
    else
        cout<<"false"<<endl;
    return 0;
}

它可以完美地给出结果。只是好奇它为什么有效。

我不怪你感到困惑。它显示了好的变量名的重要性。 f跟踪我们是否已经看到了'.'。它应该被命名为更具描述性的东西,例如 haveSeenDecimalPoint .

bool haveSeenDecimalPoint=false;
while((ch=getchar())!='n')
{
    if(haveSeenDecimalPoint)
        if(ch>='0' && ch<='9')
            num++;
        else
            break;
    if(ch=='.')
        haveSeenDecimalPoint=true;
}

它一开始是错误的,这意味着我们还没有看到.。第一个if陈述一直是错误的。当我们看到一个.时,第二个if语句将标志设置为 true。之后,任何其他字符都将触发内部if/else测试。小数点后的任何数字都会触发num++,一旦我们看到非数字,我们就完全break出循环。

f 是一个bool类型的变量(不是函数,尽管它没有一个非常描述性的名称(,在这种情况下,标记是否已遇到.字符。它以false开始,并在读取.字符后切换到true。这就是if (ch == '.') f = true的用途。

一旦找到.字符,它将开始计算数字。这就是这些行的用途:

if ('0' <= ch && ch <= '9') num++; // Count a digit character
else break;                        // If not a digit, break the loop

中断循环后,其余代码仅打印找到的位数。

这个答案应该是一个注释,但注释不允许呈现更复杂的代码......

John Kugelman 已经给出了一个合适的答案,但代码的结构还可以更好:

if(haveSeenDecimalPoint)
// while braces are optional in given case, they still better are placed
// as the following code is pretty complex; you gain better overview
{
    if('0' <= ch && ch <= '9') // optional; ressembles closer mathematical
                               // expression 0 <= ch <= 9
                               // (which cannot be written that way in C++!)
        num++;
    else
        break;
}
// if decimal point HAS been found already, no need to check any further
// so place the else to avoid unnecessary checks (if another period occures, 
// it's already covered by breaking on ch < '0' || ch >= '9')
else if(ch == '.')
{ // due to the newly introduced else: recommendation: if one branch needs 
  // braces, place on all of them – some coding conventions even mandate
  // ALWAYS placing braces
    haveSeenDecimalPoint = true;
}

不带注释的代码:

if(haveSeenDecimalPoint)
{
    if('0' <= ch && ch <= '9')
        num++;
    else
        break;
}
else if(ch == '.')
{
    haveSeenDecimalPoint = true;
}

注意额外放置的空间,它们也可以提高可读性。

该循环正在做两件不同的事情,并使用f来跟踪它正在做的一件事。这通常令人困惑,代码可能应该编写为两个单独的循环:

// skip until the decimal point
while ((ch = getchar()) != 'n' && ch != '.')
    ; // nothing to do here
// check that we haven't hit the end of the input
if (ch != 'n')
    // count digit characters
    while ((ch = getchar()) >= '0' && ch <= '9')
        ++num;

注意,在最后一个循环中没有显式检查'n';这是不需要的,因为'n'不会在'0''9'之间,所以得到'n'将结束循环。