By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
440,230 Members | 2,436 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 440,230 IT Pros & Developers. It's quick & easy.

Arrays that are passed by reference

P: n/a
If I don't specify "ref" in the argument list when passing an array to the
callee, I am passing the array (reference) by value. But this makes me
confused because it actually means a "reference" of a "reference"??As I pass
the array by value, the callee can change that array. However,when I use
ref, the callee and caller point to two different arrays. So could anyone
please explain the 2 different situations?
Jun 12 '07 #1
Share this Question
Share on Google+
9 Replies


P: n/a
On Jun 12, 11:26 am, "Jack" <j...@knight.comwrote:
If I don't specify "ref" in the argument list when passing an array to the
callee, I am passing the array (reference) by value.
Yes.
But this makes me
confused because it actually means a "reference" of a "reference"??As I pass
the array by value, the callee can change that array.
The callee can change the *contents* of the array.
However,when I use ref, the callee and caller point to two different arrays.
No they don't. Do you have some sample code which makes you think they
do?
So could anyone please explain the 2 different situations?
If you use ref, the callee can change which array the parameter refers
to, and that change will be made to the caller's variable too.

See http://pobox.com/~skeet/csharp/parameters.html for more
information.

Jon

Jun 12 '07 #2

P: n/a
"Jack" <jl@knight.comwrote in message
news:OT**************@TK2MSFTNGP03.phx.gbl...
If I don't specify "ref" in the argument list when passing an array to the
callee, I am passing the array (reference) by value. But this makes me
confused because it actually means a "reference" of a "reference"??As I
pass the array by value, the callee can change that array. However,when I
use ref, the callee and caller point to two different arrays. So could
anyone please explain the 2 different situations?
The array is always passed by reference. When you add the keyword "ref"
you are passing "a reference to the reference". Meaning that when you pass
the array without "ref", the procedure can change the contents of the array,
buy not the array to which the variable is pointing. The latter can be done
if you add "ref".

Jun 12 '07 #3

P: n/a
No; when you use "ref"", the callee and caller *still* point to the
same array. The difference is that in the latter case, if the callee
*re-assigns* the array (i.e. dataArg = new int[5]), then this is
reflected to the caller - i.e. the caller's reference is updated.
Normally this change would be local to the callee, and would not be
reflected to the caller.

For a full discussion, see Jon's pages:
http://www.yoda.arachsys.com/csharp/parameters.html

Marc
Jun 12 '07 #4

P: n/a
It was 404ing... but now it isn't... so ignore me ;-p
Jun 12 '07 #5

P: n/a
On Jun 12, 11:29 am, "Alberto Poblacion" <earthling-
quitaestoparacontes...@poblacion.orgwrote:
If I don't specify "ref" in the argument list when passing an array to the
callee, I am passing the array (reference) by value. But this makes me
confused because it actually means a "reference" of a "reference"??As I
pass the array by value, the callee can change that array. However,when I
use ref, the callee and caller point to two different arrays. So could
anyone please explain the 2 different situations?

The array is always passed by reference.
No it's not. The reference is passed by value by default. There's a
difference between passing a value type value by reference and passing
a reference by value.

See http://pobox.com/~skeet/csharp/parameters.html for more
information.

Jon

Jun 12 '07 #6

P: n/a

"Jon Skeet [C# MVP]" <sk***@pobox.com>
???????:11*********************@j4g2000prf.googleg roups.com...
On Jun 12, 11:26 am, "Jack" <j...@knight.comwrote:
>If I don't specify "ref" in the argument list when passing an array to
the
callee, I am passing the array (reference) by value.

Yes.
>But this makes me
confused because it actually means a "reference" of a "reference"??As I
pass
the array by value, the callee can change that array.

The callee can change the *contents* of the array.
>However,when I use ref, the callee and caller point to two different
arrays.

