1

I have a code which print pointer to const char, or I mean a string, recursively. My code works fine when I'm using += operator to call print() function. But, when I'm using ++ operator my code goes to an infinite loop just printing 'H'.

Here's my code: TRY IT

#include <stdio.h>

void print(const char *s){
    if(*s == 0)
        return;
    putc(*s, stdout);
    print(s += 1); // infinite loop when `s++`
}

int main(void){
    print("Hello");
    return 0;
}

I know that in any loop for an example:

for(size_t i = 0; i < 10; i++) { }

is completely equivalent to

for(size_t i = 0; i < 10; i += 1) { }

Then, please tell what I'm missing out?

Darth-CodeX
  • 2,166
  • 1
  • 6
  • 23
  • 6
    `s++` is the postincrement operator. It returns the value of `s`, then increments it. If you want to increment before passing it to the recursive function, you need `++s`, which is the preincrement operator. – Nick ODell Feb 27 '22 at 20:00
  • 1
    Ooh I see, `+=` first increment `s` then passes it to the function. Thx –  Feb 27 '22 at 20:02

2 Answers2

2

You are using the (postfix) post-increment operator ++ the value of which is the value of the operand before incrementing. So you are calling the function with the same value of the pointer. You need to use the pre-increment operator ++

void print(const char *s){
    if(*s == 0)
        return;
    putc(*s, stdout);
    print( ++s ); 
}

From the C Standard (6.5.2.4 Postfix increment and decrement operators)

2 The result of the postfix ++ operator is the value of the operand. As a side effect, the value of the operand object is incremented (that is, the value 1 of the appropriate type is added to it).

As for the for loop

for(size_t i = 0; i < 10; i++) { }

then the value of the expression i++ is not used. The variable i is used after applying the side effect of incrementing it by the operator. To check this you could write the for loop the following way

for(size_t i = 0; i < 10; printf( "%zu ", i++ ) ) { }
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
2

s++ is a post-increment. It returns the original value of s, not the incremented value. This means that

print(s++);

is equivalent to

print(s);
s++;

Since print(s) calls print(s), you get an infinite loop.


To get the value of s after it's been incremented, use a pre-increment.

print(++s);

This is equivalent to

++s;
print(s);

Finally, there's no reason to change s. You should simply use

print(s+1);
ikegami
  • 367,544
  • 15
  • 269
  • 518
  • UV, but note that `print(s++);` is not equivalent to `print(s); s++;` because there is a sequence point between evaluating the arguments and calling the function: **6.5.2.2 function calls** *9. There is a sequence point after the evaluations of the function designator and the actual arguments but before the actual call. Every evaluation in the calling function (including other function calls) that is not otherwise specifically sequenced before or after the execution of the body of the called function is indeterminately sequenced with respect to the execution of the called function.* – chqrlie Feb 27 '22 at 21:52
  • @chqlie, They're equivalent given the nothing outside of the current call has access to `s`. – ikegami Feb 27 '22 at 22:14
  • Yes, in this particular case, the statement is also equivalent to `print(s);` since `s` is not used after the call :) I was warning the OP that the equivalence you mention is not strictly correct in all cases. (Sunday night nitpick) – chqrlie Feb 27 '22 at 22:19
  • 1
    yup, a nit pick. I do those too :) (I prefix with "Nit:", but your "UV" had the same purpose.) – ikegami Feb 27 '22 at 22:20