Lab 02

Basic C programming

The goal of this tutorial is to learn basic C programming constructs. We will do this by examining some of the familiar constructs from Java and learning their C equivalents.

In order to make things more interesting than simply printing out “Hello world.” like we did in the last class, we will be using a basic bitmap drawing package base on turtle graphics.

Row of Shapes

Learning Objectives

By the end of this lab, you should be able to:

Starter Code

First, download the starter files:

IN THE LINUX LAB (ISAT 250): Download lab02.tar.gz and untar it from the command line with the following command from the folder that you saved the file in:

tar -zxvf lab02.tar.gz

IN THE MAC LAB (ISAT 248): Download lab02.zip and unzip it by either double-clicking it or using the following command line command in the Terminal from the folder that you saved the file in:

unzip lab02.zip

The starter code has four files: a main.c, which you will be modifying; turtle.h and turtle.c, which contain the turtle graphics library; and an OS-specific Makefile (the latter is why it is important to download the correct file for your lab).

Open up the main.c file, and add the following lines to int main() where it says // TODO: add your code here:

turtle_forward(100);
turtle_turn_left(90);
turtle_forward(100);
turtle_draw_turtle();

Now compile and run the main program. You’ll see that it produced an output file, output.bmp. Open this in an image viewer:

IN THE LINUX LAB (ISAT 250): Use the following command from the project folder:

eog output.bmp

IN THE MAC LAB (ISAT 248): Double-click the bitmap file in Finder or use the following command in the Terminal from the project folder:

open output.bmp

The turtle.h contains complete documentation for the functions available to you in the turtle library. The following functions should be enough for today’s lab:

To learn more about the turtle library, see the reference page.

Getting Started

Java to C: A Crash Course

Data types

C has multiple integer data types; the most common is int, which is sufficient for our current needs. It is a signed integer at least 16 bits wide. On most modern architectures, it is at least 32 bits.

You can read about the other integer data types at the wikipedia page. In future labs, we will use the size_t type, which is used by convention when we want to store non-negative size values.

Like Java, C has two floating-point formats: the 32-bit float and the 64-bit double.

Like Java, C also has a single character data type called char. However, unlike Java, C does not have a built-in string type. Rather, strings are conventionally stored as an array of char values. We will discuss strings in C next week.

Finally, if you #include <stdbool.h>, you may use the bool data type, which is the same as the boolean data type from Java. The bool data type is not part of the original C specification; it was a convention to use integers instead (0 for false and 1 for true).

Comments

Like Java, C has two kinds of comments: a single line format and a multi-line format. Here are examples of both:

c = a + b;          // this is a single line comment

/* this is a
 * multi-line comment */
d = a * b;

Console output: Using printf

The C standard library contains a very powerful string output function called printf; it can handle many different kinds of output formats. For the purposes of this class, we will only need a few features.

The printf function is rather unusual in that it can take a variable number of parameters. The first parameter is always a string, often called the “format string.” If all you want to do is print a simple string, that’s all you have to pass:

printf("Hello!\nThis is some simple text.");

The resulting output is:

Hello!
This is some simple text.

There are several important escape sequences:

Code Description
\n newline
\r tab
\" quote mark

To print the values of variables, you can embed format specifiers into the format string. For example:

int a = 42;
float pi = 3.141592;
printf("The answer is %d and %s is approximately %f.\n", a, "PI", pi);

The resulting output is:

The answer is 42 and PI is approximately 3.141592.

Here is a list of important format specifiers:

Code Description
%d signed integer (int)
%u unsigned integer (size_t)
%f floating-point number (float or double)
%e scientific notation (float or double)
%c character (char)
%s character string (char[])

There is no format specifier for the bool data type. If you wish to output the value of a boolean, you will need to use a conditional to print different strings (perhaps "true" and "false").

Here is a full reference to all the capabilities of the printf function.

Conditionals

Conditional statements in C look exactly like their Java counterparts.

if (some-test) {
    ...
} else if (a-second-test) {
    ...
} else {
    ...
}

Functions, parameters, calling, and recursion

Function definitions in C look very similar to their Java counterparts. For example:

int add(int a, int b) {
    return a + b;
}

In this example, the function add takes two integer parameters, a and b and returns an their sum as an integer.

One difference between Java and C is that in Java every “function” is a method of some class. So the add function defined above would be part of some class and to call it, you would need an object of that class. Something like:

int result = obj.add(3, 4); // add 3 and 4 using the add method of obj

C, however, is not object oriented. Functions are not part of some parent object, so you call them directly:

int result = add(3, 4); // add 3 and 4 using the add function

Exercise: Drawing Rectangles

Question: Can you define the function after main()?

Looping: for and while

As with Java, the main looping constructs in C are the for and while loops. Unlike Java, there is only one syntax for the for loop, namely:

for (int i = 0; i < n; i++) {
    ...
}

or more generally,

for (initialization; condition; update) {
    ...
}

The while loop behaves exactly the same as in Java:

while (something_is_true) {
    do_this();
}

Exercise: Rows

Optional Exercises

Polygons

Hint: * This can be accomplished using either a for or a while loop. * Note that the turning angles required to draw a square are all 90 degrees and that 90 = 360 / 4.

Grids

This function should create a rows x columns grid of squares each of size size with the lower-left corner at (x, y). The size parameter indicates teh width of the individual squares.

A grid of alternating color blocks

Random Walks

Here is some code that simulates rolling a single die, generating a single random number in the range [0,5]:

#include <time.h>
#include <stdlib.h>

/*
 * returns a random integer from 0 to 5 (inclusive)
 */
int roll_dice()
{
    static int initialized = 0;
    if (!initialized) {
        srand(time(NULL));
        initialized = true;
    }
    return rand() % 6;
}

Don’t worry about the details of how that function works right now; just copy-and-paste it into your main.c above the main() function declaration. Now write a function called turtle_random_walk that does a random walk. It should take an integer parameter telling the turtle how many steps to take.

For each step, the function should call the roll_dice function to generate a random number. If the number is 0 or 1, the turtle should move forward 10 spaces. If the number is 2 or 3, the turtle should turn left 90 degrees. If the number is 4 or 5, the turtle should turn right 90 degrees.

Run your program several times and observe the results.

Challenge Problem: Sierpinski

If you want some practice with a more complex algorithm, try writing a function that draws a Sierpinski triangle. You should be able to reuse the polygon function you wrote earlier. Here is an example of what the end result should look like:

A Sierpinski triangle

Hint: Use recursion =D.