Passing a string to a function

Started by
9 comments, last by rip-off 17 years ago
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
Advertisement
what language are you using ?
=Loren Tapia=
Quote:Original post by LorenTapia
what language are you using ?


Guess that would be crucial. ;)

C++

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 ).
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!
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 :)
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 effectsvoid foo( int i ){     i = 37;}// this function sets its parameter to 42void 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 belowvoid foo( int &i ){   i = 63;}// we would normally pass primitives by value, like foo()// but for the sake of demonstrationvoid 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 complainstd::string foo( const std::string &str ){    std::string returnValue;    for( int i = 0 ; i < str.size() ; ++i )    {        returnValue += toupper( str );    }    return returnValue;}// this function modifies the string to uppercasevoid bar( std::string &str ){    for( int i = 0 ; i < str.size() ; ++i )    {        str = touppper( str );    }}


* Strictly speaking that isn't true, due to the mutable keyword and const_cast, but most sane people don't use them.
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.
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?
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.

This topic is closed to new replies.

Advertisement