SI 204 Spring 2017 / Labs


Lab 01: Linux intro and binary numbers

1 Labs in this class

Labs in this class are your best opportunity to practice programming in a setting where you can get lots of help. Plan to have multiple conversations with your instructor and with your classmates throughout the lab time, discussing how to write, debug, format, and understand great C code.

Sometimes you might finish the assignment during the lab time itself, and other times you will have to finish outside of the lab time. The completed lab is generally due to be submitted electronically by the day before the next lab (so roughly 6 days later).

A few notes about the lab rooms (Michelson 302 and 316):

  • Our labs are available for your use many hours during the day, as well as after hours.
  • No eating is allowed in the lab. Drinks are allowed only in closeable containers (so soda cans are not permitted).
  • Be courteous and log off the computer when you leave the lab.
  • Do not attempt to physically alter any equipment in the lab.
  • Do NOT reboot the machines. If you really think a reboot is needed, talk to your instructor or to the sysadmin, Ms. Alex Nordman.

2 Coding, compiling, and submitting

2.1 The computing environment

  • To login to one of the computers in the labs, your username and password are the same as those of your USNA account.
  • You already have an account on the CS Department’s Unix machines, which are actually running GNU/Linux.
  • The Unix environment is quite different than Windows and will take some getting used to. A quick reference guide to common Unix commands is provided on the Resources page.
  • You are always welcome to work in the Unix labs throughout the semester. You should also be able to work just as well from your Virtual Machine.
  • Make sure you understand and confirm: Your home directory on the lab computers is the same as your csunix directory on your virtual machine (after running csmount from inside your VM).

The resources page is your starting point for help on how to use the computing environment and get things done for this class.

Remember this: when you leave the lab computer, log off but do not power down the machine. (That way, whoever comes in next can just sit down and login.) Specifically, you will:

  • Click the Power button in the top right corner and…
  • Choose the Log Out option. In general, you should never shutdown or restart the lab computers.

2.2 Opening the text editor

We will be using the Unix environment to create, compile, and execute C++ programs. First you want to get your terminal and folder set up and ready to go.

I recommend you get used to these steps on both your virtual machine and the lab computer.

  1. Open a terminal window. You can find the terminal window in the application menus, or just hit Ctrl-Alt-T like a wizard.

  2. If you’re on the virtual machine: mount and go into your csunix directory:

    1. Run csmount
    2. Type cd csunix

    (On the lab machines, your home directory is your csunix directory, so you don’t have to do anything here.)

  3. Make a directory for this class called si204 (if you haven’t already), by running the command

    mkdir si204

    Now set the permissions on your class directory so that no one else can access it other than you:

    chmod og-rwx si204

    All of your work for this class should go in this directory.

    Finally, do cd si204 to go into that directory.

  4. Make a directory for this assignment, and copy the si204.h header file to that directory:

    mkdir lab01
    cd lab01
    cp ~/si204.h .    # note: a dot . means the current directory

    For every assignment you work on (homeworks, labs, and projects), you should always start by making a new directory to hold your work for that assignment.

    At this point, the current directory (which is shown at the end of your prompt) should be either “~/si204/lab01” if you’re on a lab computer, or “~/csunix/si204/lab01” on your virtual machine.

Now you’re just about ready to get programming, but there’s an important, momentous decision to make first: what text editor will you use? The following are all available on your VM and on the lab computers. Choose wisely!

  • vi/vim/gvim - lightweight and powerful text editor. ← Drs. Albing and Roche’s recommended choice!
  • emacs - feature-rich text editor. ← Richard Stallman’s favorite!
  • atom - a new pretty-to-look-at editor (written in Javascript) ← Favorite of those distracted by pretty lights.
  • gedit - similar to Windows Notepad. ← Feels nice and comfortable, like an old sweatshirt. Do you want to program with a sweatshirt?
Real Programmers
Real Programmers

If you’re using VI, start with this quick intro and list of useful commands. If you’re using emacs, check out this getting started guide. The resources page also has further references to help you learn the powerful features of these text editors. (You should be able to get started in atom or gedit without any extra help.)

Now, open your text editor in the lab01 directory and create a new file called printing.c. You can open the text editor using the application menus, or directly in the terminal window by typing:

gvim printing.c &

The ampersand & at the end of the line ensures that you can keep using the terminal even after the editor opens up. (Of course, you can substitute emacs, atom, or gedit in the command above for your editor of choice.)

2.3 Creating a program

At this point, you should have a terminal window open, inside your lab01 directory. You should also have a text editor open for a file called printing.c in that directory. If you save the file and then do ls on the terminal, you should see printing.c as well as the si204.h file that we copied to the directory already.

Now use your text editor to copy in the following source code into the printing.c file:

#include "si204.h"

int main() {
  fputs("And then my heart with pleasure fills,\n", stdout);
  fputs("And dances with the daffodils.\n", stdout);

  return 0;
}

The following sequence of steps will become very familiar to you!

  1. Save your file. (Most text editors have a little + mark or something in the title bar to show you whether the file has any unsaved changes, which can be a very useful check!)

  2. Return to the terminal and compile using the command:

    gcc printing.c -o printing
  3. If you copied the file correctly, there should be no errors at this point. Run your compiled program with the command:

    ./printing

    Note the ./ part indicates that you want to run the program called printing in the current directory. A single dot . is a shortcut to indicate the curent directory.

  4. Program Output: Your program will output to the same terminal from where it was executed. You should see two lines of text, followed by a return to your prompt.

    Now, let’s view the executable file you just executed. Type ls -l to list details of the contents of your current working directory. There is are now three files: si204.h, printing.c, and printing. That last file is the executable program that you made from the compilation command.

    The numbers to the left of the dates in the ls -l output tell you how large (in bytes) each file is. Notice that the executable file printing is much larger than either source code file si204.h or printing.c. The increase in size is due to all the code that was “included” or linked into your program to make it run on its own.

3 Editing your program

3.1 The “error” of your ways

Inevitably when programming, you will make some mistakes. Some of these mistakes will be noticed by the compiler, which will print out a message that tries to indicate exactly what caused the error.

Each error message includes a number, which represents the line number of the error. Go to that line number to see where the problem is. Once you’ve tried a fix, compile again (and again…) until all the errors are fixed. Only then will you be able to run your program.

Here are a few simple rules and hints:

  • Save program files before compiling.
  • If an error is flagged on a line that looks perfectly fine, sometimes it is the preceding line that is messed up. Check it too!
  • Check for missing or extra ;, {, or } characters.
  • Compile your program in small chunks. That way you can focus on errors in a small section of code. Waiting to compile until the entire program is completed can lead to large numbers of errors.
  • Messages that say “Cannot convert from … to …” usually mean you are trying to assign the wrong type to a variable.
  • Check your names. A common mistake is to name a variable one thing but spell it wrong or use some other name later.
  • It’s almost always best to solve one error at a time, starting with the first one. Frequently, one small mistake can lead to what the compiler sees as many errors, so start by fixing the first one and re-compiling.
  • If you can’t figure out what’s wrong - ASK! Your instructors and MGSP leaders have lots of experience and are here to help you decode what the compiler is telling you.

Experience and practice help a lot here. So for each of the below, purposefully make the syntax error in your current program and try to compile to see what the error message is. Correct the error before introducing the next error into your program (e.g., only add ONE ERROR at a time). Go slowly and pay attention, this will save you time later!

  • remove a semi-colon.
  • change a comma , to a period .
  • change change one of the stdouts to stdOut
  • change one of the stdouts to stdin.
  • remove the ending }.
  • remove the #include "si204.h" line.

3.2 Changing the program

You should be getting a little more comfortable now with your text editor and compiler, which are the most important tools for programming. Now try modifying your printing.c program so that its output matches exactly what’s shown below. Try to use the features of your text editor like copy/paste, moving around, and so on, rather than just tying in more code “by hand” to make these changes.

And then my heart with pleasure fills,
And dances with the daffodils.

And then my heart with pleasure fills,
And whistles with the daffodils.

And then my heart with pleasure fills,
And sits down with the daffodils.

And then my heart with pleasure fills,
And listens to the daffodils.

I like 1 flower.
I like 2 flowers.
I like 3 flowers.
I like 4 flowers.
I like 5 flowers.

And then my heart with pleasure fills, and dances with the daffodils.