No they don't. Do you have some sample code which makes you think they
do?
The book is called "C# for experienced programmers"
On page 127-130,
Using system;
....
public class ArrayReferenceTest : System.Windows.Forms.Form
{ ...
private void showOutputButton_Click(
object sender, System.EventArgs e)
{
int[] firstArray = { 1, 2, 3 };

int[] firstArrayCopy = firstArray;

outputLabel.Text = "Test passing firstArray reference by value";

outputLabel.Text = "\n\n Contents of firstArray " + "before calling
FirstDouble:\n\t";

for (int i = 0; i < firstArray.Length; i++)
outputLabel.Text += firstArray[i] + " ";
FirstDouble (firstArray);

outputLabel.Text += "\n\nContents of firstArray after " + "calling
FirstDouble\n\t";
for (int i = 0; i < firstArray.Length; i++)
outputLabel.Text += firstArray[i] + " ";

if ( firstArray == firstArrayCopy )
outputLabel.Text += "\n\nThe references refer to the same
array\n";
else
outputLabel.Text += "\n\nThe references refer to different
arrays\n";

int [] secondArray = { 1, 2, 3 };

int [] secondArrayCopy = secondArray;

outputLabel.Text += "\nTest passing secondArray " +
"reference by reference";

outputLabel.Text += "\nContents of secondArray " +
"before calling SecondDouble:\n\t";

for (int i = 0; i < secondArray.Length; i++ )
outputLabel.Text += secondArray[i] + "\n";

SecondDouble (ref secondArray);

outputLabel.Text += "\n\nContents of secondArray " +
"after calling SecondDouble:\n\t";

for (int i = 0; i < secondArray.Length; i++)
outputLabel.Text += secondArray[i] + " ";

if (secondArray == secondArrayCopy)
outputLabel.Text +=
"\n\nThe references refer to the same array\n";
else
outputLabel.Text +=
"\n\nThe references refer to different arrays\n";

}
void firstDouble (int [] array)
{
for (int i = 0; i < array.Length; i++)
array[i] *= 2;

array = new int[] { 11, 12, 13 };
}

void SeondDouble (ref int[] array)
{
for (int i = 0; i < array.Length; i++)
array[i] *= 2;

array = new int[] { 11, 12, 13 };
}
}
=================================
results:
Test passing firstArray reference by value

Contents of firstArray before calling FirstDouble
1 2 3

Contents of firstArray after calling FirstDouble
2 4 6

The references refer to the same array

Test passing secondArray reference by reference

Contents of secondArray before calling
SecondDouble:
1 2 3

Contents of secondArray after calling SecondDouble:
11 12 13

The references refer to different arrays

============================
Thanks
Jack

>
>So could anyone please explain the 2 different situations?

If you use ref, the callee can change which array the parameter refers
to, and that change will be made to the caller's variable too.

See http://pobox.com/~skeet/csharp/parameters.html for more
information.

Jon

Jun 12 '07 #7

P: n/a
On Jun 12, 11:57 am, "Jack" <j...@knight.comwrote:
However,when I use ref, the callee and caller point to two different
arrays.
No they don't. Do you have some sample code which makes you think they
do?

The book is called "C# for experienced programmers"
On page 127-130,
<snip>

What this shows is that the callee can change the caller's variable's
value. When it says "The references refer to different arrays" is
means "the value of secondArray is different after calling
SecondDouble to the value it had before". It's *not* saying that the
value within the SecondDouble method is different to the value of
secondArray.

Jon

Jun 12 '07 #8

P: n/a
Starting to see some light on the other end after reading your+MS article,
haven't finished it though :)
Thanks
Jack
"Jack" <jl@knight.comglsD:uO*************@TK2MS FTNGP06.phx.gbl...
>
"Jon Skeet [C# MVP]" <sk***@pobox.com>
???????:11*********************@j4g2000prf.googleg roups.com...
>On Jun 12, 11:26 am, "Jack" <j...@knight.comwrote:
>>If I don't specify "ref" in the argument list when passing an array to
the
callee, I am passing the array (reference) by value.

Yes.
>>But this makes me
confused because it actually means a "reference" of a "reference"??As I
pass
the array by value, the callee can change that array.

The callee can change the *contents* of the array.
>>However,when I use ref, the callee and caller point to two different
arrays.

