[MUSIC] This lecture will talk about the use of functions in C. A very important concept. It's basically a way of encapsulating a bunch of instructions and giving them a name so you can refer to them again and again. So, we'll talk about functions, and we're gonna need these for Arduino too. They're well used functions. They're very useful. Okay, so a function, like I say, a function is a way of encapsulating a group of instructions. That's the main thing it's for. So, if we look at the top, we got two examples of code. The top, we got a main, and it executes these instructions. It has three variables, x y z. And it assigns Y equal to two, Z equal to three. It performs some operations Y equals Y plus Z, X equals Y, so on and it prints X. So fine. Simple. Three real instructions plus the definition of variables and then below that we have another example. A program that does the same thing as the top main. Okay? The program down below you got this new function called Foo. So there's a main there. If you look at the main down near the bottom you see this main. But it doesn't have the code that we just had. It changed it. All it does is it says foo, open paren closed paren. And then looking above it you see we've defined this function called foo. Void foo. And that function called foo does everything that the main did before. In fact it has basically the same code that the main had. We took that same code, we put it into this foo. Now what happens is, so we've defined that into foo. So we've given a name to those instructions. And every time we wanna execute that sequence of instructions we just call foo. So we see where it says function call. We just give the name foo, open paren, closed paren to let it know it's a function. And then you call it and that set of instructions happens. So the two programs you have up top. The one you have up top, the main. Where the one you have in the bottom, the foo. With the main, those two do exactly the same thing. The only difference is that the instructions in the top version, the instructions that do the work, are in the main directly, and in the bottom, the instructions are in this function foo. And then that function foo is called from the main. But they do exactly the same thing. Now, you might ask, what's the benefit of this, right? Right off the bat, one benefit is if these operations that foo is doing, these set of instructions, if these are something that's done over and over and over again, many times in your code, rather than copying it over and over and over again into your main, it is much more convenient to write a function that does those instructions. And then every time you just call that function. So now notice in my main, when I wanted to execute those instructions I just called foo. foo(), and it executed those instructions. Say foo is something I did 100 times in my code, right? Rather than writing all those instructions over and over again a hundred times, I just call foo a hundred times. So it just reduces space right there, it makes the code simpler and easier to understand. Another thing that I did not cover, that I didn't mention here, which is important though, is that the naming of the functions is very important. Now I'm calling it foo, which means nothing, but when you write these function, you wanna give them names that have meaning. Right? So for instance maybe foo was performing fibinocci or something, doing some kind of exotic calculation, say it was taking a derivative. You wouldn't call it foo, you would call it derivative. And then just looking at the name you can say oh, it's called derivative it must be taking a derivative and you wouldn't have to think, as a program, you wouldn't have to think of what goes on when taking a derivative You just, no look I call this function derivative and derivative is taken, right? And this is much like the advantage that you get from using libraries in arduino, right? We showed this last module, where we're talking about the ethernet controller. And there was connect function, and this connect function, you're a programmer you don't have to know all the details of how connecting happens. You just call connect and connecting happens. Same thing here. If you give a good name. So it's important that the name shouldn't be something generic like foo but it's an actual name that has meaning like connect. Connect is clear. I'm talking about connecting on the Internet, right? An ethernet controller, right? So you give it a meaningful name and it can help make the code easier to understand. So that's basically what a function is. You are grouping a bunch of instructions and giving them a name so you can reuse them. You can call them over and over again, and it's sort of a shorthand. The name is now a shorthand for that sequence of instructions. So that's what a function is. Now, there are more aspects to it, and we will talk about that now. Notice that you have to define a function before you can use it. So if you look in the bottom here we've got, sorry, if you look in the bottom here we've got this function foo defined then we call foo, right? So you've gotta define the function and then call it. Functions can take arguments. So data can be passed to a function. Now if you look at the example on the left, that's what we had in the last slide. And in that case you're calling foo, and when you call foo it executes the instructions in foo. But it doesn't pass any data to foo. There's no data to pass to foo. Foo has all of its data internally, as int x, int y, int z. Y is equal to two, z equals to three, so all the data it needs is inside foo. It doesn't need data. But if we look on the right, we've changed the definition of the function. So, take a look at, let's look at the main first. In the main, where we call foo, in parentheses you say foo(2, 3). In parentheses. Where on the left there's nothing in parentheses. Now we're passing it to number 2 and number 3. Now, why are we doing that? What we're doing is, if you look at foo's definition now when you define foo it's says void foo and then in parentheses it says int a comma int b. So that's telling you foo is gonna take two arguments. Ons is gonna be called A. One is gonna be called B. So when you make the call in the main where you say foo two comma three A equals 2. A is assigned to 2, and b is assigned to 3. And then foo is executed. And if you look at this, even though I've been changing names to a and b. This foo does exactly what the previous foo did. The foo on the right does exactly what the foo on the left does. Except the foo on the right takes variables a and b, and treats them just like the foo on the left treated y and z. Okay. So by calling the foo with 2, 3. 2 and 3 get bound to a and b and then it executes and it does exactly the same as the foo on left. So these two functions the one on the right and the one on the left, they do exactly the same thing except the foo on the right takes two arguments. Now you might say what's the benefit of this? Well one benefit right off the bat is that now this foo function is much more generic meaning the foo on the, on the left that foo it takes no argument so all it can fo is treat y=2 and z=3, but now with our new foo, we can change y and z if we want to. We can say, oh, let's call foo (2, 3), or maybe we'll call it (1, 2), and it does the same operation with different numbers. So there are many cases where you have a function where you wanna do the same thing with different numbers. Take, for instance, average, right? You wanna average a couple pair of numbers. You could make a function, average, which averages exactly two numbers, or you could make a function, average, which takes two arguments and averages whichever arguments you pass. And that makes the average function a heck of a lot more useful because now you can call it with whatever arguments you want. You can use it in a more generic way in other contexts. So functions can be passed arguments like that, so you're passing this data to the function and the function uses that data in performing whatever its operations are. And you have to declare it so the way you deal with arguments is. In the function call you put the arguments between the parentheses. In the function definition, you have to list the arguments and their types after the name of the function. So up there we say foo int a comma int b. Int a and int b have to be in parentheses and int declares what type those arguments are, int a int b. You have to put that in parentheses after the word foo, after the name of the function. When you're doing the function definition in order to take arguments. All right, in addition to taking arguments, a function can return values. Now, if we look at the foo on the left, that function doesn't return any values. It just does it's job and it prints something and that's the end of that. No need for returning values. Now, if we look at the foo on the right, though, this one. Actually, let's look at how the structure of the main is changed first. We look at the main. It calls foo still, but notice that now we've declared this new variable, p, I've called it. And I say p equals foo. Now, notice that on the left, I didn't say anything equals foo, I just called foo. But now on the right, I'm saying p equals foo. That's because the foo I'm defining on the right it's gonna return a value and I want to assign p equal to whatever value the foo returns. And then on the next line inside the main, I say print p. I print p. So if you look at the foo on the left, it includes the printf, but the foo on the right does not have a printf. Okay? Instead, I've taken the printf and put it into the main, but in order for the main to do the printing, it has to know what it's gonna print. So foo computes the values it's gonna print, but foo doesn't do the printing. Foo returns that value. So if we look at the foo definition, It has the same top two lines, y=y+z; x=y. But then the last line, instead of saying print, instead of actually doing the print, it returns x. So the result, the thing that should be printed, is not printed, it is returned. Then the caller, which is main, gets that back. So when that line where it says p = foo, whatever foo returned, the x value, p gets set to that value, and then the main prints out the p. So, this is another thing that's very useful about functions. Have a function return a value, because then the function can do some job that you needed to do, and give you a useful result in the end, okay? So, sometimes functions do have return values. Sometimes they don't. It depends on the type of function. We'll get more into that when we talk about Arduino specific problems. But, so functions can take arguments and they can also return values. Thank you. [MUSIC]