• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Tim Cooke
  • Ron McLeod
  • paul wheaton
  • Jeanne Boyarsky
Sheriffs:
  • Paul Clapham
  • Devaka Cooray
Saloon Keepers:
  • Tim Holloway
  • Roland Mueller
  • Himai Minh
Bartenders:

A Dan Mock Exam Question (Dec 4)

 
Greenhorn
Posts: 17
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
This is a Question about the Dan Dec4 Mock Exam Q30 in Study Guide -- Chapter 2: Language Fundamentals -- Exam A
Here it is:
Question 30
class M {
static int m(int i) {
System.out.print(i + ", ");
return i;
}
public static void main(String s[]) {
int i=0;
int j = m(++i) + m(++i) * m(++i) % m(++i) + m(++i);
System.out.print(j%5);
}
}

What is the result of attempting to compile and run the above program?
a. Prints: 1,2,3,4,5,1
b. Prints: 1,2,3,4,5,2
c. Prints: 1,2,3,4,5,3
d. Prints: 1,2,3,4,5,4
e. Prints: 1,2,3,4,5,5
f. Runtime error
g. Compiler error
h. None of the above
I tried to run this program and answer is C. I have some questions about this statement
"int j = m(++i) + m(++i) * m(++i) % m(++i) + m(++i);"

1) What steps did java do this? How about the directions (left -> right or right ->left)
2)When the function calls and operators like (++i) in the same one statement, how does java process the precedence of them ?
Thanks a lot
 
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Java evaluate the statement "int j = m(++i) + m(++i) * m(++i) % m(++i) + m(++i);" like this:
1.int j = m(1) + m(++i) * m(++i) % m(++i) + m(++i)
2.int j = m(1) + m(2) * m(++i) % m(++i) + m(++i)
3.int j = m(1) + m(2) * m(3) % m(++i) + m(++i)
4.int j = m(1) + m(2) * m(3) % m(4) + m(++i)
5.int j = m(1) + m(2) * m(3) % m(4) + m(5)
6.int j = 1 + m(2) * m(3) % m(4) + m(5)
7.int j = 1 + 2 * m(3) % m(4) + m(5)
8.int j = 1 + 2 * 3 % m(4) + m(5)
9.int j = 1 + 2 * 3 % 4 + m(5)
10.int j = 1 + 2 * 3 % 4 + 5
11.int j = 1 + 6 % 4 + 5
12.int j = 1 + 2 + 5
13.int j = 3 + 5
14.int j = 8
Correct me if I'm wrong.
 
Ranch Hand
Posts: 33
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I don't think so the i will be 2.beacause variable only pass its copy,so the original i is still 0.so i think the output should be:
1,1,1,1,1,2
 
Ranch Hand
Posts: 1865
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Peter,
The process that you demonstrated evaluates all of the prefix increment expressions from left to right and then evaluates the other operators from left to right. That is the process that I use when I evaluate expressions by hand but Java actually does it a little differently.
The basic rule to remember is that the left operand is evaluated completely before the right operand and operator precedence is respected. For example, if the right operand of an addition operator is an expression involving multiplication and division then the multiplication and division is completed before the addition operation.

1.int j = m(1) + m(++i) * m(++i) % m(++i) + m(++i)
2.int j = m(1) + m(2) * m(++i) % m(++i) + m(++i)
3.int j = m(1) + m(2) * m(3) % m(++i) + m(++i)
4.int j = m(1) + ((m(2) * m(3)) % m(++i)) + m(++i)
5.int j = m(1) + (6 % m(++i)) + m(++i)
6.int j = m(1) + (6 % m(4)) + m(++i)
7.int j = m(1) + 2 + m(++i)
8.int j = 3 + m(++i)
9.int j = 3 + m(5)
10.int j = 8
If you are evaluating the expression by hand then it is easier to just go ahead and do all of the increment operations first as you demonstrated but Java doesn't actually do the increment operations until it is necessary.
The question in my mock exam does not print 8 as the result. Instead, it prints the result of 8 % 5 = 3.
 
