CSPP 50101 - Lab 1

Wednesday, July 22, 2011

In this Lab: You will need a CS account to log onto the CS cluster. If you do not have a CS account you can request one here.

Lab 1 is due Friday, June 24 at 11:59pm.

Part 1 - Getting started with Linux and C

The machines you will use in this lab run Linux, an open-source operating system that is well-suited for computer programming. Users interact with Linux by typing text commands at the command line, or shell. You will learn more about using Linux in Saturday's bootcamp, but in the meantime you can refer to some of the Linux and UNIX guides on the CSPP50101 course homepage, including:

Logging in and opening a terminal

Start a terminal by choosing the "Terminal" option in the Accessories menu, which appears with this icon:

Note that you can have multiple terminals open that the same time.

Now try your first command: Type date at the prompt and hit the enter key. This will run a program that displays the current date:

   $ date
   Mon Jun 20 09:20:30 CST 2011
You can find out more about a specific command by using the man command to view a man page.
   $ man date
Use the arrow keys to scroll up and down the man page, and press 'q' to exit.

The file system

The
Linux file system organizes files into directories. During a terminal session you always have a current working directory which is where you are "located" in the file system. Use the pwd command to look up your current working directory. You will see that currently you are in your home directory.
  $ pwd
  /home/username
In your actual session, username will be replaced by your personal CS username.

The file system has a hierarchical tree structure, meaning that a directory can have one parent directory and many child directories. The root directory, denoted by "/", is at the top of the tree. Every file and directory has a pathname, which tells us where the file is located in the directory structure under the root directory. For example, the pathname /home/username tells us that the directory username is in the directory home, which is a subdirectory of the root directory.

Creating directories

Use the mkdir command to create directories for your work in CSPP50101. First, create a single directory for the course:

  $ mkdir cspp50101

Use the command cd to change your current working directory to the new directory you just created (cd stands for change directory):

  $ cd cspp50101
  $ pwd
  /home/username/cspp50101
We say that /home/username/cspp50101 is an absolute pathname because it gives a location from the root, "/". In contrast, cspp50101 is a relative pathname, because it is written relative to your current working directory.

Next create a subdirectory for your work in Lab 1:

  $ mkdir lab1
  $ cd lab1
  $ pwd
  /home/username/cspp50101/lab1
You can move up a directory, to the parent directory, with the path ".." (dot dot):
  $ cd ..
  $ pwd
  /home/username/cspp50101
  $ cd lab1
  $ pwd
  /home/username/cspp50101/lab1

A first C program

Now that you have a directory for our work, you will compile and run our first C program.

First, copy the source code file square.c from the course lab directory into your current directory:

$ cp /stage/classes/archive/2011/summer/50101-1/lab/lab1/square.c .
Here the . (dot) at the end of the line denotes the current directory, where the file will be copied to.

Use the ls command to list all the files in the current directory. You should see square.c listed in the lab1 directory

  $ pwd
  /home/username/cspp50101/lab1
  $ ls
  square.c
Next compile the program square.c with the gcc compiler. Use the -o option to place the output in binary file square. If you do not use the -o option, the default name of a.out will be used for the output file.

  $ gcc -Wall -o square square.c 
  $ ls
  square square.c

-Wall is an optional argument to tell the compiler to display all warning that may apply to the source code square.c. We recommend that you always compile with -Wall, and that you pay attention to the warning messages that are generated.

Run the compiled program with this command:

  $ ./square
  show_square:  Initial value of x:  25
  show_square:  After x=x*x:  625

  main: Value of x is now 25

Editing a file with vi

Linux programmers use powerful command-based editor such as emacs or vi to edit source code and other text files. We will briefly cover vi here. For this section you may also want to reference one of the vi tutorials on the course homepage.

In this section you will edit the file square.c so that it displays the square of 13, not 25. To do this, you need to change a line of code in the main function. Type this command to edit this file with vi:

  $ vi square.c
vi will open and you will see the contents of square.c

vi has two modes: insert mode and command mode. When the editor opens you are in command mode, where you can move the curser to different locations in the file and execute other commands. You can move the cursor around the file with keys h,j,k,and l:

Use these keys to navigate to the "25" in the main() function. Your cursor should be above the "2":
int main ()
{
   int x = 25;

   show_square(x);

   printf("\n");
   printf("main: Value of x is now %d\n", x);

   return 0;
}
In vi you also use keystrokes to edit text. Command x deletes the character under your cursor. Hit x twice to remove the number 25 in the source file. If you hit x too many times you can undo a change by typing u.

Next hit the key i. This will put you in insert mode, and you will be able to insert text at the current position of the cursor. Type "13" so it appears before the semicolon:

   int x = 13;
If you make a mistake then hit ESC to return to command mode, and then hit u to undo your changes. Remember to hit i to return to insert mode before you type new text in the file.

Next save your changes. Hit ESC to return to command mode. Now type the command :wq. This command performs two actions at once: write (save) the file and quit the vi editor. If you want to exit without saving then use :q! instead.

You have just finished editing a file with vi. Now use gcc to compile your program. Then execute the program to check your output. Your new output should look like this:

  $ gcc -Wall -o square square.c 
  $ ./square
  show_square:  Initial value of x:  13
  show_square:  After x=x*x:  169

  main: Value of x is now 13
