CSC161 2011S Imperative Problem Solving

Laboratory: Operators and Precedence

Summary:

Prerequisites: Familiarity with basic C, including output and variables.

Preparation

a. Create a directory for this laboratory. I would recommend csc161/labs/operators.

b. In that directory, create the standard Makefile. That is, the contents should read

CFLAGS=-Wall

c. In that directory, create a file called experiments.c with the following contents.


/**
 * experiments - A variety of experiments with operators and precedence.
 */

// +-------+----------------------------------------------------------
// | Notes |
// +-------+

/*
  Some of the code contained herein is hideously repetitious.  Such
  repetition could be avoided by the use of an appropriate macro.
  Unfortunately, the expected readers of this code do not yet know
  macros.
 */


// +---------+--------------------------------------------------------
// | Headers |
// +---------+

#include <stdio.h>      // For printf
#include <ctype.h>      // For isdigit
#include <stdlib.h>     // For atoi


// +---------+--------------------------------------------------------
// | Helpers |
// +---------+

/**
 * looks_like_int(str) 
 *   Determine if the string looks like an integer.
 */
int
looks_like_int (char *str)
{
  int i = 0;

  // Skip over leading sign.
  if ((str[0] == '+') || (str[0] == '-'))
    ++i;

  // Consider remaining characters.
  while (str[i] != '\0')
    {
      if (! isdigit (str[i]))
        return 0;
      ++i;
    } // while

  // We've read through all the characters.  It must be an integer.
  return 1;
} // all_digits


// +------+-----------------------------------------------------------
// | Main |
// +------+

int
main (int argc, char *argv[])
{
  int x;        // Our input variable.
  int i;        // A counter variable for loops

  // Verify that there's a command-line argument.
  if (argc != 2)
    {
      printf ("Usage: experiments INT\n");
      return 1;
    } // incorrect number of arguments

  // Verify that the command-line argument is a number
  if (! looks_like_int (argv[1]))
    {
      printf ("Usage: experiments INT\n");
      printf ("  %s is not an integer.\n", argv[1]);
      return 2;
    } // not an integer

  // Grab the number
  x = atoi (argv[1]);

  // Try the operators with multiple values.
  for (i = -5; i <= 5; i++)
    {
      printf ("%d + %d = %d\n", x, i, x + i);
      // printf ("%d - %d = %d\n", x, i, x - i);	// a
      // printf ("%d * %d = %d\n", x, i, x * i);	// b
      // printf ("%d / %d = %d\n", x, i, x / i);	// c
      // printf ("%d %% %d = %d\n", x, i, x % i);	// d
      // printf ("%d < %d = %d\n", x, i, x < i);	// e
      // printf ("%d > %d = %d\n", x, i, x > i);	// f
      // printf ("%d <= %d = %d\n", x, i, x <= i);	// g
      // printf ("%d >= %d = %d\n", x, i, x >= i);	// h
      // printf ("%d == %d = %d\n", x, i, x == i);	// i
      // printf ("%d != %d = %d\n", x, i, x != i);	// j
      // printf ("%d = %d = %d\n", x, i, x = i);	// k
      // printf ("%d += %d = %d\n", x, i, x += i);	// l
      // printf ("%d -= %d = %d\n", x, i, x -= i);	// m
      // printf ("%d *= %d = %d\n", x, i, x *= i);	// n
      // printf ("%d /= %d = %d\n", x, i, x /= i);	// o
      // printf ("%d && %d = %d\n", x, i, x && i);	// p
      // printf ("%d || %d = %d\n", x, i, x || i);	// q
      // printf ("%d & %d = %d\n", x, i, x & i);	// r
      // printf ("%d | %d = %d\n", x, i, x | i);	// r
      // printf ("%d ^ %d = %d\n", x, i, x ^ i);	// t
      // printf ("%d << %d = %d\n", x, i, x << i);	// u
      // printf ("%d >> %d = %d\n", x, i, x >> i);	// v
    } // for

  // And we're done
  return 0;
} // main



Exercises

Exercise 1: Code Reading

Read through the code in experiments.c.

a. How should the program be run?

b. What techniques does the program use to validate input? Do you think those will be successful? In what situations might they fail?

c. What seems to be the main purpose of the program?

