12 Replies - 1606 Views - Last Post: 02 May 2012 - 01:01 PM Rate Topic: -----

#1 Twigz  Icon User is offline

  • D.I.C Head

Reputation: 2
  • View blog
  • Posts: 59
  • Joined: 11-July 11

Using references to make program more efficient.

Posted 01 May 2012 - 06:17 PM

Hey all, good evening.
Here is an assignment that i have.

1) 1. Improve the Mad Lib game from Chapter 5 by using references to make
the program more efficient.

Here is the original Mad Lib game.

// Mad-Lib
// Creates a story based on user input

#include <iostream>
#include <string>

using namespace std;

string askText(string prompt);
int askNumber(string prompt);
void tellStory(string name, string noun, int number, string bodyPart, string verb);

int main()
{
    cout << "Welcome to Mad Lib.\n\n";
    cout << "Answer the following questions to help create a new story.\n";
    
    string name = askText("Please enter a name: ");
    string noun = askText("Please enter a plural noun: ");
    int number = askNumber("Please enter a number: ");
    string bodyPart = askText("Please enter a body part: ");
    string verb = askText("Please enter a verb: ");
    
    tellStory(name, noun, number, bodyPart, verb);

    return 0;
}

string askText(string prompt)
{
    string text;
    cout << prompt;
    cin >> text; 
    return text;
}

int askNumber(string prompt)
{
    int num;
    cout << prompt;
    cin >> num;
    return num;
}

void tellStory(string name, string noun, int number, string bodyPart, string verb)
{
    cout << "\nHere's your story:\n";
    cout << "The famous explorer ";
    cout << name;
    cout << " had nearly given up a life-long quest to find\n";
    cout << "The Lost City of ";
    cout << noun;
    cout << " when one day, the ";
    cout << noun;
    cout << " found the explorer.\n";
    cout << "Surrounded by ";
    cout << number;
    cout << " " << noun;
    cout << ", a tear came to ";
    cout << name << "'s ";
    cout << bodyPart << ".\n";
    cout << "After all this time, the quest was finally over. ";
    cout << "And then, the ";
    cout << noun << "\n";
    cout << "promptly devoured ";
    cout << name << ". ";
    cout << "The moral of the story? Be careful what you ";
    cout << verb;
    cout << " for.";
}




And here is the 1 i worked on.

// Mad-Lib
// Creates a story based on user input

#include <iostream>
#include <string>

using namespace std;

string askText(string prompt);
int askNumber(string prompt);
void tellStory(string& name, string& noun, int number, string& bodyPart, string& verb);

int main()
{
    cout << "Welcome to Mad Lib.\n\n";
    cout << "Answer the following questions to help create a new story.\n";
    
    string name;
	string& rName = askText("Please enter a name: ");
    string noun;
	string& rNoun = askText("Please enter a plural noun: ");
    int number = askNumber("Please enter a number: ");
    string bodyPart;
	string& rBodyPart = askText("Please enter a body part: ");
    string verb;
	string& rVerb = askText("Please enter a verb: ");
    
    tellStory(name, noun, number, bodyPart, verb);

    return 0;
}

string askText(string prompt)
{
    string text;
    cout << prompt;
    cin >> text; 
    return text;
}

int askNumber(string prompt)
{
    int num;
    cout << prompt;
    cin >> num;
    return num;
}

void tellStory(string name, string noun, int number, string bodyPart, string verb)
{
    cout << "\nHere's your story:\n";
    cout << "The famous explorer ";
    cout << name;
    cout << " had nearly given up a life-long quest to find\n";
    cout << "The Lost City of ";
    cout << noun;
    cout << " when one day, the ";
    cout << noun;
    cout << " found the explorer.\n";
    cout << "Surrounded by ";
    cout << number;
    cout << " " << noun;
    cout << ", a tear came to ";
    cout << name << "'s ";
    cout << bodyPart << ".\n";
    cout << "After all this time, the quest was finally over. ";
    cout << "And then, the ";
    cout << noun << "\n";
    cout << "promptly devoured ";
    cout << name << ". ";
    cout << "The moral of the story? Be careful what you ";
    cout << verb;
    cout << " for.";
}




Evertime i try to run the program it gives this error.

1>------ Build started: Project: chapter 5, Configuration: Debug Win32 ------
1>Mad lib re-written.obj : error LNK2019: unresolved external symbol "void __cdecl tellStory(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > &,int,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > &)" (?tellStory@@YAXAAV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@0H00@Z) referenced in function _main
1>C:\Users\Twigz\Documents\Visual Studio 2010\Projects\chapter 5\Debug\chapter 5.exe : fatal error LNK1120: 1 unresolved externals
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

And when i highlight tellStory, it says error: more than one instance of overloaded function "tellStory" matches the argument list.

