How is this variable ch allowed to be used in two places/loops?

Viewed 80

New to java, forgive the amateur question...

I am reversing a string. I understand the beginning, but I got confused when declaring char ch...

How is it that char ch is allowed in the for loop as well as again in the while loop? Does it overwrite the previous char ch, or does it look at it as new? I assume it has to remember what ch is because I can use .pop() on it, and it knows I am referring to the created stack.

Also, How is it that when I pop (remove) an item, I can immediately after store it in a string? Isn't it removed...? Is the reason because pop returns the value being popped, so I can store ch, the variable popping, and it simply attaches that result?

Code below:

public static String reverseString(String str) {
    int size = str.length();
    Stack s = new Stack(size);
    
    for(int i = 0; i < str.length(); i++) {
        char ch = str.charAt(i);
        s.push(ch);
    }

    String result = "";
    while(!s.isEmpty()) {
         char ch = s.pop();
        result = result + ch;
    }

    return result;
}
4 Answers

Java uses block scope. So when you declare ch in the For loop, it can only be used within the loop. Once you step out of the loop, you loose access to that variable and when you declare the ch in the While loop, you are creating a new variable that is only available in the While loop. The result string on the other hand is in the outer most scope in your function and can be used anywhere in your function, including the While loop.

As you have been told in the comments, etc. it is a scoping issue. But there are times this can be useful. You can encapsulate blocks of code to avoid having redeclaration conflicts.

{
   long time= System.nanoTime();
   // time some event
   System.out.println((System.nanoTime()-time)/1e9);
}

{
   long time= System.nanoTime();
   // time some other event
   System.out.println((System.nanoTime()-time)/1e9);
}

Both of the above are independent variables and local to the enclosing braces. In fact, they can be different types and not cause a conflict. And you can delete either block and the code will compile just fine.

It's because the ch variables (chars) are not created in the same scope. After one cycle of the for-loop ends, the char gets destroyed and another one is created with the next cycle. If you tried to use the char outside the for-loop, you would get warning that ch is undefined or something like that.

So basically when the while-loop begins, the char from the for-loop doesn't exist anymore, because it existed only in the for-loop scope.

Same goes for functions. If you define a variable in one function, then you cannot access it from another function, because it exists only in the first function and nowhere else.

For the pop() function I'm guessing it both modifies the string and returns what it modified.

Every method when being called pushes its parameters on the stack, and the compiler has calculated the space needed for the local variables on the call stack. (In that way it can detect a stack overflow, out of memory.)

0: str
4: size
8: s
12: i
16: ch of the first loop
12: result, I and ch gone
16: ch of the second loop
Methods frame size 20

I neglected temporary variables generated by the compiler for expression evaluation.

Both variables with the name ch are different. Here they coincidentally have the same address on the stack. Also note that declaring the variable inside the loop has no overhead, something repeated.

pop() will store the top element in a result variable, decrease the stack, and then return it. Simply juggling with two hands

Java is pass-by-value, so the value of the variable ch, a char, is pushed to the stack. A method like add can never change the passed variable. This in contrast to other languages with pass-by-reference too. A design decision to prevent bugs.

Related