C Introductory Lab 1

Table of Contents

This assignment is to be done individually. You can talk to other people in the class, me (Dave), and any of the course staff (graders, lab assistants, teaching assistants, prefects) for ideas and to gain assistance. You can help each other debug programs, if you wish. The code that you write should be your own, however, and you shouldn’t directly share your code with others. See the course syllabus for more details or just ask me if I can clarify.

1 Get started

1.1 Use GitHub classroom to create a repository for your assignment

(Updated on Oct 1, 2:50 pm: there’s a new piece at the end, make sure to pay attention to the boldfaced text below.)

The first thing you’ll need to do is to create a repository for your project using GitHub classroom. Visit this GitHub classroom link (which I’ve placed in Moodle). Log into GitHub if need to. GitHub should then hopefully respond with a screen that says “You’re ready to go!” and will supply you with a link for the repository that you are creating.

Before you click that link, look below it to see text that says “We’ve configured the repository associated with this assignment (update).” The word “update” is a hyperlink: click it. Then, click on the link to the repository itself, and you should be taken to the repository.

1.2 Create a repl in Repl.it

1.2.1 Approach 1, if the “Work in Repl.it” button is working again:

Once you see your repository in GitHub (not Repl.it), you should see a button labeled “Work in Repl.it.” Click it. That should set up a new repl in Repl.it, and you should be all set to work. As always, make sure the repl created in Repl.it is private.

1.2.2 Approach 2, if the “Work in Repl.it button” is not appearing in GitHub:

In Repl.it, create a new repl. There are multiple places you can do this from. At the home screen, I see a blue plus in the top right corner; I can also access it by opening up the left sidebar menu via the “hamburger” menu on the top left. After clicking on “New repl” (or the blue plus, or whatever), you should get a popup with two tabs. The left tab says “Create new repl”; the right tab says “Import from GitHub”. Click “Import from GitHub.” You then see a box with the title “Paste any repository URL.” Then go to GitHub, specifically, to the repository you created in the previous section. Copy the entire web address from GitHub, and paste it into Repl.it. The URL you are copying should look something like

https://github.com/carleton251-f20/clab-1-username

(where username is your username)

When you paste it into Repl.it, it will abbreviate it a bit for you.

Then click “Import from GitHub.” This then creates the repl as usual. As always, make sure the repl created in Repl.it is private.

… and you should be all set to work.

2 Your tasks

2.1 Run your first program, and push to GitHub

Create a new file in Repl.it called hello.c. To do this, look at the Files browser on the left of the Repl.it window, and click the icon with a plus on it that is superimposed over a sheet of paper. (It’s different from the icon next to it for adding a folder.) Once you’ve added the file, you can type in its name. Then, copy and paste into the Repl.it hello.c file the content from this linked hello.c file. This program (unsurprisingly) is supposed to print “Hello, world!” to the screen.

Then use Git to add it to the repository. I’m going to switch over to using Git command line instructions rather than using the Repl.it “version control” buttons on the left, but you can do it either way. To do it at the command line, issue the following commands into the Repl.it terminal window:

git status
git add hello.c
git commit -am "Adding my new hello.c"

Next, compile the program to a binary executable by running the following in the terminal:

clang -o hello hello.c

This command should produce a file named hello. You should be able to see it in the file bar on the left in Repl.it, and also if you type ls in the terminal. Try running it at the command prompt:

./hello

If this worked, you should see “Hello, world!” output to the terminal.

EXERCISE 1: Change the program to print

Hello, CS251!

Run the program again. When complete, you can also run the script ./test-m, which will run the automated M tests. The section for HelloTests should indicate passing.

2.2 Printing

The first non-commented line of hello.c is: #include <stdio.h>. This directs the C compiler (or technically, a subprocess called the C preprocessor) to include a header file named stdio.h that lists the signatures of standard IO functions, such as printf.

The documentation for most of the built-in C functions can be found in the UNIX manual (“man”) pages. Take a look at the documentation for printf in particular. It tells you which header file to include to get access to that function (in this case, stdio.h), as well as documenting the interface and behavior of the function of interest. In this case, the manual page also includes several similarly-named functions such as sprintf and fprintf. Read through the first few paragraphs the man page for printf, and skim through the rest so you get a sense of what these pages look like. There are examples at the end, which is often the most useful part.

