Confusion over Initializing variables and changing them in C++ - c++

I'm trying to make a program that will allow the user to enter in a heighth and width of a rectangle, and display the area, however every step of my program is done using functions as part of the assignment.
The issue I'm having is that I have the variables assigned and intialized, though I'm not sure how to overwrite them with user inputted data. If I don't initialize the variables at all the program will not run. I was hoping someone could tell me what I'm doing wrong. My code is:
#include <iostream>
using namespace std;
double getWidth(int x);
double getLength(int y);
double getArea(double x, double y, double a);
double displayData(double a);
int main()
{
int x = 0, y = 0, a = 0;
getWidth(x);
getLength(y);
getArea(x, y, a);
displayData(a);
system("pause");
return 0;
}
double getWidth(int x)
{
cout << "Please enter the width: ";
cin >> x;
return x;
}
double getLength(int y)
{
cout << "Please enter the length: ";
cin >> y;
return y;
}
double getArea(double x, double y, double a)
{
a = x*y;
return a;
}
double displayData(double a)
{
cout << a << endl;
return a;
}

There are two ways of passing variables. Method number one is to pass by value. This is the most common method, and it is the one your program is doing. In this method, a copy of the data in the variable is being made and supplied to the function. Your function only changes the copy and not the original variable.
The second method is to pass by reference. When passing by reference, your function effectively has a pointer to the original variable and can thus change it. To pass by reference, put in an ampersand (&) in front of the variable in the function header. Note in the code below that it is not necessary to pass x and y to getArea by reference because getArea only needs to read these variables not write to them.
This however will introduce a new problem for you. When you pass by value it is possible to change the variable type to a larger type without an explicit cast. This is not possible with passing by reference because the different parts of the program would then be trying to treat the variable as a different type. i.e. main wants to write to/read from a as if it is an integer and getArea wants to write to/read from a as if it is a double. These two data types have different sizes and and different formats so this is not possible. Thus you have to declare a is a double in main.
#include <iostream>
using namespace std;
double getWidth(int &x);
double getLength(int &y);
double getArea(double x, double y, double &a);
double displayData(double a);
int main()
{
int x = 0, y = 0;
double a;
getWidth(x);
getLength(y);
getArea(x, y, a);
displayData(a);
system("pause");
return 0;
}
double getWidth(int &x)
{
cout << "Please enter the width: ";
cin >> x;
return x;
}
double getLength(int &y)
{
cout << "Please enter the length: ";
cin >> y;
return y;
}
double getArea(double x, double y, double &a)
{
a = x*y;
return a;
}
double displayData(double a)
{
cout << a << endl;
return a;
}

You seem to be confusing a few different concepts. You should either be passing references and assigning them within the functions, or passing less values and assigning them to some variable in main. For example, your getWidth should be:
double getWidth() {
double w;
cin >> w;
return w;
}
and in your main you should have:
int main() {
/* ... */
double width = getWidth();
/* ... */
}
And so on for the others as well. You should be looking into references and pointers in C++ as well, that would be the other way that you could do this (and you are seemingly confused about). Finally you should definitely find an introduction to functions in some intro to C++ book, as someone said above.

Related

How to Understand "Pass By Reference Within a Function" w3schools example?

