Upload
lam
View
25
Download
0
Tags:
Embed Size (px)
DESCRIPTION
Functions. Functions, locals, parameters, and separate compilation. What is a Function?. A function is a named block of code Type: the type of the return value it computes Input: parameters that are passed to the function - PowerPoint PPT Presentation
Citation preview
Functions
Functions, locals, parameters, and
separate compilation
What is a Function?• A function is a named block of code
– Type: the type of the return value it computes
– Input: parameters that are passed to the function
– Output: its return value computed based on input parameters and maybe other stuff
– Local variables: variables declared inside the function block
Typical Function
int max(int a, int b){ int maxval;
if (a > b) maxval = a; else maxval = b; return maxval;}
type name input
local variable
output
codeblock{
Exercise 1• Write the max function as given• Use forward declaration for max()• Write a similar min function• Write a little main function to
Declare two ints Ask for user input to set their values Call max and min Print out the inputs, then their max and
min (with appropriate indications)• Compile and test your program
What is a Function?• Recall the two parts of a function:
Function headerFunction body (or definition)
• Recall function header:– Type: the type of the return value– Name: name of the function– Formal parameter list: the input
parameters with their types
Function Signature, Body• Function signature is:
– Name– Formal parameter type list– This allows compiler and linker to figure
out which code to invoke• Function body (or definition)
– Block of code, may have local vars– Has return statement for return value
What is a Function?• Function generally has:
– Input: parameters that are passed to the function (may be null list)
– Output: its return value computed based on input parameters (if any) and maybe other stuff
– Local variables: variables declared inside the function block – generally these go away on function return
How Does a Function Pass Parameters?
• Function names input parameters– These are “formal parameters” that may
be referenced as variables inside the function
– The scope of these variables is confined to the function code block
• When invoked, expressions are used– These are “actual parameters” – Formal parameters are “bound” to them
Another Function
int sum(int a, int b){ int sum = 0;
for (int i = a; i <= b; ++i) sum += i; return sum;}
Exercise 2• Write the sum function as given• Write a little main function to
Declare two ints X and Y Ask for user input to set their values Print out the inputs, then call sum and
print out the sum from X to Y inclusive• Compile and test your program• What could possibly go wrong?• Stand up, walk around, talk about it
Analysis
• What could go wrong with the sum function as written? • What if the actual parameter passed in as a is greater than the actual parameter passed in as b?• Did you test that case? • How do we fix it?
Exercise 3• Use the max and min functions from
before to fix the sum function• Compile and test• Did you apply max and min from
inside sum, or before you called sum?
• Which way is “safer”? Why?
Separate Compilation
• A way to make the development process more efficient and manageable • Typically three kinds of files:
– Main program file – has main()– Header file(s) – has declarations,
included in main (and elsewhere)– Implementation file(s) – has
function definitions
Exercise 4• Make a header file with declarations
for max, min, and sum• Make a main (or driver) file with only
the main() function - #include your header file
• Make an implementation file with the function definitions only
• Compile impl files with -c option• Compile main with impl.o files
Example
$ lsmainSum.cpp minMaxSum.h minMaxSum.cpp$ g++ -c minMaxSum.cpp$ g++ -c mainSum.cpp$ g++ mainSum.o minMaxSum.o$ ./a.out...
Analysis• What is going on here?• Compiler produces “relocatable
object” code that has information needed for linking–What references are dangling–What references it can bind
• Linker can then link these .o files to make an a.out executable file
Why Bother? Exercise 5
• Take your old file that had main that called max and min and make it into a driver only (no max or min function definitions in it) – just #include the header file you just made
• Now compile your new main with the minMaxSum.o file
• Test it out!
Reflection• So now you are able to define and
compile useful functions separately from the code that invokes them!
• What are some benefits of this?–Only have to recompile the files
that change (directly or indirectly)–Can have team members each
work on their own file(s)
Hey, I Know a Better Way...• Look back at the sum function• Is there a better way to compute the
same value?– Euler did this as a schoolchild– sum(a, b) = count x average = (b – a + 1) * (a + b) / 2
Exercise 6
• Take your old impl file with the definition of sum() in it and change it to compute the sum the Euler way
• Now compile your new impl with the -c option
• Now link your old main.cpp to the new relocatable object file
• Test it out!
Reflection• The header did not change• The interface to the functions did not
change• The result of the computation did not
change• So we did not need to recompile the
driver or change the header!
More Reflection• However, even though only the
sum() function changed, we had to recompile the whole impl file with max() and min() in it
• What if each of these took 10 minutes to compile?
• Better still to separate out each function in its own impl file and compile each separately
Exercise 7
• Split the impl file into three files – one each for sum, max, and min
• Note that you will need the header file (at least in sum.cpp)
• Now compile them with the -c option• Now link your old main.cpp to the
new relocatable object files• Test it out!
(Same) Reflection• The header did not change• The interface to the functions did not
change• The result of the computation did not
change• So we did not need to recompile the
driver or change the header!
How Does a Function Pass Parameters?
• There are several ways a function may pass parameters
– By value– By reference– By copy-in-copy-out– By pointer (sometimes also called
reference)– By name
Call-by-Value
• This is the most common way to pass parameters• Space for the type declared in the formal parameter list is allocated on the stack• The value of the expression used at invocation is stored into that place on the stack
Call By Valuevoid swap(int a, int b){
int temp = a;a = b;b = temp;
}
void main(){
int a = 2;int b = 3;
swap(a, b);}
Call By Valuevoid swap(int a, int b){
int temp = a;a = b;b = temp;
}
void main(){
int a = 2;int b = 3;
swap(a, b);}
a b
32
Call By Valuevoid swap(int a, int b){
int temp = a;a = b;b = temp;
}
void main(){
int a = 2;int b = 3;
swap(a, b);}
a b
32
a b
32
Call By Valuevoid swap(int a, int b){
int temp = a;a = b;b = temp;
}
void main(){
int a = 2;int b = 3;
swap(a, b);}
a b
32
a b
32
temp
2
Call By Valuevoid swap(int a, int b){
int temp = a;a = b;b = temp;
}
void main(){
int a = 2;int b = 3;
swap(a, b);}
a b
32
a b
32
temp
233
323
Call By Valuevoid swap(int a, int b){
int temp = a;a = b;b = temp;
}
void main(){
int a = 2;int b = 3;
swap(a, b);}
a b
32
a b temp
22
23
Call By Valuevoid swap(int a, int b){
int temp = a;a = b;b = temp;
}
void main(){
int a = 2;int b = 3;
swap(a, b);}
a b
32
a b temp
2
Questions?
Call-by-Reference Using Pointers
• This is used for modifying the inputs• Space for pointer only is allocated on the stack• The pointer must be dereferenced to use value• Can change the original object
Call By Referencevoid swap(int* ints, int i_1, int i_2){
int temp = ints[i_1];ints[i_1] = ints[i_2];ints[i_2] = temp;
}
public void main(){
int[] ints = {1, 2, 3, 4};
swap(ints, 0, 3);}
ints
1 2 3 4
Call By Referencevoid swap(int* ints, int i_1, int i_2){
int temp = ints[i_1];ints[i_1] = ints[i_2];ints[i_2] = temp;
}
public void main(){
int[] ints = {1, 2, 3, 4};
swap(ints, 0, 3);}
ints
1 2 3 4
ints
Call By Referencevoid swap(int* ints, int i_1, int i_2){
int temp = ints[i_1];ints[i_1] = ints[i_2];ints[i_2] = temp;
}
public void main(){
int[] ints = {1, 2, 3, 4};
swap(ints, 0, 3);}
ints
1 2 3 4
ints
temp
1
Call By Referencevoid swap(int* ints, int i_1, int i_2){
int temp = ints[i_1];ints[i_1] = ints[i_2];ints[i_2] = temp;
}
public void main(){
int[] ints = {1, 2, 3, 4};
swap(ints, 0, 3);}
ints
1 2 3 4
ints
temp
1 44
4
Call By Referencevoid swap(int* ints, int i_1, int i_2){
int temp = ints[i_1];ints[i_1] = ints[i_2];ints[i_2] = temp;
}
public void main(){
int[] ints = {1, 2, 3, 4};
swap(ints, 0, 3);}
ints
2 3 4
ints
temp
1 11
intstemp
1 4
Call By Referencevoid swap(int* ints, int i_1, int i_2){
int temp = ints[i_1];ints[i_1] = ints[i_2];ints[i_2] = temp;
}
public void main(){
int[] ints = {1, 2, 3, 4};
swap(ints, 0, 3);}
2 3 4
ints
11
Function Calls• Additionally, using the & operator
(instead of a *) will make that parameter call-by-reference.– It will hide the obtained address, but still
work with and alter the same object/variable.
Call By Reference (2)void swap(int &a, int &b){
int temp = a;a = b;b = temp;
}
void main(){
int a = 2;int b = 3;
swap(a, b);}
Call By Reference (2)void swap(int &a, int &b){
int temp = a;a = b;b = temp;
}
void main(){
int a = 2;int b = 3;
swap(a, b);}
a b
32
Call By Reference (2)void swap(int &a, int &b){
int temp = a;a = b;b = temp;
}
void main(){
int a = 2;int b = 3;
swap(a, b);}
a b
32
a b
temp
Call By Reference (2)void swap(int &a, int &b){
int temp = a;a = b;b = temp;
}
void main(){
int a = 2;int b = 3;
swap(a, b);}
a b
32
a b
2
Call By Reference (2)void swap(int &a, int &b){
int temp = a;a = b;b = temp;
}
void main(){
int a = 2;int b = 3;
swap(a, b);}
a b
32
a b
3
temp
2 3
322
Call By Reference (2)void swap(int &a, int &b){
int temp = a;a = b;b = temp;
}
void main(){
int a = 2;int b = 3;
swap(a, b);}
a b
3
a b temp
2
a b temp
2 32
Call By Reference (2)void swap(int &a, int &b){
int temp = a;a = b;b = temp;
}
void main(){
int a = 2;int b = 3;
swap(a, b);}
a b
3
Questions?