Types and Variables Lab

Computations with ints and doubles

  1. Consider the following C program segment:
    int a = 5;
    int b = 6;
    int c = a/b;
    int d = b/a;
    int e = (a + b) / 10;
    int f = (a + b) % 10;
    double x = (a + b) / 10;
    double y = (a + b) / 10.0;
    printf ("a=%d, b=%d, c=%d, d=%d, e=%d, f=%d, x=%lf, y=%lf\n",
            a, b, c, d, e, f, x, y);
    1. Without running this code, predict the program's output (i.e., the value of each variable). Make note of any promotions that occur during the expression evaluation.
    2. Include the code segment in a C program, compile the program, and observe the results.
    3. Review what is printed and explain each result, especially where your predictions were incorrect.
    4. Predict what will happen if you change the computation for variables f and y to (a + b) % 10.0;
    5. Make this change, compile, and verify your prediction.
    6. Explain why the compiler produces this result.

Observation: You may recall there is a fourth type, float, that was not involved in Step 1. doubles are often preferred to floats, because a double is stored more accurately than a float. Also, constants, such as 3.14 are almost always stored as doubles in C. Exceptions arises when memory is scarce, and one wants to use as little space as possible within a computer's memory, or when computations are optimized in the hardware for float values. With the size of main memory in today's computer, however, size often is not a consideration, and doubles typically are used rather than floats.

We will discuss details of the various data types, including both doubles and floats, in a few weeks.

Assignment and Casting

In Step 1, the computations a/b and b/a were performed with ints. That is, the result was an integer, and any fraction of an integer was discarded. Also, in the case of computing y, the presence of the double 10.0 caused the machine to promote (a + b) to a double and then perform division. In this case, the implicit type 10.0 caused promotion to double before the computation took place.

The C compiler thus assigns values implicitly to int and double variables, but we also can explicitly ask the computer to change the data type before an operation. This explicit specification of a change in type is called casting

  1. Consider the following C program segment:
    int k = 5.0;
    int m = 7.7;
    double n = 5;
    int p = k/m;
    double q = k/m;
    printf ("k = %d, m=%d, n=%lf, p=%d, q=%lf\n", k, m, n, p, q);
    double r = (double) (k/m);
    double s = (double) k / m;
    double t = k / (double) m;
    double u = (double) k / (double) m;
    printf ("r=%lf, s=%lf, t=%lf, u=%lf\n", r, s, t, u);
    1. Without running this code, predict the program's output (i.e., the value of each variable). Make note of any promotions or other conversions that occur during the expression evaluation.
    2. Include the code segment in a C program, compile the program, and observe the results.
    3. Review what is printed and explain each result, especially where your predictions were incorrect. In particular, for each result printed, explain whether the division is done with ints or doubles and which, if any, numbers are converted to doubles when.

Observation: Sometimes there can be a danger in casting. Types have sizes. If you try to put a number that is bigger than the size of the type you are casting it to, you may get undesired results.

Operator Precedence

After deciding what operator you will use, you need to put them in certain order or in parentheses because the program will be read in a certain order and so the operators will be applied in a certain order.

  1. Consider the following program segment:
    int v;
    v = 5 + 4 * 3 + 1;
    1. What will the value of v be?
    2. Copy this code in a program and verify your prediction by printing the value.
  2. Consider the following program segment:
    int w;
    w = (5 + 4) * (3 + 1);
    1. What will the value of w be?
    2. Copy this code into a program and verify your prediction by printing the value.

