-2

Today my teacher was teaching us how we could use pointers in C to simulate some common functions of this programming language, one of his examples was the rev_string function (shown below) which was created to simulate original strrev() from the <string.h> header.

void rev_string(char *s)
{
    char *t;
    int counter = 0, middle, temp, i, j, last, begin;

    for (t = s; *t != '\0'; t++)
        counter++;

    middle = (counter % 2 == 0) ? (counter / 2) : ((counter - 1) / 2);
    j = counter - 1;
    for (i = 0; i < middle; i++)
    {
        last = s[j];
        begin = s[i];
        temp = last;
        s[j] = begin;
        s[i] = temp;
        j--;
    }
}

After looking at the code above several times, I could not figured out the the use of ? and : declared inside the middle variable. Could anyone explain me why are those symbols necessary in the code above?

NoahVerner
  • 937
  • 2
  • 9
  • 24
  • 2
    So why didn't you ask the teacher? – Cheatah Nov 08 '21 at 20:37
  • 1
    Is a shortcut for `if (counter % 2 == 0) middle = (counter / 2); else middle = (counter - 1) / 2;` , the name is ternary operator. – David Ranieri Nov 08 '21 at 20:40
  • 2
    By the way, this is a pretty useless example of the ternary operator. This is because `counter / 2` will be rounded down. Therefore the 1 doesn't need to be subtracted if `counter` happens to be odd. And therefore the `counter % 2` test is rather useless. That line should just read `middle = counter / 2`. – Cheatah Nov 08 '21 at 20:43
  • This was closed as a dup of a C++ question, but the answer is the same. – ikegami Nov 08 '21 at 20:45
  • 2
    What makes you think it has anything to do with the pointer argument? The passed pointer isn't used in that statement... – Support Ukraine Nov 08 '21 at 20:45
  • @DavidRanieri: “Ternary operator” is a category or description for the operator. Its name is “conditional operator,” per C 2018 6.5.15. – Eric Postpischil Nov 08 '21 at 21:08
  • 1
    The conditional operator is unnecessary in the code shown. As long as `counter` is non-negative, which it is barring overflow from an excessively long string, `(counter % 2 == 0) ? (counter / 2) : ((counter - 1) / 2)` is equivalent to `counter/2`, which divides `counter` by two and discards the fraction. Unless the instructor was making some particular point about this or otherwise using deliberately drawn out code to illustrate something, you may have a bad instructor. – Eric Postpischil Nov 08 '21 at 21:10
  • Yes, it's not great code. A lot of the temporary variables are unnecessary. Like `j` is unnecessary because it's just taking over the role of `counter`. Then of the three `last`, `begin` and `temp` only one is necessary. There's some extra byte swapping going on. I think I would rate this code "quite terrible". – Cheatah Nov 08 '21 at 22:22

1 Answers1

2

This is the conditional operator. It is a ternary operator which takes the form "condition ? if-part : else-part".

It evaluates its first part. If the result is non-zero, the second part is evaluated and becomes the result of the expression, otherwise the third part is evaluated and becomes the result of the expression.

So this:

middle = (counter % 2 == 0) ? (counter / 2) : ((counter - 1) / 2);

Is equivalent to:

if (counter % 2 == 0) {
    middle = (counter / 2);
} else {
    middle = ((counter - 1) / 2);
}
ikegami
  • 367,544
  • 15
  • 269
  • 518
dbush
  • 205,898
  • 23
  • 218
  • 273
  • About the edit: It is called "conditional operator" in the spec, which describes what it does. Ternary operator is a thing it is, not its name. I think C only has one, but other languages have multiple ternary operators. – ikegami Nov 08 '21 at 20:52
  • The question does not ask what the conditional operator does; it asks why it is necessary. If `counter` is non-negative, then `(counter % 2 == 0) ? (counter / 2) : ((counter - 1) / 2);` is equivalent to `counter/2`, so the operator is not necessary. – Eric Postpischil Nov 08 '21 at 21:01