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

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. Click on that link, and you should be taken to the repository.

1.2 Clone your repository into Repl.it

Since this is an individual assignment, you'll again use the my-work repl in Repl.it that you created. In Repl.it, start up your my-work repl, and then make sure that you are in your home directory in the terminal window. You can always navigate there by typing

cd ~

in the terminal window. To further confirm, type pwd (which is short for "print working directory.") You should see /home/runner. If you see something different, you're not in the home directory, so try again or ask for help.

In a different browser tab (leave the one with Repl.it open), visit our our class GitHub organization page online. Once you've landed there, you should see the GitHub repository you created in the GitHub Classroom step above. It should be named c-lab1-username (where username is your username). Contact us for help if the repository isn't there. Click on that repository title. This should take you to the home page for that repository. There is a green box on the page that says "Clone or download." Click that box, and make sure it says "Clone with HTTPS." Highlight the https link shown, and copy it to the clipboard. The link that you're copying should look something like

https://github.com/carleton251-term/c-lab1-username.git

… though your username and term will be different.

Then navigate back to the Repl.it tab with the repl that you created above, and click on the terminal window within your new repl. Your next step is to clone the repository from GitHub. To do that, type git clone, then a space, then paste in the URL from the github page that you copied from above. (To paste, you might need to right-click in the terminal window and choose paste rather than using a keyboard shortcut.)

For example, I would type the following, though your username and term will be different:

git clone https://github.com/carleton251-term/c-lab1-username.git

You'll be prompted to enter your GitHub username and password.

If all goes well, you should receive a directory, titled c-lab1-username. If you type ls at the prompt, you should be able to see it. It will also appear in your file browser window with Repl.it on the left. Then navigate into that directory by typing in:

cd c-lab1-username

… 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. Make sure that it is in your c-lab1-username directory. To do this, click on the c-lab1-username folder in 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 add it to the repository by issuing 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 should commit and push your updates to GitHub. See instructions above. Verify that you can see your updates on the GitHub website.

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. Add your file with Git, commit your updates, and then push your changes to GitHub. Verify that you can see your updates on the GitHub website.

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 forumla 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.)

Add, commit, push to GitHub, and check on GitHub that your file made it there.

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." Use git to add, commit, and push to GitHub when complete.

Exercise 4 is the last exercise that is due for part 1 of this lab. You have now pushed a number of commits to GitHub, and you'll follow with more for the remaining exercises. The graders and I need to know which commit is the one that we should use for grading. This is handled well in Git with tags. Here's how to do it at the command line:

git commit -am "All my changes are committed, I may have already done this"
git push
git tag submitted
git push --tags

Then look on GitHub after the last push, and click where it says "X commits" (where X is a number). That will show you the commit history. If you click on your most recent commit, you should be able to see the tag listed there.

You should wait to tag until you're sure you have committed the version you want us to grade. That said, in the unlikely event that you goof and realize that you want to commit a newer version for us to grade, you'll need to use another tag. Reusing the same tag for a different commit is generally a really bad idea. If you need to tag another commit, append a ".1" (or whatever version number you're up to. Make sure you first add, commit, and push your commit before tagging.

Here's a long tangent. Note that GitHub displays the tags wrong. In Git a tag is associated with only a single commit, but GitHub will show you that same tag if you click on all commits that precede it. (Note that this is making a distinction between Git, the local software tool, and GitHub, the webserver.) GitHub is trying to be helpful by showing you all commits that contribute to a release, as that's how tags are often used, but GitHub is ultimately misrepresenting what a tag in Git actually is. The command line can show you a much better representation of your Git history, tags included. To do this, I recommend making a custom git log command. Copy and paste the following, if you like, to create a new command to show your git graph well.

git config --global alias.lol "log --graph --decorate --color --pretty=format:'%h %Cred%d%Creset %ad %ae %n%s%n' --abbrev-commit --date=local --all"

Then issue the following command to make it work:

git lol

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, with the single change that you have multiple files that you have added, and you have been committing them as you go. Follow those instructions, and you should hopefully be all set.