COS 126 Lecture 2: Introduction to C

slide 1

It's critical that you understand what a function is and how to write one. Some of the functions you will use in your programs are library functions. They have already been written for you. The first library function you will probably use is 'printf' The printf function prints to the screen. To use a library function, you need to 'include' its library. Later on in the course, we'll learn more about the 'include' statement. For now, just know that, for example, to use printf, you need to have the statement:

#include <stdio.h>

at the top of your program. (stdio is short for standard input/output.) In the back of K & R, descriptions of the most commonly used library functions are provided.

In C (and most programming languages), we have the concept of 'types.' They describe data used by your programs. The primitive types you will use are:

int
integer values, both negative and positive
float
like real values, but not really. There is a limit to how precise they are - kind of like values in a calculator. 1/3 is represented as 0.33333 (with some limit to the number of 3's)
char
a character, including the letters of the alphabet in addition to the character representation of digits and other symbols.

A function computes a value (usually.) When you write a function, you need to specify its type; that is, what type of value will be computed, or returned by the function. For example, if your function is counting something, it will return an int. On the other hand, if your function is computing the average of some numbers, it may return a float. The 'return' statement at the end of your function must return a value of the same type as your function.

The return value is the output of the function. You also need to specify the inputs to the function, if any. The inputs are called the 'parameters' of the function. They are enclosed within parentheses, separated by parentheses following the name of the function. The example function given on this slide has 1 parameter: float x. It has two parts: a type and a name. Its name, x, is arbitrary: you can give a parameter any name you want (but you should try to give it a meaningful name...more on this later.) You'll use the name you give the parameter within the function to refer to the input value.

For example, if you want to write a function to compute the average of three exam scores, the first part of it might look like this:

float average(int mid1, int mid2, int final)

Or, it could also look like this. The names you give values in your program don't affect the results.

float avg (int x, int y, int z)

The second part of this slide describes declarations and statements. You'll learn more about these in precept.


slide 2 - Anatomy of a C program

You should definitely work hard to develop the ability to read a C program. It will make writing programs much easier for you. This program has the format that we will generally use in this class. If you've learned to program somewhere else, you may already have your own style. And as you become more comfortable with programming, you will probably develop your own style. That's fine. Here's how to read a program in the format of the one on this slide:

Start at the top. Look at the functions that have been written for the program. You don't need to read the code within them (within the { and } ); just look at the names of the functions, for now. In this example, there's only one function (besides main), and it's named 'f'.

Now, start at main(). Main is a special function in a program. When you want to 'trace through' a program, reading it line by line, you need to start at main. It is helpful to write notes as you read through the program. The first note that I would write is that h has the initial value of 0. I would write that like this:

h
--
0

As h changes values, I'll list them in a column underneath the 'h.' If the program had more values, I'd add more columns to my table. Now, you need to check the condition in the while clause. If the value of h is less than 2, you'll continue on to the next line. Since 0 is less than 2, the printf statement will execute. It's good to write down whatever the computer will print on a piece of paper, too. The value of h (0.0) and the value of f(h) will print. To find the value of f(h), you need to 'jump' up to the function f. Step through this function, replacing x with the value 0.0. So, you will return 2 - 0.0*0.0*0.0 - the function returns 2, and so a 2 prints. When you return from a function, you pick up where you left off in the main (or calling) function. So, continue, and execute the line: h = h + 0.1

Now, I'd update my table of h values with this new value. When you reach the '}' end of the while loop, jump back up to the condition: (h < 2.0). Check whether it's still true. It is, so repeat the two statements of the while loop. When h is no longer less than 2, you will exit the while loop. There are no more statements in your main function, so you are done.

You can test your results by typing this code (or copying it from the website) into a file, compiling it (type 'lcc fileName.c'), and run it (type 'a.out'). Compare what you've written on paper with what prints on the screen. They should both match the values given on slide 5 of this lecture.


slide 3 - printf library function

Read the corresponding sections in K & R to learn about formatting. printf isn't too complicated, so don't panic. In its most simple use, you can print any phrase. Just type whatever you want to print between the quotes, like this:

printf("Hello, my name is Lisa.");

You will often want to print multiple lines. To end a line, you need to print a carriage return. (This is like telling the computer to press the 'return' button.) To do this, you type '\n' within the quotes.

