Yet Another C++ Topic From Otto
OttoDestruct
Join Date: 2002-11-08 Member: 7790Members

in Off-Topic
Erm.. I hope this one is a bit easier. Uhh.. I need help with sending back / receiving multiple data from functions. Er.. let me rephrase. I got my main function calling a function which promps for two inputs. I need that prompting function to return those inputs, and have main receive them so it can send them to another function which takes them and does some calculations. Then it returns those to ANOTHER function which displays the data. I know youre supposed to use the & symbol to return multiple data but I don't understand how to receive it.
Comments
Without advanced stuff like that people usually resort to globals =s
unless it's a gap in my knowledge (which is likely knowing me =3 ) you can only return 1 variable/value from a function ^^;
If it's possible to do without classes or globals I'd sure be interested in knowing too <!--emo&:D--><img src='http://www.unknownworlds.com/forums/html/emoticons/biggrin.gif' border='0' style='vertical-align:middle' alt='biggrin.gif'><!--endemo-->
<b>oop edit:</b> actually, there's a way of passing variables to a function in such a way that any changes made effect the variable. It's been so long since I've done it though I don't even remember how now =P
With your advanced programming knowledge, you shouldn't need more than this little hint:
Passing variables "by value"
vs.
passing variables "by reference" (<-- this is what you want)
Using structures is also a good idea.
*Edit*
Er.. I'm almost done but when I'm going to compile its giving me errors that its expecting a semicolon.. before a function??? WTH?
<!--c1--></span><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td><b>CODE</b> </td></tr><tr><td id='CODE'><!--ec1-->
cxx: Error: hwk08.cxx, line 42: expected a ";"
Calculations (sales, bonus, comm, ttl, ret, fed, state,
--^
cxx: Warning: hwk08.cxx, line 46: parsing restarts here after previous syntax
error
}
^
cxx: Error: hwk08.cxx, line 88: expected a ";"
Detail (SalesID, comm, bonus, ttl, ret, fed, state, net)
--^
<!--c2--></td></tr></table><span class='postcolor'><!--ec2-->
{
...
}
void main()
{
...
...
...
your_function(var1, var2, var3); <---------do you have this semicolon?
...
...
...
return;
}
<!--c1--></span><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td><b>CODE</b> </td></tr><tr><td id='CODE'><!--ec1-->
// Program by Aaron Friedley
// October 18, 2003
// Program takes commission & bonus then calculates payroll
#include <iostream.h>
#include <iomanip.h>
// Prototypes
void Salesman_Data (int, double&, double&);
void Calculations (double, double, double&, double&,
double&, double&, double&, double&);
void Display_Feedback (int, double, double, double, double,
double, double, double);
void Heading (void);
void Detail (int, double, double, double, double, double,
double, double);
// Constants
const double RETRATE = .08;
const double STATERATE = .10;
const double FEDRATE = .25;
const double COMMRATE = .125;
int main (void)
{
// Declarations
int SalesID = 1;
double sales;
double bonus;
double comm;
double ttl;
double ret;
double fed;
double state;
double net;
cout << "Program by Aaron Friedley MWF 10:00\n";
// Calls
Salesman_Data (SalesID, sales, bonus);
Calculations (sales, bonus, comm, ttl, ret, fed, state,
net);
Display_Feedback (SalesID++, bonus, comm, ttl, ret, fed, state,
net);
}
// *** Salesman_Data function ***
void Salesman_Data (int SalesID, double& sales, double& bonus)
{
cout << "Enter the sales for salesperson #" << SalesID
<< ": ";
cin >> sales;
cout << "\nEnter the bonus for salesperson #" << SalesID
<< ": ";
cin >> bonus;
return; // Terminate Salesman_Data
}
// *** Calculations function ***
void Calculations (double sales, double bonus, double& comm,
double& ttl, double& ret, double& fed,
double& state, double& net)
{
comm = sales * COMMRATE;
ttl = bonus + comm;
ret = ttl * RETRATE;
fed = (ttl - ret) * FEDRATE;
state = (ttl - ret) * STATERATE;
net = ttl - ret - fed - state;
return; // Terminate Perform_Calculations
}
// *** Display_Feedback function ***
void Display_Feedback (int SalesID, double bonus, double comm,
double ttl, double ret, double fed,
double state, double net)
{
Heading ();
Detail (SalesID, comm, bonus, ttl, ret, fed, state, net);
return;
}
// *** Heading function ***
void Heading (void)
{
cout << setw(50) << "Payroll Earnings Statement\n"
<< setw(40) << "Arctic Ice Company\n\n"
<< "ID" << setw(11) << "Commission" << setw(6)
<< "Bonus" << setw(10) << "Ttl Earn" << setw(7)
<< "Retire" << setw(8) << "Federal" << setw(6)
<< "State" << setw(5) << "Net\n";
return; // Terminate Heading function
}
// *** Detail function ***
void Detail (int SalesID, double comm, double bonus,
double ttl, double ret, double fed,
double state, double net)
{
cout << setiosflags(ios::fixed) << setiosflags(ios::showpoint)
<< setprecision(2)
<< SalesID << setw(9) << comm << setw(10) << bonus
<< setw(3) << "$" << setfill('*') << setw(5) << ttl
<< setfill(' ') << setw(7) << ret << setw(5)
<< fed << setw(5) << state << setw(5) << "$"
<< setfill('*') << setw(8) << net << "\n";
return; // Terminate Detail
}
<!--c2--></td></tr></table><span class='postcolor'><!--ec2-->
The easiest way to think of passing by value (not using the &) vs. passing by reference (using the &) is that when you're passing by value, your function makes its own memory location to work with the variable, and when you're passing by reference, it uses the memory location of what's being passed to it.
(I call them methods, so bear with me if I forget you call them functions.)
I'll try to make a really cheezy analogy. Let's say your Main function is packing suitcases full of stuff for a vacation. Before it sends the stuff away (destination: your screen) it has some friends or family (your function) who want/need to mess around with the suitcases giving advice on what to pack.
This mother (mothers are always giving advice on what to take with you..."Take a sweater!" "But it's Hawaii!" "Well you never know if they'll blast the air conditioning!" <!--emo&:p--><img src='http://www.unknownworlds.com/forums/html/emoticons/tounge.gif' border='0' style='vertical-align:middle' alt='tounge.gif'><!--endemo-->)...um...yeah, back on track, this mother wants to mess with two of the suitcases.
You decide that for one suitcase, you'll tell your mother what's in the suitcase; she can then get a suitcase (memory location) of her own, fill it up with the exact same stuff she was just told (data, whether its one integer or a whole string or more), adjust the contents however much she wants, and tell you (return) what the result of her adjustments are.
For the second suitcase, you don't just tell her what's in it. You give her the entire suitcase. Now when she's done messing with the stuff as much as she wants, she gives you the same suitcase and its newly-adjusted contents right back.
There's advantages and disadvantages to both. For the 2nd suitcase, she doesn't have to go out and buy a second suitcase and copy the contents (doesn't have to create a 2nd entirely new memory location and fill it with a copy of the data). This saves her money--err, saves memory. But for the 1st suitcase, you've got a different advantage: she didn't mess with your existing suitcase (she made her own to mess with), so you can hear what she has to say about her adjustments without already having your own suitcase's contents changed.
Congrats, you've just passed suitcase 1 by value and suitcase 2 by reference. The thing to remember about C++ is that no function can return more than 1 thing using a "return whatever;" statement -- the moment you say "return whatever;" that function won't be doing any more work. If you want to have it adjust and "return" more than 1 thing, you'll have to use passing by reference. You won't have to say "return whatever;" but when it's done with the normal course of its work, it'll hand those "suitcases" right back as they are (they belong to you, after all).
Now for a simpler, but in-code example. Let's say you want a simple function that takes 2 integers and multiplies both by 3 at the same time.
<!--c1--></span><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td><b>CODE</b> </td></tr><tr><td id='CODE'><!--ec1-->
int tripleMyIntegers(int first, int second)
{
? ? first = first * 3; //this also be written as first *= 3, ?if you've already learned that
? ? second = second * 3;
? ? return <!--c2--></td></tr></table><span class='postcolor'><!--ec2-->
Wait a second -- we want to find out the result of tripling <i>both</i> of them. If we just say "return first;" or "return second;" we'll never hear what happened to the other. Saying "return first;" here is fine if Main has a line that says "firstInt = tripleMyIntegers(firstInt, secondInt);" and all you care about is tripling firstInt. But if you planned on tripling secondInt at the same time, it's not going to happen this way.
<!--c1--></span><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td><b>CODE</b> </td></tr><tr><td id='CODE'><!--ec1-->void tripleMyIntegers(int & first, int & second)
{
? ? first = first * 3;
? ? second = second * 3;
}<!--c2--></td></tr></table><span class='postcolor'><!--ec2-->
But where did "return" go? Don't need it now, not for this. Note that we changed the return type from "int" to "void" because we never say "return." Now we can have in Main:
<!--c1--></span><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td><b>CODE</b> </td></tr><tr><td id='CODE'><!--ec1-->
int firstNum = 5, secondNum = 4; //can also be written as two separate lines, "int first = 5;" and "int second = 4;"
tripleMyIntegers(firstNum, secondNum);
//code to show results on-screen would go here
<!--c2--></td></tr></table><span class='postcolor'><!--ec2-->
main just gave its "suitcases" called firstNum (contents: the integer 5) and secondNum (contents: the integer 4) to tripleMyIntegers, who messed with the contents of both and passed both suitcases back with these contents altered. When you output to the screen, you should see that the change has happened.
Once you understand the differences between passing by value and passing by reference, your book or teacher should be able to explain why you don't want to use reference for everything. There are times for value, times for reference, and if you need a compromise of both, there's "const" reference (don't get scared yet, you'll learn it when you need it).
Hope this helps. If anything else is unclear, just ask.
*Edit*
Only thing **** me off now is that I can't get this ONE FRIGGIN PART to cooperate with setw.. I've tried increments of 10 and it doesnt move a single space. From 0 to 100. The line is:
cout << setw(10) << "\nPayroll Earnings Statement\n"
Hmm...I forget whether this makes a difference with setw(#), but have you tried
<!--c1--></span><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td><b>CODE</b> </td></tr><tr><td id='CODE'><!--ec1-->cout << '\n' << setw(10) << "Payroll Earnings Statement\n"<!--c2--></td></tr></table><span class='postcolor'><!--ec2-->
Should be the same having "\n" or '\n', but the point is that now you're making a whole new line <i>before</i> using setw(#). I forget if it makes any difference.