You are on page 1of 13

Lesson 14: Functions, Basics

Welcome to EasyCPlusPlus.com's free tutorial on C++ programming. This lesson covers functions. Functions are used to encapsulate a set of operations and return information to the main program or calling routine. Encapsulation is data, information or detail hiding. Once a function is written, we need only be concerned with what the function does. That is, what data it requires and what outputs it produces. The details, "how" the function works, need not be known. We have also seen encapsulation with objects. Objects in C++, which encapsulate both data and methods, will be discussed more in later lessons. The use of functions provides several benefits. First, it makes programs significantly easier to understand and maintain. The main program can consist of a series of function calls rather than countless lines of code. A second benefit is that well written functions may be reused in multiple programs. The C standard library is an example of the reuse of functions. A third benefit of using functions is that different programmers working on one large project can divide the workload by writing different functions. Defining and Declaring Functions A function is declared with a prototype. A function prototype consists of the return type, a function name and a parameter list. The function prototype is also called the function declaration. Here are some examples of prototypes. return_type function_name(list of parameters); int max(int n1, int n2); int printResults(string buffer, int status);

The function definition consist of the prototype and a function body, which is a block of code enclosed in parenthesis. A declaration or prototype is a way of telling the compiler the data types of the any return value and of any parameters, so it can perform error checking. The definition creates the actual function in memory. Here are some examples of functions. int FindMax(int n1, int n2) { if (n1 > n2) { return n1;

} void PrintHW() { cout << "Hello World" << endl. } float FtoC(float faren) { float factor = 5. Using Functions A function must be declared prior to its use. The parameter list of a function may have parameters of any data type and may have from no to many parameters. Finally. return celsius.0. } There are a few significant things to notice in these examples. The return statement is optional. Techniques for returning multiple values from a function will be covered later in the lesson. } } void PrintMax(int someNumber) { cout << "The max is " << someNumber << endl. the function PrintHW does not return a value. They have local scope. These variables are local variables and can only be used within the function. We'll see more on scope in a later lesson. float freezing = 32./9.freezing). observe that variables can be declared within a function.} else { return n2. The return statement can be used to return a single value from a function. float celsius. Scope refers to the section of code where a variable name is valid and may be used. This allows the compiler to perform type checking .. celsius = factor * (faren . For instance.

0. float FtoC(float faren). PrintMax(k). . float tempInC. PrintHW().on the arguments used in its call. void PrintHW(). int k. void PrintMax(int someNumber). return 0. A function is declared using its prototype. int n2) { if (n1 > n2) { return n1. } /* Function Definitions */ int FindMax(int n1. float tempInF = 85. /* Function Declarations */ int FindMax(int n1. cout << tempInF << " Fahrenheit equals " << tempInC << " Celsius " << endl. int main() { int i = 5. Let's use the functions defined in the previous section in a simple program.j). /* Include Files */ #include <iostream> using namespace std. int j = 7. int n2). /* Prints Hello World */ /* A nice sunny day */ k = FindMax(i. /* Prints Max Value */ tempInC = FtoC(tempInF).

that is. The function definitions are actually below main in this file. They have the same return type. . their definitions. return celsius. A program may be separated into multiple files. along with the needed function declarations may be in one file. } } void PrintMax(int someNumber) { cout << "The max is " << someNumber << endl.freezing). notice that the function definitions and declarations match. float celsius. when you use library functions. may be separated. into multiple files. For instance./9. Main. } float FtoC(float faren) { float factor = 5.. float freezing = 32.} else { return n2.0. } void PrintHW() { cout << "Hello World" << endl. the definitions are not in your file. This is usually how any large project is organized. celsius = factor * (faren . names. The functions themselves. } Notice that the functions are declared prior to their use. The function definitions need not even be in this file. and parameters. Also.

/* Note that the variable names in the prototype and function definition need not match. 100 cm = 1 meter. cout << "Before swap. cout << "After swap. y is " << y << endl. #include <iostream> using namespace std void swap(int x. Write a program that prompts a user for a measurement in feet and converts and outputs this value in meters. int y = 2. x is " << x << ". int second) . int y). Here's a first attempt. and convert centimeters to meters. Solution Returning Multiple Values From Functions and Methods So far. } void swap(int first. it will be common to need to return multiple values from a function.54 cm.Practice Problem 1) Write functions to convert feet to inches. or have returned a single value using the return statement. y is " << y << endl. In practice. x is " << x << ". all the examples shown have either not returned any values. Facts to use: 1 ft = 12 inches. swap(x. 1 inch = 2. Let's see how this can be done by developing a function to swap two integer values. Only the types and number of variables must match */ int main() { int x = 4. convert inches to centimeters.y).

#include <iostream> . first = temp. It is interesting to note that the pointer itself is passed by value. the function can change the contents of memory. The first is to pass a pointer to the variable to the function. Any modifications to the local copy do not change the original variable in the calling program.{ int temp. The pointer can then be manipulated to change the value of the variable in the calling routine. The function didn't work as expected. The main disadvantage is that pointer notation can be cumbersome and difficult to use. second = first. The function cannot change the pointer itself since it gets a local copy of the pointer. } Results: What happened? The values weren't swapped. The advantages of passing by pointer are that any changes to variables will be passed back to the calling routine and that multiple variables can be changed. Here is the same example with pointers being passed into the function. especially for beginners. and the modified value is desired in the calling routine. temp = second. The arguments were passed into the function by value. This means that the function received a local copy of the argument. C++ has two techniques that can be used if a variable is to be modified within a function. the variable. However. to which the pointer refers.

swap(&x. y is " << y << endl. temp = *second. int *y). y is " << y << endl. } void swap(int *first. *first = temp. } Results: Practice Problem 1) Write a function that will calculate the area and circumference of a circle. *second = *first. int main() { int x = 4. x is " << x << ". void swap(int *x.&y). Write a program to . cout << "After swap. return 0. cout << "Before swap. int y = 2.using namespace std. x is " << x << ". int *second) { int temp.

When references are passed into a function or class method. int y = 2. Useful facts: pi = 3. swap(x. cout << "After swap. x is " << x << ". #include <iostream> using namespace std. cout << "Before swap. y is " << y << endl. y is " << y << endl.y). int &y). x is " << x << ". In the previous lesson. int main() { int x = 4. void swap(int &x. any changes made to the references will be seen in the calling routine. Hint: Pass values that will be modified by pointer. . Continued The second method used in C++ to pass variables into functions in a way that their values are updated in the calling routine is to pass by reference. int &second) { int temp.prompt a user for a radius and write out the values calculated by the function. we saw that references are an alias to a variable. Here is the swap program implemented using references.14 area = pi * radius2 circumference = 2 * pi * radius Solution Returning Multiple Values From Functions. } void swap(int &first.

Within the main program and function body. In the main program of the pointer version. Within main and the function body the variables are used exactly as if they were passed by value. In the reference version. It is also possible that the variable to be passed in may change depending on particular data conditions or particular courses of program execution. Why are pointers ever used? Remember that references cannot be reassigned in C++. was needed. "&". within main. This is the beauty of references. the addresses of the "x" and "y" were passed into the function. In this case it is also likely that pointers rather than references must be used. the two variables appear directly in the argument list of swap. Write a program to prompt a user for a radius and write out the values calculated by the function. Compare the reference version of this program to the "pass by value" version on the previous page. Only within the parameter lists are the variables declared as references. except that any updates made in the function are seen in main. The address of operator. } Please compare the above program to the pointer version on the previous page and note how the syntax is simplified. In the pointer version. Practice Problem 1) Write a function that will calculate the area and circumference of a circle. If reassignment is necessary. Use references to pass any values that must be updated in the main program. the variables are used without any special or cumbersome notation. The compiler handles all the details. This was not the case with pointers. as we saw in the pointer version. This is not needed when using references. The programmer can write code as if using ordinary variables. . the pointers needed to be dereferenced within the function. first = temp.temp = second. second = first. as well. Notice that the only differences are in the parameter lists in the function definition and declaration. then pointers must be used.

i++) { a[i] = 2 * a[i]. void doubleThem(int a[]. for (i = 0.3. int size) { int i. doubleThem(myInts.7. Let's see how this works. i < size.Useful facts: pi = 3.8. return 0. the function receives not a copy the array. Suppose the main program has an array of 10 integers and that a function has been written to double each of these.4. void doubleThem(int *pt.2. } } Note that due to relationship between pointers and arrays in C++.6. int main() { int myInts[10] = {1. Any modifications made via this pointer will be seen in the calling program. 10).9.10}.5. int size). int size) . This function could also be written as follows and the rest of the program could be used without modification. but instead the address of the first element of the array. The function receives a pointer to the start of the array.14 area = pi * radius2 circumference = 2 * pi * radius Solution Passing Arrays to Functions When an array is passed into a function. } void doubleThem(int a[].

} d[i] = s[i]. int main() { char a[100] = "Hello From EasyCPlusPlus C/C++". for (i = 0.{ int i. void strcpy(char *dest. char s[]) { int i = 0. for (i = 0. } void strcpy(char d[]. /* Copy null terminator to dest */ . #include <iostream> using namespace std. s[i] != '\0'. strcpy(b. char b[100]. To conclude this lesson. Null terminated character arrays are also called Cstyle strings. although the use of the string class from the standard library is preferred. } } Strings can be stored in C++ as null terminated character arrays. i++) { *pt = 2 * *pt. Note that a string copy function. i++) { d[i] = s[i]. is part of the C and C++ standard library. strcpy. char *source). let's see how to pass C-style strings into and out of functions by implementing a string copy function. pt++. i < size. cout << b << endl.a).

int main() { float purchase. int calcSomeResult(int a. If any defaults are specified they must be specified for the right most parameters in the list. float b. #include <iostream> using namespace std.085).} Practice Problem 1) Try compiling and running this example. float calcSalesTax(float purchase. float d = 2). Solution Default Parameters It is possible to define defaults for some or all of the parameters of a function or class method in C++. let's look at functions. float taxRate = 0. float calcSalesTax(float purchase. int c = 1. Here's a simple program illustrating how to use a function with default parameter values. //Calculates using default rate . cout << "Enter purchase amount: ". float tax = calcSalesTax(purchase). Notice that the right most parameters are the ones with defaults.085). cout << "Tax is: " << tax << endl. cin >> purchase. For now. Let's look at some examples of function prototypes with defaults. float taxRate = 0. Compile and run. 2) Try rewriting the strcpy function using pointer notation.

copies of variables passed by value in the argument list are created in a special section of memory called the stack. return 0. The function definitions may become incorporated in libraries that may become available only in compiled form. It is better to have defaults in function definitions because typically these are in include files.075).15 Although the default is shown in the function declaration.0. float taxRate) { return purchase * taxRate. . } //Calculates using specified rate float calcSalesTax(float purchase. } Results: Enter purchase amount: 42 Tax is: 3. The source for include files is usually available for programmers as documentation for the use of functions. When passed by pointer there also can be savings.tax = calcSalesTax(purchase. Note on Efficiency of Passing by Pointer or Reference When a function is called. This operation is avoided when arguments are passed by reference. this can be less costly that copying large objects and possible needed to invoke constructors and destructors on those objects. cout << "Tax is: " << tax << endl. Although a copy of the pointer is made on the stack. For large objects such as arrays or user-defined objects this can be costly in terms of execution time and memory used. it is possible to have the default in either the declaration or the definition. but not both.57 Tax is: 3.