I'm having a hard time understanding how this example from the w3schools tutorial works.
#include <iostream>
using namespace std;
void swapNums(int &x, int &y) {
int z = x;
x = y;
y = z;
}
int main() {
int firstNum = 10;
int secondNum = 20;
cout << "Before swap: " << "\n";
cout << firstNum << secondNum << "\n";
// Call the function, which will change the values of firstNum and secondNum
swapNums(firstNum, secondNum);
cout << "After swap: " << "\n";
cout << firstNum << secondNum << "\n";
system("pause");
return 0;
}
I think I understand the first part:
void swapNums(int &x, int &y) {
int z = x;
x = y;
y = z;
}
I'm basically referencing whatever x and y are going to be when I call the function. So x is going to be "pointing" to firstNum and y is going to be pointing to secondNum. It's going to do the switcheroo using a third variable as a placeholder.
However, after I call the function swapNums(firstNum, secondNum);, I don't understand how the function with its local variables has the ability to change the values of int firstNum = 10; and int secondNum = 20;.
My understanding is that variables within a function are "local" and the scope of said variables only extend within the function itself. How do the local variables change other variables outside their own function without any return statements?
Try this
#include <iostream>
void change_val_by_ref(int &x)
{
x=100
}
void change_val_by_val(int x)
{
x=50;
}
int main()
{
int whatever=0;
std::cout<<"Original value: "<<whatever<<"\n";
change_val_by_ref(whatever);
std::cout<<"After change by ref: "<<whatever<<"\n";
change_val_by_val(whatever);
std::cout<<"After change by val: "<<whatever<<"\n";
}
The output you will see is:
0
100
100
Let's see what happened
change_val_by_ref changed the original whatever, because the ref
was "pointing" to the VARIABLE.
change_val_by_val didn't change the whatever, because the argument of the function x has just copied the value of whatever, and anything that happens to x will not affect whatever, because they are not related.
That's the point of passing by ref.
Imagine you have banana and orange placed in two different plates. You place them into big box with a robotic hand.
You, obviously, can change their destination using you hand. But you want the robotic hand to do this task. You need to tell where the banana and orange are placed, so robotic hand can do its job. !Important robotic hand doesn't care about fruit, which is placed into these plates, it only cares about changing their positions.
By using a pointer, you just tell a function the placement of an object you want to change. And you can set your local, suitable name for this. So pointer is just the name of a plate, which contains a certain value.
References are syntactic sugar for passing around addresses of variables. Instead of the variable itself, you pass its memory address and then the function uses the address of the variable to change its value. Simple as that. Equivalent C code would be:
void swap(int* a, int* b) {
int tmp = *a;
*a = *b;
*b = tmp;
}

VOID function passes array by reference, but when used, I get "No matching matching function for call to..."

I wrote the following code to fill a double array of length len (that has already been initialized) with random floating point numbers:
void FillRay(double (&array)[] , const unsigned int len, const double a , const double b)
{
for(unsigned int i = 0 ; i < len ; ++i )
{
array[i] = randFloat(a,b); // Fill array at i with random number
}
return;
}
However, when I use my FillRay function in main() (see end of main)...
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <math.h>
using namespace std;
int main(){
double a;
double b;
cout << "Please enter lower bound (a): ";
cin >> a;
cout << endl;
cout << "Please enter upper bound (b): ";
cin >> b;
cout << endl;
//Calculate mean and variance
double mu = (b - a)/2;
double sigma = pow(b - a , 2)/12;
//Declare arrays (with langths)
unsigned int shorter = 1000;
unsigned int longer = 100000;
double shortArray[shorter];
double longArray[longer];
// Fill array of length 1K
FillRay(shortArray , shorter, a , b); // ***THIS IS MY PROBLEM AREA***
return 0;
}
... I get the error No matching function for call to 'FillRay'
Can someone please explain what I am doing wrong?? Thanks!
Change your function prototype to following:
void FillRay(double* array, const unsigned int len, const double a , const double b)
Also, it is a good practice to use size_t instead of int for array sizes.
void FillRay(double (&array)[] , const unsigned int len, const double a , const double b)
double (&array)[] is an attempt to take an array by reference without specifying the array's size. This is not possible. The fact that you also specify a len parameter is technically irrelevant. If you want to use standard C++ without any proprietary extensions, then you have three choices:
Completely change the program logic such that the array size is fixed at compile time.
Have the function take a double* and let the automatic conversion (informally called "decay") from array to pointer take place.
Use std::vector<double>.

How to return values from a void function?

