How do I reiterate through a pointer array? - c++

My program is supposed to iterate through an array for as many times as there are hours using only a pointer.
for (int i = 0; i < totalHours; i++)
{
cout << " " << i + 1;
while (ptrSvr <= last)
{
rand_set(ptrSvr);
print(ptrSvr);
ptrSvr++;
}
cout << endl;
}
return 0;
With this being the function for rand_set
void rand_set(int* &ps)
{
*ps = rand() % 10;
}
And this being the function for print.
void print(int* ps)
{
cout << " " << *ps << " ";
}
Once this iterates though, I don't understand how to set the pointer back to the first address in the array so that when i increases, it will print a new row starting at the beginning. Currently, it will only print one row. There's also a catch - I can only use the given pointer to access the array. I cannot use array indices.
Additionally, the highest number randomly generated must be stored in a highestAttempts pointer and when printed, must have a * next to it. This functionality must be included in the rand_set function. I've only gotten it to print a * next to all of them, or it gets printed on the first random number, and on each one if they increase.
Thanks for any advice in advance. I am in a 200 level c++ class, so this should be as simple as possible.
Variables are declared and initialized like so.
void initialize(int ts, int* &ps, int* &pt,
int* &l, int* &ha)
{
for (int i = 0; i < ts; i++)
{
ps[i] = 0;
pt[i] = 0;
l = &ps[i];
}
ha = NULL;
srand(time(NULL));
}
...
// Pointer declarations
int *ptrSvr; // Po
int *ptrTotal; // Po
int *last; // Po
int *highestAttempts; // Po
// Variable declarations
int totalServers; // Va
int totalHours; // Va
int total; // Va
// Prompt user for number of serv
// totalServers and totalHours
cout << "Enter the number of web
cin >> totalServers;
cout << "Enter the number of hour
cin >> totalHours;
// Declares arrays for ptrSvr and
// of total servers
ptrSvr = new int[totalServers];
ptrTotal = new int[totalServers];

if you have something like
int arr [] = {};
then
ptrSvr = arr;
after while loop would reset it. otherwise you have to store the very first value of ptrSvr and reset it after while loop exits

Related

How can I modify the values of an array within a function and then use the "new" array where the function was called

So for part of my homework I need to make a yahtzee style text game. At the moment I am working on an array to hold the dice values. My issue is being able to pass an array into a function to modify values, and then use that modified array again. Initially I wanted to do it with references or pointers. I had issues with doing it that way and I haven't been able to get either way to compile. Today I talked to my teacher who told me that arrays can be modified normally inside of a function and then used again, essentially saying that they are passed by reference automatically.
Can someone please clarify what my teacher means and if it is correct. Also, what method would you guys recommend. Below is my current implementation attempting to use references
/******************************************************
** Function: runGame
** Description: Runs game and keeps track of players
** Parameters: # of players
** Pre-Conditions: c is an integer from 1 to 9
** Post-Conditions:
******************************************************/
void runGame(int players) {
Player p = new Player[players]; //needs to be deleted at the end
int dice[] = { -1, -1, -1, -1, -1 };
int category; // used to hold category chosen
while (isGameOver(p)) {
for (int i = 0; i < players; i++) {
rollDice(dice); //uses reference
p[i].scoreBoard= updateScore(p[i], dice);
p[i].catsLeft--;
}
}
}
/******************************************************
** Function: rollDice
** Description: rolls dice, prints array and either rerolls
** Parameters: int[] dice
** Pre-Conditions:
** Post-Conditions:
******************************************************/
void rollDice(int (&dice) [5]) {
int again;
string indices; // indices of dice to reroll
cout << "Your dice are" << endl;
for (int i = 0; i < 5; i++) {
dice[i] = rand() % (6) + 1;
cout << dice[i];
}
for (int i = 0; i < 2; i++) {
cout << "Roll again? Type anything except 0 to go again." << endl;
cin >> again;
if (again) {
cout << "Type each index without a space that you would like to reroll";
cin.ignore();
getline(cin, indices);
for (int i = 0; i < indices.length(); i++) {
dice[(int)indices[i] - '0'] = rand() % (6) + 1;
}
}
else
break;
}
}
At the moment I am getting compiler errors saying
error: no match for ‘operator[]’ (operand types are ‘Player’ and
‘int’)
p[i].scoreBoard= updateScore(p[i], dice);
And consequent ones for the other times I attempt to use p[i]
What your teacher meant that you can pass an array to another function as a pointer and use this to modify the values inside the array in another function. Use the following example to check the values printed before modifying the array and after modifying it. Note how the array is being passed from main funtion to modifyArray funtion.
#include "stdafx.h"
#include <iostream>
using namespace std;
void modifyArray(int * arr, int len)
{
for (int i = 0; i < len; i++)
{
arr[i] += 1;
}
}
void printArr(int *arr, int len)
{
for (int i = 0; i < len; i++)
{
cout << arr[i];
}
cout << endl;
}
int main()
{
int arr[5] = { 1,2,3,4,5 };
cout << "Before :" << endl;
printArr(arr, 5);
modifyArray(arr, 5);
cout << endl << "After : " << endl;
printArr(arr, 5);
return 0;
}
What your teacher means is that if you have a pointer with a buffer integers and with that always hold the values.
Ex:
int* p = new int[5];
This will create an array with 5 slots now everytime you fill it it will always change, there are some things that can be a little bit different if you are doing object oriented but mostly it will be like that. You can use is as a global variable for testing.
The way you can move around it is by writing either p[slot number you want]. This way will make it possible for you to use the array, another way is to return the array with the numbers(instead of having void).

