0

I'm studying two functions that invest strings the problem is that I find it hard understand how they work I see strange things in the code as, this part

return b = c & '\n';

another thing is the way you use the ternary operator

b + e ?: f(0);

the first expression is omitted I leave the two functions

int b, e;
void f(c)
{
    e = 13 & c;
    if(isspace(c)) return;

    b++, f(getchar());
    b--, putchar(c);
    b + e ?: f(0);
}

int f(c)
{
    static int b;
    if(isspace(c))
        return b = c & '\n';
    f(getchar());

    printf("(%c)\n", b);

    return putchar(c) == b && f(c);
}

someone explain to me how this goes?

cheroky
  • 755
  • 1
  • 8
  • 16
  • 1
    is this really valid `c`? – wimh Mar 21 '15 at 20:25
  • It does not make any sense to me. Maybe someone can explain – SwiftMango Mar 21 '15 at 20:25
  • 2
    @Wimmel Yes. It's making deliberate use of archaisms and is written to be confusing, but it's valid C89. – zwol Mar 21 '15 at 20:25
  • 1
    http://stackoverflow.com/questions/3319075/ternary-conditional-operator-behaviour-when-leaving-one-expression-empty explains `?:` – hyde Mar 21 '15 at 20:26
  • @zvol is `?:` really standard C89? Not just GNU extension? – hyde Mar 21 '15 at 20:28
  • 1
    @hyde Er, yes, `?:` with nothing in the middle is a GNU extension only. The thing that looks wrong but is standard C89 is `int f(c)` with no type for `c`. (Either C99 or C11 deleted this backward compatibility wart, I don't remember which one.) – zwol Mar 21 '15 at 20:35
  • Cheroku, why are you examining the code, where did you get it? Looks like intentionally obfuscated piece. – hyde Mar 21 '15 at 20:42

2 Answers2

1

Your first expression:

return b = c & '\n';

will assign the value of the expressionc & '\n' to variable b and return it. c & '\n' is a bitwise operation, doing a logical AND operation on binary representations of c and \n.

To make it more illustrious, let's take the ASCII table and decode those chars: c : decimal 99 -> binary 01100011 '\n' : decimal 10 -> binary 00001010

So we just AND them bit by bit, as a result we get 00000010, which is decimal 2. The b variable is assigned that value, and the same value is returned.

b + e ?: f(0);

is a ternary conditional statement, which will first check the logical value of b+e and if it evaluates to true will do nothing (as there is nothing before :), otherwise will call the function f.

Michał Szydłowski
  • 3,261
  • 5
  • 33
  • 55
0

Both of these functions appear to have been deliberately written to be confusing, to the point where I am not 100% sure what they are supposed to do, or whether they actually do it. So instead of explaining them, I am going to give you my own program that does what I think they are supposed to do, but in a less peculiar fashion:

#include <stdio.h>
#include <ctype.h>

void reverse_word(void)
{
    int c = getchar();
    if (c == EOF)
        return;
    if (isspace(c)) {
        ungetc(c, stdin);
        return;
    }
    reverse_word();
    putchar(c);
}

void skip_whitespace(void)
{
    int c = getchar();
    if (c == EOF)
        return;
    if (!isspace(c)) {
        ungetc(c, stdin);
        return;
    }
    putchar(c);
}

int main(void)
{
    do {
        reverse_word();
        skip_whitespace();
    } while (!feof(stdin));
    return 0;
}

You will note that reverse_word and skip_whitespace are almost the same. Ponder the differences to understand how reverse_word works.

$ echo 'the quick brown fox jumps over the lazy dog' | ./a.out
eht kciuq nworb xof spmuj revo eht yzal god
zwol
  • 135,547
  • 38
  • 252
  • 361