So i'm not sure whether i was going in the right direction or i'm totally off.

Care to help out?

Is This A Good Question/Topic? 0
  • +

Replies To: Using references to make program more efficient.

#2 gwaihir  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 46
  • Joined: 06-April 11

Re: Using references to make program more efficient.

Posted 01 May 2012 - 06:32 PM


string askText(string prompt);
int askNumber(string prompt);
void tellStory(string& name, string& noun, int number, string& bodyPart, string& verb);



These are prototypes which shouldn't have a variable name attached to it. A basic prototype goes:
string askText(string);

in the function header body is where you want a variable name:
string askText(string prompt)
{
function;
}
Was This Post Helpful? -2
  • +
  • -

#3 gwaihir  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 46
  • Joined: 06-April 11

Re: Using references to make program more efficient.

Posted 01 May 2012 - 06:53 PM

And you don't need to pass anything by reference in this program. You can cut these two functions as well: string askText, and int askNumber. Just as the questions in main, cin them, then pass to the tellStory function like this:
tellStory(name, noun, number, bodyPart, verb);
Was This Post Helpful? 1
  • +
  • -

#4 jimblumberg  Icon User is online

  • member icon


Reputation: 4063
  • View blog
  • Posts: 12,547
  • Joined: 25-December 09

Re: Using references to make program more efficient.

Posted 01 May 2012 - 06:54 PM

Quote

These are prototypes which shouldn't have a variable name attached to it.

There is nothing wrong with providing variable names in the function prototypes, in fact that is the preferred method. Having the function prototypes and the function implementation headers the same, with variable names can help document the functions, and make spotting differences easier.

The problem with this code is that the function definition does not match the function implementation exactly.

// Prototype notice the use of references.
void tellStory(string& name, string& noun, int number, string& bodyPart, string& verb);
...
// Function implementation, notice passing by value.
void tellStory(string name, string noun, int number, string bodyPart, string verb)



Remember the function prototype, function implementation and function call must all agree as to the number and exact type of parameters. Your prototype does not match your implementation.


Jim
Was This Post Helpful? 2
  • +
  • -

#5 gwaihir  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 46
  • Joined: 06-April 11

Re: Using references to make program more efficient.

Posted 01 May 2012 - 07:00 PM

You can run this program with one simple prototype
void tellStory(string, string, int, string, string);


And one method of input
 string name;
	cout << "Please enter a name: ";
	getline(cin, name);


Was This Post Helpful? 1
  • +
  • -

#6 turboscrew  Icon User is offline

  • D.I.C Addict

Reputation: 100
  • View blog
  • Posts: 615
  • Joined: 03-April 12

Re: Using references to make program more efficient.

Posted 01 May 2012 - 10:15 PM

I guess std::string is internally some kind of structure.
In C and C++ arrays are passed as pointers, but structures are stuffed into the stack.

Reference is a pointer that, from the programmer's view, acts as a value,
so there is a difference whether the parameter is a pointer or a structure.
Was This Post Helpful? 0
  • +
  • -

#7 Twigz  Icon User is offline

  • D.I.C Head

Reputation: 2
  • View blog
  • Posts: 59
  • Joined: 11-July 11

Re: Using references to make program more efficient.

Posted 02 May 2012 - 03:13 AM

View Postgwaihir, on 01 May 2012 - 06:32 PM, said:


string askText(string prompt);
int askNumber(string prompt);
void tellStory(string& name, string& noun, int number, string& bodyPart, string& verb);



These are prototypes which shouldn't have a variable name attached to it. A basic prototype goes:
string askText(string);

in the function header body is where you want a variable name:
string askText(string prompt)
{
function;
}


Sorry but according to the way I'm learning it's better for the prototypes to have a variable name attached. It makes the code clearer, and it's worth the minor effort.

Quote

The problem with this code is that the function definition does not match the function implementation exactly.Remember the function prototype, function implementation and function call must all agree as to the number and exact type of parameters. Your prototype does not match your implementation.


Jim


I think i got what you were trying to say.

Because the function ( void tellStory(string& name, string& noun, int number, string& bodyPart, string& verb); ) would pass the arguments by reference. So i did not have to create a reference of the variable. E.g string name; string& rName = askText("Please enter a name: ");.

It compiles and runs properly now. Please do correct me if i'm wrong. Thank you for all the help guys.

Here is the code.

// Mad-Lib
// Creates a story based on user input

#include <iostream>
#include <string>

using namespace std;

string askText(string prompt);
int askNumber(string prompt);
void tellStory(string& name, string& noun, int number, string& bodyPart, string& verb);

