So I was experimenting with a permutation algorithm a few days back and discovered something.
int y=5;
chomp(y);
System.out.println(y); Output is still 5. Obviously.
void chomp(int x){
y=y-1;
}
The problem starts here.
char[] a = {'a','b','c'};
chomp(a);
System.out.println(a);
void chomp(char[] a){
char temp = a[1];
a[1]=a[2];
a[2]=temp;
}// It swapped it, But I didnt return anything. And I didnt do "a = chomp(a);"
BUT MY OUTPUT IS acb. WHY??? I tried it with int and nothing affected, From my experience in c and c++ im thinking because char array gives the address or something. But there is no pointers in java right? So how can it be???
in java, arrays are reference types, so only their references are copied. Reference types behave like pointers.
ints are value types, so their values are copied.
try a = {'x','y','z'}; in the chomp function. It won't change anything, because you're not changing the value that was at a, but a itself.
Java is pass by value - always. Primitives and references are the things that are passed.
Both your examples are correct, of course.
The array example is able to do the swap because you did not change the reference that points to the array. You were able to chance its state, as you are free to do with any mutable object.
It's imporant to know, because objects live on the heap. You don't pass an object to a method; you pass a reference to the object out on the heap. You can't modify the reference, but you can modify the state of the object it points to if it's mutable.
Related
Most of the linked list implementations in C++ are like this, a pointer reference will be used as the type for the "next" node
class Node {
public:
int data;
Node* next;
}
But for languages like C#, Java and Python, why pointer is is not directly used? I could see only this kind of implementation:
// C#
class Node {
int data;
Node next;
}
// Java
class Node {
int data;
Node next;
}
What is the underlying difference? Ofcourse Java doesn't support pointers, but what about c#?
CPP"s Node* is equivalent to java's Node, and I'm pretty sure C#'s Node as well. In java, all primitives are the direct value. The primitives are int, long, short, byte, char, double, float, and boolean. These are passed directly, by value: If you call a method passing 5, 5 is pushed onto the stack. If the method you invoke changes their value, the caller can't tell.
But aside from that hardcoded list of primitives, all other types are called references which is just java-ese for pointers - except in java, you can't do pointer arithmatic. at all. You can't ask for 'the memory location 5 higher than where-ever this object lives', like you can do in C.
Here's a trivial example:
class Example {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("Hello!");
System.out.println(list);
example1(list);
System.out.println(list);
example2(list);
System.out.println(list);
}
static void example1(List<String> in) {
list.add("World!");
}
static void example2(List<String> in) {
in = new ArrayList<String>();
in.add("Bye!");
}
}
This will print:
[Hello!]
[Hello!, World!]
[Hello!, World!]
example1 never changes the variable (The reference), it merely 'dereferences it' (follows the pointer), thus the changes you make are observed in the caller.
But example2 has no effect on main's list variable: It reassigns the variable (makes a new object and then updates its reference to point at this new object). example1's list doesn't change; its pointer doesn't change.
It's like treasure maps: Everybody has a copy of the treasure map, but not of the treasure. in.add is like: "Follow the map, open the treasure chest, put a new item in". in = new ArrayList is: "Make a new treasure chest, bury it in the sand, wipe out this treasure map, and now write the location of this newly buried treasure chest on it". If I have a copy of your map, if you follow your copy and add to the treasure then I'll see that if I later follow my map. But if you make an entirely new map, then whatever you do to the treasure at your new location is never going to be noticed by me.
This matches C++'s behaviour.... at least, for Node*. Not for Node.
What is the underlying difference?
Probably none at all. At the machine-code level, each node contains the address of the next node in the chain.
The question is, rather, about how languages represent objects in source code. Is a variable declaration written as Foo bar (for example) going to be an actual instance of the type Foo or is it going to be a way to get at (handle, pointer, reference) the actual instance. If it's the actual instance, your language probably also needs some syntax to describe not-the-instance but way-to-get-at-the-instance. Perhaps more than one way (Foo*, Foo& in C++).
The possibility of different approaches is one reason why we have different programming languages.
In C++ variables (objects) can be passed by three ways:
by value
by pointer
by reference
(all of them are in reality passed by value, but very specific one)
In e.g. Java, objects are always passed by reference, while primitives by value. There are no pointers or explicit references in Java.
In C++ when you stop needing an object, you need to use delete to remove it. In Java, you just need to replace variable or just don't use it - GB will remove it for you.
After reading the posted answers and other stackoverflow stuffs related to references and pointers like this one C++ references Vs C# references
This is what Makes more sense to me,
C# References are Managed references. But in C++ there is no such
manged environment hence we need to allocate and carefully
de-allocate the memory. In C# this will be manged automatically by
GC. So it is recommended to use references where ever possible rather
than directly using pointers.
Similar to C++ Pointers, C# can also hold nulls. C++ pointers hold
address of a memory location, C# References holds the address of
another object in the memory.
In C# we can use pointers only under unsafe scope, and in java there is no such pointer concepts.
Taking all this into account we can use references rather than pointers for programming languages that execute in a managed environment.
Feel free to edit if this answer can be further improved!
public class example
{
public static void main(String[] args)
{
int[] MyArray = new int[10];
MyArray[1] = 5;
int[] NewArray = MyArray;
NewArray[1] = 10;
System.out.println(MyArray[1]);
}
}
Why does the system print out 10 instead of 5?
It seems like whatever changes we made to element in NewArray, MyArray will change along, why?
I copy this pattern to initiate like int, string variables but they don't behave like this above, why? thanks guy, I am new to CS programming.
It seems like whatever changes we made to element in NewArray, MyArray will change along, why?
You aren't changing NewArray. You're changing the array that the value of NewArray refers to. It's like this:
NewArray is a variable (an unconventionally named one, but hey)
The value of NewArray is a reference
The reference refers to an object
It's really, really important to differentiate between variables, references and objects. Don't feel worried that it didn't just come to you immediately - this is a stage a lot of people go through when they first encounter a language like Java.
The values of MyArray and NewArray both refer to the same array, so if you make changes to the array via one variable, you still see the change when you then look at the array via a different variable.
I copy this pattern to initiate like int, string variables but they don't behave like this above, why? thanks guy, I am new to CS programming.
For int, that's a value type - the value of an int variable is the number itself, not a reference to an object.
For String, I suspect you were changing the value of the variable to refer to a different String object - not changing the contents of the String object itself (which you can't - strings are immutable in Java). For example:
String x = "first";
String y = x;
x = "second"; // This doesn't change the value of `y`
I like to think of variables as pieces of paper. For value type variables, the value is just written on the piece of paper:
int i = 10;
is like having a piece of paper with the name i, and a value of 10 on it.
For classes and arrays (which are reference types) the value on the piece of paper isn't the object - it's a way of navigating to the object. A bit like having someone's home address written on a piece of paper.
Suppose you have two pieces of paper with the same address written on them. If you rub one of them out and write a different address, that doesn't change anything about what will happen if someone looks at the other piece of paper and goes to that house. That's like the String example above.
The array example, however, is more like this: I write my home address on two pieces of paper, and give them to Fred and Ginger. Fred reads the address, visits my home, and paints the front door red. (He's modifying the object - my house - without changing his piece of paper at all.) Now if Ginger reads the address on his piece of paper and visits my home, he'll see a red front door.
The reason this happens is because when you say int[] NewArray = MyArray; this is copying the reference of MyArray to NewArray.
This reason you are copying the reference is because you do not call the new operator to instantiate a new array.
So, when you say NewArray[x] it is pointing to the x position in memory of MyArray (and hence the value in memory of MyArray). No new memory is allocated when you do int[] NewArray = MyArray; since the new operator is not called.
It is beacuse when you do =, this makes the new obkect to point to the old one. So any changes made to the new one will reflect in the old one to, as they are the same technically.
You should array.clone to avoid this.
You are not copying it's value. You say:
Java create "MyArray".
Java creates a variable poiting at an object
Java create another array "NewArray" that is the same as MyArray
Java creates a variable poiting at the same object as MyArray
Java change the value of NewArray[1] to 10
Java changes the value on the object it is poiting at, not the variable itself.
Hope you get it.
As a side note, you should use [0] instead of [1]. Arrays start at 0, like everything in programming. So, the array with 10 items you created starts at 0 and ends at 9. Take note of that.
I am brand new to programming, as well as to this website, so forgive me if I screw anything up. I'm having a heck of a time figuring out how to properly post my code in here.
package tester;
import java.util.*;
public class Mainclass2 {
public static void main(String[] args) {
int y = 3;
int[] x = {1, 2, 3, 4};
editnumbersArray(x);
editnumbersNotArray(y);
System.out.println(x[2]); **//now this was changed from 3 to 9...**
System.out.println(y); //but this one went unchanged.
}
//this accepts 'x[]' into the 'a[]' parameter.
public static void editnumbersArray(int[] a){
a[2] = 9; **//<---why does this one CHANGE the actual x[2] instead of just a[2]?**
}
//this accepts 'y' into the 'a' parameter.
public static void editnumbersNotArray(int a){
a = 9; **//<--while this one only changes 'a' instead of 'y'?**
}
}
So my question is basically typed in there as comments. Why does the array that is passed into the method change the values of the original array (x[]) when the int that is passed into the other method doesnt change? I'm sure it's a simple answer, but when I did my research I couldn't figure out what to search. I don't know what this is called so everything I searched led me the wrong way. Thanks for any help!!
EDIT: Thanks for that analogy with the address! That is by far the best way you could have explained it to me. So basically when you pass an array into a parameter, its passing a reference, not the actual value? So when I make adjustments within my method, its changing whatever the array is referencing?
I noticed that this also happens with a list. So the list isnt actually passed by value? It seems as if the array/list itself is basically passed in for editing, no matter what I name it within my method (a[] in this case.)
EDIT http://javadude.com/articles/passbyvalue.htm this page really cleared it up. And sorry for posting a duplicate question. The problem was that I didn't know what I was trying to ask. I had never even heard these terms "pass-by-value/reference", so now I know
Changing the value of the parameter itself never affects the argument in Java, because all arguments are passed by value. However, look at this method:
public static void editnumbersArray(int[] a){
a[2] = 9;
}
That assignment doesn't change the value of the parameter. The value of a is still the same reference, to the same array - it just changes the contents of the array.
Imagine if I wrote my home address on a piece of paper for you. It wouldn't matter what you did to that piece of paper - that wouldn't change where I lived. However, if you visited the address and painted the front door green, without ever changing the piece of paper at all, I would see that change.
It's very important to differentiate between different concepts:
A variable is a named storage location; it holds a value, which is always either a primitive value (e.g. an int) or a reference. In my example above, the piece of paper was like the variable.
A reference is just a value which allows you to navigate to an object. It's not the object itself. It's like the address on the piece of paper.
An object contains other variables. There may be several variables which all have values which are references to the same object. It's like the house in my example: I can write my address on several pieces of paper, but there's only one house.
An array is an object which acts as a container for other variables. So the value of a is just a reference to the array.
Java uses pass by value (what you want to search for) for everything. Essentially that means it makes a copy of the parameter that it then passes to the method. That means that you cannot change what something points at by using the = operator.
That is why the (int a) version doesn't change a.
However, in the case of an Object or an array it doesn't make a copy of the Object or array, it makes a copy of the reference to the Object or the array. That means that you have two variables, the original on and the, in your example, (int[] a) one that both point to the same spot in memory. Changes to either variable will affect the other variable.
Pass by value, pass by reference, and pass reference by value are the types of things you want to search on for more information.
In java is it possible and if not how to calculate in c?
if it's really array (not a pointer), you can do sizeof(arr)/sizeof(*arr)
In Java, the length of a primitive array is array.length, while the length of an ArrayList (and most other collections) is arrayList.size()
In C, the length of an array is sizeof(array) / sizeof(array[0]), but this is nearly useless since you can't pass arrays as arguments (they degenerate to pointers). The normal way to find the size of an array in C is to pass it as an extra argument to the function, or sometimes to terminate it with a sentinel value (eg. strings are \0 terminated)
There is no way to calculate that. in C (not C++, which has std::array and std::vector) an array is transmitted as its pointer, which you might increase by some offset. So you really don't know the runtime size of an "array", except by some conventions.
In particular for formal arrays, there is no way to know the size of the actual array passed
e.g. as void f(int arr[]) { /*...*/ } unless you give a static dimension.
Likewise, with an external array declared as extern int xarr[]; you cannot get its dimension with sizeof(xarr)/sizeof(xarr[0]).
In C, there is no way of calculating the size of array if you have only a pointer to it. You must store it in separate variable.
In fact you HAVE TO keep the size of an array in separate variable because you have to allocate memory if you want to use dynamic-size array.
And if you want to use fixed-size array you know it's size by the time you're writing your code so why not use #define, variable or const to store it?
Java is totally different language than C and the philosophy of programming is different-you should always keep that in mind.
In Java, you should use array.length, look here for example: http://www.roseindia.net/help/java/a/java-array-length.shtml
Simply, there is no possibility if you recieve only a pointer. That's why main has an argc argument. It defines the number of entries in argv. If you have an array "datatype" (actually the same as a pointer, but the behaviour depends on the context), you can use
int[] arr = new int[10];
sizeof(arr)/sizeof(int) // or whatever type is contained in ``arr``
I thought I'm pretty experienced in java, but it seems that's not really the case, I just noticed something yesterday, something I used before but never really realised what it did. I googled but didn't find the answer to my question.
If I declare an int array, and use Array's static sort function to sort my array, I just need to type
Arrays.sort( numbers );
Instead of
numbers = Array.sort( numbers );
This might look very easy in C and C++ because you can use pointers there. So what I'm wondering is, how is this done? Is it an advantage sun has, or am I completely senseless here?
Pointers exist in java - all non primitive variables are pointers in java, aka references.
THey do not support the same set of operations as pointers in C tho - they are essentially opaque to the user of the language.
The reason Arrays.sort(array) works is because array is a "pointer", which allows the sort() function access to the memory location that the array variable points to.
Now, why doesn't:
void swap (Integer a, Integer b) {
Integer tmp = a;
a = b;
b = tmp;
}
work if you did
Integer x = 1;
Integer y = 2;
swap(x,y);
Its because java passes by value (which is a concept distinct from pointers). The pointer to 1 is given to swap(), not as the value of the variable x (which is a memory address, or pointer). Thus, manipulating the arguments in swap() does nothing to effect the variable x.
First, this belongs on StackOverflow. Second, you want to read the article Java is Pass-by-Value, Dammit!
It sorts the array in-place.
The sort method receives a reference to the number array (which is an object), and changes the values inside the array! No new array-object is created, it is thus good enough to just pass it to the sort function.
PS: all source code of Java is open, you can go and read the sources of the sort function yourself. You'll see, there be no magic. If Java is installed properly on your system, there should be a src.zip in the Java home folder.
I assume numbers is an int-array, and all arrays in Java are objects. So sort is passed a reference to numbers, and it can sort them in place.
This question should be migrated to Stack Overflow. The fact that Java has a NullPointerException class should give you a strong hint as to whether Java uses pointers behing the scenes.