SPA4321 Introduction to C++ 2015-16 Functions In this document you’ll learn about how to use functions to wrap up sets of instructions and parameterise them so they can be used in more than one location in you program. Function Basics Functions are collections of instructions that you can write once, and then use elsewhere in your program. Here is an example of a simple function to add two numbers together: In some simple cases a function can be thought of as being a little like a formula in maths – we often even use the same language: 𝑓(𝑎, 𝑏) = 𝑎 + 𝑏 Is a function of a and b that evaluates to the sum of the two parameters. A function is comprised of four parts: the return type, the name, the parameter list, and the body. Return type: The return type lets the compiler know what the type of the result of calling the function is going to be. This should be a valid type or the keyword void if you don’t want to get any result from calling the function. In this case the return type is float. That means that somewhere in the function must be a return statement with a value, and the value must have type float (or something that converts to a float). 1 SPA4321 Introduction to C++ 2015-16 Function Name: Every function should have name. This name is how you refer to the function elsewhere in your code – in a similar way to defining a new variable. The name of this function is myFunc. Function parameters: The parameter list is contained inside the brackets and consists of a comma separated list of typename pairs. Each parameter is listed first with its type and then its name. The name that you put here is only defined within the function and is what you use to refer to the parameter within the function body. The function parameters are defined as if they were in the scope of the function – that is – they are local to the function scope, can’t be seen outside of it and will disappear once the function reaches the end. In this case there are two parameters – both have type float. The first is called parameter1 and the second is called parameter2. Function Body: Following this you see the body of the function – enclosed in a scope. The function body consists of the instructions that belong to the function – the actions that should be carried out when the function is executed. This example contains two instructions – the first takes the two function parameters, adds them together and stored the result in a new variable called x, with type float. The second instruction indicates what to return as the value of the function, in this case, the contents of x. The return keyword is used to indicate to the compiler what the result of the function should be. In principle all functions that have a return type other than void need a return statement. In practise the compiler will let you get away with forgetting the return statement and just give you a warning. But in general your code won’t work properly. This is quite a common mistake so it is important to always check for warnings in CLion. Function signature: The function name plus the list of parameters and their types define what is called the signature of the function (note the return type is not part of the signature). When you call a function, when you try to run through its instructions, the compiler figures out which function you meant by comparing the signature used in the call with the list of functions it knows about and calls the one that matches the best. In C++ you can define functions with the same name – so long as the signature is different. This will be covered in more detail later in the course. 2 SPA4321 Introduction to C++ 2015-16 Calling a function: Execution or Invocation To execute a function – that is to run the instructions inside it - you need use its name together with brackets as follows: Here two floats are created, a and b, and initialised with values 10 and 20 respectively. Then in the third line the function is called, passing the values of a and b as parameters. The execution of the program then jumps to the function and runs through the instructions in the function until either it hits the curly bracket at the end of the function scope – or it reaches a return statement. At which point the flow passes back to the original code and continues on line-by-line in the usual way. In this example, the value returned by the function is stored in a new variable, value. Function Parameters An important feature of functions is that the parameters – also called arguments – are passed-byvalue. What that means is that the variables inside the function get a copy of the value that the function was called with – they are not attached in any way to the original variables. In the example above parameter1 is a copy of a, so changes made to parameter1 inside the function have no effect on a whatsoever, likewise for parameter2. The parameters are matched up purely by the order in which they appear in the function call and function definition – the names don’t have to match up between the definition and the function call. Pass-by-value is an important feature as it allows you to limit the side-effects of the operation of the function – it can’t modify the original variables that are passed as parameters, only the copies that are made. This can dramatically simplify debugging a broken program and save a lot of time. Default Arguments When you define your function, you can also provide default values for the arguments: In this slight modification of the previous example, a default value has been added for the second argument. What this means, is that if you call this function but only provide one parameter, its value will be copied to parameter1 and parameter2 will be set to 0. Because C++ uses the ordering of the parameters to match up with the calling arguments once you provide a default argument for one parameter you must provide default values for all the parameters that come after it in the list. For example the following code is illegal: 3 SPA4321 Introduction to C++ 2015-16 But this would be fine: One final note on this topic: if you have split your function into a declaration and a definition as described below – and this is almost always what you will want to do – then you need to put the default arguments in the declaration and do not put them in the definition. Return values Just as the parameters are passed by value, ie are copied, so too is the return value. This is important to remember since in this example, the variable x is local to the function scope – just like any other scope. That means that once the flow of the program reaches the end of the function scope the variable is destroyed. This will be particularly important when we look at a feature of C++ called references. The return value you pass, must match the return type you specified in the function definition – or at least have an implicit conversion to that type. Likewise, when assigning the return value to something: The type needs to match the return type (or an implicit conversion between the types must exist), or your code won’t compile. You might have noticed already that you get warnings from the compiler when using some of the maths functions and storing the result in a float – since most of the maths functions return values with type double. In this case storing the result in an integer will work – because a conversion exists from a float to an integer (though it might not be what you want), but storing it in a string won’t work, because there is no conversion float to string. One final thing to note is that you are not obliged to use the return value of your function. You can happily just write code like: This will execute the function, and throw away the return value. It isn’t very useful in this case, but in some instances the function might have side effects beyond simply returning a value. 4 SPA4321 Introduction to C++ 2015-16 If you don’t want your function to return a value you can declare so with a special keyword: void This function outputs the parameter to the console. It doesn’t really need a return value, so you can put void as the return type to indicate it doesn’t return anything. Declaring and Defining a function Before you can use a function in a source code file, the compiler has to already know what the name of the function means before it gets to the line where you call it. One way to do this is just to define the function before your main function: The bit where you list the actual instructions that belong to the function is called the definition. If you put it after int main in the file – it won’t work – the name myfunc has to be defined before the compiler gets to the line where you use it. Also, note, you are not allowed to define functions inside of other functions. All functions must be defined outside any other block of code- though they can be defined inside a namespace. Now for various reasons you might not want to put the function in front of int main, maybe you want it in a different file. In this case you mustn’t define it again in your main.cpp – since C++ only allows you to define a function once. So instead to tell the compiler what the name means – without defining the full set of instructions – you need a declaration. A declaration looks like the first line of the function definition – missing the curly brackets and with a semi-colon: 5 SPA4321 Introduction to C++ 2015-16 The first line of the previous example shows the function declaration. I’ve moved the function definition to the end. This version will work – if you remove the declaration it will break – even though the definition is in the same file. You can declare the function as many times as you like – but you can only define it once per program. You needn’t put it at the end of main.cpp, you could put things in different files. In this example, the main function stays in main.cpp, but the function definition has been moved to myfunc.cpp and the function declaration is now in a header file myfunc.hpp. Then to make sure the compiler sees the function declaration when it compiles main.cpp a line is added - #include “myfunc.hpp”. Note, in this case double quotes are used instead of < >. This tells the compiler that this is a user header file rather than a system header file. The difference between the two is just in the order in which the compiler looks into different folders to find the header file – in the case of < > it looks in system folders first, then user folders. In the case of “ “ it looks in the user folders first, and then the system folders. In each case it uses the first file it finds that matches the given filename. For this course, it won’t make a great deal of difference but it is important to be aware of this and get used to following the convention. main.cpp myfunc.hpp myfunc.cpp 6 SPA4321 Introduction to C++ 2015-16 Another thing you should notice is the use of include guards in the header file. The three lines beginning with # in myfunc.hpp indicate some instruction to the pre-processor that we discussed in the C++Introduction. The first line actually comes as a pair of lines: and This basically tells the pre-processor to only include the lines between these two statements if the symbol: MYFUNC_HPP_ has not already been defined. The second line: Defines the symbol MYFUNC_HPP_, it doesn’t give it any particular value – just creates it. Thus this file can only be #included once. This gets important when you have header files that do more than just declarations where including it twice might have other side-effects. This is particularly important when you have header files including other header files – you could end up accidentally including one twice or even set up an infinite loop of inclusions! A very common mistake is to forget these header guards, luckily if you create the file with Clion as a header file, it will automatically create them for you. In this example, the definition of myfunc has been moved to another file – this might be useful if you wanted to use the file in another project as well. Furthermore, this highlights the fact that the compiler doesn’t need to see the function definition to compile main.cpp. So long as it has the declaration, you have basically promised that the definition will exist somewhere, and will get compiled in another file (or exist already in a library). The eventual connection of the name to the actual set of instructions will be handled by the linker in the last step of the build process when it constructs the program. If the definition of the function isn’t found in another object file or in any of the libraries – the build will fail with an unresolved symbol error. 7 SPA4321 Introduction to C++ 2015-16 Exercises These exercises are not assessed but completing them will help you get to grips with functions. Exercise 1 : Functions1 Create a new project called Functions1 Commit and push your project to GitLab Write a new function in main.cpp: o Return type: float o Function name: add o Parameters: two floating point numbers, a and b o Function body: Your function should add together the two parameters a and b and return the result. (ie use the return statement) Now in your main function write the following code: o Read two floating point numbers from the console and store them in two variables called x and y. o Call your function with x and y as the parameters and store the return value (ie the result) in another floating point variable called z o Print z to the console Commit and push your code to GitLab 8 SPA4321 Introduction to C++ 2015-16 Exercise 2 : Functions2 Create a new project called Functions2 Create a new source code file called functions.cpp o You can do this by right-clicking on your project and selecting “New” and then “New C/C++ Source file” o You should see a window like this pop-up o Make sure the “Create associated header” and “Add to targets” boxes are ticked, then click OK. o It will then ask if you want to add the file to Git – click yes. Though if you click No you can add the files in the usual way by right-clicking on the project and selecting Git->Add You should now have two new files in your project: functions.hpp and functions.cpp o In functions.cpp write the definition (ie the bit that contains the function instructions) for a function that does the following: Return type: void Name: fizzBuzz Parameters: one integer called number Function body: Print the parameter to the console If the parameter is divisible by 3 print the word “fizz” to the console – one the same line as the number If the parameter is divisible by 5 print the word “buzz” to the console – on the same line as the number If the parameter is divisible by 3 and 5 print “fizz buzz” to the console – on the same line as the number This function has return type void so it doesn’t need a return statement o In main.cpp write code to do the following: Add in the appropriate place #include “functions.h” In the main function write code to do the following: Using a for loop, loop over the integers from 1 to 50 and for each integer call your function with the number as the parameter. 9
© Copyright 2026 Paperzz