Before you go on, take a moment to review some of the vi commands in this vi tutorial. How can you do the following in vi? For your reference, here's another vi cheat sheet.

Scope and Local Variables

Now let's look at all the file square.c that you have just updated:
/* returns the square of n */
int square( int n )
{
  return n * n;
}

/* displays the square of n */
void show_square( int x )
{
   printf ("show_square:  Initial value of x:  %d\n",x);
   x = square(x);
   printf ("show_square:  After x=x*x:  %d\n",x);

   return;
}

int main ()
{
   int x = 13;

   show_square(x);

   printf("\n");
   printf("main: Value of x is now %d\n", x);

   return 0;
}
We see that the variable x is modified in the function show_square:
  x = square(x);
but that the value of x is unchanged when this printf statement executes in the main() function:
  printf("main: Value of x is now %d\n", x);

This is because these are two different variables which both have the name x. The scope of each variable is the function where it is declared or used as an argument. So, the x variable in main cannot be modified in the body of square.

Part 2 - Remote Access

You can access the CS cluster from your own computer by using ssh. See the CS department's page on remote access for details.

You can use this page to find a Linux machine that is available for you to ssh into.

  $ ssh username@classes.cs.uchicago.edu
  username@classes's password:
  ...  
  Last login: Sun Jun 19 10:21:03 2011 from 128.35.11.76
Use exit or logout to end your session.
  $ logout
  Connection to classes.cs.uchicago.edu closed.

Part 3 - Exercises

Exercise 1: Remote access

Find three Linux machines that you can access remotely. Save these names, you will write them in the README file that you will create in Part 4.

Use ssh to access one of these machines.

Exercise 2: Understanding compiler errors

Copy file ex2.c from /stage/classes/archive/2011/summer/50101-1/lab/lab1 to your lab1 directory. (Hint: use cp.)

In this program, we use the conversion specifier "%.2f" with printf() to print floating point variables to the terminal:

   printf("%.2f USD = %.2f JPY \n", usd, jpy); 
Here the "2" indicates that these values should be rounded to two decimal places before they are displayed.

Try compiling this program. You will see these error messages:

$ gcc -Wall -o ex2 ex2.c 
ex2.c: In function 'convert':
ex2.c:11: error: 'value' undeclared (first use in this function)
ex2.c:11: error: (Each undeclared identifier is reported only once
ex2.c:11: error: for each function it appears in.)
ex2.c:12: warning: control reaches end of non-void function
ex2.c: In function 'main':
ex2.c:18: error: 'jpy' undeclared (first use in this function)
ex2.c:18: error: too few arguments to function 'convert'
ex2.c:22: error: expected ';' before 'return'
ex2.c:23: warning: control reaches end of non-void function
These are compilation errors, which tell us that gcc failed to compile this source file. As a result the binary file ex2 was not created:
$ ls ex2
ls: cannot access ex2: No such file or directory
Let's look at the first error message.
ex2.c: In function 'convert':
ex2.c:11: error: 'value' undeclared (first use in this function)
ex2.c:11: error: (Each undeclared identifier is reported only once
ex2.c:11: error: for each function it appears in.)
Here ex2.c:11 tells us that an error occurred on line 11. In vi you can enter :11 (colon eleven) in command mode to move to line 11.

Now look at the description of this error message:

ex2.c:11: error: 'value' undeclared (first use in this function)
This tells us that a variable in the convert() function is being used before it is declared. What change should you make on line 11 to fix this error?

There are four compile-time errors in this program (including the error on line 11). Use gcc to find and correct these errors.

Hints:

If you use an exchange rate of 1 USD = 80 JPY then your fixed program should have this output:

$ ./ex3
199.95 USD = 15996.00 JPY

Exercise 3: Updating a program

Modify the program ex2.c so that it also performs a conversion from US dollars to Euros (EUR). First, make a copy of ex2.c. This way, you will not loose your work from Exercise 2 if you "break" your code:
$ cp ex2.c ex3.c
Now you can make changes to ex3.c to complete this exercise. Modify the main() function by adding a second call to convert() that converts 199.95 USD to EUR. You can use a rate of 1 USD = 0.7 EUR (or, you can look up today's rate). You will also need to add a printf statement to display the new output.

Compile and test your changes. Your output should look like this:

$ ./ex3
199.95 USD = 15996.00 JPY
199.95 USD = 139.96 EUR
Hint: In vi you can use command yy followed by p to copy and then paste a line.

Part 4 - Submitting your assignment

Lab 1 is due Friday, June 24 at 11:59pm.

First, be sure that every source file that you submit includes this information in comments at the top of the file:

For example:
  /* Sonjia Waxmonsky
   * wax
   * 
   * ex2.c: Converts from USD to JPY
   * 
   * Uses exchange rates from June 22, 2011
   *
   */

You will submit these files to the TA:

You should submit these files as a single .zip or .tar file. To create a zip file for this lab:

 
  $ zip username_lab1.zip README ex2.c ex3.c 
Do not submit any compiled binary files

Finally, email your zip file to the Lab TA, wax@cs.uchicago.edu. You can do this quickly with the mutt command:

  mutt -a username_lab1.zip -s "CSPP50101 Lab 1" wax < "."
If you use another mail client, be sure to include "CSPP50101 Lab 1" in the subject line.


prepared by Sonjia Waxmonsky