Important: Your focus is on using the editor to make these changes as efficiently as possible! In other words, of course you can do it, I want you to concentrate on doing it smart! It’s almost a puzzle to use as few keystrokes as possible.

3.3 Submitting your code

Follow the instructions here to submit your printing.c file for lab01 to the online submission system.

After running the 204sub command to submit, the resulting output should include “The submission may be reviewed online at” followed by a URL. Copy that URL and paste it into your browser. The resulting page should tell you how you did. If you did not get the output 100% correct, the page should give you an indication of what’s wrong with your output. Keep fixing your program and resubmitting until it works perfectly.

4 Reading Binary Numbers

Now you will write another program from scratch. Call this program readbin.c in the same lab01 directory.

As you may recall, numbers can be represented in various bases. A base describes how many unique digits are used is representing the number. For example, we mostly represent numbers in base 10; there are 10 different digits used to represent the numbers: 0,1,2,3,4,5,6,7,8,9. Numbers can be represented in many (infinite!) other bases, such as base 8. In base 8 the numbers are represented with only 8 digits: 0,1,2,3,4,5,6,7. The actual value of a number depends on both what digits are used, and the location of the digits. Obviously, the number 123 is smaller than the number 321. In particular the farther left a digit is, the more contribution it makes to the size of the number. If we number the columns from right to left, starting with 0, then when the base is b and the digit d is in column c, the the contribution of that digit to the value of the number is d*bc. For example the number 123 base 10 (written 12310) is 1*102 + 2*101 + 3*100, which totals 123. For a less obvious example, 1238 is 1*82 + 2*81 + 3*80, which totals 83.

The reason you’re reading all this is because computers don’t store their numbers in base 10, but rather in base 2 (the only digits are 0 and 1). As computer programmers, we need to be able to convert numbers from the binary (base 2) format to the decimal (base 10) format. That is what you will do for the lab.

You will write a program (use filename readbin.c) that converts a number from binary to decimal format and prints out the decimal value of that number. In particular your program will:

  1. Prompt the user to enter a 4-bit binary number (Recall that binary digits are also called bits). You may assume that the number the user enters really is a binary number.
  2. Read the number in as four separate characters.
  3. Convert each character to an integer (either 0 or 1).
  4. Compute the single number according to the formula \(n = 8*d_1 + 4*d_2 + 2*d_3 + 1*d_4\)
  5. Print out the decimal value of the number.

Here is a sample run of the program. The program output is shown in blue, and the user input is shown in green.

roche@ubuntu$ ./readbin
Enter a 4-bit binary number: 1101
In decimal 1101 = 13

5 Converting Back to Binary (going further)

The rest of this lab is optional for your enrichment and enjoyment. Be sure to work on this only after getting everything else perfect. You should still submit this work, but make sure it doesn't break any of the parts you already had working correctly!

A few questions to ask yourself: If x = b3b2b1b0 is a 4-bit binary number, what is x/2? (Remember, this is int division!) What is x%2? What is x*2? What is x/4? What is x%4? What is x*4? Why 2 and 4? What’s interesting about those?

Just as one might want to convert from binary to decimal, one might want to perform the conversion the other direction (decimal to binary). The basic principle is the same, except instead of multiplying by powers of two, we need to divide (and mod) by the powers of two. For example, if the decimal number is 11 and we want to convert to a 4 bit binary number, then the leftmost bit (column 3) is 11/(23), or 1.

You will write a program (use filename writebin.c) that converts a number from decimal to binary format. You will then print out the binary value of that number. You need to figure out how to perform the conversion. You know the first step.

  1. Prompt the user to enter a decimal number between 0 and 15, inclusive. You may assume that the user really does enter a number in that range.
  2. Read in the number as an integer.
  3. Convert the number into four binary digits.
  4. Print out the four digits.
roche@ubuntu$ ./writebin
Enter a number between 0 and 15: 13
13 in binary is 1101

Hint: If you’re having trouble thinking about this, try doing a base 10 version first - i.e. write a program that reads a 4-digit decimal number into an int variable and then picks apart the int to figure out what the original decimal digits were - perhaps printing each digit out separated by a space. This should give a good analogy to what you’re trying to do with the binary version.