In this lesson, you learned about storing data using the advanced data techniques of structures and dynamic memory allocation.
Project 9 Listing. Allocating an array of structures on the heap.
1:// Filename: PROJECT9.CPP 2:// A stockbroker's program that lets the broker enter a client's 3:// stock portfolio into an array of pointers. Each of the 4:// pointers in the array points to nothing when the program 5:// begins but the program allocates each pointer's structure 6:// when needed for the next stock. 7: 8:#include <iostream.h> 9: 10:const int NUM = 150; 11: 12:struct Stock 13: { 14: char stockID[4]; 15: float price; 16: float dividendRate; 17: int peRatio; 18: }; 19: 20:int GetStockCount(); 21:int CreateStocks (Stock * stocks[],int stockCount); 22:void GetStocks (Stock * stocks[],int stockCount); 23:void CalculateStats(Stock * stocks[],int stockCount); 24:void DeleteStocks (Stock * stocks[],int stockCount); 25: 26: 27:void main() 28:{ 29: int stockCount = 0; // Total number of stocks entered 30: Stock * stocks[NUM]; // For use with larger arrays 31: 32: cout << "** Stock Analysis**" << endl << endl << endl; 33: // Ask broker how many stocks are in portfolio 34: stockCount = GetStockCount(); 35: 36: if (!CreateStocks(stocks,stockCount)) // Allocate the stocks 37: return; // Exit if error 38: GetStocks(stocks,stockCount); // Get the data from the broker 39: CalculateStats(stocks,stockCount);// Print statistics 40: DeleteStocks(stocks,stockCount); // Deallocate the stocks 41:} 42://************************************************************* 43:int GetStockCount() 44:{ 45: int stockCount = 0; 46: cout << "How many stocks to analyze? "; 47: cin >> stockCount; 48: cout << endl; // Blank line 49: return stockCount; 50:} 51://************************************************************* 52:int CreateStocks(Stock * stocks[],int stockCount) 53:{ 54: // Allocate memory needed for the broker's stocks 55: for (int count=0; count<stockCount; count++) 56: { 57: stocks[count]= new Stock; 58: if (!stocks[count]) 59: { 60: cout << endl << endl 61: << "The memory allocation failed."; 62: return 0; 63: } 64: } 65: return 1; 66:} 67://************************************************************* 68:void GetStocks(Stock * stocks[],int stockCount) 69:{ // Get the stock data from the broker 70: for (int count=0; count<stockCount; count++) 71: { 72: cin.ignore(80,'\n'); 73: cout << "Stock #" << (count+1) << endl; 74: cout << " What is the 3-letter ID of the stock? "; 75: cin.get(stocks[count]->stockID, 4); 76: cout << " What is the price? "; 77: cin >> stocks[count]->price; 78: cout << " What is the dividend rate? "; 79: cin >> stocks[count]->dividendRate; 80: cout << " What is the integer P/E ratio? "; 81: cin >> stocks[count]->peRatio; 82: } 83: return; 84:} 85://************************************************************* 86:void CalculateStats(Stock * stocks[],int stockCount) 87:{ 88: // Calculate and print stock statistics 89: float highPrice, lowPrice; 90: int highIndex=0, lowIndex=0; 91: highPrice = stocks[0]->price; // Set the initial values 92: lowPrice = stocks[0]->price; 93: float avgDiv=0.0, avgPE = 0.0; 94: for (int count=0; count<stockCount; count++) 95: { 96: if (stocks[count]->price > highPrice) 97: { 98: highIndex = count; 99: highPrice = stocks[count]->price; 100: } 101: if (stocks[count]->price < lowPrice) 102: { 103: lowIndex = count; 104: lowPrice = stocks[count]->price; 105: } 106: avgDiv += stocks[count]->dividendRate; 107: avgPE += stocks[count]->peRatio; 108: } 109: avgPE /= stockCount; 110: avgDiv /= stockCount; 111: cout.precision(3); 112: cout.setf(ios::showpoint); 113: cout.setf(ios::fixed); 114: cout << endl; 115: cout << "The average P/E ratio is " << avgPE << endl; 116: cout << "The average dividend rate is " << avgDiv 117: << "%" << endl; 118: cout << "The highest priced stock ID is " 119: << stocks[highIndex]->stockID << endl; 120: cout << "The lowest priced stock ID is " 121: << stocks[lowIndex]->stockID << endl; 122: return; 123:} 124://************************************************************* 125:void DeleteStocks(struct Stock * stocks[],int stockCount) 126:{ 127: // Allocate memory needed for the broker's stocks 128: for (int count=0; count<stockCount; count++) 129: { 130: delete stocks[count]; 131: } 132: return; 133:}
Output
* Stock Analysis** How many stocks to analyze? 3 Stock #1 What is the 3-letter ID of the stock? BQS What is the price? 22.75 What is the dividend rate? 2.31 What is the integer P/E ratio? 4 Stock #2 What is the 3-letter ID of the stock? WWC What is the price? 32.50 What is the dividend rate? 5.39 What is the integer P/E ratio? 19 Stock #3 What is the 3-letter ID of the stock? XRU What is the price? 58.00 What is the dividend rate? 6.21 What is the integer P/E ratio? 13 The average P/E ratio is 12.000 The average dividend rate is 4.637% The highest priced stock ID is XRU The lowest priced stock ID is BQS
Description
1: A C++ comment that includes the program's filename.
2: A C++ comment that contains the program's description.
3: Continues the program description.
4: Continues the program description.
5: Continues the program description.
6: Continues the program description.
7: Blank lines make your programs more readable.
8: cin and cout need information in the IOSTREAM.H header file.
9: Blank lines make your programs more readable.
10: Define a constant in case you want to limit the number of stocks to be analyzed, such as if you convert this to a disk file input program later.
11: Blank lines make your programs more readable.
12: Define the stock structure format.
13: Structs start with an opening brace.
14: Keeps track of a 3-character string (leaves room for terminator).
15: The stock price.
16: The dividend rate.
17: The Price/Earnings ratio.
18: struct definitions end with a brace and a semicolon.
19: Blank lines help make your program more readable.
20: You should prototype all functions.
21: Prototype of another function.
22: Prototype of another function.
23: Prototype of another function.
24: Prototype of another function.
25: Blank lines help make your program more readable.
26: Blank lines help make your program more readable.
27: main() begins.
28: All functions begin with an opening brace.
29: Define a local variable that exists for the life of the program.
30: main() defines a local array of pointers to the stock structures.
31: Blank lines help make your program more readable.
32: Prints a title.
33: Comments make the program more readable.
34: Calls a function that asks the broker how many stocks are in the portfolio.
35: Blank lines help make your program more readable.
36: Calls a function that allocates memory for each of the broker's stocks.
37: If an error occurred in dynamic memory allocation, end the program.
38: Calls a function that loops until the broker's stock data is entered.
39: Calls a function that computes statistics from the stock data.
40: Always deallocate your program's allocated memory.
41: A final brace ends all main() functions.
42: A line of asterisks helps to separate functions.
43: The definition (first line) of GetStockCount().
44: All functions begin with an opening brace.
45: Declare a temporary variable to receive input.
46: Ask the user how many stocks there are.
47: Get the number of stocks.
48: Print a blank line for subsequent output.
49: Return to the main() function.
50: A final brace ends all functions.
51: A line of asterisks helps to separate functions.
52: Defines the function that dynamically allocates memory.
53: All functions begin with an opening brace.
54: Place comments throughout your code.
55: Steps through the stocks.
56: Always use braces in the body of for loops.
57: Allocates memory for each pointer in the array.
58: Always check for allocation errors!
59: A brace starts a compound statement.
60: Print an error message if the allocation failed.
61: The message continues.
62: Return zero if an error occurred.
63: Closes the body of the if loop.
64: Closes the for loop body.
65: Returns to main() with 1 to indicate success.
66: All functions require a closing brace.
67: A line of asterisks helps to separate functions.
68: Defines the function that will get the stock data. Pass main()'s local array of pointers and the count of stocks.
69: Place comments throughout your code.
70: Steps through the stocks.
71: Always use braces in the body of for loops.
72: Gets rid of any unwanted characters from the input buffer.
73: Tells the user which stock he or she is entering.
74: Asks for the 3-letter stock ID of the next stock.
75: Gets a 3-character string from the user.
76: Asks for the price.
77: Gets the stock's price.
78: Asks for the stock's dividend rate.
79: Gets the dividend rate.
80: Asks for the price/earnings ratio.
81: Gets the P/E ratio.
82: The brace that closes the body of the for loop.
83: Return to main().
84: All functions end with a closing brace.
85: A line of asterisks helps to separate functions.
86: Defines a function that will calculate stock statistics based on main()'s local pointer array.
87: All functions begin with an opening brace.
88: Places comments throughout your code.
89: Defines variables that will keep track of the statistics.
90: Defines index of high and low price.
91: Initializes the high stock subscript with the first stock.
92: Initializes the low stock subscript with the first stock.
93: Defines two more variables that will hold statistics.
94: Steps through the stocks.
95: The brace begins the body of the for loop.
96: If the current loop's stock is more than the highest stock price so far...
97: Braces start a compound statement.
98: Updates the high stock index with the current stock index.
99: Stores the highest price for the next test.
100: Brace ends a compound statement.
101: If the current loop's stock is less than the lowest stock price so far...
102: Braces start a compound statement.
103: Updates the low stock index with the current stock index.
104: Stores the lowest price for the next test.
105: Brace ends a compound statement.
106: Adds to the dividend total for a subsequent average calculation.
107: Adds to the price/earnings total for a subsequent average calculation.
108: Closes the for loop.
109: Divides the price/earnings total for a P/E average.
110: Divides the dividend total for a dividend average.
111: Outputs three decimal places.
112: Ensures that the decimal point shows.
113: Guards against scientific notation.
114: Prints a blank line.
115: Prints the average P/E ratio.
116: Prints the average dividend rate.
117: Continues printing the dividend rate.
118: Begins printing of the highest stock price ID.
119: Continues the ID's printing.
120: Begins printing of the lowest stock price ID.
121: Continues the printing.
122: Returns to main().
123: Closes the function body.
124: A line of asterisks helps to separate functions.
125: Defines the function that will deallocate the dynamic memory.
126: All functions begin with an opening brace.
127: Scatter comments throughout your code.
128: Steps through the stocks.
129: The opening brace of the for loop body.
130: Deallocates each of the memory chunks pointed to by main()'s array of pointers.
131: Closes the for loop.
132: Returns to main().
133: Closes the function.
40: Deallocate all data that you allocate when you're done with dynamic memory.
51: Notice that you don't have to specify a subscript when you receive an array. You must pass the array of pointers to allocMemory() because the array is local to main().
57: You must allocate each pointer's data in the array.
72: The previous request for the number of stocks could have left an Enter keypress on the buffer.
75: Use the structure pointer, ->, with pointers to structures.
130: Free each pointer's heap memory.