SoFunction
Updated on 2025-03-07

The difference between passing by reference and passing by value in C#, as well as detailed explanation of the usage of ref and out keywords

Copy the codeThe code is as follows:

/Sort three integers from small to large and sum and average
//The results of the three integers to be found and their sort are passed by the reference parameters; the sum is passed by the output parameters; the average value is returned by the return value.
//Implement the input of three integers to be found and the output of the result in the Main() method
//Purpose: define methods; call methods; understand the reference transfer relationship between formal and actual parameters; be familiar with the use of reference parameters and output parameters.
using System;
class Class1
 {
//x,y,z are formal parameters, passed by value
   static void Sort(int x, int y, int z)
    {
      int temp=0;
      if(x>y)
       {
         temp=x;
         x=y;
         y=temp;
       }
      if(y>z)
       {
         temp=z;
         z=y;
         if(x>temp)
          {
            y=x;
            x=temp;
          }
         else
          {
            y=temp;
          }
       }
       ("The sorted list is {0},{1},{2}",x,y,z);
       x=x+y+z;
    }

//i,j,k,total are formal parameters, passed by reference (ref parameters and out parameters are all passed by reference)
   static double Average(ref int i, ref int j, ref int k, out int total)
    {
      double l = 0;
      total = i+j+k;
      i=total;
      l=(double)(total/3.0);
      return l;
    }

   static void Main()
    {
//a,b,c are real parameters, and they will be assigned to the formal parameters i,j,k,total;
      int a, b, c;

//Declare out parameter result, you can do not need to initialize it
      int result;

      ("Please enter the first number a =");
      a = Convert.ToInt32(());
      ("Please enter the second number b =");
      b = Convert.ToInt32(());
      ("Please enter the third number c =");
      c = Convert.ToInt32(());     

      Sort(a,b,c);

//In the Sort(int x, int y, int z) function, the parameters x, y, z are passed by values, so even if there is x=x+y+z in the function; function           //The actual parameter a value will not change after execution.
      ("The original value of /"a/" is {0}, it hadn't been changed in spite "+"of manipulating the Sort() method, because it is transmitted by a Value para /"x/"!",a);

//In the Average(ref int i, ref int j, ref int k, out int total) function, the formal parameters a, b, c, result are all passed by reference, and the actual parameter a value changes after execution.
      ("The average result is {0}",Average(ref a,ref b,ref c, out result));
//The ref parameter must be initialized several times before calling the method.
//The out parameter can not be initialized before calling the method, and they are all passed in reference pass mode

      ("The value of /"a/" has been changed due to the Average() method"    +" is manipulated, and it is transmitted by a ref para /"ref i/"! now it is {0}!",a);

      ();
    }
 }


Questions and answers:

1. When value is passed, why does the change of the formal parameter value in the called method not affect the corresponding actual parameter?
answer:Because when passing by value, the system first allocates memory space for the formal parameters of the called method, and then "copy" the values ​​in the actual parameters one by one to the formal parameters according to the position. The value stored in the formal parameter is just a copy of the actual parameter, so any change in the formal parameter value in the called method will not affect the corresponding formal parameter.

2. What is the difference between value passing and reference passing, what is a value parameter, and in what way is it passed?
answer:When passing the value, the system first allocates memory space for the formal parameters of the called method, and copies the value of the actual parameter to the formal parameters one by one according to the position. After that, any change in the formal parameter in the called method will not affect the corresponding actual parameters; and when passing the reference, the system does not copy the value of the actual parameter itself and passes the reference value (i.e., the address value) to the formal parameter. Therefore, the variables at the address referenced by the formal parameter are the same as the passed actual parameter. Any change in the corresponding formal parameter in the method body will affect the actual parameter passed as a reference.

3. What are formal parameters and what are actual parameters?
answer:
Formal parameters:
The parameters specified in the definition function are formal parameters. When no function calls occur, they do not occupy the memory unit in memory. Only when a function call occurs, the formal parameters in the function are allocated to the memory unit. After the call is finished, the memory unit occupied by the formal parameters is also released.

Actual reference:The actual argument can be a constant, a variable, and an expression, but it requires a definite value. Assign the value of the real parameter to the formal parameter when called. In memory, the actual parameter unit and the formal parameter unit are different units. When calling the function, the formal parameter is assigned a storage unit and the value corresponding to the actual parameter is passed to the formal parameter. After the call is finished, the formal parameter unit is released, and the actual parameter unit still retains the original value.

understand:
The actual argument is the thing sent into the method~~The line argument is to copy and process the thing sent into the method. After processing, the method returns an item-the return value.

When passing values, the actual parameters are unchanged. Formal parameters change with calculations.
When passing pointer/reference ~~the line parameters change ~the actual parameters change...

