# C++ Workshop - Functions, Parameters, & Scope (Ch. 5)

This topic is 3271 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Chapter 5 – Organizing into Functions

Introduction Good morning all! This week we will be covering chapter 5, which is approximately 30 pages, not counting the review stuff at the end of the chapter. The topic for this week is functions. In a way, this week will explore the basis of the early procedural languages such as C. We'll take blocks of code which may need to be executed repeatedly and we'll move it out into functions. Additionally, we'll now be able to take overly complex ideas and break them up into smaller chunks of thought, and then separate them into their own procedures. Finally, when combined with previous weeks we can use functions as handy containers for expressions that take in input, perform calculations, and return an output, thus allowing us to make a library of more complicated mathematical functions. Functions by themselves are not a difficult concept, but the implementation of functions within a programming language does provide subtle complexity that is important to understand. Some of those include arguments, the difference between function definitions and declarations, scoping of variables, function overloading, inline functions, and recursion. Many of these topics do not even become relevant until we introduce the concept of functions or procedures. Roughly half way through the week myself, tutors, or anyone else simply wishing to challenge their teammates learning C++ can post review and quiz questions in this thread. Please do not post the answers in this thread however, as a new thread will be created for that purpose. Outline of the Reading
1. What is a function?
2. Return Values, Parameters, and Arguments
3. Declaring and Defining functions
4. Execution of Functions
5. Determining Variable Scope
6. Parameters Are Local Variables
7. Considerations for Creating Function Statements
8. More About Function Arguments
9. More About Return Values
10. Default Parameters
12. Special Topics About Functions
13. How Functions Work - A Peek Under the Hood

## Good Luck!

[Edited by - jwalsh on May 30, 2007 5:30:48 PM]

##### Share on other sites
Why is this posted in "For beginners"? Any particular reason, or just forgetfulness?

##### Share on other sites
Quote:
 Original post by DivineGodWhy is this posted in "For beginners"? Any particular reason, or just forgetfulness?

It's posted in For Beginners for easy access by those who need it most. Each week we post a new chapter thread which is mirrored in FB and the C++ Workshop. Previous chapter threads are then removed from FB and archived in the C++ Workshop Forum. I'm just waiting for Fruny to swap out the stickied thread.

Had you read the first paragraph of the post, you would have known that. [wink]

Cheers!

##### Share on other sites
Oh.. sorry 'bout that, then.

Suppose I read too fast to notice everything in the first place.

##### Share on other sites
A comment and a question about Listing 5.5.

I've found a couple of mistakes: a typo in line 7 and there should be <using std::endl;> in line 21.

I know that a function can be used to do something (such as "void myFunction();") or it may be used to return a value (such as "int myFunction (int a, int b);") and, in this case, there should be a "return x;" at the end of the function prior to going back to the main code. Is it possible to return two values from the function back to the main code? For instance, if (in line 23), there's an assignment setting x to be 23, can both x (23) and y (10) be returned to main so that these values are printed in lines 13 and 14?

I know that it would be possible to call a function twice, returning x (23) and y (10) separately, but is it possible to return both values from one execution of the function?

##### Share on other sites
Quote:
 Original post by CondorManA comment and a question about Listing 5.5.I've found a couple of mistakes: a typo in line 7 and there should be in line 21.I know that a function can be used to do something (such as "void myFunction();") or it may be used to return a value (such as "int myFunction (int a, int b);") and, in this case, there should be a "return x;" at the end of the function prior to going back to the main code. Is it possible to return two values from the function back to the main code? For instance, if (in line 23), there's an assignment setting x to be 23, can both x (23) and y (10) be returned to main so that these values are printed in lines 13 and 14?I know that it would be possible to call a function twice, returning x (23) and y (10) separately, but is it possible to return both values from one execution of the function?

You can't really return 2 values. The easiest way (and the most correct usually) would be to just call the function twice for each variable.

You can also pass variables to a function by reference to achieve this. Usually a variable is passed by value, meaning only the value of the variable s sent to the function, so if you modify the vaiable in the function, its value outside will not change. Example:

// Passing by value#include <iostream>void Increment(int value){    value++;}int main(){    int value = 5;    std::cout << "orginal value: " << value << std::endl;    increment(value);    std::cout << "value after function: " << value << std::endl;    return 0;}

Output would be:
original value: 5value after function: 5

To pass a value by reference, you use the '&' operator in the parameter list of the function.

// Passing by reference#include <iostream>// notice the '&' operatorvoid Increment(int & value){    value++;}int main(){    int value = 5;    std::cout << "orginal value: " << value << std::endl;    increment(value);    std::cout << "value after function: " << value << std::endl;    return 0;}

Output would be:
original value: 5value after function: 6

Passing by reference can be nice for some things and some types of items (such as file stream objects) must be passed by reference to work properly. I only use one variable, but you can easily have multiple parameters defined to be passed by reference.

##### Share on other sites
Thank you. I suspected the best way would be to call the function twice but just wondered if there was a way of doing it which fell into the "advanced" area.

The advanced comment about passing by reference is interesting. I noticed this when I flicked through the book so I look forward to getting my teeth into that.

##### Share on other sites
Quote:
 Original post by CondorManI know that it would be possible to call a function twice, returning x (23) and y (10) separately, but is it possible to return both values from one execution of the function?

Not in C++, but it's possible in other languages.

It's really not advanced if there's language support, but I'm going to talk about tuples. The word comes from a corruption, I believe, of "multiple," as that's exactly what a tuple is: a multiple-value value. The following is a Python example:

"""apply will apply (sorry) the function supplied as the parameter fn to each value in the tuple   t, collating the results into a tuple and returning it."""def apply(fn, t):  results = []           # create an empty list  for v in t:    results.append(fn(v))  return tuple(results)  # now convert the populated list into a tuple and return it"""mul2 multiplies its parameter by 2 and returns the result."""def mul2(n):  return 2 * n...# the following is a demonstration of the functions above as would occur from the # Python interactive command line>>> apply(mul2, (3, 4, 5, 6, 7))(6, 8, 10, 12, 14)

In fact, tuples are so inherent in Python that you can use them anywhere:
return 3, 4

The function apply is unnecessary because Python supplies map, which does exactly the same thing; apply was written for illustrative purposes. Similarly, mul2 is unnecessary and can be replaced with a lambda function... but we won't get into that today. [smile]

The point is, with built-in language support, tuples become extremely natural types to use, and they allow for some very elegant programming. That said, C++ classes can be written (and have been) support tuples, however they have limits on the number of elements they can store (typically about 10 for casual applications). They are written using templates to enable them handle any type, but unlike language-supported tuples (as in Python, where you can write return 4, "blah", SomeFunction), these C++ tuple implementations also have restrictions with regard to the types they can handle.

Of course, something should have popped out at you. A tuple is a sequence type, and it's very convenient, but C++ has a few other sequence types, like std::vector (admittedly, I doubt that has been introduced in your text yet). When you need to return several pieces of data, one option is to aggregate them into a container and return the container as a single object. If they are all of the same type, then you can return a std::vector. If they are of diverse types, but the operation is important enough, you can create a new data structure to hold the various fields, and then create an instance and populate that in your function, again returning a single value.

Hey, I said it was advanced! [smile] Don't worry too much about it now. Just know that, as time goes on, you'll be able to do far more complex things with C++ functions than the limitations you see now might suggest.

##### Share on other sites

(Hey, if the previous two posts are advanced, then I figure this qualifies as well.)

C++ does sort of support tuples natively, because you can make and return structures, but they have to have a specific size, and a type for each returned value. You cannot return an array, and returning a pointer is generally speaking a bad idea (what are you going to point it at? Keep in mind that the function's local variables are dead when the function returns; 'normal' returns only work because a copy is made, at least conceptually.)

If you are returning several values of the same type, (or, with a bit more effort, where all of them are objects with a common base class), you can return a container of those objects such as a std::vector of them.

Otherwise... if you are lazy ;) or if the structure won't be used anywhere else, you can rely on the standard library. If you only need two return values, you can return a std::pair. This is a templated structure that has two members, 'first' and 'second'.

// Sample implementation: this is what std::pair MIGHT look like in your// library implementation.namespace std {  template <typename T1, typename T2>  struct pair {    T1 first;    T2 second;  };  template <typename T1, typename T2>  std::pair<T1, T2> make_pair(const T1& x, const T2& y) {    std::pair<T1, T2> result;    result.first = x;    result.second = y;    return result;  }}

See, the standard library already gives an example of the technique ;) (The reason std::make_pair() exists is so that you don't have to specify the template types when you create a std::pair object. Functions are able to infer template types from their arguments, but class constructors can't.)

"Unfortunately" the standard library doesn't provide a generic structure for three or more items. You *could*, however, abuse std::pair to do it:

typedef std::pair<std::pair<int, int>, int> triple;triple giveMeThreeInts() {  return std::make_pair(std::make_pair(1, 2), 3);}int main() {  triple t = giveMeThreeInts();  int x = t.first.first;  int y = t.first.second;  int z = t.second;}

The Boost library, among others, provides a templated tuple class holding up to some particular number of items, which is (AFAIK) basically a wrapper for this technique.

<OPINION>

But you're probably better off declaring a struct in that case.

Anyway, there are many ways to handle "returning multiple things", but as always, just because you CAN do something doesn't mean you SHOULD. Whenever it looks like a multiple return is required, always think carefully about your approach, and try to at least keep things organized.

Personally I think it's a bad idea to use the return value as a "real" return value if you will also use an out-parameter (i.e. passing something by reference and modifying it). Go for all-or-nothing; sometimes you will decide to use the return value for an error code, instead.

Sometimes, taking the "return error code and modify reference parameters" approach is a good idea even for only one return value. This is especially the case if it helps out with template parameter inference ;) But usually, you'll want to throw an exception to indicate an error anyway. As well, a function that returns a value can be used to initialize a variable, whereas if you want a variable's initial value to come from a function that uses an out-parameter, then you have to declare the variable first and then call the function with the uninitialized variable. This is quite ugly.

Oh, and about the vector returns: Some people will tell you never to return a standard library container, but instead always use out-parameters for them. This is an optimization technique (which already marks it as evil ;) ), and assumes that the calling code might already have a vector instance handy, into which the called code will dump its stuff. However, this complicates the interface, firstly because the calling code might have to declare a local vector that it wouldn't have anyway, and secondly because you have to decide whether the called code will clear out any existing items, blindly trust that there are none, or deliberately assume there may be some and append to the existing set. Plus, it's quite likely not to help in terms of optimization anyway. :)

</OPINION>

##### Share on other sites
Heya all,

I just wanted to post a quick, friendly reminder that we're in chapter 5 of the book, and have not yet covered pointers, templates, or classes. Just be mindful of the readers. [smile]

When you post an "advanced" section, it should be a more detailed discussion of the information currently being covered, and should try not to bring in concepts which have yet to be introduced. If your "advanced" post requires significant info about features we've not yet covered its a good indication the post is premature and should be saved for later.

Sorry for the interruption. Please continue. [wink]

Cheers!

1. 1
2. 2
3. 3
4. 4
frob
12
5. 5

• 16
• 13
• 20
• 12
• 19
• ### Forum Statistics

• Total Topics
632172
• Total Posts
3004561

×