Understanding of string delimiter

Asked

Viewed 54 times

1

char *strdelc(char *s, char ch)
{
    int i,j;

    for(i=j=0; s[i]!='\0';i++)
        if(s[i]!=ch)
            s[j++]=s[i];
    s[j]='\0';    
    return s;    
}

This function aims to delete the character sent by the user, but I can’t understand two things.

Like the j++ will add something to s[0], since it is incremented?

And how the s[j] = '\0' will not replace some letter, because when the is closes has nothing to increase the j?

  • j++ is post-incremented, first uses the current value of j in the expression and lastly increases.

  • For the final ' 0' the variable j has already been incremented and already indicates the position next to the last character of the array that matters and will only signal the end of the string.

1 answer

1


I will make comments showing what makes each part, I am rewriting parts to be more readable and breaking some to facilitate comments:

char *strdelc(char *s, char ch) {
    int j = 0; //faz a declaração a atribuição junto para ficar claro que a operação está completa
    for (int i = 0; s[i] != '\0'; i++) { //já declarei a variável onde vai usar, é um for clássico
        if (s[i] != ch) { //só entra em certas condições
            s[j++] = s[i]; //aqui há um ordem de precedência do que deve executar, veja abaixo
        }
    }
    s[j] = '\0'; // aqui pega a próxima posição, é a mesma explicação porque funciona o incremento
    return s;
}

I put in the Github for future reference.

j is used outside the loop and needs to declare out, but i only use inside the loop so it’s best to only exist inside.

The operator ++is an increment that occurs after using the variable’s value. In fact at first it seems confused because j += 1 it makes a pre-aincrement of 1 so intuitively people that the j++ also does, but the preincrement is done so ++j. In that case j will be incremented and then the value obtained is used in some operation.

In post-increment the incrementing operation is left last, for the compiler that code is the same as writing this:

char *strdelc(char *s, char ch) {
    int j = 0;
    for (int i = 0; s[i] != '\0'; i++) {
        if (s[i] != ch) {
            s[j] = s[i];
            j++;
        }
    }
    s[j] = '\0';
    return s;
}

When the variable being incremented in a statement, that is, a separate line, where only the increment happens no matter if you are using the pre or post-increment operator, it will be the same because it has no other effects. But when that operation is within another expression it makes all the difference because the value that will be used to complete the expression is without the increment when using the post.

Looking at this second code can understand more easily than the last execution that manipulates the j is already in the next position because the last thing that happened was the increment. IE, he used in s[j++] the current value of j, but soon after it went to the next position, so when you put the terminator will be placed in the next position.

j is always coupled to the next position, and as it starts at 0 the next before entering the loop is already the first letter.

I think you understand that j controls the actual position of where the new content is walking. And I think you understand that the moment you finish you have to put the terminator right away so that it indicates that the text ends there and other algorithms don’t read beyond that point because despite having an allocated memory and data there they are no longer part of the correct text.

In such simple situations this operator is not problematic, in other more complex situations it is, even if it used again the j on the same line (statement) could already have problems, so the recommendation would be not to use so to make clear to the compiler what is its actual intention.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.