You are here:

C++/Passing values by reference

Advertisement


Question
QUESTION: My program is almost finished ,but I am confused on how to pass values by reference through functions.  I know that you have to use the ampersand, but I do not know which values exactly need to be passed by reference.

The menu towards the top of my code should explain what each function needs to do.  Right now none of my parameters match for function calls, prototypes, or definitions.  I just can not figure out exactly how passing by reference works.

Code:

#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
#include <cmath>

using namespace std;

double const PI = 3.14159;

void wordLengths (string&);
void integers (string&);
void sphere (float&);
void cylinder (float&, float&);
void angle (double&);

int main()
{
int choice;
ifstream inFile;
float radius, height;
double degrees;
string fileName;

 do
 {
  cout << "1. Display the Longest and Shortest Word In a File"
  << endl;
  
  cout << "2. Display the Maximum and Minimum Integer In a File"
  << endl;
  
  cout << "3. Compute the Surface Area and Volume of a Sphere"
  << endl;
  
  cout << "4. Compute the Surface Area and Volume of a Cylinder"
  << endl;
  
  cout << "5. Compute the Sine, Cosine, and Tangent of an Angle"
  << endl;
  
  cout << "6. Quit" << endl << endl;
  
  cout << "Choice :  ";
  cin >> choice;
  cout << endl;
  
  switch (choice)
  
  case 1: cout << "Enter the Input File Name :  ";
         cin >> fileName;
      cout << endl;
      
         wordLengths (wordMax, wordMin);
      
         cout << "Longest Word :  " << wordMax << endl;
      cout << "Shortest Word :  " << wordMin << endl;
      break;
  
  case 2: cout << "Enter the Input File Name :  ";
         cin >> fileName;
      cout << endl;
      
         integers (maxInt, minInt);
      
         cout << "Maximum of Integers :  " << maxInt << endl;
      cout << "Minimum of Integers :  " << minInt << endl;
      break;
      
  case 3: cout << "Enter the radius :  ";
         cin << radius;
      cout << endl;
      
         sphere (surfaceSphere, volumeSphere);
      
         cout << "Surface Area :  " << surfaceSphere << endl;
      cout << "      Volume :  " << volumeSphere << endl;
      break;
      
  case 4: cout << "Enter the radius & height :  ";
         cin << radius << height;
      cout << endl;
      
         cylinder (surfaceCyl, volumeCyl);
      
         cout << "Surface Area :  " << surfaceCyl << endl;
      cout << "      Volume :  " << volumeCyl << endl;
      break;
         
  case 5: cout << "Enter the angle in degrees :  "
         cin << degrees;
      cout << endl;
      
         angle (rads, sine, cosine, tangent);
      
         cout << "Angle in Radians :  " << rads << endl;
      cout << "          Sine :  " << sine << endl;
      cout << "          Cosine :  " << cosine << endl;
      cout << "         Tangent :  " << tangent << endl;
      break;
  
  case 6: cout << "Thank You -- Goodbye!" << endl;
         exit(1);
  
  default: cout << "Invalid Option -- Try Again!"
         break;
 }
 while (choice != 6);
 
 cout << "Thank You -- Goodbye!" << endl;
 inFile.close();
 exit (1);
}

void wordLengths (string& fileName)
{
 string maxWord, minWord, word;
 
 inFile.open(fileName.c_str())
 
 if (inFile.fail())
 {
   cout << "Error opening input file -- " <<
   fileName << "please try again" << endl;
   return;
 }
 
 inFile >> word;
 
 maxWord.length() = word.length();
 minWord.length() = word.length();
 // initialize values
 
 while (inFile)
 {
   if (word.length() >= maxWord.length())
   {
      maxWord = word;
   }
  
   if (word.length() <= minWord.length())
   {
      minWord = word;
   }
   
   inFile >> word;
 }
 
inFile.close ();
return;
}