Dan Chisholm
Ranch Hand
Posts: 1865
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by feng lee:
I don't think so the i will be 2.beacause variable only pass its copy,so the original i is still 0.so i think the output should be:
1,1,1,1,1,2


Feng,
Yes, only a copy of the result of the increment expression is passed to the method. However, it is important to remember that the prefix increment expression has the side effect of changing the value of the operand. The value of i is indeed incremented so the printed result is 1,2,3,4,5,3.
 
yang ming
Greenhorn
Posts: 17
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks. Guys
I got it
 
Ranch Hand
Posts: 55
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Dan,
I calculated the same way as Peter Wu has done to arrive at the answer , But your way is more accurate.
Thanks !
 
Dan Chisholm
Ranch Hand
Posts: 1865
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Salim Mohamed:
Dan,
I calculated the same way as Peter Wu has done to arrive at the answer , But your way is more accurate.
Thanks !


Salim,
I actually use Peter's approach when I evaluate an expression by hand. It is much easier to just do the increment operations from left to right and then evaluate the other operators on a second pass through the expression. I recommend using that approach for the exam.
The process that I demonstrated is the process that is actually implemented by Java, but it is a process that is optimized for a machine and not a person.
Both processes provide the same final result.
 
Ranch Hand
Posts: 2120
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Using javap -c MyClass is possible to see the actual sequence used by the compiler, which matches Dan's one by the way.
OP is the operand stack.
"4/6/1" is the content of the operand stack being 4 the last operand pushed, and 1 the first one.
LV1 and LV2 are local variables.
iconst_0 pushes 0 on the OP
istore_1 stores the content of the OP into LV1
iinc 1 1 increments by one the content of LV1
iload_1 loads LV1 in OP
imul multiply the first two integers in OP and leave the result in the OP
iadd adds the first two integers in OP and leave the result in OP
irem computes the remainder of the first two integers in OP and leaves the result in the OP

[ December 09, 2002: Message edited by: Jose Botella ]
[ December 09, 2002: Message edited by: Jose Botella ]
[ December 09, 2002: Message edited by: Jose Botella ]
[ December 09, 2002: Message edited by: Jose Botella ]
 
Jose Botella
Ranch Hand
Posts: 2120
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Using javap to see how the compiler executes the following two expressions; the exact sequence is the same as if the expressions had been declared with the parentheses:
a) m(1) + m(2) + m(3) * m(4) ; is executed as...
( m(1) + m(2) ) ) + ( m(3) * m(4) );

b) m(1) + m(2) & m(3) % m(4) + m(5) * m(6); is executed as...
( m(1) + m(2) ) & ( ( m(3) % m(4) ) + ( m(5) * m(6) ) );
The pattern is:
When there are no parentheses, begin left to rigth, computes operand first. An operator is executed if it has the same or bigger precedence
than the one before it, and the same or bigger precedence than the operator after it.
 
Cowgirl and Author
Posts: 1589
5
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
And as always, I'm compelled to point out to anyone who might be freaking out at that question, that you will not see any questions like this on the exam! The only questions that expect you to understand precedence are with respect to casting, String concatenation, and just knowing how pre/post operators work in general.
The philosophy Simon Roberts expressed from the beginning of designing the original exam has always been (I wish I could say it with his british accent "They're just supposed to use parentheses and get on with it..."
So while I know that there are SO many places on the exam where you're expected to recognize something that involves code nobody would ever write in the real world, this knowing-operator-precedence-without-parens isn't one of them.
And as long as Simon's in charge of the exam team, it'll stay that way : )
OK, but that said, it's still a useful and interesting question and subsequent discussion. So again, I'm not dissing the question or the topic, just trying to keep new folks from being overwhelmed by things they won't see on the exam.
Cheers,
Kathy
"Helping exam candidates remain as lazy as possible, one couch at a time."
 
Dan Chisholm
Ranch Hand
Posts: 1865
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Kathy Sierra:
And as always, I'm compelled to point out to anyone who might be freaking out at that question, that you will not see any questions like this on the exam! The only questions that expect you to understand precedence are with respect to casting, String concatenation, and just knowing how pre/post operators work in general."


