Welcome back to 105. Thank you for joining me today. So didn't see any questions on the discord or anything like that. Could either be a really good sign or a really bad sign. Just in case, we will go ahead and leapfrog the other sections a little bit and move on to the next topic so you can start the next lab and also get some more questions going. So this will have some familiarities with the last lecture, but we won't tie them together until the next one. So we kind of need another piece of our programming puzzle. So we have loops for repetition. So they help us, you know, not repeat each other. Like I said, if I have to count all the way up to seven, that's too much for me and I can't do it anymore. So we have loops for going ahead and doing the same operation over and over again. But what about if we have multiple variables? Loops can't really help us. So like what if we want to take, I don't know, the average of a bunch of grades? So let's say we do something like this. So if I want to take the average of five grades, what we know so far is, well, I have to declare variable for each grade. And then I have to initialize it to whatever their grade is. And then to calculate the average, well, I have to do grade one plus grade two plus grade three plus grade four plus grade five all divided by five to calculate the average. So that will work and our average would be 78. But that kind of sucks, right? If I want to add another grade, what do I have to do? I have to declare another variable grade. So let's see, let's say I got 2%. So doing good. And then I have to remember to go ahead and I have to change this. So I have to add it here. Then I have to remember to divide by six. And that's just a whole mess. We want to be real programmers. We want to be lazy.  We want to just be able to add a new value and just have it calculated for us, right? We want to be lazy.  So here's what we had before. So calculating the average of five grades, five individual variables we have to declare, have to do our average calculation, print out the average. And every time we want to add a new grade, that means we have to add a new variable. That means we have to add it to the average calculation. We have to change the divisor. Kind of a mess, but this is all familiar to us, right? We all know how to do this. All right, at least one thumbs up. So error prone, we don't want to have to remember to do lots of things if we were just adding a single value. So that's where arrays come in. So they're for groups of related values. So we can declare a number of integers all at once. So at first this won't seem that useful, but bear with me. So the syntax for declaring arrays looks like a normal variable declaration. So type followed by a name, except there's these weird square brackets. So it's squared brackets and then an array size. And that array size is going to be how many numbers of this type are we going to declare all at once? So the type, that is the type for each value or element of the array is what we call individual values specifically in an array. Then we have to give the array a name and it will be representing a group of number. So you should probably call it whatever that group is. And then the array size, which is just going to be an integer, which is the number of values you actually want to create all at once. And then if we declare them all, we just have a big group of numbers. We want to be able to access each number individually. So how we access each number is in an expression. We can just use square brackets. So after you've declared an array in an expression, you just access it by using the array name and then the square brackets with an index. Looks a bit weird right now, but what you replace is the array name by whatever name you declared the array as and the index by the element you would like to select and you give that an integer. So you might think that, okay, well, we're human. So I might want to say, you know, element one, element two, three, four, five. Well, turns out for reasons we will get into in the next lecture. C starts counting at zero, not one, because it turns out, we'll discover later. Counting starting from zero, it's just way more convenient for computers. Basically every single programming language does this except for like really weird ones. So what we call this is we say arrays are zero indexed. That means they start at zero. So that means if I made an array called a, well array or a square bracket zero, that is the first element. And if I have a square bracket one, that's actually the second element, so on and so forth. So it's a bit off by one from how we like talking about them as humans. But as you start getting used to computers, this will become kind of second nature to you and we should get used to it now. So let us go back to this example and use an array instead. So here I have a group of related values. So I might say they're called in grades and say I have five of them. So I can declare an array like this. So this will declare five integers and that group of integers collectively is called grades. So now I can get rid of all of these declarations for the grades and now refer to them by their indexes. So grade one, well since it is an array and it's zero indexed, the first element of the array would be at index zero. And then I've index one, index two, index three, index four and it's called not grade anymore. Whoops, it is called grades. So now I don't have to declare five individual ints. I declare them all at once here and then I go ahead and I set them accordingly after that step. So now I would have to fix this as well.  So now if I compile and run that, I'm in the same situation I'm in before but I'm setting myself up for being able to get rid of this repetition. So any questions about just declaring the arrays or declaring an array and then setting all the values? Not too bad. So again, just so you have it, here's that same code using arrays. So now I can look at that calculation and I can look and try and not have to repeat the word grades over and over again. So if we look at that equation, is there a way to do that calculation without having to write grades zero, one, two, three, four, yep, not quite. Or not an easy way. So those numbers, do we know how to count up, like have an int that goes one, two, three, four, five? Yeah, yeah, it looks like a for loop, right? So well, instead of going ahead and accessing each grade individually, I will go ahead and do a for loop. So how would I, what bounds would I need if I want to, let's say declare an int called index, I'll start it at zero. And if I want it to go all the way up to four, what should my condition be? Yeah, yeah, index. I could do index less than five for my condition, right? So this will be true for zero, one, two, three, four. And then whenever we get five, then that is false and then we won't repeat ourselves. So that's right because well, we don't want to access five for reasons we'll get into later.  So this should get rid of all the grades. So instead of writing grades and then a number, I can just do grades zero. And I'm just kind of summing up all the values. So I could just create a variable that keeps track of the current running total or the current sum. So let's create a variable called sum and well, I want to start it off at zero just so I don't calculate this wrong. So I'll just initialize it for zero and then each time through the loop, I will do sum equals sum plus grades index, right? So each time through the loop, I'm going to just add whatever the current grade is to the sum and then just calculate the sum by the end of the for loop. And I could also write this if I want, just on style that I like a little better, I could do sum plus equals grades. Means the same thing. So here instead of this average, I can just get rid of this whole thing because I've calculated the sum and it should look like that. So now if I compile and run that, I get the same answer, but I don't repeat myself as much, right? So any questions about that? Still a bit unsatisfying because well, if I have to add another grade, right? What do I have to do? So if I want to add another grade, let's say I want to add grades five, say let's say it's one of the students in this class, so it's definitely a hundred. So can I just add another grade and it'll just work? No, what are the things I need to change here? Someone new, yeah. Change the size of the for loop, yeah. So I have to change this to six, uh-huh. Is that the only change? Yeah, the which one? Yeah, I have to do this average calculation to six. Is there one more? Yeah, the grades index, this, this, right? So this isn't, is not an index, it's the size of the array. So if we're using it as like accessing the array, not declaring it, it's an index. If we're declaring it, it's the size of the array. But yes, we do have to change that one. So yeah, so now do I have to change everything around? I good. All right, got a thumbs up. But still a little bit unsatisfying, right? I need to add a grade. I still have to add a line and then I have to remember to change. Actually I made it a bit worse because before I had to remember to change two things. Now I have to remember to change three things. So like I said before, it gets worse before it gets better. So let's, all we really did so far was just get rid of having to write it out, like adding each new term to the sum each time through the loop. Also, as a little bit of a review or a test of your knowledge. So I can take like the sum of everything and then here, I'll make that a bit bigger. I can take the sum of everything and divide by five. Could I also do that? Instead of taking the sum of everything and divide by five, I'll just take the current grade and divide it by five each time I add it to it. And then that's all I have to do. I'll give you a minute to think about that one. Sure we can. Yeah, we can. All right. Anyone from the middle? Is this a good idea? Oh, we got some shaking head. Anyone want to be brave enough to explain why this is a good or bad idea? Yeah. Yeah, so remember if I'm, these are all integers. So I'm doing integer division, which is also called truncated division. So each time I do a division, I might truncate it. So like say some extreme case where all the grades were say four and it was not this section, but another section. Well four divided by five in integer division is just zero. And then it would be zero plus zero plus zero plus zero and the average would be zero when you would expect four.  And we can see even for this little example, so our average is 78, which would be okay. And now if we just move the division, well because of integer division, we're doing five integer divisions instead of just one. Well, we stray further and further away from the actual answer, so we get 76 now. So hopefully we are smarter than this when we calculate the course averages for this course. Otherwise, probably going to be lower than we expect. All right, good review. All right, so again, here's the code so you have it. That's just us looping over each element of the array. So we have what I like to refer to those like fives that just randomly come up. I like referring to them as magic numbers. And in general, we want to get rid of magic numbers. Everything has a name and everything should have a name. So we can actually tell by looking and reading the program what things are actually related.  You might not be able to read it like in that example, especially if there's three fives to change. You might forget one. Who knows? So in this case, yeah, I increased the length of the array to six, set the variable, changed the loop bound to six, changed the average calculation to divide by six, just a pain. So might not be taught in the other sessions, but I think it's worth talking about. We can use a define to get, use the C processor to do some copying and pasting for us. So don't have to know what that term is. I'll show you how to use it. Basically, it's just copying and pasting for us, which we like doing anyway. So we may as well make the compiler do it for us. So basically that define will do a search and replace. So if you write at the top of your code, hashtag, I guess, hash, pound, whatever you want to say, define and then you write like just something here. It will search for that term and then replace it by whatever you write after the space. So the search thing you want to replace, usually it's a string and it's all caps and you separate all of the words with an underscore and then the replacement is just whatever you want to replace that string by in the code. So you can write defines also like a function. So you can go ahead and make them more complicated, but you won't have to write any of yourself in this course. If you do use them, you should just use them for getting rid of magic numbers. So, do do. All right. So if we go back up here, well, we might do something like do a define, we have to give it a name, probably want to be descriptive. So maybe I call it grades length. So like the length of the array and then I will do the replacement equal to five. So now every time we compile our code, it will look for grades length and if it finds it, it will replace it with five for us. So now we can get rid of our magic number. So we want to have grades length, number of integers and then here, well, we want to iterate up to grades length and then when we calculate the average, well, we want to divide by grades length. So now I was smart and I saved myself a lot of time. So now if I want to add another grade, so grades five equals a hundred, all I have to do is slightly better now. I just have to remember to change this to six, goes ahead, changes everything for me. Like I said, programmers are lazy. So this should be seen as like a triumph. So you should be proud of yourself. The less things you have to remember, the lazier you have to be or the lazier you can be, the better. So I think there was a famous quote at Microsoft where they just look for the laziest people they can find and they hire them as programmers because, well, they'll come up with good ideas like this to save themselves time, it's less error prone and it's just a better idea. So let us reset it. All right, questions about that? Yep, so the question is, would I recommend this over global constants? Depends. So in old versions of C, so the general answer is this will always work. Global constants will sometimes work depending on how old the C compiler is. So I'll just say the same thing. So this will always work. This will do the find and replace, but we could do like a constant if we wanted to. Comes down to, comes down to preference sometimes. All right, so here's that same program got rid of our magic values. So now if we look at it, we can see, okay, well, there's really no magic values here. So like the beginning of an array always going to be zero. That's not really considered a magic value. Sum equal to zero, not really a magic value. And then the only other numbers I input in this program are the grades, so that's specific. So if I just look at this program, there's no magic values anymore, except in this example, just the size. I did return zero instead of exit success. And that's just because I ran out of space on the slides. So we can actually clean this up a little bit more. So remember when we declare a variable, well, if we had like int x, we can just immediately say int x equals something. We don't have to wait and do it on a separate assignment line. So we can also do the same thing with arrays, but it's a little bit different because they are multiple values. So we can have the same array declaration. So type some name, the size of the array, and then we can have equal, and then we need some curly brackets because it's a group of numbers. And then here we just have some common separated values in order to initialize the array with all of those values. So the type name and array size, same rules as before, the common separated values, it's the values you'd like to assign again in order. So the first one you write down will be at index zero, second will be at index one, third will be at index two, et cetera. And the values must match the type of the array. So if I have an int array, they all have to be integers. If I had a double array, they would have to be doubles or so you can convert them for us. Or if I had a char array or bool array or whatever. So let us clean up the code a little better now that we know that. So instead of writing all that, which was kind of, I didn't like doing that, I could just do equals and then curly brackets. And then here I can just go ahead and write the values. So I can write 75, 85, 99, 64, 72. And then I can just boop, delete that. So now if I can type, compile, build. So now average is still the same. So good to Sandy check that we still have the same example. And now this is starting to look a lot better, isn't it? But still, if I want to add another grade, right? I still, it's like almost there. Here it's kind of nice, I just like add one. And then I have to remember to change this. So I can do that, that's not too bad. But ideally, I would like just to add a new grade and have it figure it out for me. Like I said, even remembering one thing, eh, we have a chance to screw it up. So at least for me, I do not want to take that chance. So again, here is the example, just so you have it. So turns out that array size, if you set values, just assign the values and then C will go ahead and be a nice programming language and figure out the length for us. So you can just get rid of the array size and write type name and then just empty square brackets. And then all those comma separated values. Then C creates an array with the length equal to the number of values for us, which is great. So I can just write grades, empty square brackets and then all of the values. So to first talk about arrays. So arrays, we have to talk a little bit about in memory. So they're gonna be large enough in memory to hold all of the values. So if I have int grades and array and I set five int values, well, the grades array, we say it contains five int values. And we know that an int is four bytes. So therefore the total size of this array is just how many ints they are times the size of the array. So in this case, the total size would be 20 bytes. So turns out that if we remember that size of operator, so we can check the size of the array in bytes using the size of operator. So if we did size of grades, while C would return 20 because it's 20 bytes long. And also just as a beware here, so up to this point, I said length for like how many elements are in an array. And then I only use size when I talked about the number of bytes. Turns out most programmers use the term size and length fairly interchangeably. So usually we don't actually need to know the size in bytes of an array. So in the previous example, when people are actually talking about it, they might just say the size of the array is five and no one really talks about the size of the array in bytes. So you might hear those terms used interchangeably. So don't worry about it, even though that size would be different than what you get back from the size of operator. Turns out no one really cares in general how many bytes an array takes up. They just care about how many values are in it. So why I'm saying this is because, well, this is a define you do not know how to write yourself. So we can actually use a define to calculate the length of the array for us. And then I don't have to remember to go ahead and change the value for us. So I need to just, all I need to do is use this macro, or sorry, use this define. So usually if we have a define that takes arguments that kind of look like a function, people generally call them macros, but it's just a simple search and replace. So whatever is in the brackets when you use this, it will just be substituted in for, in this case, A-R-R here and here. So still do that copy and paste. Again, don't worry about it if you don't understand it. But in the previous example, if I go ahead and use that macro, then if I do array length on grades, it says five, which is the number of elements that are in that array, which is great. So let us go back here. So what is my file? Which length? So let's go back here. All right, so here is that same program with the array length macro. Again, don't have to read it. So all I have to do now is I can just say, an array of integers, I'll call it grades, and then I'll go ahead and set them. I don't have to explicitly say the size in between the brackets because C's got my back. It'll figure it out for me. And then if I want to know the length of the array, while I just use this array length macro, and then give it the grades. And basically what it's doing is taking the size of the entire array, so in this case 20 bytes, divided by the size of one element, so the size of an integer, which is four. So 20 divided by four gives us our five. Now, everything else is the same, and I can replace the magic number that defined I had before by just grades length. So again, I don't want a magic number, so I'll replace it with grades length. So now if I compile and run this, I get the same answer as I always got. And now if I want to add another grade, it's super easy, right? So I just do add another grade. Do I have to remember to change anything else? Is this way better? Yeah, this is awesome, right? So if I compile it now and I run it, boom, 82, easy. So if I want to just add another grade, I'm off to the races. So questions about that? Yeah, yeah, in this case it'll do, so the compiler will just do a simple search and replace, so this array length macro, by the time it gets to the compiler, it's gonna look something like size of grades, divide by size of grades one, something like that. So the compiler will probably figure that out, compile time, figure out that, hey, the size of this array in bytes is 20 bytes because I have five integers, and then divided by the size of essentially an integer. So 20 divided by four is five. Oops, I'll delete that. All right, any other questions with this? Yep? So this was like a little hard. Okay, so it'd be like 75, I'm calling it between program races, and then we could do it. Sorry, what do you want me to do? So say you want to initialize an integer. Mm-hmm.  So say you want, like, it doesn't really make any sense. Oh, this? Yeah, but like, you cannot do that, right? Yeah, yeah, you can't do that. Because like, you know, you can do that, like, so it's not really, it's like, basically you can do this curly brace, you're only doing half array, or maybe, like, the other way. Yeah, so these curly braces here are only for actually declaring and initializing an array. That's it. So it's not really entered? Yeah. Like this? Yeah, this curly brace just sets the values in the array. That's it. It's not really. Yeah. All right, any other questions for this? Pretty sweet so far, eh? All right, so. I will take your joy and crush it because things are gonna get weird. So. We need to ensure all indices in the array are valid. So again, assuming we have our grades array here, which have five elements, we're only allowed to access, you know, grades zero all the way up to four. So. In general, if we have an array with some length, let's say array length, well, we can only access, you know, array zero to index array length minus one. If we do something that is not within that, some really weird things are going to happen. So here is that same program. Let me just write it. All right, so. Let's review. If I go ahead and make int x equals one. Let's say I still do all this stuff and I print the value of x. When I run this program now, what will I see printed x colon what? This isn't the tricky part. One. All right, hopefully it's one by now. Otherwise, you got a lot of work to do during reading week and that's not good. So let's just run this just in case to make sure we haven't gone insane. So x is equal to one. Okay, well, it makes sense. If I go ahead and say, I'll change grades four equal to three. Let's say 42. So if I do this and run it again, what will I see when I print x? One again, right? I'm just changing the array. Wow, you people don't trust me at all. Jesus. All right, one, yay. All right. So if I just do this and run that, x is still one, right? Yeah, x is one. No, it's 42.  What?  Help, what's going on? So what did I do that was bad? Yeah, so I did grades six. So I tried to access the six or in this case, the seventh element and my grades array is only five. So that means I should only be accessing elements zero all the way to four, right? So turns out if you do not obey C strict rules, so remember the rule was you have to access valid elements in your array. If you do not do that, C is allowed to essentially do whatever it wants. In this case, one of the things of whatever it wants happens to be that it changes x, which is a bit weird. So that's a really odd thing that may happen. So on some computers, at least mine, if I just go ahead and try to change grade, like the seventh element of the grades array, I reassigned that variable x I declared at the top. I see in that example, maybe I just assigned it to two, this one I did 42, but that's kind of confusing. So to end off, I guess we have a lot of time because that went quicker than I thought, but always make sure your rate indices are actually in bounds. Otherwise, really, really, really, really, really, really, really, really weird things are going to happen and you will be very, very confused. So we'll figure out more or less why this happened in the next lecture. So I'll, any quick questions? That's just not that. Yeah, yeah, so the question is in this case, if I just pick some invalid one, we'll just randomly set a random value. So the answer to that is maybe, which is a very unsatisfying answer and that's why this is really hard to predict because, well, it turns out, if I just change this, whoops, if I just change this to grades five instead of six and I run it, nothing seemingly bad happens. If I change it to, I don't know, seven, I haven't done this before, so let's see what it does. Nothing really bad happens. If I change it to eight, nothing really bad happens. Let's just do weird things. All right, so let's make sure everything's invalid. So we can start the loop from grades length, so that is invalid, starts at five, all the way up to, I don't know, let's say a thousand. So we'll change it to 42. So this loop, we'll start changing grades five, then grade six, then grade seven, all the way up to grades 999. So if I run that, I get a really weird error. I print X is 42, but then I get a bus error. That's cool.  So, well, I kind of know what it is, and I kind of know what happened, but the moral of the story is, always make sure your ray indexes are in bounds because seed doesn't tell you an error. Sometimes it might, like if you do it literally, so in that, I didn't even get a compiler warning or anything like that, seed was just happy just to compile it and just let us do things. When I wrote it like grade six, it actually gave us a little bit of a warning that I ignored. So it was a little bit smart where it said warning array index six has passed the end of the array, which is five elements. So it's trying to save us here. I ignored it and bad things happened, but when I had it in the loop, well, your compiler, when you hit compile, can't figure out what that bounds of the loop are.  It'll just happily let you do something that is broken. So with that, we can have Q and A come talk to me or whatever, but just remember, phone for you. We're all in this together.