Now, you will also want to print out the values of variables in your program, like h in the previous slide. To do this, you will use %f (for float values) and %d (for integer values.) After the quotes, put the names of the variables you want to print, corresponding to the %f, %d 's, separated by commas. The numbers between the % and f (or d) are formatting values. They affect how the output will look.


slide 4 - Running a program

Very important slide! Basically, you will type your program into a file. You need to give your file a name with a '.c' function. Then, you will compile your program by typing 'lcc' followed by the filename. If there are errors in your program, you will get a listing of the line numbers and a (sometimes) confusing description of the problem. You won't always be able to rely on the errors output by the compiler to fix your program, but it usually provides a good starting point.

When there are no errors, a file named a.out will be created. Type 'a.out' to run your program. There may still be problems in your code, related to errors in your logic. These are called symantic errors. You need to test your program to find symantic errors. Sometimes, your program will appear to work in some cases and fail in others. As a programmer, you need to figure out the source of your problem and fix it. This is why it's so important that you learn how to read C programs.


slide 5

see slide 2.


slide 6 - Characteristic C shortcuts

A lot of code in this course is written concisely (usually to get it to fit on 1 lecture slide). It is sometimes more difficult, especially for beginners, to read code like this. As a programmer, you do not need to worry about squeezing code onto 1 page; instead you should strive to write readble code. This will make discovering errors (a.k.a. bugs) much easier. Sometimes ``wordy'' code is more readable, but in many cases it is better to write concise code. Be careful not to sacrifice readability in the quest for terse code. Here, the for loop is certainly preferable (at least once you feel comfortable with for loops), as it should be unambiguous that you are counting from -1.0 to 2.0 in increments of 0.1.

Here is a particularly poor piece of code. Here is another. What on earth do they do?


slide 7 - Example Program: Random integers

This slide introduces a second library: <stdlib.h>. One of the function in this library is rand(). Notice that the for loop ranges from 0 up to (but not including) 10. You could get the same results by going from 1 to 11 or 120 to 130, etc. 'i' is being used very simply as a counter variable, keeping track of how many times you've executed the for loop. You should get very comfortable with simple for loops like this one.


slide 8 - Random Reals

One unusual thing that you may notice is that rand() is multiplied by 1 before it's divided by RAND_MAX. This may seem pointless, since multiplying a number by 1 doesn't change it (in mathematics.) However, in this program, it has the effect of changing the type of the numerator from an int to a float. This is necessary, since integer division is different than floating point division. In C, 4/3 is 1, while 4.0/3.0 is 1.3333333... You can read more about number conversion in K & R.


slides 9 & 10 - Random Numbers ??

Because of the algorithm used to generate random numbers, the rand() function doesn't generate completely random numbers. (Maybe, it would be better to use the linear feedback shift register from Lecture 1 to generate pseudo-random numbers.) You are asked the question: why not just use the following test? if (rand() % 2) You're probably asking, what is this test? Basically, it's testing whether the number returned by rand() is even or odd. The % operator is the 'mod' operator. It operates on integer values. It returns the remainder of the integer division. For example, 11/4 is 2 with a remainder of 3. So, 10 % 4 is 3. If you divide numbers by 2, the only two remainders you can get are 0 and 1, so x%2 will always return either 0 or 1 as a result. 0 corresponds to false, and 1 corresponds to true. If the numbers were truly random, this test be randomly true or false.

The program that has been written has an alternative test: if ((rand() b>> 13)&1). It uses two new operators. >> is the shift operator. It treats the number preceding it as a binary number and shifts it the number of bits corresponding to the number after the >> (13 in this case.) The & operator is a bitwise and. If this is all confusing, don't worry about it yet. Wait until you understand binary numbers and operators - we'll go over them in precept. Basically, the &1 has the effect of testing whether the number preceding it is even or odd, just like %2.


slide 11 - Another Example: Gambler's Ruin

This program introduces another stdio library function: scanf. scanf() is like the opposite of printf. It reads input from the keyboard. Don't worry about the meaning of the & before the variable names. We'll learn about its meaning later on in the semester. This slide gives a practical example of a use for a random number.


slide 12 - Gambler's Ruin Experiment

This program moves the gambling part into a function called doit. It returns a number corresponding to how many times the gambler 'gambles' until he/she's out of cash. For each starting cash value (from 2 to 9), the doit function is called 5 times. The output of a sample run is given.

The gambler's ruin problem is a famous problem that you would surely run across in an introdutory course on probability course. It has many applications, most notably, the stock market.