Lab 10
"To err is human, but to really foul things up you need a computer." - Paul R. Ehrlich
Cover Topics
Passing Arrays to Functions
File Processing with Arrays and Loops
Lab Materials
Prelab 10 Assignment
// Lab 10 Pre-Lab Assignment
// Write a function that multiplies each element in the array "myArray"
// by the variable "multiplyMe".
#include <iostream>
using namespace std;
// TODO - Write your function prototype here
int main()
{
const int SIZE = 10;
int myArray [SIZE] = {5, 10, 15, 20, 25, 30, 35, 40, 45, 50};
int multiplyMe = 5;
// TODO - Add your function call here
// print the array
for(int i=0; i < SIZE; i++)
{
cout << myArray[i] << " ";
}
cout << endl;
return 0;
}
// TODO - Write your function definition here
Prelab 10 Reading
- Pass by Reference
- Passing an Array to a Function
- Closer Look at Arrays
- Functions Example 1
- Functions Example 2
Pass by Reference
The previous lab was about passing a variable by value to a function. The value is passed to the called function and assigned to a newly created variable limited to the scope of the function. Any changes to this newly created function variable do not change the value of the variable in 'main' (the calling function).
Passing a variable by reference conveys the memory address of the passed variable value to the called function. The new function variable is assigned the same memory address as the argument variable.
So, what does this mean?
Variables from 'main' passed by reference to a called function will change, if the called function alters the value. This can be demonstrated with the following program.
***Note To pass a variable by reference, an ampersand (&) must be in your prototype and function definition between the parameter's data type and the parameter's name.
void myFunction(int & myVar)
#include <iostream> using namespace std; void add_Function(int, int &); int main() { int pass_by_value = 10; // variable is passed by value to function int pass_by_reference = 10; // variable is passed by reference to function cout << "pass by value in main at top : " << pass_by_value << endl; cout << "pass by reference in main at top : " << pass_by_reference; cout << endl << endl; add_Function(pass_by_value, pass_by_reference); cout << "pass by value in main at bottom : " << pass_by_value << endl; cout << "pass by reference in main at bottom : " << pass_by_reference; cout << endl << endl; return 0; } void add_Function(int val, int & ref) { val += 5; // add 5 to both val and ref ref += 5; cout << "pass by value inside function : " << val << endl; cout << "pass by reference inside function : " << ref; cout << endl << endl; }
As seen at the end of main, the pass by value variable was not changed in main, but the pass by reference variable kept the value it was assigned in the called function, even after the termination of that called function.
Passing an Array to a Function
Here is how to pass an array to a function. Note the syntax.
#include <iostream> using namespace std; // This is a function prototype with an array as a parameter. There are 2 acceptable syntaxes: // 1. returnType functionName ( dataType []) ; // 2. returnType functionName ( dataType arrayName []) ; void array_func(double []); int main() { double myArray [5] = {1.1, 1.2, 1.3, 1.4, 1.5}; // ** In the function call, you only include the name of the array! ** array_func(myArray); return 0; } // Function definition // returnType functionName ( dataType arrayName []) void array_func (double arrayName[]){ cout << "Array contents:" << endl; for(int i=0; i < 5; i++){ cout << arrayName[i] << " "; } cout << endl; }
Closer Look at Arrays
Arrays are always passed by reference. This is because an array name is simply the address of the first element, the 0th element, in an array.
Take the following example. The following is an array allocated in the memory addresses 1302 - 1305.
int array [4] = {5, 10, 15, 20}; ____________________________________________ |______|___5___|__10__|__15__|__20__|______| << values stored in memory .. 1301 1302 1303 1304 1305 1306...<< addresses of memory locations 0 1 2 3 << array index
The array name, array, will have the address 1302 stored inside of it. Therefore, passing 'array' as an argument to a function will actually be giving the function the array's address in memory. This is why the array's index starts at zero. The array's index is added to the memory address stored in the array's name to derive the memory address of the element needing to be accessed. E.g. array[2] would be 1302 + 2 = 1304, the address of the third element. These concepts are demonstrated in the following program. Note the second parameter in the function prototype and function definition in the example below. Even though it is not needed in this particular example, in real-world programming in C++, you will always need to send the size of an array to a function as a separate argument so that the function will be able to conduct bounds-checking while processing an array.
#include <iostream> using namespace std; void array_func(int [], const int); int main() { const int SIZE = 5; int my_arr [SIZE] = {10, 20, 30, 40, 50}; cout << "The address of our array 'my_arr': "<< int(my_arr); cout << endl << endl; cout << "In main at top, element 0 : " << my_arr[0] << endl; array_func(my_arr, SIZE); cout << "In main at bottom, element 0 : " << my_arr[0] << endl; return 0; } void array_func(int A [], const int S) { A[0] += 5; cout << "In function (add 5), element 0 : " << A[0] << endl; }
Functions Example 1
Using functions to process an array.
#include <iostream> using namespace std; int arraySum(double [], const int); double arrayAverage (double [], const int); int main() { const int SIZE = 5; double my_arr [SIZE] = {10, 20, 30, 40, 50}; int sum; double avg; sum = arraySum(my_arr, SIZE); cout << "The sum of all elements is : " << sum << endl; avg = arrayAverage(my_arr, SIZE); cout << "The average of all elements is : " << avg << endl; return 0; } int arraySum(double A[], const int SIZE) { int total = 0; for(int i=0; i<SIZE; i++) { total += A[i]; } return total; } double arrayAverage (double A[], const int SIZE) { return arraySum(A, SIZE) / SIZE; }
Functions Example 2
Here is an example of a function that imports data into an array. This example makes use of an input file. You will need to create your own text file named input.txt and copy and paste the data below into it. Then make sure your input file is located in the same subdirectory as your executable file.
Kara 3.5
Sally 3.7
Tristen 3.0
Kendra 3.5
Philip 3.2
** Note - you must pass ifstream and ofstream objects by reference **
#include <fstream> #include <iostream> #include <iomanip> using namespace std; void importData(ifstream &, double[], string[], const int, int &); int main() { const int MAXSIZE = 100; // max number of students that can be imported double gpa [MAXSIZE]; // students gpa string name [MAXSIZE]; // students name int numStudents; // number of students imported from file // Open input file stream object ifstream fin; fin.open("input.txt"); if(!fin){ cout << "ERROR - File not found." << endl; return 1; } // Import data - if data fails to be imported exit program importData(fin, gpa, name, MAXSIZE, numStudents); // print out arrays cout << "Name" << '\t' << '\t' << "GPA" << endl; cout << "--------------------" << endl; cout << setprecision(2) << fixed; for(int i=0; i<numStudents; i++) { cout << setw(8) << left << name[i] << '\t' << gpa[i] << endl; } fin.close(); return 0; } void importData(ifstream & fin, double G [], string N [], const int SIZE, int & count) // { count = 0; while (fin >> N[count] >> G[count] && count < SIZE) count++; }