Trying to pass an array of structures but I get a "cannot convert 'struct' to 'struct*' error

I keep getting this error when I try to pass this array of structures into the function AthleticContest():
cannot convert 'person' to 'person*'
Can someone please tell me what I am doing wrong? Am I passing the wrong thing into the function?
struct person
{
int athletic;
int smarts;
int spirit;
int contestVal;
};
int AthleticContest(person subjects[])
{
cout << "Athletic Contest!!!" << endl << endl;
for (int hh = 0; hh < 3; hh++)
{
int result = subjects[hh].athletic;
subjects[hh].contestVal = result;
cout << "Contestant # " << (hh+1) << ") " << subjects[hh].contestVal << endl;
}
int winner;
int tempWin = -1;
for (int hh = 0; hh < 3; hh++)
{
if (subjects[hh].contestVal > tempWin)
{
tempWin = subjects[hh].contestVal;
winner = hh;
}
else if (subjects[hh].contestVal == tempWin)
{
if (randomInt() > 4)
winner = hh;
}
}
cout << "Winner is Contestant # " << (winner+1) << endl;
return winner;
}
int main()
{
person subject[10];
subject[0].athletic = 5;
subject[0].smarts = 3;
subject[0].spirit = 1;
subject[1].athletic = 1;
subject[1].smarts = 3;
subject[0].spirit = 5;
subject[1].athletic = 3;
subject[1].smarts = 5;
subject[0].spirit = 1;
AthleticContest(subject[2]);
}
The error
When you call your function in main():
AthleticContest(subject[2]);
you pass as argument a single person, which is the third element of your array (the element with index 2). So the compiler understands that you try to pass this object of type person.
But your function's parameter is declared to be of type array of undetermined size (i.e. person[]). C++ treats such array arguments as if they were a pointer (to their first element), so like person*.
This is why you get this error message: these types are incompatible
The solution
To get rid of this error, a solution would be to pass a pointer to a subject, for example:
AthleticContest(&subject[2]); // passes the pointer to the third element
// or
AthleticContest(subject); // passes the pointer to the first element of the original array
However, be very careful, because your function has a very risky design: you expect the argument to be a pointer to an array of at least 3 consecutive elements. So if you call it with &subject[8], it would try to access subject[10] which would be out of bounds. If you'd call with &subject[2] it would work with garbege information, since you have initalized only the first two elements, and not the 3rd, 4th and 6th.
A better solution
It is not clear, why you do the constest just with 3 elements. A better option would be the caller to say how many contestant shall be used (the caller know the size of the array).
In main():
AthleticContest(subject, 2); // 2 is the number of contestants in array
Your function would be defined as:
int AthleticContest(person subjects[], int participants)
{
cout << "Athletic Contest!!!" << endl << endl;
for (int hh = 0; hh < participants; hh++)
...
for (int hh = 0; hh < participants; hh++)
...
}
A much better solution
You'd better go for std::vector instead of C++ arrays. They can behave like arrays:
vector<person> subject(2); // create a vector of 2 items
subject[0].athletic = 5;
...
But they are much more convenient because they can have a dynamic size and grow as you add new participants:
person hbolt = {4, 2, 1, 0};
subject.emplace_back (hbolt); // one more participant
AthleticContest(subject);
Your function could get the vector by reference or by value. Let's take by reference, since you intend to modify its content and could possibly want this modified data after the return:
int AthleticContest(vector<person> &subjects)
{
...
}
The big advantage, is that you can always know the size of the vector:
for (int hh = 0; hh < subjects.size(); hh++)
...
Here is an online demo.
Of course, if you don't want to take all the participants in the vector, you'd have to think about your function's argument(s): would you prefer a second argument n and always take the n first elements of the vector ? Or would you prefer n participants but start at an arbitrary offset ? In both case, you'd be wise to check that your indexing never goes out of bounds.
One thing you need to change to compile: You're passing a reference to a single element of the array instead of the array itself.
One more thing you might want to check is to change your signature for AthleticContest() so it'll be the right one in C++ to receive fixed-sized array or person as a parameter.
When fixed to compile, and you're code looks like this:
#include <iostream>
using namespace std;
struct person
{
int athletic;
int smarts;
int spirit;
int contestVal;
};
template <std::size_t size>
int AthleticContest(person (&subjects)[size])
{
cout << "Athletic Contest!!!" << endl << endl;
for (int hh = 0; hh < 3; hh++)
{
int result = subjects[hh].athletic;
subjects[hh].contestVal = result;
cout << "Contestant # " << (hh+1) << ") " << subjects[hh].contestVal << endl;
}
int winner;
int tempWin = -1;
for (int hh = 0; hh < 3; hh++)
{
if (subjects[hh].contestVal > tempWin)
{
tempWin = subjects[hh].contestVal;
winner = hh;
}
else if (subjects[hh].contestVal == tempWin)
{
if (5 > 4)
winner = hh;
}
}
cout << "Winner is Contestant # " << (winner+1) << endl;
return winner;
}
int main()
{
person subject[10];
subject[0].athletic = 5;
subject[0].smarts = 3;
subject[0].spirit = 1;
subject[1].athletic = 1;
subject[1].smarts = 3;
subject[0].spirit = 5;
subject[1].athletic = 3;
subject[1].smarts = 5;
subject[0].spirit = 1;
AthleticContest(subject);
}

