ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I am hoping somebody can explain why I am getting 8 as the answer in r instead of 6.
Program
int a = 2;
int b = 4;
int c = 6;
int r = 0;
//Increment-decrement in original location
cout << "a = " << a << " b = " << b << " c = " << c << " r = " << r << endl;
r = a * b + (--b) / (c--);
cout << "r = a * b + (--b) / (c--)" << endl;
cout << "a = " << a << " b = " << b << " c = " << c << " r = " << r << endl<< endl;
Output (from g++ 3.3.4)
a = 2 b = 4 c = 6 r = 0
r = a * b + (--b) / (c--)
a = 2 b = 3 c = 5 r = 8
Since the (--b) are in "( )" you would think b would be = to 3 so the final answer in r should be
6. Thanks.
--b is pre-incrementation and c-- is post incrementation.
The --b is done before any of the other math is done. The c-- is done after any of the other math is done.
So you start with a = 2, b = 4, c = 6, r = 0;
b gets changed to 3 (--b). So then you get r = (2*3) + (3/6) = 8. Then c gets changed to 5.
jtshaw,
I agree with the first part of your analysis. However I think the second part is wrong; both b and c are ints so (3/6) = 0 because the ints get truncated, so why does (2*3) + 0 = 8 it does not! The only explanation I can think of is the computer is executing (2*4) + 0 = 8. But as you say -b is pre-decrement and is in "( )" so it should run first. This seems like such a simple problem but something is screwy. Thanks for the help!
I gather that this is a simple exercise with no purpose in the real world? Because I cannot explain for certain exactly *why* C's gothic order-of-precedence rules work their black magic for every instance. In the real world for actual applications, you simply put parenthesis around every step of an operation, so that your results will always be predictable!
Originally posted by Hosiah you forgot a set of parenthesis:
r = a * (b + (--b) / (c--));
I gather that this is a simple exercise with no purpose in the real world? Because I cannot explain for certain exactly *why* C's gothic order-of-precedence rules work their black magic for every instance. In the real world for actual applications, you simply put parenthesis around every step of an operation, so that your results will always be predictable!
Ok this works and while this is a simple exercise I want to know why, when the precedence table that I got out of my C++ book clearly states "( )" come before "*". Hosiah maybe operator precedence is
black magic but it should not be? Just for fun I get the same result for gcc and Visual Studio C++ version 6.
I'll hazard a guess (I'm not at a computer I can test this on... so it might be way off).
The decrement operator evaluates as you expect, but only for that instance of b. What I mean by that is, the value substituted for "( --b )" in your expression is 4 - 1 = 3. The assignment of b's new value does not come until after processing of the line is complete. If that is the case, your first reference to b substitutes the unaltered value of b. In other words:
Code:
r = a * b + (--b) / (c--);
= 2 * 4 + ( 3 ) / ( 6 );
= 8 + 0;
= 8;
The values for the variables should then be:
a = 2
b = 3
c = 5
EDIT A quick check against this could be made by using the distributive property of mathematics. change your expression to this:
Code:
r = (--b) * ( a + 1 / (c--) );
I would bet that will give you r = 6.
Last edited by Dark_Helmet; 03-21-2005 at 08:56 PM.
Hosiah maybe operator precedence is
black magic but it should not be?
oops, sorry if I sounded critical! Yes, by all means, knowledge for the sake of knowledge is a valuable goal!
I guess my attitude reflects my needs. I've programmed in C, C++, BASIC, Lisp, Perl, Awk, and assembler (note: I do NOT claim to have mastered all of the above!), and have found order of operator precedence to have different rules jumping between different languages, platforms, etc. I get my brain boggled trying to remember which punctuation character means modulus in which language, let alone whether "boolean and" comes before "left shift" and etc! So I just parenthesize on those rare occasions when I actually need to do multiple calculations in a single statement (usually in complex conditionals).
Happy hunting!
Incidentally, if you enjoy puzzling out perplexing problems in C, try googling "Duff's device", and the "obfuscated C contest". That will have you up all night!
I managed to find a computer I could play with and test some things. It appears that your expression falls into the "grey area" of compiler-dependent evaluation. I don't believe there are any rules for evaluation order when the same variable is referenced twice in a single expression, with one reference having a pre-decrement operator.
To illustrate this, try this code:
Code:
#include <stdio.h>
int main( int argc, char *argv[] )
{
int a, b, c, r;
a = 2;
b = 4;
c = 6;
r = a * b + (--b) / (c--); // Your original version
printf( "r = %d\n", r );
printf( "a = %d b = %d c = %d\n", a, b, c );
a = 2;
b = 4;
c = 6;
r = a * (--b) + b / (c--); // What should be an "equivalent" version
printf( "r = %d\n", r );
printf( "a = %d b = %d c = %d\n", a, b, c );
return 0;
}
My version of gcc produced this output:
Code:
r = 8
a = 2 b = 3 c = 5
r = 6
a = 2 b = 3 c = 5
The moral of this story: Don't reference a variable you plan to pre-increment/decrement more than once in your expression. The compiler can choose to evaluate them in any order it likes.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.