Game Basics Functions
Hello, everyone
This is Lee Yeong-hoon, in charge of C# object-oriented programming lecture
Today, we'll talk about
concept and coding of functions
We’ll explore the concept of functions and coding methods
We’ll learn how they are processed
as Call by Value and Call by Reference
depending on the parameter type
We’ll also cover function overloading
and how functions are called
Function Concept, Syntax, Parameters, and Overloading
If you look up function in a dictionary like Naver,
you’ll find that it translates
to Function in English
Looking up Function again shows
that it means feature or functionality
When we learned about functions
in math class as kids,
we understood them as mathematical concepts
But in reality, the word function also
means feature or functionality
So, in computer programming,
a function
refers to a specific functionality
Now, let’s represent a function
with a diagram
A function looks like this
This is how it looks like
You’ve probably seen something like this before
Does it remind you of a juicer?
If you put a lemon in here,
something happens inside, right?
Then, juice comes out
Similarly, a function
has an input section,
performs some process inside,
and then outputs a result
In C#, a function is expressed
with a return type,
followed by the function name,
and parentheses
Inside the parentheses,
we can include some information,
such as variables
These are called parameters
In English, they are called parameters
A function may or may not have parameters
It also has its own scope
The fact that it has a return type
means it returns a value
In English, returning a value
is called return
So, we say return type
Inside the function, we use the return keyword,
followed by the return value
This is the general structure
of a function
Now that we’ve talked
about structure,
let’s cover the concept
A function
has a defined space
It may or may not return a value
When a function starts, it may or may not receive input values
These are the parameters we just discussed
So this is the parameter
Likewise, a function may have parameters
or none at all
It may have one only,
or many at once
And since we talked about variables,
we can define variables
inside the function as well
A variable declared inside a function
is called a local variable
In C#, there are also variables outside the function
We’ll cover this in the next lesson about classes,
but functions can also have external variables,
which are called fields
Fields are sometimes called member variables
or methods
If a variable is outside a function but isn’t a field,
it is considered a global variable
This is how these concepts are categorized
A function consists of internal
and external components
Now, let’s talk about their different types
There are three types: fields,
parameters, and local variables
These are the three
In fact, parameters
behave similarly to local variables
For example, say
we declare an integer variable int,
called A
Then, inside a function, we can declare another variable A
If we assign
a value within that,
such as A = 10 inside the function,
which function will be affected?
Which function is being referred to here?
The variable A
refers to the closest function
to itself
That’s why it is considered a local variable
Functions have these characteristics like this
We’ve discussed the concept
and structure of functions
Now, let’s write some code
to implement it
Let’s go here
and create a new project
Right-click on the solution,
click Add,
then select New Project
Again, choose Console App
or NET Framework,
click Next,
and name it Function
since we are working with functions
Now, let’s look at the Main function
It's a function too
Here, we have a return type,
which we haven’t covered yet,
but it’s called void
This means nothing or empty
Think of it as the void character in Chinese
So, void means
there is no return value
So it does not return anything
That’s why there is no explicit
return statement here,
as you see here
The Main function also has parameters
If you hover over them,
you will see that they are labeled as parameters
Before implementing a function,
let’s create a simple calculation
using two numbers
Let's begin
First, let’s declare an int num1 variable
We’ll set its value to 10
Next, let’s declare int num2
We’ll set its value to 20
Now, I want to add these two numbers
Let’s perform the four basic
arithmetic operations
We’ll start with addition
We’ll declare a result variable of type int
Then, we’ll assign it the sum of num1 and num2
Shall we print this out?
Console WriteLine(result);
If we run this,
let's do this too
We should set Function
as the startup project first
Then, let’s run it
Now, we can see 30
as the output
Adding these two numbers gives 30
Now, let’s try subtraction
We cannot declare int result again,
because variables must have unique names
within the same scope
You cannot declare the same variable name
twice within the same space
If you want a new variable,
you can add a number
or use a different name
But I will just reuse it
I can reuse this,
the existing result variable
Since this is subtraction,
I’ll assign num2 - num1 to result
Let’s print the result
like so
I’ll do the four basic arithmetic operations in the same way
I’ll quickly copy and modify it
For multiplication,
we multiply the two numbers
I changed it from num2 to num1
For subtraction, I adjusted the order
so that the larger number is first,
like this
Now I’ll also perform division
For division,
I’ll divide the larger number by the smaller number,
like 20 divided by 10
Let's run it
Now, we can see addition, subtraction, multiplication,
and division printed out
Now, imagine
that we repeat this process multiple times
We wrote quite a bit of code just now
If I want to do this twice,
I would need to copy and paste everything again,
something like this
This approach would
make the code repetitive,
executing the same operation twice
Like this
We use a function
for various reasons,
one of which is this
It's to group multiple operations
into one reusable unit,
making it easier to manage
That's one of the reasons
So, I’ll delete the duplicate code
and instead, I’ll create a function
to handle all four arithmetic operations
A function cannot be declared
inside another function
It must be outside
Since this function performs calculations,
I’ll name it Calculate
I’ll write void Calc() to define it
Let’s write void Calc()
Now, select all the code
we’ve written so far
Click the top line, hold Shift,
and click the last line to select everything
Now we have everything
Press Ctrl+X
or right-click
and choose Cut
Ctrl+X is the hotkey for this
Then, paste it inside the function
Now, we have successfully moved the code
As I explained earlier,
a function has a return type,
a name, and parameter
Right now, I created
a function without parameters
To summarize,
a function’s structure consists of:
Return type → Name →
Parentheses,
with or without parameters
There could be many parameters
or none at all
For example, this is no parameters
Then, we use curly braces
Inside, we can include return,
but if the return type is void,
we can omit return
In our Calc() function,
there’s no return
This is a valid way to write it
Now, let’s try running the function
So we write it
like this here
However, this will cause an error
because Main() is static,
which means it exists from the beginning,
but Calc()
does not have static
This relates
to classes, which we’ll cover next time
It's because it belongs to a class
If you hover over Calc(),
you’ll see it belongs to Program Calc
This means it is part of the Program class,
so it's included in this class
This may look like
it's inside the same thing
This Main
may look like it belongs to Program
But because it’s static,
it cannot access Calc() directly
To fix this,
we have two solutions
One is to create an instance
of Program
and call Calc()
Two is to make Calc() static,
so it belongs to the class itself
See this?
That's how you can do it
Now, you can see that the error disappears
Since both functions are static,
they exist from the beginning,
allowing them to be called directly
Let's run thi
As expected, it prints the results correctly
Now, let’s try something different
The Calc() function we created earlier
combines multiple operations,
but this time, I’ll create a function dedicated
solely to addition
I’ll write this function below
So this is addition
Since Calc()
didn’t need to return anything,
I didn’t specify a return type
But now, because this is an addition function,
it needs to combine these two
and it should return a value,
process it,
and do things like that
Let's create this part
I’ll set the return type to int
This function will take two integers,
add them,
and return the result
That's the gist of this function
I’ll name the function
Add(), a common convention for addition functions
I’ll define it as int Add
and int A, int B
For one parameter,
this is how I write it
If I needed to pass more numbers,
I could separate them with commas
Same with three numbers
Use comma like int A, int B, int C
For now, I’ll stick to two numbers
Now, I need to define the function’s scope
by adding this
Like so
But you’ll notice an error
We see the red line
The issue is that I defined a return type
but didn’t specify what to return
That's why we're seeing an error
So, I’ll write return here
Then, I’ll return the result of A and B
Let's return it, but instead of
just returning it directly,
I’ll store it in a variable first
I’ll create int result = A + B
and then return result
Now, the error disappears
So that's how it looks like
I will not make this into a comment
Next, I’ll call the Add function
I just did it the last time,
but let's now really talk about this
When you create a function like this,
it’s called
defining or implementing a function
Defining
or implementing a function
But just defining a function
doesn’t mean
that it will run automatically
To execute it, you need
to call the function
So, we call the function using its name, like this
Same thing,
to use it here, we need to add static
So let's go ahead and add static here
Now we need a value here
This is how it'll work
Let's write 10 and 20 here
By doing so,
notice how I used a comma
between 10 and 20
So now, we need to find
a function that has a same structure of Add
See this?
So the parameter
This is the parameter
Those values are called arguments
Those who receive those arguments, are called parameters
When you pass values into a function, those are argument
So, when we have two argument values,
like here, 10 and 20,
these values get passed into the Add function
The values 10 and 20 are copied into the function parameters
So, 10 is assigned to a,
and 20 is assigned to b
Now, inside the function, a holds 10, and b holds 20
In addition, that's 30
That value 30 gets assigned using the assignment operator
The right-hand side performs the calculation,
and the result gets passed to the left-hand side
So, 30 is stored in the variable result
The stored value, 30,
gets returned
Since the Add function is returning a value,
that means the function gives back 30
to wherever it was called
It called the function,
and it returns the result
Earlier, when I explained functions,
I mentioned input and output
Here, in the output section,
this is exactly what happens
So it prints here
And since we’re using the assignment operator,
we can handle it more easily
Write this,
and add int result to the left
By doing this, the = assignment operator
takes the result from the right side
and assigns it to the left side
In other words, the function Add(10, 20) runs first,
calculates the sum, and then returns the result
That returned value is stored in the variable
I used the same name for these two variables,
but in reality,
they’re completely different, right?
Earlier, I explained that
if a local variable
has the same name
as a field outside,
they’re still not the same variable
Even though they share the same name, they’re separate
So what does that mean?
It means we can create multiple functions, right?
Let’s say we have two different functions,
one called A and another called B
Now, if I declare int a inside both functions,
this a, this a, and this a
they all look the same,
but they’re actually different
Only the name is the same
They exist separately
They’re completely different variables
To prove it,
let’s print the values
I’ll copy the code above
and run it
As expected,
30 is printed again
Now, let’s take it a step further
Let's try this
I’ll create a static int result.
Now, look at this
We have result here, result here, and another result here
This can get really confusing
That’s why it’s generally not a good coding practice
to reuse variable names like this.
But sometimes it happens
So the key is to fully understand what’s happening
If you’re using Visual Studio,
you can hover over the variable with your mouse,
and it will highlight where the same variable is used
See this?
If I remove the int declaration
from the result inside the Main function,
then since there’s no local declaration,
it will now use
the existing result
If I hover over result,
you can see
that it’s now linked to the static result
outside the Main function
See?
So this is a static variable
Static means it’s fixed
That means result is a static variable,
specifically static int result, which belongs
to the program itself
And this makes it a field
So functions
are structured like this
Inside them, we can
declare variables
But these variables need to be properly managed
because their names matter
and they have a scope that defines their accessibility
For example, the result variable inside Add and the result inside Main
are completely separate
Main cannot directly access
the result inside Add, and vice versa
They are completely isolated
Even visually,
you can see they’re completely isolated
They can never access each other
However, the field we created outside,
the one I labeled as static,
for this field,
this can be accessed from both
A and B functions
That mean
if two different functions
need to share data,
defining a field outside of them is a useful approach
That's a way of thinking about this
Right now,
we have this Add function,
and I'll try something new
Let's remove this part
We have this Add function,
but what if we create another one?
The same static,
but instead of returning an int, I’ll use float,
a decimal number type
I’ll keep the function logic exactly the same,
just change the return type
and parameter types to float
Here we have it
Now, look at this We now have two functions
with the exact same name, Add
So, what happens when we call Add?
The system is smart,
which means this
It automatically figures out
which version to call
based on the parameter types
and number of parameters
before it calls the function
This feature is called function overloading
Function overloading
Again
The function name is the same
But if the parameters
are different,
or even the return type,
If the return type and parameters are different,
then when
calling the function,
the compiler decides which function to use
This is called
function overloading,
or simply overload
Some people just call it
duplication,
function duplication
That's the overload
So right now, we have 10 and 20, both integers
Since they’re both integers, this is what's called in
You can check this by hovering your mouse over Add()
in Visual Studio, it will show which function is being used
I’ll add an f at the end
Then, I’ll also change the result variable to a float
Now, when I click on Add(),
you’ll see that this time,
the floating-point version
of Add is called
This is what we call function overloading,
overloading
Inside the function parameters,
we can also set default values
For example, I’ll give b a default value of 100
So now,
when you hover over the function,
it says overload
You’ll see that b is displayed inside square brackets,
showing that it has a default value of 100
That's what it gives us
You can also press Ctrl + Shift + Space
to see the overloaded versions of the function
So now, we have two versions
that are overloaded
That's what's happening
Now, if I write the function this way,
even if I delete this part,
the second function
will be called automatically
Since this is a float, it’s better to add an f
Now, let’s run this
You can see that the result 110 is printed
Why? Because I only passed one value, 10,
but the second parameter b automatically received its default value of 100,
so the function added them
together to get 110
This is called a default parameter
or a default argument
The parameter that
gets a default value
is called a default parameter
Those are the terms for these
This is a really useful feature,
so it’s good to know
Call by Value, Call by Reference
Now, when we pass values into a function like this,
the parameters receive them
In C#, data types are broadly
categorized into two types
One is value type
Another is reference type
Value means an actual value
So we call these value types
Reference means it refers to something,
so we call these reference types
So these are the two types
In C#, we use class a lot
We’ll cover it in the next lesson,
but basically, a class is also a data type
A class is what we call a user-defined type
A type
simply means a data type
So when we say user-defined type,
we’re talking about a type that the user creates
If it’s a class,
then it’s a reference type
If it’s anything else,
like an enum,
and other things,
those are all this
It's something simple
If class, reference If else, it’s a value type
That's how it works
Let's see this in action
Write 20 again
Let's reset this part
So this passed 10 and 20 as arguments,
and they got received here
to be processed
See here,
let me change this
Int num, no, not an int
Float num1
Add 10 to this
And 20 to num2
Let's just work with this
Now, when we pass arguments into a function,
we can directly input literal values, like this
But we can also use variables instead
So the values stored in those variables
are what get passed into the function
Since we’re passing the actual value,
this method is called Call by Value
Call by Value
Call by Value means we’re passing the value itself
So, when the function is called, it’s handling a copy of the original value
So the term for this
is Call by Value
Now, what if we don’t want to pass a copy
but instead pass a reference?
Earlier, I mentioned that only classes are reference types,
while everything else
is a value type
That means basic data types like int and float
are value types as well
For example, if you press F12
on int or float,
you can see that these types are actually structs
So they are all structs
Let's go back
Since structs and enums
are value types,
and all basic data types
are based on structs,
as you see here, struct,
they’re also value types
However, we can force
value types
o act like reference types
To do that,
we use the ref keyword
I’ll add ref here in both places
So ref stands for reference
By adding ref, parameters a and b
are now treated as references, not values
That means instead of passing a copy,
let's write ref here
Now,
even though int and float are value types,
using ref turns them into reference types temporarily
Now we need to know the difference
between the two types
To understand the difference,
let’s create two versions of the function
This is Add and value
Let's remove this
This is Add value
This is Add reference
Let's call each
This is Add call by value
This is call by reference
Call by Value
Let' change the function name
So we need to remove ref now
Now let's print this
Let's print this num1
We know the result already
So this,
we have the a that has been passed
Let's actually start with value
Let's move it down a little
Let's try it with this
At call by value,
num1 has 10
and we passed num1 to this
So the variable a
now receives the value within num1
The parameter
So I will now
change the value of a
to 100
Let's now print
What I did is this
So, when we call a function,
let’s look at how the execution flows
First, Main function runs,
and then the code executes line
by line from top to bottom
Now, when it reaches this = operator,
the right-hand side runs first
That means the AddValue function
is called first
At this point, execution jumps to the function,
so the flow of time moves to AddValue
Now, num1 and num2,
are 10 and 20
Next, a is set to 10 again
and then we add the numbers together
After that, the function returns the result
Now, back in Main,
the returned value is stored in result,
and then we print num1
to check its value
So, here’s what we’re testing
We passed num1
into the function, right?
The value num1,
that's what has been passed here
And inside the function,
the value for a
was changed to 100
It used to be 10,
but we changed it to 100
So the question here is this
So, does num1 also become 100?
Let’s check the output
for num1
So it has not changed to 100
See?
This happens
because Call by Value means
the function only gets
a copy of the value
Imagine you have
a 100-won coin in your hand
And you give it to someone,
but here's the twist
Instead of giving the actual coin to someone,
you make a duplicate
and hand that over
Now, whatever they do
with that 100-won coin,
even if they draw on it
or scratch it,
your original coin
stays the same
That's what happens here, making a copy
That’s exactly what Call by Value does
The function works with a copy,
making a duplicate
This is why
changes don’t affect the original variable
That's what Call by Value does
Let's not move on
to Call by Reference
This time, let’s call AddReference
and store the result in result
We’re passing in num1 and num2 just like before,
but now, we must add ref here,
since this is Call by Reference
So we need to update
the function definition as well
Now, let’s label this section with a comment
Call by Reference
So this is Call by Reference
It's a comment
Comment
For a reference, the original value changes
So, what happens is that
when you pass a value using ref,
the function receives a
as num1 itself
Technically, it’s a bit different,
but this is the basic idea
There is a memory space
where the data is stored, right?
This memory space reference
is passed along as information
So now, this function
actually retains
the memory location of num1
So it means the original value itself is being transferred
Now, let’s assign
100 to a
The same logic applies
This num1 originally held the value 10
But since we passed num1 as a reference,
in the AddReference function,
we changed a to 100
What happens next?
The value of num1 itself
is updated to 100
Let’s add an f at the end
and run it
See that?
The value has changed to 100
Call by Value
and Call by Reference
are two important concepts
When you’re working on something,
if a variable is created using a class,
it operates under Call by Reference
Please remember this
Otherwise,
if you pass such a variable as a function parameter
and modify it inside the function,
the original value will change
That’s why you need to be clear on
whether you’re working with a copy
or directly modifying the original
This has to be clarified first
Now, let’s look
at one last thing
I’ll create another
Add function here
static
I'll keep the float
float Add
So now we have it
Now, return result
That's the code we have
But this time, let's change
this flat to void
And remove return result
Instead, let's write
add a comma,
and use a keyword called out
out
And this result here,
let's write this out here
And remove what we have here
Remove the data type
Let's create the code like this
You may have already noticed
This keyword out is this
It's essentially a way
to return a value indirectly
That's what it is
Right?
In a typical function,
you specify the return type
and return a value explicitly
That's how it works
However, in some cases,
you might want to handle things differently
For example, let’s say you want to perform addition
but also determine
whether one number is greater than the other
While this might not be a typical use case,
you could return a boolean
That's the case
Let's try this
If a is greater than b,
return True
If not,
return False
That's the function
that we may want to make
So, for the return value,
if a is greater than b, we return true
a is bigger than b, it's true
That's a way of doing this, right?
This means
the function is now
structured to return two things
First, whether a is greater than b,
and second, the sum of a and b
These are the two pieces of information
we can get with this structure
And the characteristic of the out keyword is that,
as I explained earlier with Call by Reference
using the keyword ref,
the keyword out
also works as a reference type
A reference type
Since it is a reference type,
it directly affects the original value
But here's the thing
about ref and out
Here's the thing
For example, I could choose not to assign a value
That means, if I use the out keyword
for a parameter but do not actually
assign a value inside the function, it will cause an error
With out, assigning a value is mandatory
before the function exits
On the other hand, if we use ref,
we don’t necessarily need to assign a new value inside the function
It won't give us an error without the = sign
But it will for out
We need a value inside
That's the difference
So, when calling the function, you can do it like this
If we call the Add function,
let's say this
Let's write it out
Like this
Call Add
And we pass in num1 and num2 as usual
Let me do it again
We first create a variable to store the result
Bool type, isGreater
Is it correct?
That's the way we can write this
Is a greater?
This may feel a bit forced
but that's a way of doing it
Now we write the keyword out
And add it here
Let's see what it does
Let's print it
Then the entire result is this
a, b, the out keyword, result
And the fact that a is greater than b
is returned as a feedback
in a Bool type like this
So when we call this function,
this is what happens
We previously discussed int.TryParse
Remember the int.TryParse function?
This is how it looks like
It returns a bool value
Then, when you pass a numeric string,
the function processes it and returns the result
using the out keyword
So this is usually
how we make this
So to the out keyword,
add it here like so
And print it
Of course it will print 30, right?
And let's check our IsGreater part
Let's do this
This will calculate and decide
which of a and b is bigger
Since a is bigger than b, it's false
So false, and the result, 30
This is what we get out of this
Like this, we can do
many thing using a function
Let's recap the important things about a function
It has a return type
Now, a function name
Next, parameters
There are many kinds of a parameter
This is the basic structure
You could add keywords
like out and ref
Now, to the variable,
you can add default values like this
However, when using out,
setting default values can be tricky
Nonetheless, functions provide
various ways
to structure logic
Let's summarize what we've learned today
Functions: Concept, Syntax, Parameters, and Overloading Performs a specific task Return type, function name, parameter, return
Parameters Have different types of parameters, which define relationships between function spaces Local variable: Declared inside Field: Outside
out, ref keywords can be used or default values can be set
Functions must be called to execute; definition alone does not run them Defining a function
Calling a function
Overloading When multiple functions have the same name, the compiler selects the correct one based on parameter types, count, and return type
Call by Value and Call by Reference C# Data Types Reference type: Created using classes Value type: Everything except classes
Call by Value Arguments are copied when passed to a function The original value remains unchanged
Call by Reference Specify ref in parameters and arguments to force reference type conversion
Calling AddReference accesses the data’s memory space, altering the original value Class-based variables use Call by Reference