Goals
- Learn how to compile and run a C program on the EECS instructional computers.
- Examine different types of control flow in C.
- Look at the internal representation of numbers.
Setup
We recommend you create a new directory for each assignment. For example, to create a directory named lab02 in your home directory, type:
$ mkdir ~/lab02
Afterwards, copy the contents of ~cs61c/labs/02 to the directory.
$ cp -r ~cs61c/labs/02/* ~/lab02
Compiling and Running a C Program
In this lab, we will be using the command line program gcc to compile programs in C. The simplest way to run gcc is as follows.
$ gcc program.c
This compiles program.c into an executable file named a.out. This file can be run with the following command.
$ ./a.out
gcc has various command line options which you are encouraged to explore. In this lab, however, we will only be using -o, which is used to specify the name of the executable file that gcc creates. Using -o, you would use the following commands to compile program.c into a program named program, and then run it.
$ gcc -o program program.c $ ./program
Exercise 1: Simple C Program
In this exercise, we will see an example of preprocessor macro definitions. Macros can be a messy topic, but in general the way they work is that before a C file is compiled, all macro constant names are replaced exactly with the value they refer to.
In the scope of this exercise, we will be using macro definitions exclusively as global constants. Here we define CONSTANT_NAME to refer to literal_value (an integer literal). Note that there is only a space separating name from value.
#define CONSTANT_NAME literal_value
Now, look at the code contained in eccentric.c. We see four different examples of basic C control flow. First compile and run the program to see what it does. Play around with the constant values of the four macro: V0 through V3. See how changing them changes the program output. Modifying only these four values, make the program produce the following output.
$ gcc -o eccentric eccentric.c $ ./eccentric Berkeley eccentrics: ==================== Happy Happy Happy Yoshua Go BEARS!
There are actually several different combinations of values that can give this output. You should consider what is the minimum number of different values V0 through V3 can have to give this same output. The maximum is four, when they are all distinct from each other.
Checkoff [1/3]
- Explain the changes you made.
- Explain the minimum number of different values needed for the preprocessor macros.
Exercise 2: Bit Operations
For this exercise, you will complete bit_ops.c by implementing the following three bit manipulation functions. You will want to use bitwise operations such as and (&), or (|), xor (^), not (~), left shifts (<<), and right shifts (>>). Avoid using any loops or conditional statements.
// Return the nth bit of x. // Assume 0 <= n <= 31 unsigned get_bit(unsigned x, unsigned n); // Set the nth bit of the value of x to v. // Assume 0 <= n <= 31, and v is 0 or 1 void set_bit(unsigned * x, unsigned n, unsigned v); // Flip the nth bit of the value of x. // Assume 0 <= n <= 31 void flip_bit(unsigned * x, unsigned n);
Once you complete these functions, you can compile and run your code using the following commands.
$ gcc -o bit_ops bit_ops.c $ ./bit_ops
This will print out the result of a few limited tests.
Checkoff [2/3]
- Show how you implemented get, set, and flip.
- Show the output of running the tests.
Exercise 3: Bit Analysis
For this exercise, you will complete bit_count.c by defining and implementing a function that analyzes the bits in a given integer. You must define a function that given some unsigned integer input x, computes the following:
- How many 1 bits there are in x.
- The highest position of a 1 bit in x.
- The lowest position of a 1 bit in x.
We are assuming 32-bit integers, so valid positions range from 0 to 31. If all bits are 0, both bit positions are -1 to indicate that there are no 1 bits.
During your implementation, you are not allowed to use structs.
Once you have declared and implemented this function, you can compile and run your code using the following commands. The program takes in a single input, which is parsed as the number to be analyzed.
$ gcc -o bit_count bit_count.c $ ./bit_count 0x801 NUMBER: 2049 BITS: 2 HIGHEST 1: 11 LOWEST 1: 0
You should test your program on various inputs.
Checkoff [3/3]
- Show how you declared and implemented your bit analysis function.
- You will be asked to run your program on a few specific inputs.