Peace For All

August 28, 2006

What is the difference between these two methods of calling?

Filed under: Programming, technology — Devlin Bentley @ 10:06 am

Edit: I have added an explation of (the more typical) Call by Value vs. Call by Reference since everybody who comes to this page seems to be looking for it. 🙂

Call by Value VS Call by Ref explanation:

Variables all have a value. For instance:

int a = 5

Here, a has the value of 5.

Now realize something. THERE IS NO VARIABLE CALLED a. The second you hit compile (build), that variable vanishes. What really happen is that when your program is run, 32 bits (4 bytes)[1] of RAM inside the computer is allocated, and the value 5 is stored there. The compiler automatically figures out what address of memory to use.

From the computers point of view, it may very well decide that the memory address 4c00h is where the variable a always goes, and when that above line of code loads, it may looks something like this:

MOV 4C00h 5

4c00h is an address in memory, and 5 is the value that is placed there. mov is the assembly[2] command to move data into memory (amongst other things).

The compiler replaces all your usages of the variable a with the memory address 4c00h. The point here is that variable names are just a label that is there so we don’t have to try and remember memory address numbers.

This is a BIG deal. You have to separate “Variables” from the concept of “Values”. They are two different things. Remember this: A variable is just a way for US, the humans, to LABEL SOMETHING that is stored inside the computer.

You will notice that a relates directly to a a number in this case. Hey, cool. That is easy to understand.

There is no rule saying that variables have to always label just numbers or string. Variable can label darn nearly anything.

Think for a minute. What are functions? They are a label we apply to a bunch of code that we want run. We want that code run, type in the function name, the compiler goes and inserts the instructions needed to make it so that the function is run.

This is also pretty simple. Here, variables just label functions. Not too complicated.

What if we want to label something more complex though? Like say an Array? Arrays can have many values inside of them, and they can take up a lot of memory.

int[5] hoursWorked = [8, 9, 7, 8, 8]

The compiler cannot just go through and replace all occurances of hoursWorked with a single address of memory. Now, hoursWorked is taking up a lot of addresses in memory!

Thankfully, (I am not going to explain this right now. 🙂 ) arrays are setup in memory so that all the values are right next to each other. This means that the compiler goes

MOV 4C01h 8
MOV 4C02h 9
MOV 4C03h 7
MOV 4C04h 8
MOV 4C05h 8

If you ignore the h at the end there (it is just shorthand for something else, if you know what, great! If you don’t don’t worry about it. 😉 ) you can see that the numbers are increasing. 1, 2, 3, 4, 5. This means that if you could look at the values stored in RAM on your computer, you would see the numbers 8, 9, 7, 8, 8, all lined up right next to each other.

Here is the cool part. We ONLY need to have the address of the first element in the array. 4C01h If we know that address, we can find the other ones just by walking forward, remember, they are all right next to each other!

So what does any of this have to do with passing values in functions? Well, quite a bit!

Lets pretend we have the following function:


int calculateSalary( int numberOfDaysWorked, int[] hoursWorkedEachDay )
{
  int totalPay = 0;
  int hourlyPay = 7;  for( int i = 0; i < numberofDaysWorked; i++ )
{
totalPay = totalPay + (hourlyPay * hoursWorkedEachDay[i]);
}

  return totalPay;
}

This function simply goes through the array of how many hours you worked each day, multiplies the hours of each day by how much you earn each hour (in this case, $7), and adds that days pay to the weeks total.  Notice if you only worked 4 days, you pass in numberofDaysWorked as 4, and you only read the first 4 values from the array.

The function most likely will get called like this:

int totalPay = 0;
totalPay = calculateSalary(a, hoursWorked);

I use a and hoursWorked from above.

The variable a is pretty simple.  The compiler can just read whatever value is at the memory address a refers too, in this case the memory address is  4C00h and the value is 5.  The computer just reads the value at memory address 4C00h and passes it to the function calculateSalary.  Cool.  Wenow have

 totalPay = calculateSalary(5, hoursWorked);

What about the array hoursWorked?  The compiler cannot just copy a value here, it is an array!

So what happens is that the memory address of the array is passed instead.  It ends up looking like

totalPay = calculateSalary(5, 4C00h);

4C00h is a reference to where we can find the array at.  If you look up the definition of reference, it says that:

a reference is something that refers or points to something else

en.wikipedia.org/wiki/Reference

Well, that is exactly what 4Cooh does, it POINTS to where the array hoursWorked is at in memory.

In languages like C and C++, you say that something is a pointer by putting the character * in front of it.  Newer languages (such as Java and C#) handle a lot of this for you, and when you pass an array, you don’t have to worry about syntax so much.

Oh, and you now understand pointers too.  🙂  I have work to do, my apologizes for the lack of spell checking.

[1] This is a vast simplification and may not be true on all computers. INTs can be of any number of sizes, PLEASE DO NOT RELY UPON INTS BEING 32BITS IN SIZE. Especially not because I said so. :)[2] Assembly is a human readable represenation of the language that your computer understands, actual machine code. Machine code is all in binary and consists of 0’s and 1’s, and is even harder to understand! And yes, this example is greatly simplified.


Original post is below, you can safely ignore it, someone else explained it to me. 🙂Call by Value (where the value is always an object reference, not the value of the object)

compared to

Call by Reference

They end up being functionally the same, don’t they?

This is in reference to Python, which then says at the bottom of the tutorial page:

call by object reference

THEN WHY did they just say Call by Value?

Call By Val

Call By Ref

Then there is C’s awesomeness of ALWAYS Call By Val, but we’ll pass the value of a memory address along if ya want cuz hey why not?

I am a proponent for Call By Ref whenever you have objects, since when I am doing OO I want abstraction, but when I am doing C I am in a mood for understanding, comprehension, and I can feel the entire machine surrounding me. It is awesome, it is fast, it is efficient, my code has less bugs, and damnit, I WANT that power because it feels good.

Advertisements

Leave a Comment »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Create a free website or blog at WordPress.com.

%d bloggers like this: