-3

関数に送信される値はデフォルトで値として渡され、メソッドは変数のコピーを受け取ることを知っています。変数が参照によって渡されると、メソッドは呼び出された変数の値を変更できることを知っています。そうは言っても、これらの単純な図で何が起こっているのかを説明できる人はいますか? 前もって感謝します。式は参照渡しですか?

using System;
class Program
{
    static void Main(string[] args)
    {
        int x = 2;
        int y = 20;
        Console.WriteLine(Add(x, y));
    }

    static int Add(int x, int y)
    {
        int ans = x + y;
         x = 20;
         y = 40;
       // return x+y;
         return ans;
        //returns 22
    }
}

その後

using System;
class Program
{
    static void Main(string[] args)
    {
        int x = 2;
        int y = 20;
        Console.WriteLine(Add(x, y));
    }

    static int Add(int x, int y)
    {
        int ans = x + y;
         x = 20;
         y = 40;
       return x+y;
      //   return ans;
        //returns 60
    }
}
4

9 に答える 9

2

奇妙なことは何も起こっていませんし、パラメータがどのように渡されるかについても何もありません。

最初の例では:

// parameters in: x = 2, y = 20.
int ans = x + y;
// now ans contains the value 22.
x = 20;
y = 40;
// now x and y has changed, but the value in ans
// is already calculated and doesn't change.
return ans;
// returns 22;

2 番目の例では:

// parameters in: x = 2, y = 20.
int ans = x + y;
// now ans contains the value 22.
x = 20;
y = 40;
// now x and y has changed, but not ans.
return x+y;
// the value of the expression is calculated with the current
// values, and 60 is returned.
// the variable ans still contains 22, but that isn't used here.
于 2012-09-27T18:12:55.303 に答える
1

式は常にRVALUE ..を生成します。

例が役立ちます

int x=50,y=20;

-> RVALUE

右辺値に何かを割り当てることはできません。

Example 
x+y=500;//INVALID

-> LVALUE

それに値を割り当てることができます。

Example
x=500;//VALID
y=545*33+4;//VALID

したがって、式を参照渡しすることはできません

于 2012-09-27T18:14:09.707 に答える
1

最初のケースでAddは x + y を返します。2 番目のケースでAddは 20 + 40 を返します。

関数内で値を代入すると、変数のローカルコピーが変更されます。実際の値ではありません。

例えば:

using System;
class Program
{
    static void Main(string[] args)
    {
        int x = 2;
        int y = 20;
        Console.WriteLine(Add(x, y));
        // x is still 2, y is still 20
    }

    static int Add(int x, int y)
    {
        int ans = x + y;
        // You calculate the parameters and store it in the local variable
        x = 20;
        y = 40;
        // You've adapted your local COPIES of the variables
        return ans;
        // You return the answer which was calculated earlier
    }
}

structただし、これは値型 ( )を扱っているためです。参照型 ( ) を扱っている場合はclass、別の問題です。たとえば、次のようになります。

using System;
class Program
{
    private class Numbers
    {
        public int X;
        public int Y;
    }

    static void Main(string[] args)
    {
        Numbers num = new Numbers();
        num.x = 2;
        num.y = 20;
        Console.WriteLine(Add(num)); // Prints 2 + 20 = 22
        // num.x is now 20, and num.y is now 40
        Console.WriteLine(Add(num)); // Prints 20 + 40 = 60
    }

    static int Add(Numbers num)
    {
        int ans = num.x + num.y;
        // You calculate the result from the public variables of the class
        num.x = 20;
        num.y = 40;
        // You change the values of the class
        return ans;
        // You return the answer which was calculated earlier
    }
}

C# には、パラメーターを渡す 4 つの「タイプ」があります。

  • 値型 ( ) を値で渡すstruct
  • class参照型 ( ) を値で渡す。
  • 参照による値の型の受け渡し。
  • 参照による参照型の受け渡し。

これら 4 を示す短い例:

static void Main()
{
    int x = 5; // Value type
    List<int> list = new List<int>(new [] { 1, 2, 3 }); // Reference type

    ValueByValue(x); // x is still 5
    ReferenceByValue(list) // list still contains { 1, 2, 3 }
    ValueByReference(ref x); // x is now 10
    ReferenceByReference(ref list); // list is now a new list containing only { 4, 5, 6 }
}

static void ValueByValue(int x)
{
    x = 10; // Changes local COPY of x
}

static void ReferenceByValue(List<int> list)
{
    list = new List<int>(new [] { 4, 5, 6 }); // Changes local COPY of list
}

static void ValueByReference(ref int x)
{
    x = 10; // Changes the actual x variable in the Main method
}

static void ReferenceByReference(ref List<int> list)
{
    list = new List<int>(new [] { 4, 5, 6 }); // Changes the actual list in the Main method
}
于 2012-09-27T18:09:40.760 に答える
1