int main()
{
    cout << "Welcome to Mad Lib.\n\n";
    cout << "Answer the following questions to help create a new story.\n";
    
    string name = askText("Please enter a name: ");
    string noun = askText("Please enter a plural noun: ");
    int number = askNumber("Please enter a number: ");
    string bodyPart = askText("Please enter a body part: ");
    string verb = askText("Please enter a verb: ");
    
    tellStory(name, noun, number, bodyPart, verb);

    return 0;
}

string askText(string prompt)
{
    string text;
    cout << prompt;
    cin >> text; 
    return text;
}

int askNumber(string prompt)
{
    int num;
    cout << prompt;
    cin >> num;
    return num;
}

void tellStory(string& name, string& noun, int number, string& bodyPart, string& verb)
{
    cout << "\nHere's your story:\n";
    cout << "The famous explorer ";
    cout << name;
    cout << " had nearly given up a life-long quest to find\n";
    cout << "The Lost City of ";
    cout << noun;
    cout << " when one day, the ";
    cout << noun;
    cout << " found the explorer.\n";
    cout << "Surrounded by ";
    cout << number;
    cout << " " << noun;
    cout << ", a tear came to ";
    cout << name << "'s ";
    cout << bodyPart << ".\n";
    cout << "After all this time, the quest was finally over. ";
    cout << "And then, the ";
    cout << noun << "\n";
    cout << "promptly devoured ";
    cout << name << ". ";
    cout << "The moral of the story? Be careful what you ";
    cout << verb;
    cout << " for.";
}



Was This Post Helpful? 0
  • +
  • -

#8 gwaihir  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 46
  • Joined: 06-April 11

Re: Using references to make program more efficient.

Posted 02 May 2012 - 08:24 AM

Quote

Sorry but according to the way I'm learning it's better for the prototypes to have a variable name attached. It makes the code clearer, and it's worth the minor effort.


Don't get me wrong, its perfectly ok to do this in your program. I think more along the lines as if you developed this program for someone else, i.e. a client, and you've gone and named their variables in a prototype. It wouldn't be "clearer" to the end user, who wants to define their own variable names based on their desire. If you feel like you're "going the extra effort" and it helps you learn, then more power to ya. But, at least in my experience, a client would reject that effort and your program, because you've developed a program with variables that can't be manipulated in main.
Was This Post Helpful? 0
  • +
  • -

#9 JackOfAllTrades  Icon User is offline

  • Saucy!
  • member icon

Reputation: 6062
  • View blog
  • Posts: 23,513
  • Joined: 23-August 08

Re: Using references to make program more efficient.

Posted 02 May 2012 - 08:30 AM

Quote

But, at least in my experience, a client would reject that effort and your program, because you've developed a program with variables that can't be manipulated in main.


WHAT???

The MSDN page for the CreateProcess function

The prototype for this function:

BOOL WINAPI CreateProcess(
  __in_opt     LPCTSTR lpApplicationName,
  __inout_opt  LPTSTR lpCommandLine,
  __in_opt     LPSECURITY_ATTRIBUTES lpProcessAttributes,
  __in_opt     LPSECURITY_ATTRIBUTES lpThreadAttributes,
  __in         BOOL bInheritHandles,
  __in         DWORD dwCreationFlags,
  __in_opt     LPVOID lpEnvironment,
  __in_opt     LPCTSTR lpCurrentDirectory,
  __in         LPSTARTUPINFO lpStartupInfo,
  __out        LPPROCESS_INFORMATION lpProcessInformation
);


Are you trying to tell us you think that to use this function in your code, you need to use the same variable names presented above???
Was This Post Helpful? 1
  • +
  • -

#10 gwaihir  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 46
  • Joined: 06-April 11

Re: Using references to make program more efficient.

Posted 02 May 2012 - 08:38 AM

View PostJackOfAllTrades, on 02 May 2012 - 08:30 AM, said:

Quote

But, at least in my experience, a client would reject that effort and your program, because you've developed a program with variables that can't be manipulated in main.


WHAT???

The MSDN page for the CreateProcess function

The prototype for this function:

BOOL WINAPI CreateProcess(
  __in_opt     LPCTSTR lpApplicationName,
  __inout_opt  LPTSTR lpCommandLine,
  __in_opt     LPSECURITY_ATTRIBUTES lpProcessAttributes,
  __in_opt     LPSECURITY_ATTRIBUTES lpThreadAttributes,
  __in         BOOL bInheritHandles,
  __in         DWORD dwCreationFlags,
  __in_opt     LPVOID lpEnvironment,
  __in_opt     LPCTSTR lpCurrentDirectory,
  __in         LPSTARTUPINFO lpStartupInfo,
  __out        LPPROCESS_INFORMATION lpProcessInformation
);


Are you trying to tell us you think that to use this function in your code, you need to use the same variable names presented above???