Parameter transfer is divided into: 1. Value-based parameter transfer, 2. Reference-based parameter transfer.
1) Pass by value (real parameters cannot be changed)
Real arguments are numerical values ​​such as variables, expressions, etc.

When a function is called, the actual parameter and the formal parameter exist in two different areas in memory. The actual parameter first copies a copy by itself, and then passes the copy to the formal parameter. Since it is a copy that is passed, the actual parameter will not be affected by the formal parameter and the actual parameter value will not be changed.

2) Pass by address (real parameters can be changed)
The actual argument is a pointer/reference.

When a function is called, the pointer is passed to you. The formal parameters and the actual parameters pointer are the same. Any operation on the formal parameters is equivalent to the operation on the actual parameters. The value of the actual parameter can be changed.

Effects on parameters:
2 data types: value type + reference type
2 ways to pass parameters: value parameters + reference parameters (ref and out keywords);

The combination of the above four parameters. In addition to the value-passing method, the other combination methods will affect the operation of the parameters and will change!

Value type:Simple type (int, float, double, long, char, bool) + structure + enumeration
Storage structure:Data is stored in the stack (stack: first in and then out; single entrance, single exit); high efficiency
Assignment method:The value passed

Reference type:Types other than simple types (int, float, double) + structure + enumeration are all reference data types. Such as string;object;class;array;delegation;interface. . .
Storage structure:Store address in the stack; put data in the heap;
Assignment method:The address of the data is transmitted.

Formal parameters:The full name "formal parameters" is a parameter used when defining the function name and function body. The purpose is to receive the parameters passed in when calling the function.
Actual reference:The full name is "actual parameter" which is passed the parameter of the function when called.

The types of formal parameters and actual parameters must be consistent, or they must comply with the implicit conversion rules.
When formal parameters and actual parameters are not pointer types (i.e., when they are not passed by reference, but by value),
When this function is running, formal parameters and actual parameters are different variables.
They are located in different locations in memory, and the formal parameters will be
Copy a copy of the content of the parameter, and the formal parameters are released when the function is run.
The actual content will not change.

If the parameter of the function is a pointer type variable (passed by reference), the process of calling the function
In, the address passed to the function is the actual parameter, and it is also used inside the function body.
The address of the actual parameter is the actual parameter itself. Therefore, it is inside the function body
The value of the actual parameter can be changed.

The biggest purpose of passing by reference is to implement "operator" overloading!

The difference between the ref parameter and the out parameter is that the ref parameter must be initialized several times before calling the method. The out parameter can not be initialized before calling the method, and they are all passed in reference pass mode

After C++ has "reference transfer", "change of formal parameters does not affect actual parameters" is judged invalid. Because what is passed to the function is not a value, but the variable itself. Although the formal parameters defined in the function are still local variables, they are a reference. Although the scope of this reference is limited to the inside of the function, since it is the same as the actual parameter, the operation on it is completely equivalent to the operation on the actual parameter. For example, if you call "Black Tornado" and buy fish, or if you call "Iron Niu" and buy fish, you will all go to the same person.

Why does C++ have the "reference pass"? One statement is that only references can achieve the purpose of operator overloading, and I will talk about this later. However, putting aside this, whether formal parameters are references directly affects the efficiency of program execution. As mentioned earlier, when calling a function, the value of the actual parameter should be used to initialize the formal parameters. The initialization process includes two processes: defining a variable and then assigning a value to it. If this variable is not an internal variable, but a class object, then defining a class object may be very complicated, and initializing this object will be very complicated. References just give an alias to the object, and do not involve definition and initialization, and do not need to be released when leaving the scope.

In contrast, passing with pointers can avoid the definition, initialization and release of class objects. You only need to pay the price of defining, initializing and releasing pointer variables. However, the pointer is too lethal. Even skilled programmers cannot guarantee that there will be no "wild pointers". The cost of wild needles is almost unexpectedly the program crash.

Quotation is not a vegetarian. If pointer transfer is "for you to get a key to my house", then quote transfer is to hand over all my house's property to you directly. Sometimes, we use reference pass only for efficiency and do not want the actual parameters to be modified, so remember to mark the formal parameters as const, such as "UINT GetLength(const CString&)".

By the way, pointer passes can do the same. Defining a formal parameter as a pointer to a const object (rather than a const pointer) can reduce lethality and protect the memory corresponding to the actual parameter. If it is a normal value passing, then whether there is const does not affect the external function. However, I personally think that sometimes adding const is also a good thing. If the logic of the program does not need to change the parameters, but actually write the code incorrectly, adding const can allow the compiler to help us find out the bug.