YTread Logo
YTread Logo

Pointers as function arguments - call by reference

May 04, 2020
In our previous lessons, we defined pointer variables and also saw how to operate with pointer variables, how to work with pointer variables in c or c++ programs, but we didn't really talk about the actual use cases of pointer variables, in what scenarios it is You may want to use pointer variables. So in this lesson we will talk about one of the use cases of pointer variables and the use case is to use them, use

pointers

as

function

arguments

and we also

call

it

call

by

reference

, so let's walk through a scenario, Albert. He is a beginner programmer and recently learned about the concept of user-defined

function

s.
pointers as function arguments   call by reference
Now, he tries to apply this concept and writes a simple C program like this, what he is trying to achieve here is to have an integer variable declared and initialized. in the main method and you want to increment the value in this variable by one, so instead of writing something like a plus plus, or an equal to plus one, instead of writing a statement like this, you write an increment function that It will take an integer a as an argument and inside this function you are writing a statement like a equals plus one. He calls this increment function from the main method passing a as an argument and then prints the value of a.
pointers as function arguments   call by reference

More Interesting Facts About,

pointers as function arguments call by reference...

Now what you expect here is that the value of a will be incremented to eleven and therefore the print statement will print a = 11, but when you run the program, the result of the print statement is a = 10. Now, Albert doesn't understand why this happens; You have declared a value a and then you have initialized this variable to 10 and then you pass the same a to the increment function and the same a is incremented by one in this function, then why the value of a that is printed is not eleven, for what is 10 and now what? Albert does not understand well or what he probably forgot is that whenever we declare a variable inside a function then we call that variable local variable because as such by just using the name of the variable we can access that variable only inside the same function in the one we have declared the variable, so these two a this a in the function increment and this a in the main function are actually not the same and the 'a' in the function increment is another 'a' when main call the increment method and pass this a as an argument to the function, then only the value of a is copied to this other 'a' which is another variable local to the increment function, so what I'll do is make a couple of modifications in this code to show you a better picture I will write two print statements in this code, the first print statement in the increment method, something like this address of variable 'a' in increment is uh... as we know, yes we put the ampersand operator in front of a variable name, we get the address of that variable and I will comment out this print and write one more print in the main method like this and here I print that the address of the variable 'a' in main is the ampersand 'a', let's now run this and see what happens uh... let me also put a line ending after printing the statement and the output is the address of the variable 'a' in the increment method it prints as four four five four four six zero and in main it is equal to four four five four six six two these two look similar but they are not the same one has four four six seven zero at the end and the other has four four six zero what the values ​​are it is not important what are the addresses Not important, what is important is that these addresses are different if the 'a' in the main method and the 'a' in the increment method were the same, these two addresses would have been the same.
pointers as function arguments   call by reference
To understand this even better, we will try to understand how things work. happens in the computer's memory when a program is executed When a program is started in an application, the computer reserves or reserves a certain amount of memory for the execution of this program the memory reserved for the application is divided into Usually, it is divided into these four parts that we are showing here. A portion of memory is allocated to store the various instructions in the program. The computer needs to keep all of these instructions in memory. These instructions that we have in the program, such as increment or declaration. variables all these sequential instructions a part of memory is a part of memory allocated is for static or global variables if we do not declare a variable inside a function in c++ or c then it is a global variable Now global variables can be accessed and are modified anywhere in the program, unlike local variables that can be accessed and modified within a particular function or within a particular block of code, now the third part of applications memory is called the stack and this is really important, this is where all the local variables go and We'll talk mainly about stack in this lesson and the fourth part is heap and we'll get to this later in our next lessons of these four segments of the allocated memory uh... the text segment, the global variable segment and the stack segment.
pointers as function arguments   call by reference
These three are fixed and are decided when the program starts running the application; however, it may continue to request more memory for its heap segment during its execution. We will only cover all these things in detail in our next lessons, don't panic. With these terms, let's now see what happens when a program is executed, let's say this is the general memory of our computer, the RAM and as we know, each byte of the memory is addressable. So, let's say... the memory allocated for our program is from address two zero zero to eight zero zero and these are the various memory segments of our application and from this let's say... address three hundred to six hundred is allocated for the stack now there is more memory, of course, in the RAM after uh... address 800 and before address 200 Ok, so from 200 to 800 this part of the memory is allocated for our program, let's say this C program which we have on the left Now, when a function is invoked, such as when the program is started, the main method is initially invoked all the information about the method all the information about the method call such as its parameters, all the local variables the function that call which must return the current value of the instruction in which it is being executed, all this information is stored on the stack, so we will pop a part of the stack for the main method and create a unit that we will call stack frame .
Each function will have a stack frame now that we have a variable. a' now the memory is allocated for 'a' from this stack frame and the value of 'a' is 10. now the main method calls the increment function. What happens when the main method calls increment is that uh... the machine says, "Hey, I'll do it." Stop its execution for some time. I will dwell on this particular instruction. Let me go ahead and finish this increment method and then I'll go back to the main method once I'm done with the increment. Another stack frame is now allocated for the increment method and the parameters in the increment method as if we had a parameter 'a', so new local variables corresponding to these parameters are created and the values ​​that have been passed are copied to these variables.
These parameters now, when we say a = a+1 here in this statement, what happens to this 'a' that is local to the increment? function, in this particular stack frame, this 'a' is incremented, they cannot access a variable outside their stack frame and now the increment ends. When the increment is finished, control returns to the main method and what the machine does is clear the stack. The frame that was allocated for the increment and the main method resumes again. So the main method stopped at this particular statement increment, so the lifetime of a local variable is until the time the function is executed.
Now, the following statement in the main method is a call to the printf function printf is not a user-defined function. It is a library function, the main method execution state is paused, and printf is running. Now we often call this particular structure call stack or function call stack, whatever function is at the top of the stack is being executed and remember this stack is fixed. in size. So if you have a scenario where a function keeps calling another function indefinitely, as in the case of indefinite recursion, then the memory of this stack will overflow and our program will fail, but that is not relevant to this scenario, so You should now be getting a picture of what happens when a function calls another function.
This 'a' is in the stack frame of the main method. main is our calling function and increment is our called function. When we call a function in the calling function, the argument is also known as actual argument and in the called function, the argument is known as formal argument, all that happens is that the actual argument is actually assigned to a formal argument. , so when this function call happens, 'a' is assigned to 'a' as an actual agreement. The argument is assigned to another 'a' which is a formal argument instead of 'a'. If we had an 'x' here, we would have written something like int x is the argument and 'x' is x plus one, then 'a' would have been assigned to x, so the value of 'a' will be copied to the variable ' x'.
Now when we make a function call in which we basically have a variable assigned to another variable, the value of one variable is copied to another variable, then such a function call is also called call by value, so this is what Albert I was doing making a call by value and that's why I couldn't get the desired result, but can we get the result that Albert? I wanted Albert to want to use this variable 'a' which is local to the main method inside the increment function. Can we really do it? Good ! yes, we can do it if we use