Incrementing and Decrementing Numbers

  1. Consider the following code, in which variables are incremented as the only part of an expression.
    int a = 1;
    int b = 7;
    printf ("a = %d, b = %d\n", a, b);
    a++;
    ++b;
    printf ("a = %d, b = %d\n", a, b);
    In this code the ++ operations are the only part of the statement.
    1. Predict the output of this code.
    2. Verify your prediction by copying the code into a program, compiling, and running it.
  2. Now consider the following example that combines the increment operators with other operators (e.g., assignment)
    int a,b,c;
    a = 0;
    b = a++;
    c = ++a;
    printf (" a = %d b = %d c = %d\n", a,b,c);
    a = 0;
    b = ++a;
    c = a++;
    printf (" a = %d b = %d c = %d\n", a,b,c);
    1. Predict the output of this code.
    2. Verify your prediction by copying the code into a program, compiling, and running it. In particular explain any differences you observe between the two increment operators in this mixed-use context.
  3. The next block combines the increment operators within a print and within arithmetic expressions.
    int r, s;
    r = 5;
    s = 7;
    printf (" r = %d s = %d\n", ++r, s++);
    printf (" r = %d s = %d\n", r, s);	
    int t = r++ + s++;
    printf (" r = %d s = %d, t = %d\n", r, s, t);	
    int u = ++r + ++s;
    printf (" r = %d s = %d, u = %d\n", r, s, u);
    1. Predict the output of this code.
    2. Verify your prediction by copying the code into a program, compiling, and running it. What is the difference, if any, between the two increment operators in this context?
  4. In addition to the increment operators, ++a and a++, C provides pre- and post-decrement, --a and a--, that subtract one from the variable.

    Repeat Step 7, replacing ++ by -- throughout. Again, examine the output and explain what is printed.

Conclusion: When combined with other operations, the increment operations ++a (pre-increment) and a++ (post-increment) cause different values to be used in processing. This observation yields the following programming observation and suggestion:

Characters

  1. The program ascii-print.c prints many of the ASCII values along with their corresponding characters. Codes smaller than 32 correspond to characters that are not printable (e.g., a backspace, tab, line feed, return, etc.). Similarly, codes larger than 126 may not print properly in terminal windows (e.g., code 177 is ±, code 181 is µ, and code 216 is Ø). Since only codes between 32 and 126 (inclusive) reliably print in a terminal window, the program uses a for loop that starts with code 32, the code for a space character, and ends at 126.
    1. What character corresponds to the ASCII value 85?
    2. What is the ASCII value for the character 'A'?
    3. What is the ASCII value for the character 'a'?
    4. What is the (subtractive) integer difference between the values of 'A' and 'a' ?
    5. What relationship can you observe for the codes for 'a', 'b', 'c', 'd', and the other lower case letters?
    6. What relationship can you observe for the codes for '0', '1', '2', '3', and the other digit characters?
    7. What relationship can you observe for the codes for 'A', 'B', 'C', 'D', and the other upper case letters?
    8. What code is used for the character 0? (Note that the code for char 0 is not zero!)

Adding ints to chars

Because characters are stored according to their integer codes, it is possible to add an integer value to a char value.

  1. Consider the following C program segment:
    char ch = 'a';
    ch = ch + 7;
    printf ("ch + 7  = '%c'\n", ch);
    1. What do you predict the code output will be?
    2. Verify your prediction by including the code within a program.
  2. Suppose you add 7 to ch again (e.g., by repeating the last two lines).
    1. What is do you predict will be printed?
    2. After answering, verify your prediction
  3. In C, a char is considered a type of small int, so it is possible to assign a char variable an integer value. Set ch to 48 and print out the result:
    ch = 48;
    printf ("char ch = '%c'\n", ch);
    Explain what is printed.
  4. Set ch equal to the integer 0 and print it again.

    You may notice the print statement doesn't print out ch as being zero; rather the two single quotes are printed next to each other. The reason is that the character code for the integer 0 is called a "NULL"; when printed the cursor does not move in any way—effectively printing of the character for code 0 is ignored in the output.

For those with extra time

  1. As an example of how not to write code, consider the following expressions.
    int a = 2;
    int b = 4;
    
    a /= (b++) % (++a);
    
    printf("%d\n",a);
    1. Foreshadowing the next reading and lab, write out step-by-step what you think happens to the values for a and b as the code is executed.
    2. Verify whether you were correct by compiling a program with this code.
    3. If you were not correct, identify the proper order of operations using Appendix A in King.