CPS 202 Class 4 Chapter 4 Review Homework for chapter 3 ----------------------------- Review Quiz 1 ------------- Expressions ----------- There are three major types of expressions in C: o Arithmetic - math o Relational - less than, greater than o Logical - ANDs and ORs In this chapter, we will review the first category, the arithmetic, or math, expressions. There are dozens of operators in C, and we will learn about most of them. Of all the operators, the math operators are the most well-used. We have already used many of them in our programs up to now. The five main math operators we will see and use are: + - * / % + is used for two things. The first is unary positive, or to force a number to be positive: +4 The use of the + for unary positive is redundant, because unsigned numbers are positive, but if it is important to force a number to be positive, it could be useful. The more prevalent use of the +, though, is for addition. Two numbers or variables can be added together with the + sign: 1 + 5 a + 5 a + b To add many numbers together, just string the addition along: 1 + 5 + 6 + 10 a + b + 5 + c The - is also used for two things. The first is unary negative, and is much more useful than unary positive: -4 -a // take the value in a and use its negative But like +, the more prevalent use of - is to subtract numbers and variables. Subtractions can also be strung together: 5 - 1 a - b 5 - 2 - 1 a - b - c The * operator has other uses, but we'll get to them later. The major use is for multiplication: 5 * 5 a * b a * b * c The / operator is used only for one thing: division. It also works differently depending upon the types of data that it is operating one, whether integer or floating point. In floating point, when dividing, the fractional part is retained. In integer division, the fractional part is lost. So: 4.0 / 3.0 is 1.3333 4 / 3 is 1 5.0 / 2.0 is 2.5 5 / 2 is 2 This can have a big impact on calculations: (4/3) * pi * 10.0 * 10.0 * 10.0) = 3141.59 (4.0 / 3.0) * pi * 10.0 * 10.0 * 10.0) = 4188.79 We must always be careful, especially when dividing, that we divide correctly. One other thing: dividing by 0 is dangerous - it will crash your program. If dividing by a user-input number, we must always test that data to see if it is 0 and reject the input if it is (we'll learn about testing in chapter 5). The fifth operator has a few different names: mod, modulus, or remainder. It is used with integer values only. The mod value is related to the division value. To see the relationship: 10/3 = 3 10%3 = 1 12/3 = 4 12%3 = 0 13/3 = 4 13%3 = 1 14/3 = 4 14%3 = 2 15/3 = 5 15%3 = 0 16/3 = 5 16%3 = 1 Here's how it works: 10/3 = 3 3 (the result) * 3 (the divisor) = 9 10 (the dividend) - 9 = 1 10%3 = 1 The % operator has an especially nice property when used with the mod value 10. Any number mod 10 returns the last digit in the number: 14 % 10 = 4 123 % 10 = 3 12342 % 10 = 2 This can lead to some interesting algorithms that we will see in the problems for this chapter. Operator Precedence ------------------- As everyday users of math, we expect math to work the way we want it to, the way we put it to paper. C, however, often has its own ideas about math, and we must adapt to conform to those ideas. The first one to conform to is the integer division issue. The other main issue is operator precedence. Given this calculation: 2 + 3 * 5 we would probably come up with "25" as the answer. 2 + 3 is 5, 5 * 5 is 25. But C will give an answer of 17, and you must keep this in mind. The reason for 17 is that C will do all multiplication first, because multiplication has a higher operator precedence than addition. So, the C answer is 3 * 5 is 15, 2 + 15 is 17. You can certainly force the program to do math in a specific way, and that is by "forcing precedence". By forcing precedence, you tell the program to use the order you proscribe, and not the natural order. To force precedence, use parentheses: (2 + 3) * 5 Anything within parentheses will be calculated first, with the resulting values being used in the subsequent math. So here, 2 is added to 3 first, then the result is multiplied by 5. See the table on page 595 for the full operator precedence chart. One other thing to be aware of, and this may have been seen by some in the chapter 3 homework, is the limit of the int in a 16-bit compiler. Turbo and QuickC are both 16-bit compilers, and as mentioned on page 49, these compilers will limit the size of an int to 32767. The ISBN of this text would have thrown off the ISBN program on a 16-bit compiler. As seen in the upc.c program on page 49, we can get around that be reading digits one at a time. Follow the logic of the upc.c program for an interesting use of programming languages (check digits). Assignment ---------- The main assignment operator is the = sign. We've already used it quite a bit. To assign a value to a variable, we set that variable equal to something: i = 12; a = b + 3; If a value of the wrong type is assigned, it is converted automatically: int a; a = 1.23; // a is 1 This brings us to another concept, the lvalue and the rvalue. An lvalue, simply, is a value that can be on the left-hand side of an assignment. An rvalue is a value that can be on the right-hand side. Every variable and value is an rvalue, so we hardly ever talk about them. Certain things, however, can never be an lvalue, and this is a common error. The compiler will report the error as "so-and-so is not an lvalue". Example: 12 = a + b; 12 is not a lvalue. It is a fixed value and cannot be modified. #define PI 3.141 PI = 3.14159; // PI is not an lvalue Compound assignment ------------------- Many common assignments have shorthands in C which we will use quite frequently. All have "long-hand" equivalents, but the shorthand ones are very common. i = i + 2; // Adding a value to a variable i += 2; Each of the operators have one of these shorthand equivalents: i -= 2; // Subtracts 2 from i and places the result in i i *= 2; // Multiplies i by 2 and places the product in i i /= 2; // Divides i by 2 and places the result in i i %= 2; // Mods i by 2 and places the result in i i = 12; i %= 10; // i is now 2 Note the order of the operator and the = ... there is no =+ operator i =+ 2; This actually translates to i = +2; Increment/Decrement ------------------- The ++ operator is the increment operator, and is used to do a very common thing: increase a variable by 1. The -- is the decrement operator and is used to decrease a variable by 1. These two operations are very common in C. i = i + 1; i += 1; i++; All of the above are the same, functionally. The ++ and the -- can be used in two places with two very different results. Placing the ++ in front of the variable pre-increments it. Placing the ++ after the variable post-increments it. There is no difference if the operator is used alone: i = 1; // i is 1 i++; // i is 2 ++i; // i is 3 Where the difference comes in is when it is combined with other pieces of C: i = 1; printf("i is %d\n",i++); // prints "1" // i is 2 printf("i is %d\n",++i); // prints "3" In the first printf, the printf was done, the value of i was sent to printf, and after all that, the value of I was increased by 1. In the second printf, the value of i was increased by 1, then the printf was called and passed the value of i. For this reason, I almost always use ++, and whenever feasible, I separate my increments from other code. -- works the same way. There is no **, // or %%.