どちらの場合も、値渡しです。

しかし、2 番目のケースで、呼び出し関数で x と y の値を出力しようとすると、x=2 と y=20 のみが返されます。

x=20 と y=40 は、2 番目のケースの add 関数で変更されただけで、変更された状態で呼び出し元に返されません。

于 2012-09-27T18:09:45.307 に答える
1

これらは両方とも、値渡し、および一般的には値型のセマンティクスを示しています。

最初の例では、次のように言っています。

int ans = x + y;

これは、その時点で と を評価し、それらを一緒に追加して ans に格納します。後で と を新しい値に設定xしても、 の値には影響しませんyxyans

次のように考えてください。

static int Add(int x, int y)
{
    int ans = x + y;  // evaluates ans = x + y = 2 + 20 = 22
     x = 20;          // here ans = 22, x = 20, y = 20
     y = 40;          // here ans = 22, x = 20, y = 40
     return ans;      // returns ans which is still 22 since x & y are independent
}

2番目の例では、新しい値を設定するまで加算を遅らせているため、 と の新しい値はxy計算に使用されます。

return x + y;

したがって、本質的には、次のようになります。

static int Add(int x, int y)
{
    int ans = x + y;  // ans = 22, x = 2, y = 20
     x = 20;          // ans = 22, x = 20, y = 20
     y = 40;          // ans = 22, x = 20, y = 40
   return x+y;        // evaluates x + y = 60
}

あなたを混乱させるかもしれないのは、次のことだと思います:

ans = x + y;

関数ではなく、評価されて返される式です。このステートメントの実行後xまたは変更しても、再度影響はありませんyans

繰り返しますが、覚えておくべき重要な点は、そのステートメントが実行された時点でans = x + y;評価さxれるということです。yおよびへのさらなる変更は、ここでは関係xありyません。

于 2012-09-27T18:10:18.607 に答える
1

2 つの唯一の実際の違いは、最初の return ステートメントが、ans22 の値を保持する によって識別されるメモリ位置に保持されている値を返すことです。

2 番目の return ステートメントは、 で識別されるメモリ位置にxある現在の値と、 で識別されるメモリ位置にある現在の値の値を返しますy。これらは、そのメソッドに対してローカル (値渡し) であり、ユーザーが 20 に変更したものです。と 40、それぞれ。もちろん、その値は 60 です。

値渡しとは、ローカル スタック メモリ (または何でも) が値に割り当てられx、呼び出し元のメソッドからy値 y` を参照しないことを意味することに注意してください。x and

于 2012-09-27T18:11:40.150 に答える
0

ここでパラメータは値渡しです。2 番目の例では、x と y がそれぞれ 20 と 40 に変更されているため、2 つの合計として 60 が返されます。

于 2012-09-27T18:10:03.630 に答える
0
 static int Add(int x, int y) 
 { 
      int ans = x + y; 
      x = 20; 
      y = 40; 
      // return x+y; 
      return ans; 
      //returns 22 
 }

この方法では、計算は変更前に実行されるため、変数が変更される前に保存されます。

 static int Add(int x, int y) 
 { 
      int ans = x + y; 
      x = 20; 
      y = 40; 
      return x+y; 
      // return ans; 
      //returns 60 
 }

このメソッドでは、ans変数は使用されず、x と y の値が変更され、 ではx + yなくの数学的な結果が返されますans

また、これらのメソッドはどちらも参照渡しではありません。どちらも値渡しであり、参照渡しメソッドrefにはパラメーターの前にキーワードがあります。

 static int Add(ref int x, int y) // x is the referenced variable in this example
于 2012-09-27T18:10:17.623 に答える
0

いいえ、この式は参照による呼び出しではなく、値による呼び出しのみです。参照による呼び出しは、変数の参照を渡すことを意味する引数の値を変更します。

例 :

using System;
class Program
{
    static void Main(string[] args)
    {
        int x = 2;
        int y = 20;


        Console.WriteLine("SUM  :: " + AddByValue(x, y));  // Call by value
        Console.WriteLine("X :: " + x + ", Y :: " + y);  // Nothing change to variable

        Console.WriteLine("SUM  :: " + AddByRef(ref x, ref y));  // Call by reference
        Console.WriteLine("X :: " + x + ", Y :: " + y);  // Value changed

    }

    static int AddByValue(int x, int y)
    {
        int ans = x + y;
         x = 20;
         y = 40;
       return ans;
    }

    static int AddByRef(ref int x, ref int y)
    {
        int ans = x + y;
        x = 20;
        y = 40;
       return ans;
    }


}

出力:

SUM  :: 60
X :: 2, Y :: 20

SUM  :: 60
X :: 20, Y :: 40
于 2012-09-27T18:12:48.237 に答える