Passing arrays and pointers with access violation

I am working on an assignment which must pass pointers for all function
parameters. No global variables are allowed except global constants.
I'm to create an array of "bids" in main and fill it with readBids() function. This works, but I am then supposed to pass it to a function to bubble sort it. My program breaks once my sortBids function is called. I'm learning pointers now and I can't see what I am doing wrong. The Call Stack gives Project4.exe!main()Line32, which points to sortBids(bidArray, numBids);
Any help and an explanation would be very appreciated.
#include <iostream>
#include <string>
using namespace std;
string* readProductName();
int* readNumBids();
double* readBids(string,int);
void sortBids(double*, int*);
void averageBid();
void maxBid();
void totalBid();
void printReport();
int main(){
string* productName;
int* numBids;
productName = readProductName();
numBids = readNumBids();
double* bidArray = readBids(*productName, *numBids);
sortBids(bidArray, numBids);
cout << *productName << " " << *numBids << endl;
for (int i = 0; i < *numBids; i++){
cout << bidArray[i] << endl;
}
system("PAUSE");
delete productName;
delete numBids;
delete bidArray;
return 0;
}
string* readProductName(){
string* productName = new string;
cout << "\n Please enter a product name\n";
cin >> *productName;
return productName;
}
int* readNumBids(){
int* numBids = new int;
cout << "\n Please enter the number of bids\n";
cin >> *numBids;
return numBids;
}
double* readBids(string productName, int numBids){
int* size = new int;
size = &numBids;
string* productNamePtr = new string;
productNamePtr = &productName;
double *bidArray;
bidArray = new double[*size];
cout << "\nHow many bids for the " << *productNamePtr << endl;
for (int i = 0; i < *size; i++){
cout << "Please enter bid #" << i + 1 << endl;
cin >> bidArray[i];
if (bidArray[i] <= 0){
cout << "\nPlease enter an amount larger than 0\n";
i--;
}
}
return bidArray;
}
void sortBids(double* array, int *size){
bool* swap = bool{ false };
double* temp = new double;
do
{
*swap = false;
for (int count = 0; count < *size - 1; count++)
{
if (array[count] > array[count + 1])
{
*temp = array[count];
array[count] = array[count + 1];
array[count + 1] = *temp;
*swap = true;
}
}
} while (*swap);
}
Problem:
You intialise swap to 0. As swap is a pointer to bool, you have a null pointer.
You later dereference this pointer without ever having it point to a valid bool object:
*swap = true;
Tha is UB and this is why you get an access violation !
Solution
Either you define this variable as plain object bool swap = false; and use swap everywhere. Or you initialize it correctly bool *swap = new bool{false}; and you use *swap everywhere.
Miscellaneous advice:
Attention: bidArray is allocated with new[], so you have to delete[] it or risk undefined behaviour !
In pointer definitions, take the habit of puting the star next to the variable and not to the type. Why ? Because optically it is confusing:
bool* a,b; // defines a pointer to bool a, but a PLAIN BOOL b !
bool *a,b; // invites otpically to right interpretation by human reader

