Skip to main content
Engineering LibreTexts

10.4: Pass by Value vs Pass by Reference

  • Page ID
    29092
  • \( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)

    \( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)

    \( \newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\)

    ( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\)

    \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)

    \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\)

    \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)

    \( \newcommand{\Span}{\mathrm{span}}\)

    \( \newcommand{\id}{\mathrm{id}}\)

    \( \newcommand{\Span}{\mathrm{span}}\)

    \( \newcommand{\kernel}{\mathrm{null}\,}\)

    \( \newcommand{\range}{\mathrm{range}\,}\)

    \( \newcommand{\RealPart}{\mathrm{Re}}\)

    \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)

    \( \newcommand{\Argument}{\mathrm{Arg}}\)

    \( \newcommand{\norm}[1]{\| #1 \|}\)

    \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)

    \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\AA}{\unicode[.8,0]{x212B}}\)

    \( \newcommand{\vectorA}[1]{\vec{#1}}      % arrow\)

    \( \newcommand{\vectorAt}[1]{\vec{\text{#1}}}      % arrow\)

    \( \newcommand{\vectorB}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)

    \( \newcommand{\vectorC}[1]{\textbf{#1}} \)

    \( \newcommand{\vectorD}[1]{\overrightarrow{#1}} \)

    \( \newcommand{\vectorDt}[1]{\overrightarrow{\text{#1}}} \)

    \( \newcommand{\vectE}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash{\mathbf {#1}}}} \)

    \( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)

    \( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)

    \(\newcommand{\avec}{\mathbf a}\) \(\newcommand{\bvec}{\mathbf b}\) \(\newcommand{\cvec}{\mathbf c}\) \(\newcommand{\dvec}{\mathbf d}\) \(\newcommand{\dtil}{\widetilde{\mathbf d}}\) \(\newcommand{\evec}{\mathbf e}\) \(\newcommand{\fvec}{\mathbf f}\) \(\newcommand{\nvec}{\mathbf n}\) \(\newcommand{\pvec}{\mathbf p}\) \(\newcommand{\qvec}{\mathbf q}\) \(\newcommand{\svec}{\mathbf s}\) \(\newcommand{\tvec}{\mathbf t}\) \(\newcommand{\uvec}{\mathbf u}\) \(\newcommand{\vvec}{\mathbf v}\) \(\newcommand{\wvec}{\mathbf w}\) \(\newcommand{\xvec}{\mathbf x}\) \(\newcommand{\yvec}{\mathbf y}\) \(\newcommand{\zvec}{\mathbf z}\) \(\newcommand{\rvec}{\mathbf r}\) \(\newcommand{\mvec}{\mathbf m}\) \(\newcommand{\zerovec}{\mathbf 0}\) \(\newcommand{\onevec}{\mathbf 1}\) \(\newcommand{\real}{\mathbb R}\) \(\newcommand{\twovec}[2]{\left[\begin{array}{r}#1 \\ #2 \end{array}\right]}\) \(\newcommand{\ctwovec}[2]{\left[\begin{array}{c}#1 \\ #2 \end{array}\right]}\) \(\newcommand{\threevec}[3]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \end{array}\right]}\) \(\newcommand{\cthreevec}[3]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \end{array}\right]}\) \(\newcommand{\fourvec}[4]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \\ #4 \end{array}\right]}\) \(\newcommand{\cfourvec}[4]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \\ #4 \end{array}\right]}\) \(\newcommand{\fivevec}[5]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \\ #4 \\ #5 \\ \end{array}\right]}\) \(\newcommand{\cfivevec}[5]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \\ #4 \\ #5 \\ \end{array}\right]}\) \(\newcommand{\mattwo}[4]{\left[\begin{array}{rr}#1 \amp #2 \\ #3 \amp #4 \\ \end{array}\right]}\) \(\newcommand{\laspan}[1]{\text{Span}\{#1\}}\) \(\newcommand{\bcal}{\cal B}\) \(\newcommand{\ccal}{\cal C}\) \(\newcommand{\scal}{\cal S}\) \(\newcommand{\wcal}{\cal W}\) \(\newcommand{\ecal}{\cal E}\) \(\newcommand{\coords}[2]{\left\{#1\right\}_{#2}}\) \(\newcommand{\gray}[1]{\color{gray}{#1}}\) \(\newcommand{\lgray}[1]{\color{lightgray}{#1}}\) \(\newcommand{\rank}{\operatorname{rank}}\) \(\newcommand{\row}{\text{Row}}\) \(\newcommand{\col}{\text{Col}}\) \(\renewcommand{\row}{\text{Row}}\) \(\newcommand{\nul}{\text{Nul}}\) \(\newcommand{\var}{\text{Var}}\) \(\newcommand{\corr}{\text{corr}}\) \(\newcommand{\len}[1]{\left|#1\right|}\) \(\newcommand{\bbar}{\overline{\bvec}}\) \(\newcommand{\bhat}{\widehat{\bvec}}\) \(\newcommand{\bperp}{\bvec^\perp}\) \(\newcommand{\xhat}{\widehat{\xvec}}\) \(\newcommand{\vhat}{\widehat{\vvec}}\) \(\newcommand{\uhat}{\widehat{\uvec}}\) \(\newcommand{\what}{\widehat{\wvec}}\) \(\newcommand{\Sighat}{\widehat{\Sigma}}\) \(\newcommand{\lt}{<}\) \(\newcommand{\gt}{>}\) \(\newcommand{\amp}{&}\) \(\definecolor{fillinmathshade}{gray}{0.9}\)

    Argument Passing Techniques in C/C++

    There are different ways in which parameter can be passed into and out of methods and functions. Let us assume that a function B() is called from another function A(). In this case A is called the “caller function” and B is called the “called function or callee function”. Also, the arguments which A sends to B are called actual arguments and the parameters of B are called formal arguments.

    Terminology

    • Formal Parameter : A variable and its type as they appear in the prototype of the function or method.
    • Actual Parameter : The variable or expression corresponding to a formal parameter that appears in the function or method call in the calling environment.
    • Modes:
      • IN: Passes info from caller to calle.
      • OUT: Callee writes values in caller.
      • IN/OUT: Caller tells callee value of variable, which may be updated by callee.

    Important methods of Parameter Passing

    1. Pass By Value : This method uses in-mode semantics. Changes made to formal parameter do not get transmitted back to the caller. Any modifications to the formal parameter variable inside the called function or method affect only the separate storage location and will not be reflected in the actual parameter in the calling environment.
      Showing how call by value creates a copy of the values of the arguments and the function works on the copies, not on the original values
      Figure \(\PageIndex{1}\): Call by Value. ("Call by Value" by Geeks for Geeks, Geek for Geeks is licensed under CC BY-SA 4.0)

      This method is also called as call by value. In the example to the left, the call to geek_func passes the value of 2 arguments, 10, and 12. The copies of the 2 values are known within the function itself as num1 and num2. Assigniing the value 40 to the variabl num1 and 50 to the variable num2 within the geek_func() only affect the variable num1 and num2. Those changes have no impact on the variable val1 or val2...they continue to maintain the values of 10 and 12. C++ is passing the VALUE of val1 and val2...therefore it is just a copy and impacts nothing else.

     

    // C program to illustrate 
    // call by value 
    #include <iostream> 
    using namespace std;
    
    void func(int inVal1, int inVal2) 
    { 
        inVal1 += inVal2++; 
        cout << "In func, inVal1 = " << inVal1 << " inVal2 = " << inVal2 << endl; 
        return;
    } 
    
    int main(void) 
    { 
        int num1 = 5, num2 = 7;      // Passing parameters 
        func(num1, num2); 
        cout << "In main, num1 = " << num1 << " num2 = " << num2 << endl; 
        return 0; 
    } 
    

    The two cout statements show the the changes in the function do NOT impact the original variables in the main() function. 

    In func, inVal1 = 12 inVal2 = 8
    In main, num1 = 5 num2 = 7
    1. Pass by reference(aliasing) : This technique uses in/out-mode semantics. Changes made to formal parameter do get transmitted back to the caller through parameter passing. Any changes to the formal parameter are reflected in the actual parameter in the calling environment as formal parameter receives a reference (or pointer) to the actual data. This method is also called as call by reference. This method is efficient in both time and space.

     

    In the example to the right, we have an integer variable named n, with a value of 10. This variable is used in the function call func(). Notice the ampersand, &, in front of the argument n. This tells the compiler to pass the address of n - in our example that value is memory address 2008.

    Now in the function func() we see the argument variable add has an asterisk in front of it. This syntax says that the variable add is a pointer, that is the value of that variable is an address. So, the statement *add = 20; says, "Set the memory address contained in the variable add, which is 2008, to 20". So the original variable n, which is at memory address 2008, is set to 20.

    We will talk a lot more about addresses and pointers later in the semester...so if you don't understand this completely that's okay at this point.

    Showing pass by refernece - pasing the address of the variable, and in the function using a pointer to access that address space so changes actually reflected in original variable
    Figure \(\PageIndex{1}\): Pass by Reference. ("Call by Reference" by Geeks for Geeks, Geek for Geeks is licensed under CC BY-SA 4.0)

     

    // C program to illustrate
    // call by reference
    #include <iostream>
    
    void swapnum(int* input1, int* input2)
    {
       int temp = *input1;
       *input1 = *input2;
       *input2 = temp;
       return;
    }
    
    int main(void)
    {
       int val1 = 10, val2 = 20;
    
       // passing parameters
       swapnum(&val1, &val2);
    
       cout << "val1 is " << val1 << " and val2 is " << val2 << endl;
       return 0;
    } 

    Output:

    val1 is 20 and val2 is 10
    

    Adapted from:
    "Parameter Passing Techniques in C/C++" by Krishna Bhatia, Geeks for Geeks is licensed under CC BY-SA 4.0


    This page titled 10.4: Pass by Value vs Pass by Reference is shared under a CC BY-SA license and was authored, remixed, and/or curated by Patrick McClanahan.