void integers (string& fileName)
{
 int maxInt, minInt, integer;
 
 inFile.open(fileName.c_str())
 
 if (inFile.fail())
 {
   cout << "Error opening input file -- " <<
   fileName << "please try again" << endl;
   return;
 }

 inFile >> integer;
 
 maxInt = integer;
 minInt = integer;
 // initialize values
 
 while (inFile)
 {
   if (integer >= maxInt)
   {
      maxInt = integer;
   }
  
   if (integer <= minInt)
   {
      minInt = integer;
   }
  
   inFile >> integer;
 }
 
inFile.close();
return;
}

void sphere (float& radius)
{
 double surfaceSphere, volumeSphere;
 float radius;
 
 surfaceSphere = 4 * PI * radius * radius;
 
 volumeSphere = 4.0 / 3 * PI * pow(radius, 3);
 
 return;
}

void cylinder (float& height, float& radius)
{
 double surfaceCyl, volumeCyl;
 float radius, height;
 
 surfaceCyl = (2 * PI * radius * radius) +
 (2 * PI * radius * height);
 
 volumeCyl = PI * radius * radius * height;
 
 return;
}

void angle (double& degrees)
{
  double tangent, cosine, sine, rads, degrees;

  rads = degrees * PI / 180;

  tangent = tan(rads);

  cosine = cos(rads);

  sine = sin(rads);

  return;
}


ANSWER: Hello Chris.

Your syntax for passing by reference is correct. You use an ampersand in the function declaration.

You should pass by reference whenever you are passing an object because otherwise, a copy of the object will be made and passed to the function. Sometimes its ok to make a copy, and the only disadvantage is that it takes more time. Other times making a copy can actually lead to problems if you don't have a proper copy constructor in your class. In general, passing objects by reference saves time.

You also need to pass by reference if you intend the function to modify the thing being passed in, and you want the change being visible to the caller. For example, say you needed multiple values returned from a function, you would return the values by setting reference variables. In this case the thing can be an object or a simple data type like int or double.

Because passing by reference often implies that the thing being passed will be modified, we generally specify the reference to be const if we don't intend the thing to be modified.

For example if
void wordLengths (string& fileName)
does not need to modify fileName, then the reference should be const. It would look like
void wordLengths (const string& fileName)

That tells you, the programmer, that fileName is passed by reference only for efficiency. It also prevents you from accidentally writing code that modifies fileName.


Now consider
void angle (double& degrees)
angle does not need to modify degrees, and degrees is a simple datatype, so there is no need to pass it in as a reference.


So in conclusion

A simple datatype should be passed by reference only if it is to be modified.
An object should generally be passed by const reference but if it needs to be modified, then it should be passed in by "regular" reference.

There is one more use for reference. Only reference and pointer types can be used polymorphically.

Hope that helps.


---------- FOLLOW-UP ----------

QUESTION: I have changed my parameters, but I am getting many compiler errors.  I can't figure out whether it is because of my parameters, whether I have extra ones, or the wrong ones passed by reference.  The complier tells me that I have to define the function parameters in the main function.  Maybe my function calls are incorrect?

New code:

#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
#include <cmath>

using namespace std;

double const PI = 3.14159;

void wordLengths (string&, string&, string&);
void integers (string&, int&, int&);
void sphere (float, double&, double&);
void cylinder (float, float, double&, double&);
void angle (double, double&, double&, double&, double&);