d. Assume that we've compiled the code to an executable called experiments. What output do you expect when the user types

$ ./experiments 5

e. Check your answer experimentally.

f. What output do you expect when the user types

$ ./experiments -1

g. Check your answer experimentally.

h. What output do you expect when the user types

$ ./experiments 9876543210

i. Check your answer experimentally.

Exercise 2: Other Operators

As you may recall, C has a wide variety of integer operations. For each of the following operations:

a. -

b. *

c. /

d. %

e. <

f. >

g. <=

h. >=

i. ==

j. !=

k. =

l. +=

m. -=

n. *=

o. /=

p. &&

q. ||

r. &

s. |

t. ^

u. <<

v. >>

Exercise 3: Increment

As you may recall, the prefix and postfix ++ operators add one to a variable.

a. Add some lines to your experiment (or create a new experiment) of the form:

  x = atoi (argv[1]);
  printf ("x = %d\n", x);
  y = ++x;
  printf ("x = %d, y = %d\n", x, y);
  y = x++;
  printf ("x = %d, y = %d\n", x, y);
 

b. What do you expect the output to be when the program is run with 5? With -5?

c. Check your answer experimentally.

d. Consider the following:

  x = atoi (argv[1]);
  y = ++x - ++x;
  printf ("x = %d, y = %d\n", x, y);

What output do you expect for an input of 5?

e. Check your answer experimentally.

f. Consider the following:

  x = atoi (argv[1]);
  y = x++ - x++;
  printf ("x = %d, y = %d\n", x, y);

What output do you expect for an input of 5?

g. Check your answer experimentally.

Exercise 4: Precedence

As you know from your prior work with arithmetic, we typically assign precedence to arithmetic operations. For example, in the expression 3+4*5, we do the multiplication before the addition, even though the addition appears first.

We can see that C incorporates precedence and that it gives multiplication higher precedence than addition because it evaluates 3+4*5 to 23 rather than 35 and because it evaluates 3*4+5 to 17 rather than 27. (The first experiment alone is not enough, because C might simply evaluate operators back to front.)

a. Verify that C gives multiplication higher precedence the addition.

b. Pick about six operators (including at least one assignment operator) and determine their relative precedence.

Exercise 5: Associativity

As you know from your prior work with arithmetic, we typically have an order in which we apply operations in an expression in which the operator is repeated (or in which equal precedence operators are repeated). For example, 3-4-5 is -6, rather than 4, because we do the subtaction from left to right.

a. Verify that C does subtraction left-to-right.

b. What do you expect the result of the following code to be?

  int q = 5;
  int r = 4;
  q -= r -= 3;
  printf ("q = %d, r = %d\n", q, r);

c. Check your answer experimentally.

d. Consider the following:

  int b = 0;
  printf ("%d\n", b == b == 2);

If C applies == left to right, what will the output be?

If C applies == right to left, what will the output be?

e. Given your analysis, determine which the order in which C applies ==.

f. Choose a variety of operators and see if they are left-associative (C does the operations left-to-right), right-associative (C does the operations right-to-left), or neither (C won't let you put multiple copies of the operation on the same line).

For Those with Extra Time

If you find yourself with extra time, continue your work on the current homework assignment.

 

History

Tuesday, 22 February 2011 [Samuel A. Rebelsky]

 

Disclaimer: I usually create these pages on the fly, which means that I rarely proofread them and they may contain bad grammar and incorrect details. It also means that I tend to update them regularly (see the history for more details). Feel free to contact me with any suggestions for changes.

This document was generated by Siteweaver on Tue Feb 22 11:39:21 2011.
The source to the document was last modified on Tue Feb 22 11:39:20 2011.
This document may be found at http://www.cs.grinnell.edu/~rebelsky/Courses/CSC161/2011S/Labs/operators-lab.html.
A PDF version of this document may be found at http://www.cs.grinnell.edu/~rebelsky/Courses/CSC161/2011S/Labs/_

Samuel A. Rebelsky, rebelsky@grinnell.edu

Copyright © 2010 Samuel A. Rebelsky. This work is licensed under a Creative Commons Attribution-NonCommercial 2.5 License. To view a copy of this license, visit or send a letter to Creative Commons, 543 Howard Street, 5th Floor, San Francisco, California, 94105, USA.