-7

How can I convert C code to C++? When I try my best, I failed every time. Can anyone help me?

In particular, I'm trying to understand the following:

v=v%10?v%(5*r)*n--:v/10

I know if v == v mod 10,v%(5*r)*n--. if not, v/10. But I don't understand v%(5*r)*n--.

Here's the code in context:

long v=1,r=1e9;
main(n){
    for(scanf("%d",&n);v=v%10?v%(5*r)*n--:v/10;n||printf("%d",v%r));
    }
Toby Speight
  • 27,591
  • 48
  • 66
  • 103
TC2Bee
  • 1
  • 1
  • 5

2 Answers2

0

This C expression is also valid in C++. Expression v%(5*r)*n-- is equivalent to expression v % ((5*r)*(n--)) due to operator precedence rules. Postfix decrement operator --(it decreases a variable by one) will evaluate first, what remains is an expression of type A % B * C. Since operators % (remainder) and * (multiplication) are on the same precedence level, left to right associativity rule will be applied. Therefore, we have v % ((5*r)*(n--)). For more information check out these links:

http://en.cppreference.com/w/cpp/language/operator_precedence

https://en.wikipedia.org/wiki/Operator_associativity

You also do no understand the ternary operator. In your case, the whole statement v=v%10?v%(5*r)*n--:v/10 means: if v%10 is true (different from zero) then assign result of v%(5*r)*n-- to variable v, otherwise assign result of v/10 to variable v. For more information check out

http://www.cprogramming.com/reference/operators/ternary-operator.html

Btw, please note that the person writing this blog produces some awful code. You probably do not want to learn from it.

Marko Popovic
  • 3,999
  • 3
  • 22
  • 37
  • Your answer would be good if you hadn't mixed up left and right and thus gave the wrong parenthesis for the equivalent expression. – Armali Oct 27 '17 at 09:10
0

Your definition for main is bad. C++ does not allow implicit typing for functions1, and main takes either zero or two arguments; it should be written as

int main( int argc, char **argv )
{
  ...
}

if the program takes any command line arguments2 and

int main( void )
{
  ...
}

if it doesn't3.

The expression v=v%10?v%(5*r)*n--:v/10 is equally valid (if unspeakably ugly) in C and C++, so that's not an issue.

The expression n||printf("%d",v%r) is a bit of a head-scratcher, though; what do you think it's trying to accomplish?

Edit

Sorry, wasn't quite awake when I wrote that last bit. Obviously, the intent of that expression is to only write the value of v%r when n is 0.

The || is the logical-or operator - the expression a || b evaluates to 1 if either a or b is non-zero, or 0 if both a and b are zero. The operator short-circuits; if a is non-zero, then the result of a || b is 1 regardless of the value of b, so b won't be evaluated at all.

Thus, in the expression n || printf( "%d", v%r ), if n is non-zero, then the printf call won't be executed.

Note that the line

for(scanf("%d",&n);v=v%10?v%(5*r)*n--:v/10;n||printf("%d",v%r));

is hideous; even with some whitespace it would be hard to follow and debug. This should not be taken as an example of good code. That style of programming is only suitable for the IOCCC, except that it's not ugly enough for that particular competition.

A better way to write it for C++ would be

#include <iostream>

int main( void )
{
  long v=1,r=1e9; // no reason to make these global
  int n;

  if ( std::cin >> n )
  {    
    while ( v ) // v != 0
    {
      if ( v % 10 )
        v = v % (5 * r) * n--; // whitespace is your friend, use it
      else
        v = v / 10;

      if ( n ) // n != 0
        std::cout << v % r;
    }
  }
  else
  {
    std::cerr << "Error while reading \"n\"...try again" << std::endl;
  }

  return 0;
}


1. Neither does C since the 1999 standard, and it's bad practice anyway.
2. You don't have to use the names argc and argv, although they are the common convention.
3. Implementations may provide additional signatures for main (such as extra arguments in addition to argc and argv), but those additional signatures must be documented; don't assume any random signature is going to be valid.
John Bode
  • 119,563
  • 19
  • 122
  • 198