int main()
{
int choice, maxInt, minInt;
ifstream inFile;
float radius, height;

double degrees, surfaceSphere, volumeSphere surfaceCyl
volumeCyl, rads, sine, cosine, tangent;

string fileName, maxWord, minWord;

 do
 {
  cout << "1. Display the Longest and Shortest Word In a File"
  << endl;
  
  cout << "2. Display the Maximum and Minimum Integer In a File"
  << endl;
  
  cout << "3. Compute the Surface Area and Volume of a Sphere"
  << endl;
  
  cout << "4. Compute the Surface Area and Volume of a Cylinder"
  << endl;
  
  cout << "5. Compute the Sine, Cosine, and Tangent of an Angle"
  << endl;
  
  cout << "6. Quit" << endl << endl;
  
  cout << "Choice :  ";
  cin >> choice;
  cout << endl;
  
  switch (choice)
  
  case 1: cout << "Enter the Input File Name :  ";
         cin >> fileName;
     cout << endl;
     
         wordLengths (fileName, maxWord, minWord);
     
         cout << "Longest Word :  " << maxWord << endl;
     cout << "Shortest Word :  " << minWord << endl;
     break;
  
  case 2: cout << "Enter the Input File Name :  ";
         cin >> fileName;
     cout << endl;
     
         integers (fileName, maxInt, minInt);
     
         cout << "Maximum of Integers :  " << maxInt << endl;
     cout << "Minimum of Integers :  " << minInt << endl;
     break;
     
  case 3: cout << "Enter the radius :  ";
         cin << radius;
     cout << endl;
     
         sphere (radius, surfaceSphere, volumeSphere);
     
         cout << "Surface Area :  " << surfaceSphere << endl;
     cout << "      Volume :  " << volumeSphere << endl;
     break;
     
  case 4: cout << "Enter the radius & height :  ";
         cin << radius << height;
     cout << endl;
     
         cylinder (height, radius, surfaceCyl, volumeCyl);
     
         cout << "Surface Area :  " << surfaceCyl << endl;
     cout << "      Volume :  " << volumeCyl << endl;
     break;
         
  case 5: cout << "Enter the angle in degrees :  "
         cin << degrees;
     cout << endl;
     
         angle (degrees, rads, sine, cosine, tangent);
     
         cout << "Angle in Radians :  " << rads << endl;
     cout << "          Sine :  " << sine << endl;
     cout << "          Cosine :  " << cosine << endl;
     cout << "         Tangent :  " << tangent << endl;
     break;
  
  case 6: cout << "Thank You -- Goodbye!" << endl;
         exit(1);
  
  default: cout << "Invalid Option -- Try Again!"
         break;
 }
 while (choice != 6);
 
 cout << "Thank You -- Goodbye!" << endl;
 inFile.close();
 exit (1);
}

void wordLengths (string& fileName,
string& maxWord, string& minWord)
{
 string word;
 ifstream inFile;
 
 inFile.open(fileName.c_str())
 
 if (inFile.fail())
 {
   cout << "Error opening input file -- " <<
   fileName << "please try again" << endl;
   return;
 }
 
 inFile >> word;
 
 maxWord.length() = word.length();
 minWord.length() = word.length();
 // initialize values
 
 while (inFile)
 {
   if (word.length() >= maxWord.length())
   {
      maxWord = word;
   }
  
   if (word.length() <= minWord.length())
   {
      minWord = word;
   }
   
   inFile >> word;
 }
 
inFile.close ();
return;
}

void integers (string& fileName,
int& maxInt, int& minInt)
{
 int integer;
 ifstream inFile;
 
 inFile.open(fileName.c_str())
 
 if (inFile.fail())
 {
   cout << "Error opening input file -- " <<
   fileName << "please try again" << endl;
   return;
 }

 inFile >> integer;
 
 maxInt = integer;
 minInt = integer;
 // initialize values
 
 while (inFile)
 {
   if (integer >= maxInt)
   {
      maxInt = integer;
   }
  
   if (integer <= minInt)
   {
      minInt = integer;
   }
  
   inFile >> integer;
 }
 
inFile.close();
return;
}

void sphere (float radius, double&surfaceSphere,
double& volumeSphere)
{
 surfaceSphere = 4 * PI * radius * radius;
 
 volumeSphere = 4.0 / 3 * PI * pow(radius, 3);
 
 return;
}

void cylinder (float height, float radius,
double& surfaceCyl, double& volumeCyl)
{
 surfaceCyl = (2 * PI * radius * radius) +
 (2 * PI * radius * height);
 
 volumeCyl = PI * radius * radius * height;
 
 return;
}

