This laboratory exercise provides practice with basic elements of editing, compiling, and running programs written in the C programming language. This lab will ask you to use concepts from today’s assigned reading. You are welcome to refer back to readings during class, but you should work on building recall for many of the basic C concepts we’ll cover in the first phase of this class. My recommendation is to try to do as much of the exercise as possible before you turn to a reference. You and your lab partner may be able to reconstruct most of the important details if you work together.
For this part of the lab, you will write a simple program that creates, uses, and prints a variable. You’ll start your work from a blank source file.
Create a directory called c-basics to hold your work for this lab under ~/csc161/labs/ in your home directory.
The following terminal commands will do that for you, and then open the directory in VSCode:
$ mkdir ~/csc161/labs/c-basics
$ cd ~/csc161/labs/c-basics
$ code .
At this point you can continue to use the terminal you used to launch VSCode, but you may want to use the terminal built into VSCode instead. To open a VSCode terminal, go to View | Terminal. The terminal will start in the directory you opened with VSCode, but other than that it should work the same as the separate terminal program.
Once VSCode has opened, choose File | New Text File from the menu in VSCode, and then save the file as partA.c.
You can also do this with the new file button (a file icon with a “+” over it) in the file browser, but VSCode only shows the button while your mouse is over the file browser so it may be hard to spot at first.
Be careful to match the name exactly, including capitalization.
Once you’ve created partA.c you can move on to the exercises.
partA.c with a basic starting C program.
See how much of this you can reconstruct from memory before you go to the reading for reference.main function, create a new integer variable named x.
Give x some initial value.x.clang to compile the code in partA.c and save the output to a program named partA.
Make sure the compilation completes without errors or warnings, and then run the program to ensure it works as you expect.In this part of the lab you will intentionally add some common errors to your program from part A so you can learn to recognize common errors from the compiler.
Start by making a copy of partA.c so you can keep the working version intact:
$ cp partA.c partB.c
Open partB.c in VSCode by double-clicking it in the file browser.
Pay close attention to the file name that appears above the editor to make sure you are editing the correct file.
Once you have the file open, complete the exercises below.
You don’t need to keep all the broken versions you create, but you should write down notes about what you see as you introduce different errors.
partB.c that ends in a semicolon.
Remove the semicolon, save the file, and try to compile it to a program named partB.
What error message do you get?
What contextual information does clang give you with the error message?
Hint: part of the message tells you the exact source line where the error occurs.
If you are using the terminal built into VSCode, you can hold ctrl and click on that part of the error and VSCode will jump to the error in your source.
Make sure you understand all the parts of the message before you move on to the next error.x its initial value.
You should still have a variable named x, but it should never appear on the left side of the = (assignment) operator.
Try compiling the program.
What happens?
If the program was compiled, does it run correctly?-Wall to your compile command (this turns on all compiler warnings).
What happens?
Make sure you understand the message before moving on.partB.c file to a working state.
Next, edit the file so instead of a main function you instead have a mian function (we’ll pretend this was a typo).
Compile the program and see what happens.
Depending on how you wrote your original program you may see a warning about a missing return.
You can resolve this warning by adding a line that reads return 0; before the closing brace of the mian function.
There will definitely be an error from the linker telling you it couldn’t find a main function though.
Linker errors are just as serious as compilation errors, but they happen later in the process so they tend to give much less context.
The “undefined reference” error is a good clue that you’ve misspelled a name somewhere, or that you might have forgotten to write main at all in your program.main, we’ll introduce a typo in the name of x.
Change x so it is named y, but don’t update your use of the variable x in printf.
What happens when you compile the program?
Hopefully this error message looks more helpful than the error in the previous exercise.
We get errors about incorrect names from the compiler any time they appear inside one file.
Linker errors only pop up when get the name of main wrong or later when we work on projects with multiple source files.In this part of the lab you will practice writing a program to convert between measurements in different units.
As with part A, you’ll start from a blank file and build up to a working program.
Write your program in a file named partC.c.
Your program should create an integer variable called gallons and give it the initial value of 3.
From this value, you are going to compute the number of teaspoons in three gallons.
The following conversions should be helpful:
gallons variable.
Save each intermediate converted value in a new integer variable (e.g. quarts holds the number of quarts equavalent to the number of gallons stored in gallons, pints holds the number of pints in the calculated number of quarts, and so on).
Finally, print the result in a nicely formatted message.
When you compile and run your program it should produce output like this:
$ ./partC
3 gallons = 2304 teaspoons
gallons.
Test at least two other initial values and check the result by manually calculating the answer using the unit equivalents above.
Remember that all your calculations are using integer values, so your tests will all need to start with whole numbers of gallons.For this part of the lab, you will practice understanding C expressions that contain multiple operators. For each exercise, you will need to predict what a C expression evalutes to, write down that prediction, and then check it against the actual result you get by running the code. You’ll need to write a simple C program to evaluate these expressions, but you won’t need to submit this program so feel free to edit it as you work through the exercises.
Your small test program will need all the pieces of your program from part A, so that code may be a good starting point. You will need to assign the result of the provided expression to a variable and print the variable to see the result. Racket/Scamper allows you to evaluate expressions anywhere you like, but C requires all the code that runs in your program to appear inside a function.
5 + 4 * 3 + 1 evaluate to?
Make a prediction, write it down, and then check your prediction with a test program.50 / 4 * 10 / 2 evaluate to?
Again, make a prediction and then check the prediction by writing and running a test program.19 % 3 * 9 - 2 evaluate to?
Don’t forget to make a prediction first.One of the characteristics that sets C apart from Racket/Scamper is that many things you do in the language will have side effects. That means that a line of code doesn’t just compute some value; it will change the state of the program, e.g. the value stored in a particular variable. In the imperative style of programming we use sequences of state changes to perform computations.
The exercises below all refer to this C code fragment:
int j = 1;
int k = ++j;
int l = (k = j) * 4;
printf("j=%d, k=%d, l=%d\n", j, k, l);
j *= k;
k++;
l /= 4;
printf("j=%d, k=%d, l=%d\n", j, ++k, l++);
j, k, and l at the first printf.
Copy that part of the code fragment into a C source file, compile it, and run it to check your predictions.
Remember, this code will need to be inside of a main function for your program to work correctly.j, k, and l at the second printf.
Copy the rest of the program fragment into your C source file, compile it, and run it again to check your predictions.++x and x++).
Write a short explanation and try to come up with a good way to remember what each one does.
You might find it helpful to write a short test C program to check their behavior.