pointers

as function

arguments

.
Let's now look at this code and here I will draw only the stack so that I can clearly show the simulation of the program execution. Now what we are doing here is we don't have an argument that is an integer in this function increment, we have an argument that is a pointer to an integer and a pointer to an integer, as we know, will store the address of a integer, so now what we do What we are doing is that in the increment function, we are passing the address of 'a' so that when the program starts running, the main method is called first.
Let's say this is the stack frame of the main method, say 300 to 350, this address is the stack frame of the main method and of the main method there would be a local variable 'a' in this main method, say The address at which stores 'a' is 308, this may not be proportional, but still let's say this is how it is stored. Now when the main method calls increment, a local variable corresponding to parameter 'p' is created and this is a pointer. to an integer and the value that is passed to this particular function, the value that is stored in this particular function, sorry, it's not a function, it's a variable. the value that is copied or stored in this particular variable would be 308, the address of 'a'.
So. 'p' points to 'a' Now, in this statement here, when we say asterisk 'p' we de

reference

this address, so we are saying here that *p is the value stored at address p, so we say which increments the value stored at address p by one, the value stored at address 308 is incremented by one. So 'a' is now eleven, now when initiatives are incremented and we go back to the main method and the next line is executed, which is the print statement, then a is now 11. If you run this program, what is printed is a = 11. a function call in which instead of passing the value of a variable, we pass the address of the variable, so that we have a reference to the variable and can dereference it and perform some operations is called call by reference, so If we use pointers as function arguments, then we are using call by reference.
Calling by reference can save us a lot of memory because instead of creating a copy of a large and complex data type, if we just use a reference and using a reference will also cost us some memory, but a very small amount of memory. so we will save ourselves from creating a new copy of a complex data type in the next few lessons, we will see more about application memory layout and everything we can do using pointers. So, thanks for watching!

If you have any copyright issue, please Contact