I don't understand if I have created an infinite loop or it is just taking long.
int wuerfeln_bis_wurfverteilung(Wurfverwaltung ww) { //takes object of class with x number of die rolls
Wurfverwaltung xx(ww.anzahl); //creates object with x (from param.) no. of rolls
cout << xx << endl;
int z=0;
while (!(xx == ww)){ // while the two objects are unequal
Wurfverwaltung xx(ww.anzahl); //keep creating new objects
z++; //and increase z by one
cout <<xx<< " " << z<< " ";
}
return z;
}
//class looks like this
class Wurfverwaltung{
friend int wuerfeln_bis_wurfverteilung(Wurfverwaltung&);
private:
unsigned int anzahl;
Wurf *w; // pointer to an array of objects from a previous class
... bunch of functions
Question: is it always testing for xx from the before the while loop and comparing to ww? or is xx getting updated every loop? the code doesn't seem to break even if I take 2 as the no. of rolls. (answered. Thanks!)
Edit:
The point of the function is to take an object with a random array and recreate an array with the same combination and return the number of attempts it took.
You are shadowing a variable by creating a new variable with the same name in a new scope.
int wuerfeln_bis_wurfverteilung(Wurfverwaltung ww) {
Wurfverwaltung xx(ww.anzahl); // 1
cout << xx << endl;
int z=0;
while (!(xx == ww)){
Wurfverwaltung xx(ww.anzahl); // Creates new variable, doesn't change (1)
z++;
cout <<xx<< " " << z<< " ";
}
return z;
}
If you change it to x = ww.anzahl; you'll be changing the values and maybe exit the loop.
You compiler can help you detect these kind of issues, but you have to activate more flags (-Wshadow in this case on GCC)
The condition of the while loop
while (!(xx == ww)){ // while the two objects are unequal
Wurfverwaltung xx(ww.anzahl); //keep creating new objects
z++; //and increase z by one
cout <<xx<< " " << z<< " ";
}
deals with the variable xx declared before the loop
Wurfverwaltung xx(ww.anzahl);
The variable xx declared within the loop does not influence on the condition of the loop. It just hides the variable declared before the while loop in the compound statement of the while loop. That is the declaration region of the variable declared in the while loop is the compound statement. Outside the compound statement the variable does not exists.
So the initial value of the condition of the while loop
while (!(xx == ww)){
is not being changed and you have an infinite loop.
Related
so i get how sentinel loops work, they use the expression at the beginning of the the loop declaration to determine where the loop stops. However i don't understand how to connect variables in the scope of the loop and outside the scope. For example
int i;
int sum = 0;
cout << "Enter a number" << endl;
cin>> i;
while (i > 0)
{
sum = sum + i;
cout << "Enter a number" << endl;
cin>> i;
}
cout << "The sum of the numbers entered is" << endl;
cout << sum;
return 0;
So the sum in the loop is correct since its within scope but the i or number entered to define i out of the scope in the initial i . How do you go about this, can you connect the variables inside and outside the loop? Or can you use uninitialized memory to make a sentinel loop? Do you have to add a separate variable outside the loop and connect the sum of i outside and inside the loop? So just trying to understand how you'd connect the variables inside and outside the scope. If sentinels need to have the variable defined prior to the loop.
Thank you for any light you can shed on this.
Variables are defined in a particular scope and become visible to all scopes within the outer scope unless overwritten (which most programmers tell you is a very, very bad idea). For instance:
#include
using std::cout;
using std::endl;
int main(int, char **) {
int i = 5;
int k = 10;
if (true) {
int j = 15;
int i = 20;
cout << "i inside if: " << i << ". J: " << j << endl;
}
cout << "i outside if: " << i << ". K: " << k << endl;
}
Running it produces:
i inside if: 20. J: 15
i outside if: 5. K: 10
In this case, the scope of method main() contains two variables, i and k. Those variables are also available inside the if-statement. The if also defines two variables, j and i. They are only available inside the if-statement.
The i inside the if-statement hides the larger i (which is dangerous / confusing), but I wanted to demonstrate it. As you can see, i outside the if retains it's original value -- it wasn't modified when we declared the inner copy.
In your code, i and sum are defined outside the if-statement, so they're available inside it, and changes you make to them persist. That is, because you haven't defined new variables, everything just works.
So I'm having some trouble with my program. It doesn't seem to fill the array properly. It dosen't seem to populate pass element 0, even though I'm increasing i. When I debug and go back, i remains zero. Should I be doing something different? I feel like I'm passing or updating the array improperly. Can't really use any STL libraries. Thank you in advance for any help.
struct Client
{
string name;
string zip;
double balance;
};
Client bAccounts [30]; //structural array in main()
int addClnt(Client(&bAccounts)[30], int); //prototype
int addClnt(Client(&bAccounts)[30], int clientCount) //function to add
elements
{
cout << "Enter Account Name:" << endl;
cin >> bAccounts[i].name;
cout << "Enter Account Zip:" << endl;
cin >> bAccounts[i].zip;
cout << "Enter Account Balance:" << endl;
cin >> bAccounts[i].balance;
cout << "Enter Last Transaction" << endl;
cin >> bAccounts[i].lastTrans;
clientCount++; //to return number of clients added
i++; //to populate different element of array on next call of function.
return clientCount + 1;
}
So I added + 1 to return clientCount and then set i = clientCount. However, clientCount remains at zero and dosen't update.
The reason the array doesn't have any values after the first one is because you never reach passed the first element. You increment i at the end of the function, but at the top of your addClnt function, i is set back to 0 . This will just keep resulting on overwriting the old previous data
EDIT:
#include <iostream>
//use pass by reference (&)
void add_client(int& index_loc){
//do whatever
//this changes the actual value passed into the function
index_loc++;
}
int main(){
int loc = 0;
add_client(loc);
add_client(loc);
add_client(loc);
//outputs 3
std::cout << "current #: " << loc << "\n";
}
clientCount is only getting incremented in that functions scope. When that function goes to it's return statement, all variables and all the work it did has completely died.
You are passing clientCount by value and not by reference, so clientCount will always be 0, and incrementing it inside that local function won't actually change clientCount's value outside of the function.
What you need to do is pass it by reference.
EDIT: The chosen answer does not explain why his solution works. The answer provided is incorrect.
The reason why the code works because again, you pass by reference and not by value.
Okay, im just about done with my exercise and stuck on how to get each dice to roll their own individual randomly generated number. The program does in fact roll random numbers, it's just every time you re-roll both dice always roll the same exact numbers. And this simple but yet head scratching problem occurred, for some reason i'm also having
cout << "Adding both dices up you rolled a total of: " << totalScore() << "." << endl;
I was also told by a class mate that my faceValue was an illegal value and should be set to a legal value. I didn't quite get what he meant and I'm sure it'll knock off (not a lot) a few of my grade.
#include "stdafx.h"
#include <iostream>
#include <string>
#include <ctime>
using namespace std;
class PairOfDice
{
private:
int diceOne;
int diceTwo;
int score;
int faceVaule;
public:
PairOfDice(){
srand(time(NULL));
roll();
}
void roll(){
diceOne = (rand() % 6) + 1;
diceTwo = (rand() % 6) + 1;
setdiceOne(diceOne);
setdiceTwo(diceTwo);
}
void setdiceOne(int value){
faceVaule = value;
}
int getdiceOne(){
return faceVaule;
}
void setdiceTwo(int value){
faceVaule = value;
}
int getdiceTwo(){
return faceVaule;
}
void totalScore(){
score = diceOne + diceTwo;
}
void display(){
cout << "The first Dice rolled a " << getdiceOne() << " ." << endl;
cout << "The second Dice rolled a " << getdiceTwo() << " ." << endl;
// adding both dices gives an: No operator " < < " matches these operands
cout << "Adding both dices up you rolled a total of: " << totalScore() << "." << endl;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
PairOfDice game;
game.roll();
game.display();
game.totalScore();
return 0;
}
First of all: you roll two dice, store the results in dice1 and dice2, but then you send those values to two functions that put the value into a variable called faceValue.
It is logical that getting the value back will return only the second dice value, because that's what you last entered in faceValue.
That is why the same values are shown for both dice.
Now for the error: your totalScore function returns a void while the << operator expects some kind of type.
The totalScore function adds the two dice (correct values by the way) and puts the result in score, but nowhere, the value in score is returned.
Your code is really messy. You shouldn't have one member variable (faceValue) holding a copy of two different values. You shouldn't have this member at all. Just use the diceOne and diceTwo values.
When the values are set ( = rand() % 6 + 1 ), they should not be set again by calling the set-function: Either create a correct set-function (because this one isn't correct) and put the random as a parameter in there, or set the member variable diceOne and diceTwo directly in the constructor as you already do. Don't do both.
When returning the sum of the two dice, why not just return this sum (hint: the function totalScore should return something of the int-type). Why are you putting the summed result into a member variable? There is no need for that.
I could post the corrected code here, but it seems that you really have to learn this yourself.
Edit: And by the way: as stated above, learn to use the debugger. You will soon discover that the things I am telling you are correct. You will notice that faceValue first gets the value of diceOne and then the value of diceTwo, never getting the diceOne value back.
In some new territory working with pointers and references, I am attempting to pass an array by reference into a function using a pointer, however I keep getting errors no matter what I try, I am sure the problem is very simple to fix but I just cant seem to wrap my head around it, can anyone see the mistake im making? any help will go a long way thanks
#include<iostream>
#include<cmath>
#include <iomanip>
#include <cstdio>
#include <cstdlib>
#include <new>
using namespace std;
//Inline function
inline double getFahrenheit(double theCelsius)
{
//Convert the celcius to farenheit
return (theCelsius + 32) * 5 / 9;
}
void outputWeather(double *temperaturesArray, const string WEEK_DAY_NAMES[], const double MAX_NUMBER)
{
//this is a counter that will increment through the days and various
int counter;
//reset the counter to 0 so we can use it again
counter = 0;
//print a header
cout << "THIS WEEKS TEMPERATURE REPORT " << endl;
//print a divider
cout << "=============================" << endl;
//while the counter is less than 7 repeat again
while(counter < MAX_NUMBER)
{
//print out the temperatures by day
cout << WEEK_DAY_NAMES[counter] << " " << temperaturesArray[counter] << "\370C " << getFahrenheit(temperaturesArray[counter]) <<"\370F "<< endl;
//increase the counter by 1
counter +=1;
}
}
//Function that will determine whether or not the value the user entered was numeric and within the range
double checkValidation(string weekDay)
{
//Create a variable to store a valid number
double validNumber;
//This will hold the value for the lowest
const double MIN_NUMBER = 1;
//This will hold the value for the highest temperature
const double MAX_NUMBER = 365;
//This will hold the value for the valid number that the user will eventually enter
validNumber = 0.0;
//This will alert the user to enter a temperature for that day of the week
cout << "Please enter the temperature for " << weekDay << endl;
//This will take in teh value the user entered for teh temperature
cin >> validNumber;
//If the text the user entered was not numeric start again
if(cin.fail())
{
//C++ built in methods for clearing the cin
cin.clear();
fflush(stdin);
//alert the user what they typed was wrong
cout << "invalid input. please try again and enter a numeric value" << endl;
//pass in the weekeday and start over
checkValidation(weekDay);
}
else
{
//if teh number falls outside the range
if(validNumber < MIN_NUMBER || validNumber > MAX_NUMBER)
{
//Alert the user that it was outside the range
cout << "invalid input. please try again and enter a value between -90 and 60" << endl;
//pass in the weekday and try again
checkValidation(weekDay);
}
}
//return the valid number
return validNumber;
}
int main()
{
//this is a counter that will increment through the days and various
int counter;
//a constant to hold the variable for the number of days
const int MAX_COUNTER = 7;
//an array that will hold all the days of the week
const string WEEK_DAY_NAMES[] =
{
"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
};
//this will hold all of teh temperatures
double temperaturesArray[MAX_COUNTER];
//start the counter off at 0
counter = 0;
//begin telling the user to enter temperatures by printing a header
cout << "Please enter the temperature for every day of the week " << endl;
//while the counter is less than 7 we will repeat
while(counter < MAX_COUNTER)
{
//add temperature to the array
temperaturesArray[counter] = checkValidation(WEEK_DAY_NAMES[counter]);
//add 1 to the counter
counter +=1;
}
double * arrayPointer = new double[MAX_COUNTER];
arrayPointer = &temperaturesArray;
outputWeather(arrayPointer, WEEK_DAY_NAMES, MAX_COUNTER);
system("PAUSE");
return 0;
}
In C++, the size of an array is encoded into its type.
There is no general "array of doubles" type. But there is an "array of 7 doubles" type, and an "array of 13 doubles" type, and so on.
So to pass an array as an array, and not simply as a pointer, to a function, you need to encode the precise type in the function's signature.
It won't be "a function which takes an array", but "a function which takes an array of size 7".
The way to do that is as follows:
void f(double (&arr)[7]);
Or of course, you can template it, if the array size is not fixed:
template <size_t N>
void f(double (&arr)[N]);
But really, what you're trying to do shouldn't be done using raw arrays at all.
Use the standard library vector.
Briefly, replacing line
arrayPointer = &temperaturesArray;
with
arrayPointer = temperaturesArray;
makes the code to compile.
Notice that arrayPointer is of type double* and temperaturesArray is of type double[MAX_COUNTER] (with MAX_COUNTER = 7). Hence, you can assign arrayPointer to the address of a double but you cannot assign arrayPointer to the address of a double[MAX_COUNTER]. That's what the original code attempted to do and thus, it failed to compile.
On the other hand, each element of a double[MAX_COUNTER] is a double. In particular, the first element is a double and you can assign its address to arrayPointer:
arrayPointer = &temperaturesArray[0];
The fix above is just a synctatic sugar for this line. Indeed, when you assign an object of type "array of type T" (e.g. double[MAX_COUNTER]) to a "pointer of type T", then the compiler performs the so called array-to-pointer conversion which means that is assigns the address of the first array element to the pointer.
Now a little remark on your code (with the provided fix), specifically, the following lines:
double * arrayPointer = new double[MAX_COUNTER];
arrayPointer = temperaturesArray;
The first line above allocates heap memory to store an array of MAX_COUNTER objects of type double. Then the address of the first element of this array is assigned to arrayPointer.
Then, the following line reassigns arrayPointer to the address of the first element of temperaturesArray. Therefore, the address of the first element of the heap allocated array is lost and you can no longer delete it. Remeber that every call to new must be matched by a call to delete (otherwise you have a memory leak). In this particular case, however, the best thing to do isn't call delete. Actually, you should eliminate the call to new since the heap memory is never used. More precisely, you can remove the first line above.
#include <iostream>
using namespace std;
int main (void) {
cout << " 1\t2\t3\t4\t5\t6\t7\t8\t9" << endl << "" << endl;
for (int c = 1; c < 10; c++) {
cout << c << "| ";
for (int i = 1; i < 10; i++) {
cout << i * c << '\t';
}
cout << endl;
}
return 0;
}
Hey so this code produces a times table...I found it on Google Code's C++ class online...I'm confused about why "i" in the second for loop resets to 1 every time you go through that loop...or is it being declared again in the first parameter?
Thanks in advance!
It "reverts" to 1 because you explicitly set it to 1 as the start condition of the loop...
The "i" name does not exist outside this loop, so each time this loop is run (for each iteration of 'c'), then "i" is a new variable, set to a start of 1.
As TZHX has written. FOR statements usually have three clauses that are in the parantheses (technically they always have three but you don't have to specify them), and a statement that is repeated (often a statement block).
Of those three clauses, the first is an initializer, the second controls the looping, and the third is the increment. So as TZHX says, i is reset to 1 at the beginning due to the initializer clause. This will keep repeating while i<10 (the second clause), and i is incremented by 1 with each iteration (the third clause).