No they don't. Do you have some sample code which makes you think they
do?

The book is called "C# for experienced programmers"
On page 127-130,
Using system;
...
public class ArrayReferenceTest : System.Windows.Forms.Form
{ ...
private void showOutputButton_Click(
object sender, System.EventArgs e)
{
int[] firstArray = { 1, 2, 3 };

int[] firstArrayCopy = firstArray;

outputLabel.Text = "Test passing firstArray reference by value";

outputLabel.Text = "\n\n Contents of firstArray " + "before
calling FirstDouble:\n\t";

for (int i = 0; i < firstArray.Length; i++)
outputLabel.Text += firstArray[i] + " ";
FirstDouble (firstArray);

outputLabel.Text += "\n\nContents of firstArray after " + "calling
FirstDouble\n\t";
for (int i = 0; i < firstArray.Length; i++)
outputLabel.Text += firstArray[i] + " ";

if ( firstArray == firstArrayCopy )
outputLabel.Text += "\n\nThe references refer to the same
array\n";
else
outputLabel.Text += "\n\nThe references refer to different
arrays\n";

int [] secondArray = { 1, 2, 3 };

int [] secondArrayCopy = secondArray;

outputLabel.Text += "\nTest passing secondArray " +
"reference by reference";

outputLabel.Text += "\nContents of secondArray " +
"before calling SecondDouble:\n\t";

for (int i = 0; i < secondArray.Length; i++ )
outputLabel.Text += secondArray[i] + "\n";

SecondDouble (ref secondArray);

outputLabel.Text += "\n\nContents of secondArray " +
"after calling SecondDouble:\n\t";

for (int i = 0; i < secondArray.Length; i++)
outputLabel.Text += secondArray[i] + " ";

if (secondArray == secondArrayCopy)
outputLabel.Text +=
"\n\nThe references refer to the same array\n";
else
outputLabel.Text +=
"\n\nThe references refer to different arrays\n";

}
void firstDouble (int [] array)
{
for (int i = 0; i < array.Length; i++)
array[i] *= 2;

array = new int[] { 11, 12, 13 };
}

void SeondDouble (ref int[] array)
{
for (int i = 0; i < array.Length; i++)
array[i] *= 2;

array = new int[] { 11, 12, 13 };
}
}
=================================
results:
Test passing firstArray reference by value

Contents of firstArray before calling FirstDouble
1 2 3

Contents of firstArray after calling FirstDouble
2 4 6

The references refer to the same array

Test passing secondArray reference by reference

Contents of secondArray before calling
SecondDouble:
1 2 3

Contents of secondArray after calling SecondDouble:
11 12 13

The references refer to different arrays

============================
Thanks
Jack

>>
>>So could anyone please explain the 2 different situations?

If you use ref, the callee can change which array the parameter refers
to, and that change will be made to the caller's variable too.

See http://pobox.com/~skeet/csharp/parameters.html for more
information.

Jon


Jun 12 '07 #9

P: n/a
Key code is this (where "array" may or may not be "ref")
for (int i = 0; i < array.Length; i++)
array[i] *= 2;

array = new int[] { 11, 12, 13 };
When called without "ref", the values in the existing array are
doubled, and then a new unrelated array is created and assigned to
"array" - but the "array" variable and the "firstArray" variable are
unrelated; after the method ends, the caller just sees the original
array reference (whose contents have been doubled).

When called /with/ "ref", the values are doubled as before, and then a
new array is created and assigned (via some pointer dereferencing that
is a little complex) into the variable, but in this case "secondArray"
and "array" are one-and-the-same. The "ref" basically means "don't
create your own variable (on the stack) - use this one instead". So
the values are doubled, but are then discarded in preference for the
new array {11, 12, 13}. As such, at the end of the method the caller
can see the updated reference "secondArray".

The following is also slightly misleading:
int[] firstArray = { 1, 2, 3 };

int[] firstArrayCopy = firstArray;
This is a copy if the variable, /not/ the array (contents).

Marc
Jun 12 '07 #10

This discussion thread is closed

Replies have been disabled for this discussion.