Incorrect Variable output with Vector Class C++

My output for the call to the temporary array size wont correctly output. It resizes as according, but I can't get the MAX to display the new value of the new array. My error is within the Resize function within the class.
#include <iostream>
#include <vector>
#include <string>
#include <math.h>
#include <ctime>
using namespace std;
class VectorClass {
private:
int * Vector;//This will be our resizeable array
int Size; //Keep track of vector current size
int MAX=10;
int growth = 5;
int num;
int Resize(int growth, int MAX);
public:
VectorClass(int growth, int Size);
~VectorClass();
int AddItem(int num);
void RemoveItem();
void Print(void);
};
VectorClass::VectorClass(int growth, int Size)
{
Size = 10;
growth = 5;
Vector = new int[Size];
}
VectorClass::~VectorClass()
{
cout << "Destructor was called." << endl;
}
//Will insert num into the vector at the current open position
int VectorClass::AddItem(int num)
{
Vector[Size] = num;
Size++; //Indicate that there isnt as much free space
if (Size == MAX)
{
Resize(Size, MAX);
}
Print();
return num;
}
//Get rid of the most recently added item
void VectorClass::RemoveItem()
{
Size--; //Tricks the vector into one fewer elements in it it currently does
Print();
}
int VectorClass::Resize(int growth, int MAX)
{
cout << "Array is full! Resizing the Array!" << endl;
//Step 1: make a copy
int * temp = new int[MAX]; //Make a new array, same size as exiting array
//loop that copies the original into the copy
for (int i = 0; i<MAX; i++)
{
temp[i] = Vector[i];
}
//Step 2: Delete the original
delete[] Vector; //Deletes all elements in the array Vector from the Heap
//Step 3: Make a bigger vector
Vector = new int[MAX + growth];
//Step 4: Reverse the copy and record the size change
for (int i = 0; i<MAX; i++)
{
Vector[i] = temp[i];
}
MAX = MAX + growth;
//Step 5: Delete the copy
delete[] temp;
cout << "Resize was called.\n" << endl;
return MAX;
}
void VectorClass::Print()
{
cout << "*******************************************************" << endl;
for (int i = 0; i< Size; i++)
{
cout << Vector[i] << endl;
}
cout << "Size = " << Size << "\tMAX = " << MAX << "\t Growth = " << growth << endl << endl;
cout << "*******************************************************" << endl;
}
int main(void)
{
VectorClass V(5,10);
for (int i = 0; i <= 4; i++)
{
int x = rand();
V.AddItem(x);
}
//Print the Vector #1
V.Print();
//Delete 2 Items
V.RemoveItem();
V.RemoveItem();
//Add 9 random Numbers
for (int i = 0; i <= 8; i++)
{
int x = rand();
V.AddItem(x);
}
//Print the Vector
V.Print();
system("pause");
return 0;
}
Several things are wrong with you code. The first one, probably not the one you care about most, is that you never free the memory. You should do it in your destructor, or even better use a std::unique_ptr to handle your memory.
Now, i believe you are yourself confused about your own variables. I see that you possess a variable member named num that you never use. Even worse, you have a parameter in AddItem with the same name. Are you sure it does what you want? The same is true for growth. I would advise you to name your member variable differently, so that you know what they are quickly. I prefixe them with "m_" for example, but you can do as you wish.
You do not need to declare your function parameters inside your class. Only in the function prototype.
Then, in your AddItem function, you use your variable Size to determine where to add the new element, but you initialize your array with it too, which means that not only you do not add your elements at the beginning of your array, you try to write them in memory you do not own!
I could continue for a long time. I am sorry but it only appears to me that you do not know C++ at all. You should go learn the basics again, and maybe start with an easier project to begin your C++ learning.
Good luck :-)