Here is parts of my program and I need to return the value of length back to main
Any help?
void getLength(double length)
{
cout << "Enter the length: ";
cin >> length;
if (length < INVAL){
cout << "Do not accept negative values for length. Try again: ";
cin >> length;
}
return length;
}
....
int main()
{
double length = 0;
double width = 0;
double area = 0;
getLength(length);
getWidth(width);
calcArea(length, width, area);
printData(length, width, area);
}
Is this a locked room mystery?
Easiest way is to change it from a void to a double. Alternatively you could have the function modify a public variable in main.
Do you need to keep it a void?
Make the parameter length a reference. void getLength (double & length) and delete the return. After calling the function the passed parameter has the value assigned to it in the function.

How does one pass by pointers with two arguments in function?

Can someone demonstrate how to pass by pointers using one function that takes two arguments from two variables as input?
#include <iostream>
using namespace std;
int passPoints(int *x, int *y)
{
int y = *x * *y;
return(y);
}
int *X, *Y;
int main()
{
cout<<"enter two values: ";
cin>>*X;
cin>>*Y;
cout<<"RESULT = "<<passPoints(X,Y);
return 0;
}
Having trouble.
Like this:
int X, Y;
int main()
{
cout<<"enter two values: ";
cin>>X;
cin>>Y;
cout<<"RESULT = "<<passPoints(&X,&Y);
return 0;
}
The biggest problem in your code (if it is not a typo when you are extracting for question) is, int* X and Y are null pointer and the location they are pointing at are not valid for you to update. You need to make sure that these pointers are pointing to a valid memory location, either by:
int x, y;
int* xPtr = &x;
int* yPtr = &y;
passPoints(xPtr, yPtr);
or simply
int x, y;
passPoints(&x, &y);
now the pointers received by passPoints() are valid pointers

Why wont the vector be empty?

I am wondering why this wont recognize the vector is empty and supply vector pStack with double start? The object of the program is just to simply supply the stack vector with 50 the first time around when it is empty. Then once it is supplied with the starting amount it should subtract with the user input (being bet). Then since its a vector it carries over the old sum into the 2nd time around so it can be subtracted with the user input of bet again.
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class Bet
{
public:
void set_stack(double n);
void set_bet(double n);
double analyze();
double get_stack();
double get_bet();
private:
double pCount;
double bet;
};
double Bet::analyze()
{
double p = pCount;
double b = bet;
double z = p - b;
return z;
}
void Bet::set_bet(double n)
{
bet = z;
}
double Bet::get_bet()
{
return bet;
}
void Bet::set_stack(double n)
{
pCount = n;
}
double Bet::get_stack()
{
return pCount;
}
double start = 50; // Start needs to go inside of pStack
double bbet;
vector<double> pStack(1);
int main()
{
bool con = true;
while(con){
if(pStack.empty()){
pStack.push_back(start); // pStack should be supplied with start when empty
}
double adjst = pStack[0];
Bet rr;
rr.set_stack(adjst);
pStack.clear();
cout << "Enter min 1 Bet: ";
cin >> bbet;
rr.set_bet(bbet);
double aStack = rr.analyze();
pStack.push_back(aStack);
rr.set_stack(aStack);
double newStack = rr.get_stack();
cout << "Stack: " << newStack << endl;
cout << "Bet: " << bbet << endl;
}
system("pause");
return 0;
}
vector<double> pStack(1);
You are initializing your vector with it having an initial size of 1, that's why your pStack.empty() check returns false.
Do this instead to make its initial state empty.
vector<double> pStack;
Also, remove the empty() check and hoist your push_back outside your while loop.
bool con = true;
pStack.push_back(start);
while(con){
...
You might also want to reconsider your usage of global variables. As far as I can see, you can just put start, bbet and pStack inside main().
You are using the fill constructor. This line will initialize the vector to 1 element, default constructed.
vector<double> pStack(1);
If you wanted the vector to start out empty, you should just use the default constructor.
vector<double> pStack;
When you define the pStack vector you use the constructor that takes an integer that represent the number of elements to allocate.
vector<double> pStack(1);
As a result your vector will have 1 default-initialized element.
To create an empty vector do this:
vector<double> pStack;