-4

Consider this code:

# include <iostream>
using namespace std;

int main()
{
    for(int i = 5; i>0;)
    {
        i--;
        cout <<i<<" ";
    }
    return 0;
}

The output of this code would be 4 3 2 1 0.

Can I change the decrement/increment value?

In detail, this means that the default decrement/increment value is 1. So you either minus 1 or add 1.

Can I change it to minus 0.2 or add 1.3?


If so, is there a way to tell the compiler that I want to change the -- value from 1 to 0.2 and still using the -- operator instead of changing it to -= 0.2?

  • 3
    **Yes you can.** See [this C++ reference](https://en.cppreference.com/w/cpp) and open source software coded in C++ like [RefPerSys](http://refpersys.org/) or [fish](https://fishshell.com/). Contact me by email if interested. Read also the documentation of your C++ compiler (e.G. [GCC](https://gcc.gnu.org/) to be invoked as `g++ -Wall -Wextra -g`) – Basile Starynkevitch Jun 29 '22 at 11:20
  • 2
    Do you already know the difference between type `int` and `float` (or `double`)? Are you already aware of https://stackoverflow.com/questions/588004/is-floating-point-math-broken ? – Bob__ Jun 29 '22 at 11:20
  • Why aren't you writing: `for(int i = 4; i>-1; --i)`? And the "decrement" can be any expression you like. E.g. `for (double d = 4; d > 0; d = cos(d) + 1 / d) { ... }` – Goswin von Brederlow Jun 29 '22 at 11:21
  • Yeah, the bytes are different. And the int does not have decimal places. – CPP_is_no_STANDARD Jun 29 '22 at 11:23
  • @GoswinvonBrederlow, the decrement of this code is just a example. – CPP_is_no_STANDARD Jun 29 '22 at 11:25
  • Note that you can use the loop variable to *calculate* any other value: `for (int i{}; i < 5; ++i) { double j = 4.0 - i * 0.2; ... }` – Bob__ Jun 29 '22 at 11:28
  • 1
    i-- is an abbreviation to subtract 1. Do you know how to subtract 2? – user253751 Jun 29 '22 at 11:30
  • 1
    @user253751, that's what I'm finding for. – CPP_is_no_STANDARD Jun 29 '22 at 11:36
  • to calculate the value of i minus two and make that the new value of i, you can use `i = i - 2;` or for short `i -= 2;` – user253751 Jun 29 '22 at 11:44
  • It is not clear what you like to print if you decrement by 0.2.. – Phil1970 Jun 29 '22 at 11:55
  • 1
    Instead of "decrement by 0.3", you can use the integer loop counter , and then multiply current value by 0.3 to use in whatever calculation you mean to use it in. Having a floating point loop counter raises issues with exact comparison for the loop condition (e.g. 0.3 - 0.3 may give 0.00000000001 which tests greater than zero). – M.M Jul 22 '22 at 03:49

5 Answers5

5

d-- is shorthand for d -= 1, which is shorthand for d = d - 1. You should not read this as a mathematical equation, but as "calculate d - 1 and assign the result as the new value of d".

#include <iostream>

int main()
{
    float day = 1.2;
    for(int i = 0; i < 5; i++)
    {
        day -= 0.2;
        std::cout << day;
    }
    return 0;
}

(I also removed using namespace std as it is bad practice).

Note the second part of the for loop is a condition that keeps the loop going as long as it is true. In your case, i > 5 is false from the beginning (because 0 < 5) so the loop will never run. I assumed you meant i < 5 instead.

CompuChip
  • 9,143
  • 4
  • 24
  • 48
  • Good answer, but you may want to clarify that you used `float` since `0.2` is a non-integer value. It looks like @CPP_is_no_STANDARD may not have realized this. – Jonathon S. Jul 27 '22 at 03:30
  • And perhaps it would have been better to avoid the float subtraction at all and use `float day = 1.2 - 0.2 * i` inside the loop to avoid propagating rounding errors. – CompuChip Jul 27 '22 at 05:58
1

i-- is the post-fix decrement operator. For builtin types it means that i is decremented by one (1). The value of the expression i-- is the value of i before decrementing it.

--i is the pre-fix decrement operator. For builtin types it means that i is decremented by one (1). The value of the expression --i is the value of i after decrementing it.

For the builtin types you cannot change the behaviour of the increment or decrement operators. If you want to have another behaviour, you need to fallback to the operators += and -= where you can add whatever you want. But please note that your code used int and you probably want to change to float or double first before adding or subtracting 0.1 or 0.2.

You can change the behaviour for increment and decrement operators for your own types, though. Here is an exammple

#include <iostream>

struct S {
    S& operator++() { // prefix increment "++s"
        d += increment_value;
        return *this;
    }
    S& operator--() { // prefix decrement "--s"
        d -= decrement_value;
        return *this;
    }
    S operator++(int) { // postfix increment "s++"
        S copy{*this};
        d += increment_value;
        return copy;
    }
    S operator--(int) { // postfix decrement "s--"
        S copy{*this};
        d -= decrement_value;
        return copy;
    }

    double d{};
    double increment_value{0.2};
    double decrement_value{0.1};

    friend std::ostream& operator<<(std::ostream& os, const S& s) {
        os << s.d;
        return os;
    }
};

int main(int, char**) {
    S s{1};
    std::cout << "val=" << s.d << '\n';
    std::cout << "prefix++=" << ++s << '\n';
    ;
    std::cout << "val=" << s.d << '\n';
    std::cout << "postfix++=" << s++ << '\n';
    std::cout << "val=" << s.d << '\n';
    std::cout << "prefix--=" << --s << '\n';
    std::cout << "val=" << s.d << '\n';
    std::cout << "postfix--=" << s-- << '\n';
    std::cout << "val=" << s.d << '\n';
}

The output is

val=1
prefix++=1.2
val=1.2
postfix++=1.2
val=1.4
prefix--=1.3
val=1.3
postfix--=1.3
val=1.2

You might notice that I added two operator ++ and two operator--. One of each is getting no parameter, the other is getting an int. As cppreference describes, the int parameter is only a dummy parameter to differentiate between the prefix and the postfix versions of the operators. (*)

As you can also see, the prefix operators are more performant as they don't need the extra copy. So normally please use the prefix versions (compare the CppCoreGuidelines).

But, please ignore the possibility to change the increment and decrement operators. It is counter intuitive and only a source of errors and head aches. Don't do it this way!

(*) This parameter could also be used for even more confusing behaviour, but it should be clear that this is making the idea even worse. So see this just as an example of what is technically possible.

#include <iostream>

struct S {
    S operator++(int diff) { // postfix increment "s++", diff defaults to zero (0)
        S copy{*this};
        d += diff ? diff : increment_value;
        return copy;
    }
    S operator--(int diff) { // postfix decrement "s--", diff defaults to zero (0)
        S copy{*this};
        d -= diff ? diff : decrement_value;
        return copy;
    }

    double d{};
    double increment_value{0.2};
    double decrement_value{0.1};

    friend std::ostream& operator<<(std::ostream& os, const S& s) {
        os << s.d;
        return os;
    }
};

int main(int, char**) {
    S s{1};
    std::cout << "val=" << s.d << '\n';
    s++;
    std::cout << "val=" << s.d << '\n';
    s.operator++(2);
    std::cout << "val=" << s.d << '\n';
    s--;
    std::cout << "val=" << s.d << '\n';
    s.operator--(2);
    std::cout << "val=" << s.d << '\n';
}

results in

val=1
val=1.2
val=3.2
val=3.1
val=1.1

Werner Henze
  • 16,404
  • 12
  • 44
  • 69
0

You can change the loop variable both inside the for and the body any way you like. For example:

for (double d = 4; d > 0; d = cos(d) + 1 / d) {
    d = sin(d);
    std::cout << d << " ";
}

C++ does not have a fixed count loop like other languages for i = 0 to 10 do ... done where the i can not be changed. Do whatever you like.

Note: I change the type to double since you asked about decrementing by 0.2. The type int doesn't allow that.

Goswin von Brederlow
  • 11,875
  • 2
  • 24
  • 42
0

Can I change the decrement/increment value?

Yes, that is what the third parameter(?) in the for loop does.

#include <iostream>

int main()
{
    
    for(int i = 5; i > 0; i -= 2)
    {
        std::cout << i << std::endl;
    }
    return 0;
}

Can I change it to minus 0.2 or add 1.3?

Yes, you'd simply change the first parameter to be a float and the third parameter to decrement/increment by whatever you'd like.

#include <iostream>


int main()
{
    for (float i = 5; i > 0; i -= .2)
    {
        std::cout << i << std::endl;
    }
    return 0;
}
WillyB
  • 23
  • 4
0

If I understand correctly what you want to do is to change the behavior of T operator --();.
You can do that with your own type:

struct Foo {
  float boat;
  auto operator --() noexcept { return boat -= .2f; }
  operator float() const noexcept { return boat; }
};

#include <cstdio>
int main() {
  for (Foo i{ 5 }; i > 0; --i) {
    std::printf("%1.2f, ", static_cast<float> (i));
  }
}

Live on Compiler Explorer
Should you ever do that? No, you shouldn't. But now you know how not to do it should the opportunity not come.

viraltaco_
  • 814
  • 5
  • 14