【问题标题】:Difference between s[++i]; and s[i]; ++i;s[++i]; 之间的区别和 s[i]; ++i;
【发布时间】:2020-02-26 20:38:27
【问题描述】:

我正在从“C 编程语言”做一些练习,但无法弄清楚发生了什么来给我一定的输出。并不是真正的障碍,因为我得到了我想要的输出,但我不明白为什么更改我的某段代码实际上给了我想要的输出。只是在寻找解释。

这是按我想要的方式工作的代码。我不理解的部分是'k' for 循环中的s[++i] = ' ';。在我使用s[++i]之前,我使用过:

s[i] = ' ';

++i;

无论 k 循环运行多少次,它只会在数组中放置 1 个空格。

然后,为了测试,我将++i; 放在s[i] = ' '; 上方,我的输出中没有包含一个空格。

#include <stdio.h>
#define MAXLINE 1000
#define TABSTOP 5

/* Write a program "detab" that replaces tabs in the input with a proper
number of blanks to space to the next tab stop. Assume a fixed set of tab
stops, say every n columnns. Should n be a variable or a synbolic parameter? */


int main() {

  char c;
  int i, j;
  int modTabStop, numTabs, k;
  char s[MAXLINE];

  i = 0;
  while((c = getchar()) != EOF) {
    if(c == '\t') {
      modTabStop = i % TABSTOP;
      numTabs = TABSTOP - modTabStop;
      for(k = 0;k <= numTabs; ++k)
        s[++i] = ' ';
    }
    else if(c == '\n') {
      ;
    }
    else {
      s[i] = c;
      ++i;
    }
  }

  for(j = 0;j <= i;++j)
    printf("%c", s[j]);

  return 0;
}

我只是想知道为什么s[++i] 有效而其他人都没有。我的预期输出在主函数上方的注释中定义。但为了澄清起见,我使用的是测试字符串“the(tab)dog”。当它正常工作时,应该只在“the”和“dog”之间放置 2 个空格来代替制表符,因为我的制表位是 5 并且“the”是三个字母长(“the(space)(space)dog” )。如果我将++i; 放在s[i] = ' ' 之后,那么我会在两者之间得到一个空格(“the(space)dog”)。如果我之前放置它,我就没有空格(“thedog”)。

我只是想确保在继续之前完全理解所有这些。谢谢大家!

【问题讨论】:

  • char c 应该是 int c 因为 getchar 返回一个 int
  • Ed,谢谢 - 从现在开始我会做出改变并记住这一点

标签: c loops for-loop post-increment pre-increment


【解决方案1】:

对于初学者来说这个循环

  for(k = 0;k <= numTabs; ++k)
              ^^^

不正确。它应该看起来像

  for(k = 0;k < numTabs; ++k)
              ^^^

在这种情况下,数组中将插入恰好 numTabs 个空格,

这个作业

    s[++i] = ' ';

也是不正确的,因为i 位置的字符没有改变。由于预增量运算符++i,该位置被跳过。

你应该改写

    s[i++] = ' ';

所以最后循环看起来像

  for(k = 0;k < numTabs; ++k)
    s[i++] = ' ';

注意这个循环

while((c = getchar()) != EOF) {

不正确。

你应该改写

while( i < MAXLINE && ( c = getchar() ) != EOF && c != '\n' ) {

或者至少喜欢

while( i < MAXLINE && ( c = getchar() ) != EOF ) {

在最后一种情况下,您应该在循环中编写

else if(c == '\n') {
  s[i++] = ' ';
}

否则,如果您要输入多个语句,它们将不会分开。

在第一种情况下,这个 if 语句应该被删除。

而不是声明

char c;

你应该使用声明

int c;

因为 char 类型可以表现为 unsigned char 类型(取决于编译器选项)。在这种情况下,比较 c != EOF 将始终为真。

【讨论】:

  • 弗拉德,感谢所有的帮助。我会将所有这些信息复制到我的笔记中并进行更改。非常感谢您抽出宝贵的时间
【解决方案2】:

两者有很大区别

s[i]
i++;

和

s[++i]

在解释之前,让我将第一种形式简化为s[i++],这样你就有了

s[i++]

和

s[++i]

我相信这会让事情更清楚,这就是前增量和后增量之间的区别。

不同之处在于,在将i 的值注入到表达式中之前,预增量s[++i] 会增加它的值,在我们的例子中是数组访问运算符。虽然后增量首先将 i 的值注入到数组访问运算符中,然后稍后将其递增,就像您最初在扩展的两行表单中所做的那样。

【讨论】:

  • 感谢您的超级快速回复!好的,前后增量是有意义的。但是有什么理由为什么两行形式不起作用而单行形式会起作用?这是最让我困惑的。就像 s[++i] 在我的代码中工作一样,但是两行形式给了我错误/不同的输出(1 个空格对 2 个空格)
  • 如果你想使用两行形式 WHILE pre-incrementing,你必须先做i = i + 1 然后用它访问数组
  • @ubernoob1010 — 当您尝试两种语句形式时,您是否为循环体添加了大括号?此外,当您使用两个语句形式时,您分配给数组的不同元素
  • 乔纳森,不,我完全忘记了牙套,现在发布这个感觉真的很愚蠢。我搞砸了这么久,我想我完全掩盖了这么简单的事情。感谢您的帮助,很抱歉浪费您的时间!
【解决方案3】:

考虑代码:

for(k = 0;k <= numTabs; ++k)
    s[i] = ' ';
    ++i;

这相当于

for(k = 0;k <= numTabs; ++k){
    s[i] = ' ';
}
++i;

因为不使用大括号时,只有第一条语句在 for 循环中。

这意味着:将空间写入s[i] for numTabs-times,然后递增i。有效地写一个空格。

类似的:

for(k = 0;k <= numTabs; ++k)
    ++i;
    s[i] = ' ';

将增加i numTabs 次,然后写入一个空格。这会在数组中留下numTabs 乱码字符,并且可能是终止NULL。

解决方法很简单:使用大括号

【讨论】:

  • 是的,我怀疑这也是 OP 所做的,所以问题不在于 i++ vs ++i。
  • Burdui,感谢您的回答。很抱歉把你的时间浪费在这么简单的事情上。来自 Python 背景,所以我有时会完全忘记大括号,因为我刚开始学习 C。这绝对是问题所在。我只是假设 s[++i] 和循环方法有所不同。感谢所有帮助
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-12
  • 2016-06-29
  • 2021-12-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多