printf is similar to Python’s string formatting operator, in that it accepts a string that includes format specifiers to print integers, floats, etc. To see more about how printf and other operations work, create a file in Repl.it called printing.c, and then copy and paste in the contents from this printing.c file. It contains within a number of different examples of print formats. To compile and run your code, go back and look at how we did it for the hello.c program, and change accordingly.

Here are some common C types and their printf formatting specifications:

Format specifier Type
%c char
%i or %d int
%li or %ld long
%f float
%s string (really a char *)
%p pointer (e.g. int *

EXERCISE 2: Add code to printing.c that subtracts the value 15 from 87 and prints the result, together with an appropriate message. Check the PrintingTests section of the results from ./test-m to see if you’ve got it working correctly.

2.3 User Input

You can get user input using the scanf function (the manual page is here):

int i;
scanf("%i", &i);
printf("You entered: %i\n", i);

The first argument to scanf is a string containing formatting specification(s) for the type of input expected. In this case we expect an int.

The second argument should look pretty weird to you. How is scanf able to modify the value of i? What’s that ampersand symbol? The answer is that we’re actually passing a pointer to i’s location, not i itself - so the value of i can be modified from within scanf. There will be much more on pointers later.

EXERCISE 3: Write a program temperature.c that asks the user for a temperature in Fahrenheit and prints the temperature converted to Celsius. Assume that the input is handled as a float, instead of as an int. The relevant formula is:

temp_c = (temp_f - 32) * 5/9

For example, here’s what a sample run of temperature.c might now look like:

What is the temperature in degrees Fahrenheit? 42.5
42.500000 degrees Fahrenheit is 5.833333 degrees Celsius.

(If you’re interested: there are variants on the formatting specifiers that limit the number of zeroes. Read up on that further if you like.)

Check the TemperatureTests section of ./test-m to see if you have the output correct.

2.4 Loops and if statements

C has basically the same syntax for if statements, for loops, while loops and do/while loops as Java. However, there is a critical and very subtle difference with if statements that you should be aware of. C doesn’t have boolean variables, exactly. It just has integers, so false is 0 and true is any non-zero value. So the following abomination is legal C code:

int x = 1;
int y = 0;
if (x - y) {
    printf("You entered two different numbers!\n");
} else {
    printf("You entered the same number!\n");
}

If you want to make your code more clear, you can use the library stdbool.h as follows:

#include <stdbool.h>

int main() {
    bool x = true;
}

However, this is just syntactic sugar, which is a fancy phrase which means that we haven’t changed the underlying language, we’ve just changed the syntax a little bit. With the above, x is really just an int, and true is really just a 1. Why does this matter? Try running the following BUGGY code and see what happens. (You can create a new file for this called buggy.c for it.)

#include <stdio.h>

int main() {
    int x = 3;
    if (x = 5) {
        printf("x must be 5, even though I assigned it to 3.\n");
    }
}

Happily, clang does try to warn you when you do this.

EXERCISE 4: What happens if the user enters an impossible temperature in Exercise 3? Absolute zero, which is the coldest temperature anything can possibly be, is -459.67 Fahrenheit. Modify temperature.c so that if a temperature lower than that is input, it displays the text “Invalid temperature.” This test is in ./test-e; run that test to see if you have this part correct.

Exercise 4 is the last exercise that is due for part 1 of this lab. When done, you should commit and push your work to GitHub. One change we’ll make is that in order to get the M tests to run on GitHub, you should put a prefix of “M:” in your commit message. In order to get both the M and E tests to run, you should put a prefix of “E:”. (I’m making this change because we’ve been eating up a lot of our free testing minutes on GitHub, and so this gives you the freedom to push to GitHub without running any tests at all, if you like, while you’re experimenting.) So your commits might look like:

git commit -am "E: All my changes are committed"
git push

When you are done, follow the instructions from Scheme lab 2 as usual regarding using a commit message of “M:SUBMITTED” or “E:SUBMITTED”.

3 How to test and submit your work

Go back and look at the sections at the end of Scheme Lab 2 labeled “How to test your work” and “How to submit your work.” Those should apply identically here.