Function setInvoice() has five parameters of types Invoice, character array (for name and for phone), long (for account number), double (for gallons used). It sets the fields of its Invoice parameters using the values of its other parameters. Call this function in the first loop in main() after the test for array overflow.

Function computeAmount() has two parameters of type Invoice and double (for gallons used). It sets the value of the Invoice field 'amount' by adding the flat fee ($12) and the price per gallon ($0.05) multiplied by the number of gallons used (use global const symbolic values). Call this function in the first loop in main() after the call to setInvoice().

Function printData() has one parameter of type Invoice. It prints the fields 'name' in width 16 and 'phone' in width 14 (both are left-aligned), the field 'account' (in width 11, right-aligned), the field 'gallons' (in width 9, right-aligned), the field 'amount' (in width 8, right-aligned). Call this function from the second loop in main() instead of printing bill data explicitly.

Function getAmount() has one parameter of type Invoice. It returns the value if the parameter's field 'amount'. It is called from the global client function computeAmount(). This function has two parameters, an Invoice array and the count of valid elements in the array. It returns a double value that the total of all amounts in the array. This function computeAmount() defines a double local variable 'amount', goes in a FOR loop through all valid elements of the parameter array, calls getAmount() for each valid component of the parameter array and adds the return value of getAmount() to 'amount'. At the end, computeAmount() returns the accumulated tally. Call this function from main() to initialize the value of local variable 'total' (after the printing loop).

Pass structure variables by reference; pass built-in types by value; use the const modifier for structure and for array parameters that do not change as the result of the function execution. There is no need to use prototypes or multiple files: you will do that later. Instead, place the functions in the source code file between the structure definition and the start of main().

Turn in the source code, the results of test runs and your explanations why you think that using access functions is better than making necessary computations in-line. Explain how the compiler distinguishes between two functions with the same name computeAmount().

b) Using Classes and Member Functions

Convert the Invoice access functions setInvoice(), computeAmount(), getAmount(), printData() into member functions of class Invoice. In the main() client code, send messages to Invoice objects instead of passing these Invoice objects to access functions as parameters.

The simplest way to accomplish this task is to convert the access functions one by one. Use the keyword struct rather than class, leave data members public for a while, so that the program could be compiled and tested incrementally. There is no need to implement the functions outside the class specification. There is no need to use constructors and destructors: you will do that later.

First, move the Invoice closing brace and the semicolon beyond the access function setInvoice() so that this function becomes an Invoice member function. Change the parameter list of setInvoice(); in main(), comment out the function call to setInvoice() and send a setInvoice() message to an Invoice target instead. Compile and run the program, make sure it runs correctly.

Next, move the Invoice closing brace and the semicolon beyond the access function computeAmount(). Change the parameter list of computeAmount(); in main(), comment out the function call to computeAmount() and replace it with a computeAmount() message. Compile and run the program, make sure it runs correctly.

Next, move the Invoice closing brace and the semicolon beyond the access function printData(). Change its parameter list; in main(), comment out the function call to printData() and replace it with a message. Compile and run the program, make sure it runs correctly.

Next, move the Invoice closing brace and the semicolon beyond the access function getAmount(). Change its parameter list; in the global client function computeAmount(), comment out the function call to getAmount() and replace it with a message getAmount() sent to the element of the Invoice array. Compile and run the program, make sure it runs correctly.

Finally, make Invoice data members private and its member functions public. Make sure that the program runs as before.

Make sure that all the member functions that do not change the state of the target object are labeled with the const modifier. All structure and array parameters that do not change as the result of the call also should be labeled with the const modifier.

Turn in the source code, the results of test runs and your explanations why you think that using classes, member functions and access specifiers is better than using global access functions. Also explain a) the meaning of each const modifier you use in the program and the advantages of using them, b) how the compiler distinguishes from two functions with the same name computeAmount() and how it is different from the part (a) of this homework.