void angle (double degrees, double& rads, double& sine,
double& cosine, double& tangent)
{
  rads = degrees * PI / 180;

  tangent = tan(rads);

  cosine = cos(rads);

  sine = sin(rads);

  return;
}


Answer
Hello Chris.

When you write a program, you should compile often. Every time you finish a function, or a major structure like a loop, switch, or if/else you should compile. Of course you'll need to make sure that you have enough closing braces to finish off the function you are working on.

In that way, you will not be overwhelmed by hundreds of compiler errors. You will also learn about any wrong syntax ideas before you spread them throughout your project.

When faced with any number of compiler errors, always start with the first one on the file. Often fixing the first one will make many errors go away. I usually fix the first few, then recompile. Read the error carefully, but don't always assume the error message is going to guide you correctly. You also need to look at the line and see what might be out of place.

For example
double degrees, surfaceSphere, volumeSphere surfaceCyl
volumeCyl, rads, sine, cosine, tangent;

The error is
main.cpp(24) : error C2146: syntax error : missing ';' before identifier 'surfaceCyl'

Well you're not really missing the semicolon because you know you want to declare many doubles. But the compiler is correct that you are missing something before 'surfaceCyl'. It's a comma. Adding a comma before and after surfaceCyl gets rid of 2 errors.


The next error
main.cpp(63) : error C2046: illegal case
is tricky. There is nothing wrong with the line. Your eye has to wander backwards to the start of the switch statement to see that you're missing an opening brace.

For cin you say cin >> xx, not cin << xx
After fixing all the cin errors, we're down from over 100 errors to 12


Are you using Visual Studio ? If so, hit Ctrl+A to select your entire file. Then do Ctrl+K Ctrl+F or using Menus, Edit->Advanced->FormatSelection. That will reformat your code and using indentation, you can see if you are missing a brace, and you are missing a brace to close main. That's why void is unexpected at the line
void wordLengths (string& fileName,
       string& maxWord, string& minWord)
because its still in main.

Another good tool in Visual Studio is the "Find matching brace" tool. You put your cursor before or after a brace, hit Ctrl+} and the cursor jumps to the matching brace.

Now we're down from 12 errors to 5, just by adding the closing brace.

There is a tricky error next where the closing of the switch is written as the closing of a do/while. The find matching brace feature on a few braces pointed that out. I had to hunt around a bit for that one.

Next
      maxWord.length() = word.length();
       minWord.length() = word.length();

You cannot assign a value to a function result. What you need here are two integer variables maxWordLength and minWordLength, not strings.

That's it. I hope that I've given you some ideas about how to help yourself.

Best regards
Zlatko

#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
#include <cmath>

using namespace std;

double const PI = 3.14159;

void wordLengths (string&, string&, string&);
void integers (string&, int&, int&);
void sphere (float, double&, double&);
void cylinder (float, float, double&, double&);
void angle (double, double&, double&, double&, double&);

