s [++ i]之间的区别;和s [i]; ++ i;

时间:2019-10-31 13:12:06

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

我正在使用“ 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] = ' '之后,那么我会在它们之间得到一个空格(“(空格)狗”)。如果我将其放置在前面,我将没有空格(“狗”)。

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

3 个答案:

答案 0 :(得分:4)

对于初学者而言,此循环

  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可以表现为无符号类型char(取决于编译器选项)。在这种情况下,比较c != EOF将始终为真。

答案 1 :(得分:3)

两者之间有很大的区别

s[i]
i++;

s[++i]

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

s[i++]

s[++i]

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

区别在于,预递增s[++i]在将i的值注入表达式(在本例中为数组访问运算符)之前会对其进行递增。后递增首先将i的值注入到数组访问运算符中,然后稍后将其递增,就像您最初在扩展的两行形式中所做的那样。

答案 2 :(得分:1)

考虑代码:

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

这等效于

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

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

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

类似:

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

i递增numTabs次,然后写一个空格。这样会在数组中留下numTabs个乱码,并且可能会终止为NULL。

解决方案很简单:使用花括号

相关问题