Kathy,
I agree that the operator precedence questions on the real exam are very simple and I have reorganized my exam such that only very simple operator questions appear in the comprehensive exams and the more difficult questions appear in single topic exams marked "Optional".
The question at the top of this thread requires a person to know only some very basic concepts.
  • Expressions are evaluated from left to right.
  • Multiplication and division have higher precedence than addition and subtraction.
  • The prefix increment operator returns the value of the operand after the increment operation.
  • The prefix increment operator produces the side effect of incrementing the value of the operand.
  • If a prefix increment expression appears as a method argument then the evaluation of the expression occurs before control passes to the method and the result of the expression is not discarded when the method returns.

  • I think that most every Java programmer understands that multiplication and division have higher precedence than addition and subtraction so I don't believe that operator precedence is the primary source of difficulty with this question. Instead, I think that new programmers have more difficulty understanding that expressions are evaluated from left to right. The left-to-right issue is not a problem until the prefix increment operator is added to the expression. Once the side effects are added then the order of evaluation becomes critical.
    From my point of view it is reasonable for Sun to make the determination that memorization of the operator precedence chart is not necessary. However, I think that every Java programmer should understand the impact of adding side effects to an expression. A programmer that lacks an understanding of something so basic is likely to develop programs that produce unexpected results.
    Regardless of my own opinion, the real exam does indeed require some knowledge of operator precedence. I think we all know that a favorite real exam question requires a person to know that the binary arithmetic operators have lower precedence than the type cast operator.
    My opinion is that the question at the top this this thread is not beyond the scope of the exam objectives. However, I agree that it is not like any of the questions on the real exam. While the real Sun exam is designed to validate what a person already knows, my exam is designed to help people uncover weaknesses and expand their knowledge to include critical fundamental concepts. The question at the top of this thread is designed to uncover a weakness in the understanding of the left-to-right evaluation of expressions and the impact of side effects.
    Having said the above, I agree that a mock exam should not be an unnecessary source of fright. For that reason, I have reorganized my exam such that difficult questions have been removed from the comprehensive exams and are now found only in single topic exams marked "Optional". As mentioned earlier, the question at the top of this thread only covers some very basic concepts so I have not moved it to the optional section.
    [ December 13, 2002: Message edited by: Dan Chisholm ]
     
    Dan Chisholm
    Ranch Hand
    Posts: 1865
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Here's an interesting follow-up question that should demonstrate that even the addition of parenthesis won't make this question a lot easier.

    I won't spoil the fun by posting the correct answer now but I invite others to give it a try and explain the results.
     
    Ranch Hand
    Posts: 96
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    I just read the whole thread twice and I'm going to need to re-read again. Cool tips for the exam! I'm going to need to bookmark this.
     
    Ranch Hand
    Posts: 109
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    I don't understand this:
    The prefix increment operator returns the value of the operand before the increment operation.
    Could you give me an example?
     
    Dan Chisholm
    Ranch Hand
    Posts: 1865
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Thank you, I need to be a little more careful. Yes, the prefix increment operator returns the value of the operand AFTER the increment operation. I made the correction in the earlier post.
     
    Greenhorn
    Posts: 18
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Hello everyone,
    This is really an interesting discussion. I took sometime to read through and it enriched my understanding a lot.
    Thanks to all.

    Morah Ikechukwu
     
    yang ming
    Greenhorn
    Posts: 17
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    =================================================
    Question 8
    class M
    {
    static int m(int i) {
    System.out.print(i + ", ");
    return i;
    }
    public static void main(String s[]) {
    int i=0;
    int j = ++i + ((++i * ++i) % ++i) + ++i;
    System.out.print(j%5); }}
    What is the result of attempting to compile and run the above program?
    a. Prints: 1
    b. Prints: 2
    c. Prints: 3
    d. Prints: 4
    e. Prints: 5
    f. Runtime error
    g. Compiler error
    h. None of the above
    =================================================
    Here is my answer to the Question 8:
    int j = ++i + ((++i * ++i) % ++i) + ++i;
    = (++i) + (((++i) * (++i)) % (++i)) + (++i)
    = 1 + (((++i) * (++i)) % (++i)) + (++i)
    = 1 + ((2 * (++i)) % (++i)) + (++i)
    = 1 + ((2 * 3) % (++i)) + (++i)
    = 1 + (6 % (++i)) + (++i)
    = 1 + (6 % 4) + (++i)
    = 1 + 2 + (++i)
    = 1 + 2 + 5
    = 3 + 5
    = 8
    System.out.print(j%5);
    The answer should be "c"
    At the first time, I got "1". After I run the program, I got the answer "3". So I found I made a mistake because I did the parenthesis expression first. I guess that it should be java complier adds some parenthesises in the statement, just like I showed above.
    I also tested my thought using this statment (just modified the first "i++" -> "i")
    int i=0;
    int j = i + ((++i * ++i) % ++i) + ++i;
    System.out.print(j%5);
    The answer is "1".
    It should be done like this:
    int j = (i) + (((++i) * (++i) % (++i)) + (++i)
    = (i) + ((1 * (++i) % (++i)) + (++i)
    = 0 + ((1 * 2) % (++i)) + (++i)
    = 0 + (2 % (++i)) + (++i)
    = 0 + (2 % 3) + (++i)
    = 0 + 2 + (++i)
    = 0 + 2 + 4
    = 2 + 4
    = 6
    System.out.print(j%5);
    So according to my understanding, these rules are important to me:
    1. Java complier will add some parenthesis
    implicitly to simply the statment.
    2. Expressions are evaluated from left to right (Dan mentioned it in his early posted message)

    You just do it like the complier does using these rules and don't add any more you can imange. That is why I made a mistake at first time and got the "1" answer because I thought the parenthesis shoud be done first.
    The reason I posted the thread here is I want to know clearly about how the java complier to handle precedence of the operators. I have developed java program for almost one year. And I don't think I will use this statment style in my program because it is very confusing. I always use the simple statment in my program.
    "The simple is best".

    But I found the program we are talking about can greatly help you to understand more detail about java language and how it works. Many people attending the java certification test have their own thoughts Some have fun. Some want to pass the test. Some want to learn more deeply about java. According to my experience, I found that even if I can do a lot of java coding, I still have some wrong concepts about the java programming. So I decided to attend java programmer certification to get more details about java. Also I found the best place "javaranch" and good exams like "Dan mock exam". I have to say after you have done Dan mock exam, you will find more information and clearly concepts about java . The more diffcult questions you do, the more good feeling you have. The difficult questions will help you a lot to understand deeply about java language. I hope Dan will not move these questions out of his Mock exams in the future.
    You can use them according to your thought and objection.
    These are just my currenct studying opinions. Please correct me if my solutions have errors.
    My english is not good, so I hope I make them clearly.
    Let us move ahead together.
    Thanks
     
    Dan Chisholm
    Ranch Hand
    Posts: 1865
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Ming,
    You are correct!
    Thank you for your response and explanation.
    Yes, without an understanding of how Java evaluates expressions a person is likely to start the evaluation from within the inner most set of parenthesis. When side effects are involved in the expression the result might not be properly calculated.
    Even though Java does respect parenthesis, the sequence of evaluation is always from left to right. Unlike people, Java does not have a set of eyes that allow it to look at an entire expression and jump straight to the inner most set of parenthesis. Instead, Java just starts at the left and moves to the right. When side effects are not present the difference between our approach and that of Java is not obvious.
    This question is a good demonstration of why the use of side effects in a complex expression can be dangerous.
     
    Jose Botella
    Ranch Hand
    Posts: 2120
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Another example:
    int i=0;
    i + i * (++i + ++i);
    this prints 0.
    a) the first operand is evaluated (0) and stored, thus subsequent changes to i does not affect it.
    b) the same happens to the second operand
    c) the precedence of the first operator is checked against the precedence of the second. Because * has a bigger precedence than +, + is not executed. Had the second operator been +, the first addition would have been performed.
    d) the first ++i is evaluated to 1
    e) the second ++i is evaluated to 2
    f) the parentheses yields 3
    g) 0 * 3 is executed and then added to 0
     
    reply
      Bookmark Topic Watch Topic
    • New Topic