int main()
{
   int choice, maxInt, minInt;
   ifstream inFile;
   float radius, height;

   double degrees, surfaceSphere, volumeSphere, surfaceCyl,
       volumeCyl, rads, sine, cosine, tangent;

   string fileName, maxWord, minWord;

   do
   {
       cout << "1. Display the Longest and Shortest Word In a File"
         << endl;

       cout << "2. Display the Maximum and Minimum Integer In a File"
         << endl;

       cout << "3. Compute the Surface Area and Volume of a Sphere"
         << endl;

       cout << "4. Compute the Surface Area and Volume of a Cylinder"
         << endl;

       cout << "5. Compute the Sine, Cosine, and Tangent of an Angle"
         << endl;

       cout << "6. Quit" << endl << endl;

       cout << "Choice :  ";
       cin >> choice;
       cout << endl;

       switch (choice)
       {
       case 1: cout << "Enter the Input File Name :  ";
         cin >> fileName;
         cout << endl;

         wordLengths (fileName, maxWord, minWord);

         cout << "Longest Word :  " << maxWord << endl;
         cout << "Shortest Word :  " << minWord << endl;
         break;

       case 2: cout << "Enter the Input File Name :  ";
         cin >> fileName;
         cout << endl;

         integers (fileName, maxInt, minInt);

         cout << "Maximum of Integers :  " << maxInt << endl;
         cout << "Minimum of Integers :  " << minInt << endl;
         break;

       case 3: cout << "Enter the radius :  ";
         cin >> radius;
         cout << endl;

         sphere (radius, surfaceSphere, volumeSphere);

         cout << "Surface Area :  " << surfaceSphere << endl;
         cout << "      Volume :  " << volumeSphere << endl;
         break;

       case 4: cout << "Enter the radius & height :  ";
         cin >> radius >> height;
         cout << endl;

         cylinder (height, radius, surfaceCyl, volumeCyl);

         cout << "Surface Area :  " << surfaceCyl << endl;
         cout << "      Volume :  " << volumeCyl << endl;
         break;

       case 5: cout << "Enter the angle in degrees :  ";
         cin >> degrees;
         cout << endl;

         angle (degrees, rads, sine, cosine, tangent);

         cout << "Angle in Radians :  " << rads << endl;
         cout << "          Sine :  " << sine << endl;
         cout << "          Cosine :  " << cosine << endl;
         cout << "         Tangent :  " << tangent << endl;
         break;

       case 6: cout << "Thank You -- Goodbye!" << endl;
         exit(1);

       default: cout << "Invalid Option -- Try Again!";
         break;
       }
   }
   while (choice != 6);

   cout << "Thank You -- Goodbye!" << endl;
   inFile.close();
   exit (1);
}

void wordLengths (string& fileName,
         string& maxWord, string& minWord)
{
   string word;
   ifstream inFile;

   inFile.open(fileName.c_str());

   if (inFile.fail())
   {
       cout << "Error opening input file -- " <<
         fileName << "please try again" << endl;
       return;
   }

   inFile >> word;

   unsigned int maxWordLength = word.length();
   unsigned int minWordLength = word.length();

   // initialize values

   while (inFile)
   {
       if (word.length() >= maxWordLength)
       {
         maxWord = word;
       }

       if (word.length() <= minWordLength)
       {
         minWord = word;
       }

       inFile >> word;
   }

   inFile.close ();
   return;
}

void integers (string& fileName,
         int& maxInt, int& minInt)
{
   int integer;
   ifstream inFile;

   inFile.open(fileName.c_str());

   if (inFile.fail())
   {
       cout << "Error opening input file -- " <<
         fileName << "please try again" << endl;
       return;
   }

   inFile >> integer;

   maxInt = integer;
   minInt = integer;
   // initialize values

   while (inFile)
   {
       if (integer >= maxInt)
       {
         maxInt = integer;
       }

       if (integer <= minInt)
       {
         minInt = integer;
       }

       inFile >> integer;
   }

   inFile.close();
   return;
}

void sphere (float radius, double&surfaceSphere,
         double& volumeSphere)
{
   surfaceSphere = 4 * PI * radius * radius;

   volumeSphere = 4.0 / 3 * PI * pow(radius, 3);

   return;
}

void cylinder (float height, float radius,
         double& surfaceCyl, double& volumeCyl)
{
   surfaceCyl = (2 * PI * radius * radius) +
       (2 * PI * radius * height);

   volumeCyl = PI * radius * radius * height;

   return;
}

void angle (double degrees, double& rads, double& sine,
         double& cosine, double& tangent)
{
   rads = degrees * PI / 180;

   tangent = tan(rads);

   cosine = cos(rads);

   sine = sin(rads);

   return;
}

C++

All Answers


Answers by Expert:


Ask Experts

Volunteer


Zlatko

Expertise

No longer taking questions.

Experience

No longer taking questions.

Education/Credentials
No longer taking questions.

©2016 About.com. All rights reserved.