C K&;R答案册练习1.21
问题是: 编写程序entab,用最少的制表符和空格数替换空格串,以达到相同的间距。使用与detab相同的制表位。当一个制表符或一个空格足以到达制表位时,应优先选择哪一个 我自己做了这个练习,这本书的答案有一个不同的解决方案。我不理解从输入流读取选项卡时执行的数学公式。代码如下:C K&;R答案册练习1.21,c,C,问题是: 编写程序entab,用最少的制表符和空格数替换空格串,以达到相同的间距。使用与detab相同的制表位。当一个制表符或一个空格足以到达制表位时,应优先选择哪一个 我自己做了这个练习,这本书的答案有一个不同的解决方案。我不理解从输入流读取选项卡时执行的数学公式。代码如下: #include <stdio.h> #define TABINC 8 main() { int c, nb, nt, pos; nb = 0; nt = 0; for (pos = 1; (c =get
#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;
}
}
通过在VisualStudio中的调试,我可以看到当输入流中出现一个制表符时,这个构造将pos带到下一个制表符停止点。这是正确的吗
我真正不明白的是这个公式是如何工作的,或者他们是如何想出这个公式的。这是编程中常见的公式吗?它有用吗?它有名字吗
编辑:我确实理解模运算符的作用。很抱歉,我没有指定它。它没有名字或类似的东西。
详细信息:
首先,必须增加多少pos取决于pos%TABINC,
例如,TABINC是8,因此如果pos是8的倍数,则添加8,
如果位置%8是1(如9,17…),则添加7,
如果位置%8为2(10,18…),则添加6,依此类推。
完整列表:
位置%8->要添加的编号
0->8
1->7
2->6
3->5
4->4
5->3
6->2
7->1
这将是
8-pos%8
或更一般的TABINC-pos%TABINC
重要提示:将C中的某物模化的负数在数学上是不正确的
在C中,对于
a,b>=0
:(-a)%b==-(a%b)
代码中添加的内容是
(TABINC-(pos-1)%TABINC)-1
通过一些基本的数学和上述事实,这是
(TABINC-(pos-1)%TABINC)-1
=TABINC-((位置-1)%TABINC))-1
=TABINC-((位置%TABINC)-1)-1
=TABINC+1-(位置%TABINC)-1
=TABINC-(位置%TABINC)
这与我上面的简短公式相同,只是毫无原因地更加复杂。
这个公式没有特定的名称-它是一种相对简单的方法,可以将小学数学应用于日常问题。下面是发生的情况:
'\t'
字符将pos
向前推进多个位置,范围从1到TABINC
- 当
是pos
的倍数时,跳转整个TABINC
TABINC
- 当
比pos
的下一个倍数低一倍时,您跳一次TABINC
- 当
比pos
的下一个倍数低两倍时,您跳两倍TABINC
- 以此类推-当
为pos
时,其中x
,在0
的下一个倍数下方,您跳转TABINC
x
pos
和TABINC
的下一个倍数之间的差值。这可以通过计算pos
和TABINC
的除法余数,然后从TABINC
中减去余数来实现。这是通过%
运算符完成的
由于pos
是以一为基础的*,因此公式所做的第一件事就是将其设置为以零为基础,以便计算余数。接下来,公式计算余数,这是一种数学方法,表示“最后一个TABINC
stop上方的位置数”。现在,您只需从TABINC
中减去余数即可得到结果
*发现'\n'
时的赋值pos=0
似乎与pos
基于一的断言相矛盾。但是,循环头在每次迭代后执行pos++
,因此循环的下一次迭代在下一次迭代中看到pos=1
else if (c == '\t')
pos = pos + (TABINC - (pos - 1) % TABINC) - 1;