CS50 - Section 3

Section Information


Functions

We've already seen how to use functions (such as printf and GetInteger) that someone has already written and put into a library. Now we're ready to learn how to write functions of our own.

We already know how to write one function, the main function, which must appear in all C programs and is where C program start executing. Other functions are defined in much the same manner, although they may look slightly more complicated, since they may take arguments or return values.

A function definition has the following form:

type function-name ( parameter-list ) { function-body }

These have the following significance:

type

The type of value that the function returns, such as int or double.

A function that doesn't return a value is given a special type, named void. This is described in more depth later in this document.

function-name

The name that you are giving this function (and the name that will be used to call this function later). The name should be different from the names of any other functions or variables in your program, and must obey the rules for the names of a function or variable.

parameter-list

A list of the parameter names (immediately preceded by the type of the parameter) of this function. If this function does not have any parameters, then a parameter list of void is used.

function-body

The statements that are executed when the function is called.

Note that the function body must be enclosed in curly braces. Unlike other statements (i.e. if statements) where the curly braces may be omitted if the body consists of a single statement, the curly braces are mandatory here.

For example, imagine that we want to write a function which takes two integers, prints them out on the screen, and then returns their sum:

	int		add_ints (int a, int b)
	{
		int		sum;

		sum = a + b;

		printf ("The two numbers are %d and %d\n",
				a, b);

		return (sum);
	}
Then we can write a main function that calls this function:
	void		main (void)
	{

		add_ints (12, 13);
	}

Why Write Functions?

A Word About void

Something that seems to have confused a large number of students is the void type. A function is of type void if it doesn't return anything. A function has a parameter list of void if it doesn't take any arguments. For example, the following function doesn't take any arguments, just prints hello on the screen, and doesn't return anything:

	void		hello (void)
	{
		printf ("hello");
	}
A function like GetInteger, however, does return something (an integer), but it doesn't take any arguments, so its definition is:

	int		GetInteger (void)
	{ /* etc. */ }

Return

To return a value from a function, the return statement is used. The statement is simply the word return followed by the value that the function should return. (I typically enclose the value to be returned in parenthesis, from force of habit, but this is optional.) If the function has a return type of void, then the return value must be omitted.

Note that execution of the function ends immediately when a return statement is executed; no more statements of the function are executed. For example, consider the following function:

int		foo (int x)
{

	return (x + 5);

	printf ("hello!\n");
}
As currently written, there is no way that the statement containing the call to printf will ever be executed, since it would be executed after a return statement.

The manner in which return causes a function to abruptly cease can be quite useful at times (since it can allow you to jump out of any number of nested loops or conditional statements). We will see examples of this soon.


Arrays

Arrays are a new kind of variable. Arrays are variables that can be be used to hold a bunch of values (all of the same type) at the same time.

Some key properties of C arrays:

For Further Reading...


Yet more C

New Control Flow Statements

Operator Review

The ?: operator

The ?: operator (pronounced "question mark colon") can be very handy. It is like an abbreviated form of the if-else statement, with the limitation that it can only contain expressions, and the benefit that it returns a value.

For example, here is a function that takes two integers and returns the larger:

	int		max (int x, int y)
	{

		return ((x > y) ? x : y);
	}
	

Multiple assignments

The assignment operator, =, is a binary operator in the sense that it has two operands which is operates on, and it produces a value which can be used as an expression itself. Unlike the other binary operators we've seen, assignment works right-to-left instead of left-to-right. For example:

	a = b = c = d;
	
The value of d is assigned to c, and then this value is assigned to b, and so on.

Note that not all expressions are allowed on the left side of an assignment! For example, 55 is a perfectly good expression, but 55 = a is not; C will not allow you to assign a new value to 55. The kind of expressions that are allowed on the left side of an assignment are called lvalues (where the l stands for left). So far, the only kind of lvalue that we know about are variables, but soon we'll meet another in lecture (and we'll see a few more as the semester progresses).

Type casting

C provides an operator to force a conversion from one type to another, called a type cast (or simply a cast). We saw some of these in the early lectures. The form of a cast is simply the name of the type that you want to convert to, surrounded by parenthesis. For example,
		a = b + (double) c;
		d = (int) (e + f);
	
In the first example, c is cast to type double before it is added to b. Note that this forces C to do this addition using real arithmetic, rather than integer arithmetic.

In the second example, the sum (e + f) is converted to type int before it is assigned to d.

Note that C doesn't have the ability to cast strings to integers or doubles (although there are library functions to do this). The following will compile, but not do what you want at all:

	{
		int	foo;
		string	bar;

		foo = (int) "123";
		bar = (string) 456;
	}
	

To convert back and forth from strings and other types, other methods are necessary. We'll study these soon enough.

Macros

The #define directive defines a macro. The compiler the substitutes the definition of the macro wherever it sees the macro appear in your program. For example,

	#define	TIMES_TO_LOOP	4

	for (i = 0; i < TIMES_TO_LOOP; i++) {
		printf ("%d\n", i);
	}
In this example, 4 will be substituted in wherever TIMES_TO_LOOP appeared in the original code.

Macros can also behave a little bit like functions, taking arguments and substituting them as well:

    #define PRINT_TWICE(str)	printf ("%s %s", str, str)
    #define MAX(x, y)		((x > y) ? x : y)
    #define MIN(x, y)		((x < y) ? x : y)

Fun With printf

Review the printf options. They're very useful, but not terribly intuitive until you get used to them. The best place to see all the options for printf in one place is the online manual page.


Other General Concepts


The First CS50 Hourly

There will be review sessions before the midterm- one on Friday 2-4 in Science Center A, and another on Monday from 7:30-9:30 in Science Center C. There may be a Quad review section (and maybe other random gatherings); stay tuned.

In addition to the review sessions, each TF will be on duty in the terminal room during their normal office hours in order to answer questions about the midterm or the next programming assignment (due the following week), and of course you can always send me or lib50 email.

Due to the size of the class, we'll be split into three different rooms for the test. Please arrive early if possible, so we can start the test on time. Students with last names starting with A-K will be in Science Center B, L-Q in Lowell Lecture Hall, and R-Z in University Museum 100. (Double-check with the cs50.motd for more info.)


Assignment 3

Please read the assignment carefully and start thinking about it soon. Even if you don't spend a lot of time working on it before the midterm, if you start to think about what you will need to do for this problem set before you study for the midterm, you'll probably see a lot of things that apply to the assignment. Working on assignment 3 is an excellent way to help study for the midterm!


vi Tricks

Here's this week's dose:

Notes for Pascal Programmers

This section is mostly aimed towards people who already know how to program in Pascal. If you don't know Pascal, this section is irrelevant.

If you've previously programmed in Pascal, here are a few differences between functions in C and Pascal:


Please bring any errors or inconsistencies in this document to the attention of the author.

Dan Ellard <ellard@deas.harvard.edu>