c - K&R答题簿练习1.21

标签 c

问题是:

Write the program entab that replaces strings of blanks by the minimum number of tabs and blanks to achieve the same spacing. Use the same tab stops as for detab. When either a tab or a single blank would suffice to reach a tab stop, which should be given preference?

我自己做的,书上的答案有不同的解法。我不理解从输入流中读取选项卡时执行的数学公式。这是代码:

#include <stdio.h>
#define TABINC 8

main()
{
int c, nb, nt, pos;

nb = 0;
nt = 0;
for (pos = 1; (c =getchar()) != EOF; ++pos)
    if (c == ' '){
        if (pos % TABINC != 0)
            ++nb;
        else {
            nb = 0;
            ++nt;
        }
    }
    else {
        for ( ; nt > 0; --nt)
            putchar('\t');
        if (c == '\t')
            nb = 0;
        else
            for ( ; nb > 0; --nb)
                putchar(' ');
        putchar(c);
        if ( c == '\n')
            pos = 0;
        else if (c == '\t')
            pos = pos + (TABINC - (pos - 1) % TABINC) - 1;
    }
}

我不理解的部分如下:

else if (c == '\t')
    pos = pos + (TABINC - (pos - 1) % TABINC) - 1;

我可以通过 visual studio 中的调试看到,当输入流中出现制表符时,此构造将 pos 带到下一个制表位。这是正确的吗?

我真正不明白的是这个公式是如何运作的,或者他们是如何想出这个公式的。这是编程中出现的常见公式吗?有用吗?它有名字吗?

编辑:我确实理解模运算符的作用。抱歉,我没有具体说明。

最佳答案

此公式没有具体名称 - 它是将小学数学应用到日常问题的一种相对简单的方法。这是发生了什么:'\t'字符推进 pos从 1 到 TABINC 的多个位置, 包括在内。

  • 何时posTABINC 的倍数,你跳完整TABINC
  • 何时posTABINC 的下一个倍数以下的一个,你跳了一个,
  • 何时posTABINC 的下一个倍数小二,你跳了两个,
  • 等等 - 当posx , 其中0 < x < TABINC , 低于 TABINC 的下一个倍数,你跳x

现在计算跳跃的问题被简化为计算pos之间的差值。和下一个 TABINC 的倍数.这可以通过计算 pos 的除法余数来完成。和 TABINC ,并从 TABINC 中减去余数.这是通过 % 完成的运营商。

pos是从一开始的 *,公式做的第一件事是使它从零开始,以便计算余数。接下来,该公式计算余数,这是表示“最后一个 TABINC 止损上方的持仓数”的数学方式。现在你需要做的就是从 TABINC 中减去余数。得到你的结果。

* 赋值 pos=0关于发现'\n'似乎与 pos 的断言相矛盾是基于一个的。但是,循环 header 执行 pos++每次迭代后,循环的下一次迭代会看到 pos=1在下一次迭代中。

关于c - K&R答题簿练习1.21,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21061127/

相关文章:

c - 无法读取指针数组的元素,第 0 个元素除外

c - 读取文件中的数据问题

c - 如何在列表中添加更多字段

c - 在这种情况下, int x 的最小值和最大值是多少?

C 段错误,即使使用 EOF

java - 为什么 switch 语句上有奇怪的缩进?

c - 第一个 C 编译器是如何编写的?

c - 如何避免多次提示用户输入?

c - getchar() 和 putchar() 宏如何?

c# - 下面代码中的1.e0是什么意思