Mode Function: How does it work? [duplicate]

This question already has answers here:
C++: Mean Median and Mode
(3 answers)
Closed 9 years ago.
I've recently created a C++ program to find the mean median and mode of an array of values.
I was able to modify a snipbit from something I found online to create a function that generates the mode, or at least the 1st most occurring values it can find, that I was able to implement. However, I am not 100% sure of how to wrap my head around what is actually happening within the function.
A better understanding of what is happening in the mode function would be greatly appreciated.
This is my code so far:
#include <iostream>
using namespace std;
void mode(int[], int);
void mean(int[], int);
void sort(int[], int);
void median(int[], int);
int main()
{
int array[15];
float total, mode;
int n = 15;//number of elements in array
//fill in the value of array
for(int i=0; i<n; i++){
cout << "fill in the "<< i+1 << " number. :";
cin >> array[i];
}
sort(array, n);
return 0;
}
///////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////
void mean(int new_array[], int num){
//GET TOTAL & CALCULATE MEAN
float total = 0;
for(int i=0;i<num; i++){
total += new_array[i];
}
cout << "The mean is " << total/num << endl;
mode(new_array, num);
}
///////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////
void median(int new_array[], int num){
//CALCULATE THE MEDIAN (middle number)
if(num % 2 != 0){// is the # of elements odd?
int temp = ((num+1)/2)-1;
cout << "The median is " << new_array[temp] << endl;
}
else{// then it's even! :)
cout << "The median is "<< new_array[(num/2)-1] << " and " << new_array[num/2] << endl;
}
mean(new_array, num);
}
///////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////
void mode(int new_array[], int num) {
int* ipRepetition = new int[num];
// alocate a new array in memory of the same size (round about way of defining number of elements by a variable)
for (int i = 0; i < num; i++) {
ipRepetition[i] = 0;//initialize each element to 0
int j = 0;//
while ((j < i) && (new_array[i] != new_array[j])) {
if (new_array[i] != new_array[j]) {
j++;
}
}
(ipRepetition[j])++;
}
int iMaxRepeat = 0;
for (int i = 1; i < num; i++) {
if (ipRepetition[i] > ipRepetition[iMaxRepeat]) {
iMaxRepeat = i;
}
}
cout<< "The mode is " << new_array[iMaxRepeat] << endl;
}
///////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////
void sort(int new_array[], int num){
//ARRANGE VALUES
for(int x=0; x<num; x++){
for(int y=0; y<num-1; y++){
if(new_array[y]>new_array[y+1]){
int temp = new_array[y+1];
new_array[y+1] = new_array[y];
new_array[y] = temp;
}
}
}
cout << "List: ";
for(int i =0; i<num; i++){
cout << new_array[i] << " ";
}
cout << "\n";
median(new_array, num);
}
///////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////
At a very high level, first it leaks memory.
int* ipRepetition = new int[num];
allocates a new array and nothing calls delete[] afterwards.
Second, it fills the new array with zeros by walking through the size of the original array of data one at a time up to the current place it has got toi, if (new_array[i] != new_array[j]) (which it checks twice just to be sure) it increments j.
If it finds a match or gets to the end of the elements it has filled so far it adds one to the ipRepetition array in position j.
This is trying to keep track of how often the number in new_array at index i is used.
The next for loop then walks through these numbers to find the index i largest value.
It then prints the value in the original array at this index.
It might be more useful if the function were changed to return the value. Since it is C++ you could use a vector instead to avoid the memory leak.
You have two parallel arrays: one for the numbers and one to count the repetitions.
The way repetitions are counted is by iterating through the list up to the current number, stopping at the first match and incrementing its repetition count. Say you have the following array:
5 5 2
On the first iteration, you set the first value of the parallel array to 0, then end up breaking out of the inner loop immediately and incrementing it, leaving you with:
1 ? ?
in the parallel array. In the second iteration, the loop will again break on the first item, because new_array[1] == new_array[0] == 5. So you'll be left with:
2 0 ?
...and of course in the third iteration the third value will end up set to 1.
If you still have difficulty understanding, you can think of it like giving one "point" to each number in the original list, then moving the points backwards to the first instance of each number. You could try this on paper even.