Sign in to follow this  
madk

Passing a string to a function

Recommended Posts

Quick question - Just curious as to how I would go about passing a string to a function and also returning a string from a function. The book I am using is slightly outdated and doesn't cover strings. (planning on getting a new reference book soon) Thank you, Matt

Share this post


Link to post
Share on other sites
Quote:
Original post by madk
Quote:
Original post by LorenTapia
what language are you using ?


Guess that would be crucial. ;)

C++


#include <string>

void functionThatTakesAString( const std::string &str )
{
// use str
}

std::string functionThatReturnsAString()
{
return "42";
}



If you don't pass a reference to the function, you could end up copying the string ( which isn't usually what you want, and could be expensive if the string was large ).

Share this post


Link to post
Share on other sites
The & symbol tells you that the variable is a reference. This way only the location (in memory) of the original string is copied (and not the complete string). The const keyword tells you that you can't modify the variable.
So if you would have wanted to modify the var in that function, you should remove the const keyword.

functionThatTakesAString( const std::string &str )
functionThatTakesAString( const std::string str )
functionThatTakesAString( std::string &str )
functionThatTakesAString( std::string str )

These are all valid :)

Share this post


Link to post
Share on other sites
Quote:
Original post by madk
Quote:

const std::string &str


Could you please explain exactly what this means and why you have to use it like this?

Thanks for the help so far!


Well, there are 2 parts which you may not understand, so I'll try explain both.

The "&" in the function signature marks the parameter as a reference. A reference is like a pointer in many ways, it refers indirectly to an object that exists elsewhere. References are a lot nicer than pointers though, they can never be NULL and you can't accientally treat them like an array.

A simple example of a non-const reference:

// this functionhas no side effects
void foo( int i )
{
i = 37;
}

// this function sets its parameter to 42
void bar( int &j )
{
j = 42;
}

void bar()
{
int x = 0;

foo(x);
std::cout << x << std::endl; // prints 0
bar(x)
std::cout << x << std::endl; // prints 42!
}




The const is fairly simple, it prevents you from modifying the string accidentally. A const object can only be read from*. This means that you cannot assign to any of its public member variables. Also, only member functions marked const can be called. For example, the length of the string can be obtained from calling the function "std::string::length() const" on the string.

A simple example, using ints, shows the compiler stopping us from modifying the value:

// compare with below
void foo( int &i )
{
i = 63;
}

// we would normally pass primitives by value, like foo()
// but for the sake of demonstration
void bar( const int &j )
{
// if we tried j = 58 here the compiler would complain
}




An example featuring std::string:

// this example returns an uppercase version of the string
// note if we accidentally tried to modify "str"
// the compiler would complain
std::string foo( const std::string &str )
{
std::string returnValue;
for( int i = 0 ; i < str.size() ; ++i )
{
returnValue += toupper( str[i] );
}
return returnValue;
}

// this function modifies the string to uppercase
void bar( std::string &str )
{
for( int i = 0 ; i < str.size() ; ++i )
{
str[i] = touppper( str[i] );
}
}




* Strictly speaking that isn't true, due to the mutable keyword and const_cast, but most sane people don't use them.

Share this post


Link to post
Share on other sites
string AddGibberish(string s)
{
return s+"kjhagkhdfgkhldfhgk";
}

You pass strings by value, just like anything else. You can pass them by const reference which in most cases is more efficient. However that is a bad idea, as elegance is 15x more important than performance. Always make your code elegant first. Elegant code is more likely to be correct. Obscuring your code for a maginal performance boost (if any, as there is an additional dereference per string operation, the sum of which may end up costing more than the copy) is the wrong move until piles of money are on the line.

Share this post


Link to post
Share on other sites
Wow! Thank you so much for the detailed answer! So just to make sure I understand:

functionThatTakesAString( const std::string &str )
- pass just the location and making it a const so it can't be modified

functionThatTakesAString( const std::string str )
- pass the actual string as const so it can't be modified which would probably eat up to much memory if the string is large

functionThatTakesAString( std::string &str )
- pass just the location and allow it to be modified

functionThatTakesAString( std::string str )
- pass the actual string and allow it to be modified but will also possible take up too much memory

Is my understanding correct?

Share this post


Link to post
Share on other sites
Quote:
Original post by madk
Wow! Thank you so much for the detailed answer! So just to make sure I understand:

functionThatTakesAString( const std::string &str )
- pass just the location and making it a const so it can't be modified

functionThatTakesAString( const std::string str )
- pass the actual string as const so it can't be modified which would probably eat up to much memory if the string is large

functionThatTakesAString( std::string &str )
- pass just the location and allow it to be modified

functionThatTakesAString( std::string str )
- pass the actual string and allow it to be modified but will also possible take up too much memory

Is my understanding correct?


Perhaps, but it depends what you mean by modified. If you pass a normal string to a function (ie functionThatTakesAString( std::string str ) ), then the function creates a copy of the string inside the function. The function can modify the copy of the string, but the original passed string will remain unmodified. Creating copies requires overhead. That's why passing by reference is preferred when speed is an issue (a copy is not created, just the address of the passed item). I'm not too sure you should worry about running out of memory with strings because each char element inside it is only 1 byte large.

Share this post


Link to post
Share on other sites
Quote:

functionThatTakesAString( std::string str )
- pass the actual string and allow it to be modified but will also possible take up too much memory


Yes, provided you understand that any modifications will be on the copy of the string, and not the original. The calling code will not see any changes.

Its not so much the memory ( which could be an issue ), its just most functions dont modify the strings the receive and the copy is not realy required.

Quote:

You pass strings by value, just like anything else. You can pass them by const reference which in most cases is more efficient. However that is a bad idea, as elegance is 15x more important than performance. Always make your code elegant first. Elegant code is more likely to be correct. Obscuring your code for a maginal performance boost (if any, as there is an additional dereference per string operation, the sum of which may end up costing more than the copy) is the wrong move until piles of money are on the line.


I would argue that in c++ it is idiomatic to pass non POD objects by reference or const reference. A const reference is just as elegant as a copy, with slightly more typing at the point of declaration.

This is not a particularly low level optimisation, nor is it one that makes the code significantly harder to understand (IMO).

Most high level languages use pass-a-reference-by-value for parameters, which I like. I also like combining this with "const".

Of course, your mileage may vary. [smile]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this