Home > other >  why pre increment works with pointer but not post increment
why pre increment works with pointer but not post increment

Time:11-02

I stumbled into this while solving an exercise:

void    ft_striteri(char *s, void (*f)(unsigned int, char*))
{
    unsigned int    i;

    if (!s || !f)
        return ;
    i = 0;
    while (s[i  ])
        f(i, s   i);
}

Why doesn't the post increment in the while work while if i do this:

void    ft_striteri(char *s, void (*f)(unsigned int, char*))
{
    unsigned int    i;

    if (!s || !f)
        return ;
    i = -1;
    while (s[  i])
        f(i, s   i);
}

It works?

I'm new and still very confused to the whole pointer concept is there any nuance here that I don't know about?

CodePudding user response:

The problem is the match between the comparison and the function call.
Consider the first iteration. In the first snippet it would be:

if(!s[0]) break;
f(1, s   1);

In the second snippet it would be:

if(!s[0]) break;
f(0, s   0);

CodePudding user response:

If you do simple debugging you will see what the problem is.

void    ft_striteri(char *s, void (*f)(unsigned int, char*))
{
    unsigned int    i;

    i = 0;
    while (s[i  ])
    {
        printf("i = %d\n", i);
        if(f) f(i, s   i);
    }
}

void    ft_striteri1(char *s, void (*f)(unsigned int, char*))
{
    unsigned int    i;

    i = -1;
    while (s[  i])
    {
        printf("i = %d\n", i);
        if(f) f(i, s   i);
    }
}

int main()
{
    ft_striteri("Hello", NULL);
    printf("\n");
    ft_striteri1("Hello", NULL);
}

https://godbolt.org/z/cqb1aMGje Result:

i = 1
i = 2
i = 3
i = 4
i = 5

i = 0
i = 1
i = 2
i = 3
i = 4

Function with postincrement iterates from index 1 to 5 instead of 0 to 4.

But your both functions do not use the correct type for the indexes. It should be size_t instead of int.

I would personally write another way, having "positive" test checking if parameters are OK and have only one return point:

void ft_striteri(char *s, void (*f)(unsigned int, char*))
{
    size_t i = 0;

    if(s && f)
    {
        while (s[i])
        {
            f(i, s   i);
            i  ; // or   i; - it makes no difference
        }
    }
}

CodePudding user response:

I don't know about nuance, but here is an equivalent to your first:

void    first(char *s, void (*f)(unsigned int, char*))
{
    unsigned int    i;

    if (!s || !f)
        return ;
    i = 0;
    while (s[i]) {
        f(i, s   i   1);
        s = s   1;
    }
}

and second:

void    second(char *s, void (*f)(unsigned int, char*))
{
    unsigned int    i;

    if (!s || !f)
        return ;
    i = -1;
    while (s[i 1]) {
        f(i, s   i   1);
        i = i   1;
    }
}

Really, neither look right to me; I would think you would want:

void    ft_striteri(char *s, void (*f)(unsigned int, char*))
{
    unsigned int    i;

    if (!s || !f)
        return ;
    i = 0
    while (s[i]) {
        f(i, s   i);
        i  
    }
}

which, in idiomatic style might be:

void    ft_striteri(char *s, void (*f)(unsigned int, char*))
{
    int c;

    if (!s || !f)
        return ;

    for (; *s; s  )
        f(i, s);
}
  •  Tags:  
  • c
  • Related