More C Programming ------------------ Section 2.3 -- Displaying Numerical Results ------------------------------------------- This section continues discussion of the printf() function. We will work through a number of examples. Example 1 --------- #include main() { printf("The total of 6 and 15 is %d",6+15); } The output is: The total of 6 and 15 is 21 Note: The cursor is still on that line and in some cases when you execute this statement, nothing may come back. This is because the messages are sent to a buffer which is dumped to the screen and sometimes this buffer doesn't get sent to the screen. This can be fixed by putting a "\n" at the end of the printf() message. This forces the buffer to clear to the screen: printf("The total of 6 and 15 is %d\n",6+15); We could add a period to make it a complete sentence: printf("The total of 6 and 15 is %d.\n",6+15); The new output is: The total of 6 and 15 is 21. These examples contained integers. Let us do the same with floating point or real numbers. Example 2 --------- #include main() { printf("The sum of 12.2 and 4.7 is %f.\n",12.2+4.7); printf("The summ of %f and %f is %f.\n",12.2, 4.7, 12.2+4.7); } The output is: The sum of 12.2 and 4.7 is 16.900000. The sum of 12.200000 and 4.700000 is 16.900000. Note that the %f specification in the printf() function causes the floating point values for 12.2 and 4.7 to be represented with 6 digits of precision after the decimal point. Let us try an example using characters. Example 3 --------- #include main() { printf("The character I selected is %c.\n",'a'); } The output is: The character I selected is a. Lets change the last printf() statement to: printf("The character I selected is a.\n"); The output is the same thing. However, in the first character example we could substitute a variable in place of the 'a' . Here is another example with a variable: Example 4 --------- #include main() { /* declare variables first */ char letter = 'a'; /* main part of program goes here */ printf("The letter chosen is %c.\n", letter); } The output is: The letter chosen is a. What happens in the following example: Example 5 --------- #include main() { char letter1 = 'e', letter2 = 'z'; printf("The letters are %c and %c.\n", letter1, letter2); letter2 = letter1; letter1 = 'b'; printf("The letters now are %c and %c.\n", letter1, letter2); } The output is: The letters are e and z. The letters now are b and e. The assignment of letter2 = letter1 reassigned letter2 to the value of letter1 which was 'e'. Then letter1 was reassigned to 'b'. Let's do some more with the printf() format specifiers. Say you wanted to output values in terms of dollars. An example might be: $10.97 . First, we need to use floating point values. If we tried to print the value of 10.97 as a floating point value using the %f specification, it will print 6 digits of precision as: 10.970000 . That is not acceptable when representing U.S. dollars. We need a specifier that controls the number of decimal places. Here is the required specifier: %.nf where n is the number of decimal places. EX: %.2f will print 2 decimal places. Example 6 --------- #include main() { printf("I have $%.2f to my name.\n",2004.56); } This outputs: I have $2004.56 to my name. If we changed the number to 2004.5675 it would round it to 2 decimal places. This would output: I have $2004.57 to my name. What if we want to line output numbers up in columns? Lookat this simple example: 1 + 12 ---- 13 If these values were in variables, there would be a problem in getting them to always line up. If 1 was replaced with 10, then the output would be: 10 + 12 ---- 22 These line up nicely. So how do we fix the first case? We need a width specifier. This is done using %wd where w is the width of the output field. In our example, it should be 2 digits. Example 7 --------- #include main() { int a = 1; int b = 12; int c; printf(" %2d\n",a); printf("+ %2d\n",b); printf("----\n"); printf(" %2d\n",a+b); } The output is: 1 + 12 ---- 13 Try the same example with different variable value assignments like 10 and 12 for a and b, respectively. We can use a combination of the width specifier and the decimal digit specifier. Here are a few examples. Look at Table 2-7 in the book for more examples. Input number Specifier Output number -------------------------------------------------------------------------- 12 %2d 12 100 %2d 100 12.333 %4.2f 12.33 1.34567 %9.1f 1.3 -------------------------------------------------------------------------- The first number 12 is 2 digits long and fits in the width specifier. The second number 100 is 3 digits long and is larger than the width specifier, so the width specifier is ignored. The third number has 6 characters including decimal and is larger than the width specifier (it is ignored) and then the number is limited to 2 decimal places. The fourth number has 7 characters which fits in the width specifier and is limited to 1 decimal place, thus is printed with 6 blanks in front plus the 3 characters it contains (1.3). Left justification is performed by inserting a "-" sign in the format specifier like this: %-10d . This will left justify the numbers and leave the remainder of the 10 field width characters blank. printf("The number %-10d is cool.\n",20); This printf() statement would return: The number 20 is cool. There are other ways of outputting numbers. You may convert numbers to octal or hexadecimal as well. Octal numbers are in base 8 and hexadecimal numbers are in base 16. Decimal Octal Hexadecimal etc... To output a number in octal use %o . To output a number in decimal use %d . (we already know this one decimal is the same as integer) To output a number in hexadecimal use %x . Example 8 --------- #include main() { printf("Decimal is %d\n",10); printf("Octal is %o\n",10); printf("Hex is %x\n",10); } The output is: Decimal is 10 Octal is 12 Hex is A Section 2.4 -- Variables and Declarations ----------------------------------------- Legal Variable Names -------------------- 1. The variable name must begin with a letter or underscore and may contain only letters, underscores or digits. 2. It cannot contain commas, blanks or special symbols such as (,),&,$,#,.,!,\,? . 3. A variable name cannot be a keyword (remember Table 1-2). 4. The variable name consists of no more than 31 characters. Example Assignments ------------------ num = 60 if variable num is an integer num = 60. if variable num is a floating point number num = num + 1 increments num by 1 num++ increments num by 1 num-- decrements num by 1 num = a + b assigns num the sum of a and b num = a - b assigns num the difference of a and b num = a * b assigns num the product of a and b num = a / b assigns num the division of a and b num = a % b assigns num the remainder of a divided by b Example 9 --------- #include main() { int a,b; int sum,diff,prod,div,rem; a = 10; b = 20; sum = a + b; diff = a - b; prod = a * b; div = a / b; rem = a % b; printf("The sum of %d and %d is %d.\n",a,b,sum); printf("The difference of %d and %d is %d.\n",a,b,diff); printf("The product of %d and %d is %d.\n",a,b,prod); printf("The division of %d and %d is %d.\n",a,b,div); printf("The remainder of %d divided by %d is %d.\n",a,b,rem); } The output is: The sum of 10 and 20 is 30. The difference of 10 and 20 is -10. The product of 10 and 20 is 200. The division of 10 and 20 is 0. The remainder of 10 divided by 20 is 10. Example 10 ---------- #include main() { char c; char d; c = 'a'; d = c + 1; printf("c is %c\n",c); printf("d is %c\n",d); } The output is: c is a d is b Characters can be added as well. 'a' + 1 is 'b' 'b' + 2 is 'd' Refer to Section 2.1 for more details on ascii code and problem 7 in exercises 2.2 . Section 2.5 -- Integer Qualifiers --------------------------------- This section talks about memory sizes of integers. Integers on UNIX-based systems are typically 4 bytes long. This means, that the computer uses 4 bytes to encode each integer. On smaller systems, like a machine running DOS, the size of integers will typically be 2 bytes long. If you want larger integers than that, you need to include a qualifier in front of the integer such as: long int. If your integers are 2 bytes, the range of values for an integer is -32768 to 32767 (-2^(15) to 2^(15)-1). On our UNIX machines, we have 32-bit integers (4 bytes). Long integers are also 32-bit. If you want shorter integers, you need to specify: short int. This can be used when trying to save memory. EX: short int i; EX: long int i; EX: int i; On our systems (machine dependent), the first example is 2 bytes, the second example is 4 bytes and the third example is default to 4 bytes. On a pc, the first example is probably 2 bytes, the second is 4 bytes and the third is default to 2 bytes. If you are only dealing with positive numbers, then you may use the following qualifier: unsigned int . This gives a range of integers from 0 to 65535 (0 to 2^(16)-1). EX: unsigned int i; EX: signed int i; The first example allows positive numbers only. The second example is the default. The "signed" is unnecessary in the case of integers, but may be useful with characters. EX: signed char a; Signed character variables are 1 byte long and with a range of -128 to 127. With unsigned, values may range from 0 to 255. You can use the signed char variable for arithmetic. The size of each variable may be obtained with a command called: sizeof(varname); This returns an integer value representing the number of bytes in the variable. Example 11 ---------- #include main() { signed char a; unsigned int b; short int c; long int d; int e; int szofb; szofb = sizeof(b); printf("size of a is %d\n",sizeof(a)); printf("size of b and c are %d and %d\n",szofb,sizeof(c)); printf("size of d is %d and e is %d\n",sizeof(d),sizeof(e)); } The output is: size of a is 1 size of b and c are 4 and 2 size of d is 4 and e is 4 Section 2.6 -- Common Programming Errors ---------------------------------------- 1. Forgetting to declare all variables in a program. 2. Storing an incorrect data type in a declared variable. 3. Using a variable in an expression before a value has been assigned to the variable. EX: int a,b; b = a * 30; <-- error since a is undefined 4. Dividing integer values incorrectly. EX: 3.4 + 2/3 + 5.0 = 3.4 + 0 + 5.0 = 8.4 Correction: 3.4 + 2.0/3.0 + 5.0 5. Mixing data types in an expression without clearly understanding what may happen. It is legal to mix, but the results may be undesirable. 6. Not including the correct conversion qualifier in the printf() function. 7. Not closing the control string in printf(). 8. Forgetting to separate all arguments passed to printf() with commas. Section 2.7 -- Chapter Summary ------------------------------ See pages 75-76 in the book. Section 3.1 -- Assignments -------------------------- Almost all of C's processing statements, except for function calls, use expressions. So, it is important to have a clear understanding of what an expression is before proceeding. Expression In it's most general form is any combination of variables, constants, and operators that can be evaluated to yield a result. Examples: 10 + amount count + 1 16.3 + total turtle + rabbit + turkey Assignment Operator This causes the value of the expression to the right of the equal sign to be stored in the variable to the left of the equal sign. Examples: year = 1994 sum = 12 + 25 + 89 total = total + newvalue inter = apple + 19 - banana The order of expression evaluation is important. The assignments have the lowest precedence (are the last performed). The expression on the right hand side of an assignment is first evaluated and then the assignment is made. EX: tax = salestax * amount 1. salestax * amount is computed first 2. then that value is assigned to the variable tax This is TRICKY. The assignment itself has a value. Look at this example: Example 12 ---------- #include main() { int i = 7; printf("The value of the assignment is %d\n", i=9); } The output is: The value of the assignment is 9 Note: The initial value of i (i=7) was overwritten by the expression (i=9). The value of the expression (i=9) is printed. More TRICKY stuff: Assignment Status ---------- ------ amount + 25 = 10 invalid since left hand side can only be a variable a = b = c = 10 valid since this is equivalent to: c = 10 b = 10 a = 10 in that order. Here is a list of assignment operators: operators equivalent --------- ---------- n++ n = n + 1 n-- n = n - 1 n += m n = n + m n -= m n = n - m n *= m n = n * m n /= m n = n / m n %= m n = n % m ++n n = n + 1 --n n = n - 1 Note: --n and n-- are similar, but the evaluation is slightly different. Take a look at this example program: Example 13 ---------- #include main() { int m = 10; int n = 10; printf("The increment value var++ is %d.\n",m++); printf("The increment value ++var is %d.\n",++n); } The output is: The increment value var++ is 10. The increment value ++var is 11. Any clues to why this is so? The evaluation order is different. The values of n and m were inotially the same at 10. When m++ was executed the current value was printed out, and then the value for m was incremented AFTER (the ++ part is after the variable--relationship). When ++n was executed the current value was incremented BEFORE the value was printed out (the ++ part is before the variable--relationship). i = 10 printf("%d\n",i++); /* 10 prints out */ printf("%d\n",i); /* 11 prints out */ i = 10 printf("%d\n",++i); /* 11 prints out */ printf("%d\n",i); /* 11 prints out */ Problem #2a in Exercises 3.1 ---------------------------- Problem: Write a C program to calculate and display the average of the numbers 32.6, 55.2, 67.9 and 48.6 . Solution: #include main() { /* input declarations */ float num1 = 32.6, num2 = 55.2, num3 = 67.9, num4 = 48.6; /* output declarations */ float avg; /* compute the average */ avg = num1 + num2 + num3 + num4; avg /= 4; /* output the average */ printf("The average is %f.\n", avg); } The output is: The average is 51.075001.