By the time you have completed this lab, you should be able to
Carefully choose the first pilot. Let the person who was the pilot for the shortest duration in lab01 be the pilot first this time. Switch roles after awhile, before the pilot gets tired, and before the navigator gets bored or distracted.
If your assigned partner is more than 5 minutes late, ask the TA to pair you with someone else for this week.
This lab's pilot should log in. You will (both) work in this account for the rest of the lab.
Create a ~/cs16/lab02 directory and make it your current directory:
mkdir ~/cs16/lab02 cd ~/cs16/lab02
Start ch. As a reminder, here is what it looks like started from kyledewey's account:
-bash-4.2$ ch Ch Professional edition, version 6.1.0.13751 (C) Copyright 2001-2009 SoftIntegration, Inc. http://www.softintegration.com /cs/student/kyledewey/cs16/lab02>
Now accomplish the following steps in order (we show you exactly how to do the first few steps, but after that you are mostly on your own):
;
(semicolon) is optional in ch,
but it is mandatory in Standard C.
/cs/student/kyledewey/cs16/lab02> int x;
/cs/student/kyledewey/cs16/lab02> x = 341; 341
%d
(for decimal) conversion specifier. Print a newline character too.
Normally the format string of our printf statements will end with a \n
(newline) character, but we can omit it now since ch prints its own newline whenever it
executes a statement that is not a declaration.
/cs/student/kyledewey/cs16/lab02> printf("decimal: %d", x); decimal: 341
%x
as the conversion specifier. [Note: the up arrow repeats the
previous command, but you can edit it before entering.] Second print and label the octal
(base 8) representation - use %o
for octal. Finally print it in binary
(base 2) - ONLY IN CH - there is a %b
conversion specifier, but this is not
available in Standard C.
Verify the results exactly match the following before going to part e:
hex: 155 octal: 525 binary: 101010101
/cs/student/kyledewey/cs16/lab02> char c = x;Hmmm ... apparently that is okay, but let's find out what really happened.
%c
as the conversion specifier.
The scanf function uses (mostly) the same conversion specifiers as printf does, but its purpose is to store the value of user input data into the memory locations of variables.
The memory location of a variable means the (numerical) address where the
first byte of the variable is stored in memory. The C operator &
is known
as the "address of" operator. Assuming x was already declared (e.g., as int above), then
ch will actually display this address in hexadecimal form if you type the expression:
/cs/student/kyledewey/cs16/lab02> &x 0x9c95534
The address of your variable probably will be different than the one in the example. But it
doesn't matter, right? What matters is that you get to refer to that address with &x
.
Now use scanf to let the user (you in this case) enter a new value of x in decimal form, and then display x to verify it worked. For example:
/cs/student/kyledewey/cs16/lab02> scanf("%d", &x); 17 /cs/student/kyledewey/cs16/lab02> /cs/student/kyledewey/cs16/lab02> x 17
Curiously, ch seems to enter an extra newline when scanf is used. Don't worry about that, and know that it won't happen in Standard C. The main thing is we can store user data in a memory location for later use.
In fact, scanf does return a result - the count of values that it converts - in addition to storing user values in the specified memory locations. To verify, initialize a new int named count with the result of scanf (input 17 again), then let ch display count:
/cs/student/kyledewey/cs16/lab02> int count = scanf("%d", &x); 17 /cs/student/kyledewey/cs16/lab02> /cs/student/kyledewey/cs16/lab02> count 1
This count is scanf's way of reporting success. Try it again (without declaring count again),
but this time, enter something that is not a number. BE PREPARED though, as this operation
likely will confuse ch - enter ctrl-d
(hold the ctrl button and touch d) to return
to normal ch mode. Then display the values of count, to verify it equals 0, and x to verify it
still equals 17:
/cs/student/kyledewey/cs16/lab02> count = scanf("%d", &x); cat 0 <-- here ch printed result of scanf, and echoed bad input on next line /cs/student/kyledewey/cs16/lab02> cat <-- after this, ch got stuck until ctrl-d /cs/student/kyledewey/cs16/lab02> count 0 /cs/student/kyledewey/cs16/lab02> x 17
Do one more exercise before proceeding to Step 4, to find out what happens when the user enters a floating point number where an int is expected. Repeat the last few steps, but enter 92.5 or another value with a decimal point in it. Try to understand the results, and at least jot down what happened in case the TA asks you about it later.
First: switch roles between pilot and navigator if you did not
already do that.
Always stay logged into the original pilot's account.
Accomplish each of the following steps in ch (using the int variable named x):
%d
with %x
). Do enter a hexadecimal number like beef
,
and then display x (should be decimal 48879 if you entered beef).%i
which allows the user to enter the value as any legitimate C constant
for integers. That is, the value can be entered either in decimal form (the default),
or octal (has a leading 0), or hexadecimal (has 0x at the beginning). Use the following
statement and display the resulting value of x at least three times to find out how it
works:
scanf("%i", &x);First enter a decimal value such as
59
, then an octal value such as
0100
(verify it equals decimal 64), and finally a hexadecimal value
such as 0xbeef
.Note: in CH ONLY, you may also specify an integer constant in binary form by leading it
with 0b as in 0b11110
, but it doesn't seem to work with the %i
conversion specifier, and it is not available in Standard C. This should work though:
try typing such a constant at the ch prompt and watch as the decimal value is displayed:
/cs/student/kyledewey/cs16/lab02> 0b11110 30
After you finish these exercises, exit ch and proceed to Step 5.
Save a copy of this bases.c skeleton as bases.c in the original pilot's lab02 directory. You can cp a copy from the instructor's account:
cp ~kyledewey/cs16/lab02/bases.c ~/cs16/lab02
Add the following features to this file using emacs (or another editor of your choice). Then save, and quit the editor.
YOUR NAME(S)
" inside the comment at the top with your names.
[Probably we won't give this instruction explicitly in future labs, but you should
ALWAYS DO IT.] All other changes will be inside the main function - insert the statements
immediately after each informative comment in the file.:
(colon), but there is no newline printed
in this example. Try to mimic that behavior.You can use ch to test your program without starting a ch session. Here is a test of our solution (note the user entered the value in hexadecimal form this time, but it should work with other C constants too):
-bash-4.2$ ch ./bases.c enter an integer: 0x1ff decimal: 511 octal: 777 hex: 1ff -bash-4.2$
If errors occur: (a) don't panic, and (b) don't immediately ask the TA for help! Instead, take a deep breath, and then actually read the message that comes up. It will often give a line number, and some hint as to what might be wrong.
If you've really looked, and are still stumped after two or three tries, then you might ask the TA for help. But try to fix it on your own first.
When you are satisfied it works, make an executable version of it. Then run that version to show the TA:
-bash-4.2$ make bases cc bases.c -o bases -bash-4.2$ ./bases enter an integer: 755 decimal: 755 octal: 1363 hex: 2f3 -bash-4.2$
If no errors, proceed to Step 7. Otherwise try to figure out the problem and fix it yourselves before asking for help.
Submit the assignment with the turnin program. You MUST have both your name and your partner's name in the file in order to receive credit. Remember that the original pilot needs to do this step, since that is whose account you have been using in Cooper Lab.
Bring up a terminal window on CSIL, and cd into the original pilot's cs16 directory, and cd again into the lab02 directory. Then type the following:
turnin lab02@cs16 bases.c
Respond "yes" when the program asks if you want to turn in (be sure to read the list of files you are turning in), and then wait for the message indicating success.
Optional Extra Challenge
- Did you try any negative values in the exercises above? Try it now by entering a negative value in decimal form to your bases program:
-bash-4.2$ ./bases enter an integer: -92 decimal: -92 octal: 37777777644 hex: ffffffa4 -bash-4.2$Does the value look odd to you in its octal and hexadecimal forms. The reason is that negative values are stored in "two's complement" encoding.
See http://en.wikipedia.org/wiki/Two's_complement for an explanation.- Start ch and use printf with the special ch conversion specifier
%b
to find out the binary representations of some negative values. Especially find out how -1 is represented. After printing a few negative values in binary form, try to figure out the binary representation of different values by hand, and then check your answers.- Recall that you can specify the field widths in which printf will display a value. For example, the following statement prints the value of x right-justified in a field of width 10:
printf("%10d", x);Experiment with this feature. Then modify a copy of bases.c (call it fbases.c for instance) to print the three different bases neatly lined up on the right. First decide how wide a field is necessary to print the widest possible value, then use that field width as a guide to select widths for the other bases. Remember to consider the lengths of the labels too. Here are results from our revised solution:-bash-4.2$ ./fbases enter an integer: -52 decimal: -52 octal: 37777777714 hex: ffffffcc- Experiment more with printf, scanf, and/or integer bases if the lab period is not done yet.
Adapted by Kyle Dewey from the work of Michael Costanzo.