删除C字符串 - 此代码如何工作?

时间:2015-09-14 17:52:26

标签: c arrays string char

我有一段C代码可以完全删除字符数组中的每一个字符,使原始数组的大小减半(如果大小为奇数,则为半+ 1)

..但我无法弄清楚它是如何运作的。

void del_str(char string[]) {
    int i,j;
    for(i=0, j=0; string[i]!=0; i++) {
        if(i%2==0) {
            string[j++]=string[i];
        }
    }
    string[j]=0;
}

//
example input: 'abcdefgh'
output from that: 'aceg'
what I thought the output would be: 'aacceegg'

我不明白的是

string[j++]=string[i];

我可以编写省略每秒char的代码,因此输出将是:

'a c e g '

但是我无法解决这个问题。

或者,您如何编写一个完全删除原始数组中每个第n个字符及其空间的程序? (产生与上述代码相同的输出)

3 个答案:

答案 0 :(得分:4)

此代码使用两个位置索引ij。最初,两个索引都初始化为零。索引i用于阅读; index j用于写作。

索引i在循环的每一步都会递增,因为增量i++位于循环的标题中。另一方面,索引j每隔一次迭代递增一次,因为j++仅在i为偶数时才会发生。索引i始终与索引j一样接近或接近字符串的结尾,因为它移动得更快"。

Null终结符位于循环结尾的j的最终位置,表示字符串结束的新位置。

也许通过一个小例子可以更容易看到。考虑"abcdef"的初始字符串。它在算法开始时在内存中的表示如下:

'a' 'b' 'c' 'd' 'e' 'f' '\0'

以下是循环的每个步骤后它将如何变化:

'a' 'b' 'c' 'd' 'e' 'f' '\0'
'a' 'c' 'c' 'd' 'e' 'f' '\0'
'a' 'c' 'e' 'd' 'e' 'f' '\0'
'a' 'c' 'e' '\0' 'e' 'f' '\0'

由于C字符串会忽略'\0'之后的所有内容,因此" tail" 'e' 'f' '\0'的{​​{1}}不被视为字符串的一部分。

答案 1 :(得分:1)

i和j不是最清晰的变量名。也许将j重命名为output会有所帮助。

注意更新j时,仅当您处于奇数位置时。所以i正在遍历整个列表,而j会将读取内容从i复制回j位置,覆盖之前的内容。最后一行string[j]=0终止了您的字符串。

答案 2 :(得分:1)

你忘记了if(i%2==0)这是至关重要的。这条线基本上会跳过每一个字符。然后,您识别的行可以分为两部分:

string[j]=string[i]; // Overwrite the character at position j
j++;                 // Now increase j

变量i会在阅读时跟踪您已达到的字符串的位置; j用于写作。最后,在位置j写0以终止字符串。