Replacement for global variables

So, my professor assigned this project where we cannot use global variables.
(I DO NOT HAVE ENOUGH SPACE TO FIT CODE IN THIS POST, SO I WILL ATTACH IT AS A REPLY)
This is the assignment:
Important note: You must declare two global named constants as specified below. DO NOT USE global variables and NO inline functions (i.e.., functions defined above main), Each function should have an appropriately named function prototype (aka. a function declaration) with or without a parameters listed above main and the related function algorithm with a function heading defined directly after main.

Make sure to do your best to also include function specific documentation, such as (1) data flow comments in function prototype and function heading parameter lists and (2) detailed function descriptions above each function heading which should also include comments related to pre/post conditions.
You have recently collected reviews from four movie reviewers where the reviewers are numbered 1- 4. Each reviewer has rated six movies where the movies are numbered 100 -105. The ratings range from 1 (terrible) to 5 (excellent).

Note: To store the sample data below in a two-dimensional array the reviewer numbers must be mapped to 0-3 (row subscript or index) and the movie ID’s must be mapped to 0-5 (column subscript or index). The movie rating does not include data for unrated movies and only includes values related to the rating range provided. Your program begins by storing the sample data set with initial movie review ratings as shown in the following table:

100 101 102 103 104 105
1 3 1 5 2 1 5
2 4 2 1 4 2 4
3 3 1 2 4 4 1
4 5 1 4 2 4 2

Based on this information your program should allow the user a menu of 6 options. The options are:

Display current movie ratings.
Show the average rating for each movie.
Show a reviewers highest rated movie/s. (enter reviewer# 1-4)*
Show a movies lowest rating. (enter movie# 100-105)
Enter new ratings (1-5) for movie# 100-105 for four reviewers.
Exit the program.
*If a selected reviewer has rated multiple movies with the same highest rating, display all the movie numbers with the same highest rating in your output (this maybe on a single line or on multiple lines and would depend on how you have written the procedure in the function that is called for option#3). Points will not be deducted if it does not match the sample output below, but I must see all the movie numbers listed if there are multiple movies with the same highest rating.
The size or dimensions of the array should be declared as two global named constants directly above main.
const int NUM_ROWS = 4, NUM_COLS = 6; //2D array dimensions declared as global named constants above main
Each function prototype listed above main must include a two-dimensional array type parameter and must contain a size declarator for the number of columns. Here are a couple of sample function prototypes with array parameters ...
void getRatings(int someArray [][NUM_COLS]); //array is passed by reference to the function with read/write access
void showRatings(const int someArray [][NUM_COLS]); //the array is passed by "const" reference to the function but with read only access
In the main function you must first declare a two-dimensional array with an initialization list and store the initial sample reviewer rating data (see table above). This is to ensure that valid data exists in the two-dimensional array in case the user chooses options 1 - 4 before exiting the program. Another option is to write a separate initialRatings function that will be tasked to fill a local two-dimensional array with the initial ratings provided and then pass the array contents into the array in main via a function call.
Each option in the menu must call a function. Each function call must at minimum include an argument with an identifier name of the array initialized in main to be passed to the function and in the case of menu choice 3 and 4 an additional argument representing a single row (representing a reviewer#) or column (representing a movie#) subscript or index that also needs to be passed to the functions. (see also Gaddis text Chapter#7, Passing Two Dimensional Arrays to Functions page 428). Here is a sample function call from within switch case in main....
switch (choice) //calls to various functions in each case should match the menu item#
{
case 1: displayRatings(someArray); //a function call
break;
....
....
}
Important Note.......
(1) When a multidimensional array parameter is passed through a function declaration (prototype) and corresponding function heading (definition), the size of the first dimension is not given, but the remaining dimension sizes must be given in square brackets. The assumption here is that the array dimension sizes (integer values) have been declared either globally or locally.

(2) Arrays passed in function declaration (prototype) or function heading (definition) parameter lists are reference parameters by default. Depending on the algorithm and purpose of an array processing related function you may choose to add the keyword const to any function related array parameter to prevent any accidental writing to the original array from within the function definition. The following are two examples of function declarations or prototypes with a two-dimensional array parameter someArray,

const int NUM_ROWS = 4, NUM_COLS = 6; // global constants for array size declarations
//function prototypes or declarations
void getRatings(int someArray [][NUM_COLS]); //the array is passed by reference to the function with read/write access
void showRatings(const int someArray [][NUM_COLS]); //the array is passed by reference to the function but with read only access
* note: since NUM_ROWS (the first dimension) is declared as a global constant, a second int parameter to pass number of rows to each of the above functions is not needed.


You may use the partial program framework provided below (or p5b_sample.cpp Download p5b_sample.cpp) as an initial set-up guide to begin writing your own algorithms for each function (void and/or value returning). If you prefer, you are welcome to start entirely with your own approach and implement the necessary interface to this programming project. Value returning functions maybe used for function algorithms that determine or return a single value.
The requirement is that I see function prototypes listed above main and well-documented separate function procedures defined after main that are called when menu options 1-5 are selected. The function algorithms should process the two-dimensional array data correctly and display properly formatted program output similar to what is provided in the sample program run below. Your program algorithms should work as intended even if we change the global constants for different array size dimensions with a corresponding update to the array initialization list or initialization function.
The program run-time output shown below is based on compiling the program to test each menu option. Use this as a guide while you write and test your programs interface and calls to specific function procedures.
Use meaningful identifiers and include function documentation (see syllabus) particularly in the function header and elsewhere in the function body where appropriate. Credit is provided only for those function procedures that correctly process the array data based on the option selected.
Prior to submission make sure that you compile and test each option in your program to ensure that the output is similar to the sample program output shown below. This last programming project is due by Wednesday August 3, 2022 (with a 48 hour final submission time limit ending Friday August 5, 2022).
INPUT VALIDATION: Prevent out of bound array access. For example with menu option#3 limit the user input to reviewer#1-4 and similarly with menu option#4 limit the user input to movie# 100-105. With menu option#5 limit the data entry for ratings to 1-5. Non integer input should not cause a premature exit or an infinite loop as a result of the cin stream failure and should be display an appropriate error message followed by a prompt for input.

DO NOT use array pointers or setup a vector with any vector related processing for this project.
Last edited on
Code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
#include <iostream>
#include <iomanip>
 
using namespace std;
 
const int NUM_REVIEWERS = 4;    //Number of rows in reviews array
const int NUM_MOVIES = 6;       //Number of columns in reviews array
 
void displayRatings(/*in*/const int[][NUM_MOVIES], /*in*/const int[], /*in*/int);
void showAverageRatings(/*in*/const int[][NUM_MOVIES], /*in*/const int[], /*in*/int);
void showReviewersHighestRating(/*in*/const int[][NUM_MOVIES], /*in*/const int[], /*in*/int);
void showReviewersLowestRating(/*in*/const int[][NUM_MOVIES], /*in*/const int[], /*in*/int);
void getNewRatings(/*out*/int[][NUM_MOVIES], /*in*/const int[], /*in*/int);
 
int main()
{
// Variable declarations
// 2D array to store initial ratings
int movieReviews[NUM_REVIEWERS][NUM_MOVIES] = {{3,1,5,2,1,5},
                                               {4,2,1,4,2,4},
                                               {3,1,2,4,4,1},
                                               {5,1,4,2,4,2}};
// 1D array to store movie IDs
int movieID[NUM_MOVIES] = {100,101,102,103,104,105};
int choice;         // user choice of menu options
 
   do
   {               //program interface with menu options
       cout<<"---------------------------------------------------"<<endl;
       cout<<"2-D ARRAY PROCESSING MENU OPTIONS"<<endl;
       cout<<"---------------------------------------------------"<<endl;
       cout<<"1. Display current movie ratings"<<endl;
       cout<<"2. Show the average rating for each movie."<<endl;
       cout<<"3. Show a reviewers highest rated movie. (enter reviewer# 1-4)"<<endl;
       cout<<"4. Show a movies lowest rating. (enter movie# 100-105)"<<endl;
       cout<<"5. Enter new ratings (1-5) for movie# 100-105 for four reviewers"<<endl;
       cout<<"6. Quit program"<<endl;
       cout<<endl<<"Enter your choice:";
       cin>>choice;
       cout << endl;
       switch (choice)
       {
           case 1 : displayRatings(movieReviews, movieID, NUM_REVIEWERS);
                   break;
           case 2 : showAverageRatings(movieReviews, movieID, NUM_REVIEWERS);
                   break;
           case 3 : showReviewersHighestRating(movieReviews, movieID, NUM_REVIEWERS);
                   break;
           case 4 : showReviewersLowestRating(movieReviews, movieID, NUM_REVIEWERS);
                   break;
           case 5 : getNewRatings(movieReviews, movieID, NUM_REVIEWERS);
                   break;
           case 6 : cout << "Array processing test now concluded. Exiting program ....." << endl;
                   return 1;
                   break;
           default : cout << "Please enter a choice from 1 to 6.";
       }
   }while(choice!=6);
return 0;
}
 
 
 
void displayRatings(const int ratings[][NUM_MOVIES], const int movie[], int rows)
 
{
   cout << "********************** MOVIE RATINGS ********************" << endl;
   cout << setw(9) << "REVIEWER\\";
   
   for (int m = 0; m < NUM_MOVIES; m++)
       cout << setw(5) << "MV#" << movie[m];
   cout << "\n*********************************************************" << endl;
 
   for (int i = 0; i < rows; i++)
   {
       cout << setw(5) << "#" << i + 1;
       for (int j = 0; j < NUM_MOVIES; j++)
           cout << setw(8) << ratings[i][j];
       cout << endl;
   }
   cout << endl;
}
 
 
 
 
void showAverageRatings(const int ratings[][NUM_MOVIES], const int movie[], int rows)
 
{
   displayRatings(ratings, movie, rows);   // call to display current values
   cout << "Average rating for each movie:" << endl;
   for (int j = 0; j < NUM_MOVIES; j++)
   {
       int sum = 0; // set sum to 0 for each column
       for (int i = 0; i < rows; i++)
           sum = sum + ratings[i][j];
       cout << "Movie #" << movie[j] << setw(6) << float(sum)/rows << endl;
   }
   cout << endl;
}
void showReviewersHighestRating(const int ratings[][NUM_MOVIES], const int movie[], int rows)
 
{
   displayRatings(ratings, movie, rows);  // call to display current values
   int j;              // loop control variable
   int reviewer = 0;   // variable to store user input
   int count = 0;      // counter for highest ratings
 
   cout << "Enter a reviewer number (1-4), to find the Movie they rated the highest:";
   cin >> reviewer;
 
   // validate reviewer number range 1 - 4
   while (reviewer < 1 || reviewer > 4)
   {
       cout << "That is an invalid reviewer number." << endl;
       cout << "Enter a reviewer number (1-4), to find the Movie they rated the highest:";
       cin >> reviewer;
   }
 
   cout << "Reviewer #" << reviewer << " rated Movie #";
   int highest = ratings[reviewer - 1][0]; // initialize highest to 1st element
                                           //  of a given row
 
   // loop through array to find highest ratings
   for (j = 0; j < NUM_MOVIES; j++)
   {
       if (ratings[reviewer - 1][j] > highest)
           highest = ratings[reviewer - 1][j];
   }
 
   // loop through array to count all highest occurencies
   count = 0;
   for (j = 0; j < NUM_MOVIES; j++)
   {
       if (ratings[reviewer - 1][j] == highest)
           count++;
   }
 
   // loop through array to print out highest rated movies
   for (j = 0; j < NUM_MOVIES; j++)
   {
       if (ratings[reviewer - 1][j] == highest)
       {
           cout << movie[j];
           count --;
           if (count == 1)
               cout << " and ";
           else if (count > 1)
               cout << ", ";
           else if (count == 0)
               cout << " as the highest." << endl << endl;
       }
   }
}
void showReviewersLowestRating(const int ratings[][NUM_MOVIES], const int movie[], int rows)
{
   displayRatings(ratings, movie, rows);    // call to display current values
   int movieNum;       // variable to store user input
   int j;              // loop control variable
   cout << "Enter a movie number (100-105), to find the lowest rating:";
   cin >> movieNum;
 
   // validate movie numbers
   while (movieNum < 100 || movieNum > 105)
   {
       cout << "That is an invalid movie number." << endl;
       cout << "Enter a movie number (100-105), to find the lowest rating:";
       cin >> movieNum;
   }
 
   // loop through 1D array to find the index of movieNum
   for (j = 0; j < NUM_MOVIES; j++)
       if (movieNum == movie[j])
           break;
   cout << "Movie #" << movieNum << "'s lowest rating is ";
 
   int lowest = ratings[0][j];
 
   // loop through array column to find the lowest rating
   for (int i = 0; i < rows; i++)
   {
       if (ratings[i][j] < lowest)
           lowest = ratings[i][j];
   }
   cout << lowest << endl << endl;
}
 
void getNewRatings(int ratings[][NUM_MOVIES], const int movie[], int rows)
 
{
   cout << "********DATA ENTRY FOR NEW MOVIE RATINGS ***********" << endl;
 
   // outer loop
   for (int i = 0; i < rows; i++)
   {
       cout << "****************************************************" << endl;
       cout << "REVIEWER# " << i + 1 << endl;
       cout << "****************************************************" << endl;
       // inner loop
       for (int j = 0; j < NUM_MOVIES; j++)
       {
           cout << "Enter rating (1-5) for movie #" << movie[j] << ": ";
           cin >> ratings[i][j];
           // validate user entry range 1 - 5
           while (ratings[i][j] < 1 || ratings[i][j] > 5)
           {
               cout << "Invalid rating.  It must be from 1-5." << endl;
               cout << "Enter rating (1-5) for movie #" << movie[j] << ": ";
               cin >> ratings[i][j];
           }
       }
   }
   cout << endl;
}
Last edited on
sorry, if there was a question in all that, I lost it.
it just looks like the assignment text. And honestly, it looks like one we just saw, with the same nonsense about inline functions (incorrectly described).
As I understand it, they simply want forward-declarations of the functions in front of the main() function, whereas the actual definition of those functions should be located after the main() function.

Also, if global variables are not allowed, simply restrict yourself to only local variables. And, if data needs to be "shared" between functions, then simply pass that data via function parameters.
Last edited on
Okay thank you Kigar, how do I pass that data via function parameters?
jonnin, the question was how do I get rid of the global variables because I can't use them.
alexdieter wrote:
how do I pass that data via function parameters?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>

void Foo_Fighter(int);

int main()
{
   int foo { 15 };

   Foo_Fighter(foo);
}

void Foo_Fighter(int foo)
{
   std::cout << "You fought and killed " << foo << " Foos!\n";
}
You fought and killed 15 Foos!
I don't see any variables, only constants.
but if you mean those, put them in main:
int main()
{
const int NUM_REVIEWERS = 4;
const int NUM_MOVIES = 6;
}

and pass them into functions:

void whatever( type anything, const int NR, const int NM)
{
code;
}

so now main or whatever function can say
whatever(something, NUM_REVIEWERS, NUM_MOVIES);
which is dumb. Constants are not global variables. A variable *varies*. Constants do not vary. The big problems with global variables ... there are a good 10 or more ... don't exist for constants. There are minor issues, easily resolved by putting a namespace around the constants.
From the assignment:

You must declare two global named constants as specified below


This has been done as required. No other global variables are used.

However, this assignment does NOT require the size of an array to be passed as a function arg as these are now global.
Last edited on
Maybe something like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
#include <iostream>
#include <iomanip>

using std::cout;
using std::cin;
using std::setw;

const int NUM_REVIEWERS { 4 };    //Number of rows in reviews array
const int NUM_MOVIES { 6 };       //Number of columns in reviews array

void displayRatings(const int[][NUM_MOVIES], const int[]);
void showAverageRatings(const int[][NUM_MOVIES], const int[]);
void showReviewersHighestRating(const int[][NUM_MOVIES], const int[]);
void showMovieLowestRating(const int[][NUM_MOVIES], const int[]);
void getNewRatings(int[][NUM_MOVIES], const int[]);

int main() {
	int movieReviews[NUM_REVIEWERS][NUM_MOVIES] { {3, 1, 5, 2, 1, 5},
												   {4, 2, 1, 4, 2, 4},
												   {3, 1, 2, 4, 4, 1},
												   {5, 1, 4, 2, 4, 2} };

	const int movieID[NUM_MOVIES] { 100, 101, 102, 103, 104, 105 };
	int choice {};

	do {
		cout << "---------------------------------------------------\n";
		cout << "2-D ARRAY PROCESSING MENU OPTIONS\n";
		cout << "---------------------------------------------------\n";
		cout << "1. Display current movie ratings\n";
		cout << "2. Show the average rating for each movie.\n";
		cout << "3. Show a reviewers highest rated movie. (enter reviewer# 1-4)\n";
		cout << "4. Show a movies lowest rating. (enter movie# 100-105)\n";
		cout << "5. Enter new ratings (1-5) for movie# 100-105 for four reviewers\n";
		cout << "6. Quit program\n";

		cout << "\nEnter your choice:";
		cin >> choice;
		cout << '\n';

		switch (choice) {
			case 1:
				displayRatings(movieReviews, movieID);
				break;

			case 2:
				showAverageRatings(movieReviews, movieID);
				break;

			case 3:
				showReviewersHighestRating(movieReviews, movieID);
				break;

			case 4:showMovieLowestRating(movieReviews, movieID);
				break;

			case 5:
				getNewRatings(movieReviews, movieID);
				break;

			case 6:
				break;

			default:
				cout << "Please enter a choice from 1 to 6.\n\n";
				break;
		}
	} while (choice != 6);

	cout << "Array processing test now concluded. Exiting program .....\n";
}

void displayRatings(const int ratings[][NUM_MOVIES], const int movie[]) {
	cout << "********************** MOVIE RATINGS ********************\n";
	cout << setw(9) << "REVIEWER\n";

	for (int i {}; i < NUM_REVIEWERS; ++i) {
		cout << setw(5) << "#" << i + 1;
		for (int j {}; j < NUM_MOVIES; ++j)
			cout << setw(5) << "MV#" << movie[j] << setw(8) << ratings[i][j];

		cout << '\n';
	}

	cout << '\n';
	cout << "\n*********************************************************\n";
}

void showAverageRatings(const int ratings[][NUM_MOVIES], const int movie[]) {
	cout << "Average rating for each movie:\n";

	for (int j {}; j < NUM_MOVIES; ++j) {
		double sum {};

		for (int i {}; i < NUM_REVIEWERS; ++i)
			sum += ratings[i][j];

		cout << "Movie #" << movie[j] << setw(6) << sum / NUM_REVIEWERS << '\n';
	}

	cout << '\n';
}

void showReviewersHighestRating(const int ratings[][NUM_MOVIES], const int movie[]) {
	int reviewer {};

	do {
		cout << "Enter a reviewer number (1 - 4), to find the Movie they rated the highest: ";
		cin >> reviewer;
	} while ((reviewer < 1 || reviewer > 4) && (cout << "That is an invalid reviewer number.\n"));

	cout << "Reviewer #" << reviewer << " rated Movie(s) #";

	int highest { ratings[reviewer - 1][0] };

	for (int j {1}; j < NUM_MOVIES; ++j)
		if (ratings[reviewer - 1][j] > highest)
			highest = ratings[reviewer - 1][j];

	for (int j {}, count {}; j < NUM_MOVIES; ++j)
		if (ratings[reviewer - 1][j] == highest) {
			if (count++)
				cout << ", ";

			cout << movie[j];
		}

	cout << " as the highest.\n\n";
}

void showMovieLowestRating(const int ratings[][NUM_MOVIES], const int movie[]) {
	int movieNum {};

	do {
		cout << "Enter a movie number (100 - 105), to find the lowest rating: ";
		cin >> movieNum;
	}  while ((movieNum < 100 || movieNum > 105) && (cout << "That is an invalid movie number.\n"));

	int j {};

	for (; j < NUM_MOVIES; ++j)
		if (movieNum == movie[j])
			break;

	cout << "Movie #" << movieNum << "'s lowest rating is ";

	int lowest { ratings[0][j] };

	for (int i {1}; i < NUM_REVIEWERS; ++i)
		if (ratings[i][j] < lowest)
			lowest = ratings[i][j];

	cout << lowest << "\n\n";
}

void getNewRatings(int ratings[][NUM_MOVIES], const int movie[]) {
	cout << "********DATA ENTRY FOR NEW MOVIE RATINGS ***********\n";

	for (int i {}; i < NUM_REVIEWERS; ++i) {
		cout << "****************************************************\n";
		cout << "REVIEWER# " << i + 1 << '\n';
		cout << "****************************************************\n";

		for (int j {}; j < NUM_MOVIES; ++j)
			do {
				cout << "Enter rating (1 - 5) for movie #" << movie[j] << ": ";
				cin >> ratings[i][j];
			} while ((ratings[i][j] < 1 || ratings[i][j] > 5) && (cout << "Invalid rating. It must be from 1 - 5.\n"));
	}

	cout << '\n';
}

Last edited on
Topic archived. No new replies allowed.