lol calm down I misspoke. I'm saying, why bother writing something like string& name in a prototype?
Was This Post Helpful? 0
  • +
  • -

#11 jimblumberg  Icon User is online

  • member icon


Reputation: 4063
  • View blog
  • Posts: 12,547
  • Joined: 25-December 09

Re: Using references to make program more efficient.

Posted 02 May 2012 - 08:50 AM

Quote

because you've developed a program with variables that can't be manipulated in main.

What? Just because you provide a name to a variable in a function prototype does not mean you can't name that variable something else in your calling function.

#include <string>

void myFunction(std::string& mySaying);
void yourFunction(std::string&);

int main()
{
   std::string test;

   myFunctoin(test);

   yourFunction(test);

   std::cout << test << endl;

   return(0);
}

void myFunction(std::string& saying)
{
   saying = "Hello World";
}

void yourFunction(std::string& someSaying)
{
   std::cout << someSaying << std::endl;
   someSaying = "Good Bye cruel world";
}



The above should compile and run without problems.

Also the variable name in the prototype can be different than the variable name used in the function implementation, it makes no difference to the compiler whether you supply the variable names in the prototype or not. The only place the actual name means anything is in the implementation, which a "customer" may never actually see. By supplying the same name in both the implementation and definition you make it easier, for you to spot differences between the prototype and the implementation.

Quote

lol calm down I misspoke. I'm saying, why bother writing something like string& name in a prototype?

Because when you pass a string by reference you avoid copying that string to a temporary. Copying a class can be quite expensive and you should consider passing the value by reference whenever possible. If you don't want the function to be able to modify the value then pass a constant reference.

// Don't allow function to modify this string.
// Same as passing by value except it avoids the copying.
void printString(const std::string& toPrint);
// Allow this function to modify the string.
void getString(std::string& stringToGet);



Jim

This post has been edited by jimblumberg: 02 May 2012 - 08:57 AM

Was This Post Helpful? 0
  • +
  • -

#12 JackOfAllTrades  Icon User is offline

  • Saucy!
  • member icon

Reputation: 6062
  • View blog
  • Posts: 23,513
  • Joined: 23-August 08

Re: Using references to make program more efficient.

Posted 02 May 2012 - 12:06 PM

Quote

why bother writing something like string& name


Because YOU may not be the only person to ever use that code. Write code with an eye to the person who comes after you, that will be responsible for maintaining and updating it, and make your code should be as self-documenting as possible.
Was This Post Helpful? 0
  • +
  • -

#13 baavgai  Icon User is online

  • Dreaming Coder
  • member icon

Reputation: 5820
  • View blog
  • Posts: 12,672
  • Joined: 16-October 07

Re: Using references to make program more efficient.

Posted 02 May 2012 - 01:01 PM

View PostTwigz, on 02 May 2012 - 05:13 AM, said:

It compiles and runs properly now. Please do correct me if i'm wrong. Thank you for all the help guys.


Looks good. Why no reference in the ask part? Also, look at the questions you pass. You can kill off some repetition there.

Here's how I'd do it, if it helps:
#include <iostream>
#include <string>

using namespace std;

string askText(const string &prompt);
int askNumber(const string &prompt);
void tellStory(const string &name, const string &noun, int number, const string &bodyPart, const string &verb);

int main() {
    cout << "Welcome to Mad Lib.\n\n";
    cout << "Answer the following questions to help create a new story.\n";
    tellStory(
		askText("a name"),
		askText("a plural noun"),
		askNumber("a number"),
		askText("a body part"),
		askText("a verb")
    );
    return 0;
}

string askText(const string &prompt) {
    string text;
    cout << "Please enter " << prompt << ": ";
    cin >> text; 
    return text;
}

int askNumber(const string &prompt) {
    int num;
    cout << "Please enter " << prompt << ": ";
    cin >> num;
    return num;
}

void tellStory(const string &name, const string &noun, int number, const string &bodyPart, const string &verb) {
    cout << "\nHere's your story:\n";
    cout << "The famous explorer ";
    cout << name;
    cout << " had nearly given up a life-long quest to find\n";
    cout << "The Lost City of ";
    cout << noun;
    cout << " when one day, the ";
    cout << noun;
    cout << " found the explorer.\n";
    cout << "Surrounded by ";
    cout << number;
    cout << " " << noun;
    cout << ", a tear came to ";
    cout << name << "'s ";
    cout << bodyPart << ".\n";
    cout << "After all this time, the quest was finally over. ";
    cout << "And then, the ";
    cout << noun << "\n";
    cout << "promptly devoured ";
    cout << name << ". ";
    cout << "The moral of the story? Be careful what you ";
    cout << verb;
    cout << " for.";
}



Was This Post Helpful? 0
  • +
  • -

Page 1 of 1