introduction to c programming -...

85
Introduction to C Programming Lesson 1: Getting Started Lesson 2: Editing Files Lesson 3: Introduction to C Lesson 4: Compiling Lesson 5: Variables and Data Types Lesson 6: Math Lesson 7: Output Lesson 8: Input Lesson 9: Conditional Statements Lesson 10: Loops Lesson 11: Arrays Lesson 12: Compiling: Revisited Lesson 13: Functions Lesson 14: Random Numbers Lesson 15: Pointers Lesson 16: More Pointers Lesson 17: Character Arrays and Strings Lesson 18: Structures Lesson 19: Reading/Writing Files Lesson 20: Recursion Copyright © 1998-2014 O'Reilly Media, Inc. This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License. See http://creativecommons.org/licenses/by-sa/3.0/legalcode for more information.

Upload: lekhanh

Post on 13-Apr-2018

218 views

Category:

Documents


2 download

TRANSCRIPT

Introduction to C ProgrammingLesson 1: Getting StartedLesson 2: Editing FilesLesson 3: Introduction to CLesson 4: CompilingLesson 5: Variables and Data TypesLesson 6 : MathLesson 7: OutputLesson 8 : InputLesson 9 : Conditional StatementsLesson 10: LoopsLesson 11: ArraysLesson 12: Compiling: RevisitedLesson 13: FunctionsLesson 14: Random NumbersLesson 15: Po intersLesson 16: More Po intersLesson 17: Character Arrays and StringsLesson 18: StructuresLesson 19: Reading/Writing FilesLesson 20: Recursion

Copyright © 1998-2014 O'Reilly Media, Inc.

This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.See http://creativecommons.org/licenses/by-sa/3.0/legalcode for more information.

Lesson 1 -- Getting StartedGetting Started

Welcome. In this course we expect you to follow along with us, and try the examples wesuggest and experiment on your own. The only way to learn a new computer languageto by experiment ing with it . Since you're going to need to programming along with us,we've provided you with some simple tools in this learning environment so that you caneasily follow along with us and experiment with C code on your own.

Before we get started with C we need to get familiar with the environments we'll beworking in. We'll be learning C in the Unix environment. Why? Unix allows you to write Cprograms on our computers so you don't have to worry about your having any specialsof tware on your own computer. We have an ent ire Useract ive course on Unix, but I'mjust going to go over the few things you'll need to get started learning C.

About CodeRunner

Below is a web distributed editor and development tool we call CodeRunner. With it youcan program in a number of dif ferent languages (including C) and you can enter a Unixshell and a MySQL database shell. In this course we'll using the editor to create C f iles,save C f iles and compile C f iles (we'll def ine what we mean by 'compile' later on). We'llalso be using the Unix shell to execute and test programs.

For this lesson, we'll be using the Unix shell to learn some simple Unix tasks. In the nextlesson we'll show you how to use CodeRunner to edit and save C f iles (and later onhow to compile). To put CodeRunner into a Unix Shell simply click on the Unix button atthe bottom of CodeRunner:

You will be asked for your username and password, then you will be asked by the shellfor your password. Click on the shell and retype your password.

Getting familiar with Unix

If you are new to Unix, we suggest that you go through the f irst 5 Unix Tutorials.

Put CodeRunner in Unix mode by clicking on the UNIX but ton at the bottom of thepage. When you start Unix mode, it will come up with a login prompt.

NOTE: below is a gray box. Gray boxes mean that you are simply supposed to observesome code and no action is required of you.

Observe the following:

Trying cold.useractive.com ...

Connected to cold.useractive.com.

Linux 2.2.16 (cold.useractive.com) (ttyp4)

cold login: usernamePassword:

The username will be your login name. You need to type your password to f inishlogging in and then you'll be at a unix prompt.

Observe the following:

NoMad ...

Last login: Mon Jul 24 10:31:29 -0500 2000 on ttyp3 fromhottub.useractive.com. No mail.

cold:~$

Listing Files

Alright . We've got a unix prompt: cold:~$ Now what? Let 's explore a lit t le. We can usethe ls command to list the f iles in the current directory.

NOTE: Below is a WHITE box. White boxes mean that we want you to type thecommands or code given in the box. Action is required of you.

Type the following command at your unix prompt:

cold:~$ ls -a. .bash_history .bash_profile .emacs .screenrc.. .bash_logout .bashrc .ncftp

The -a f lag makes ls show all of the f iles. (Otherwise, f iles that start with a dot (.)won't show up.) Your directory list ing probably looks dif ferent f rom the one above,especially if you've taken other courses with us. We can also list f iles using a wildcard (*).

Type the following command at your unix prompt:

cold:~$ ls -a .bash*.bash_history .bash_logout .bash_profile .bashrc

Directories

Let 's make a new directory within your home directory called stuff. We do this with the

mkdir or make directory command.

Type the following command at your unix prompt:

cold:~$ mkdir stuffcold:~$

Now if we list our f iles we can see the new directory.

Type the following command at your unix prompt:

cold:~$ lsstuff

Again, you may have a lot more f iles. Let 's move into the new directory by using thechange directory command, cd.

Type the following command at your unix prompt:

cold:~$ cd stuffcold:~/stuff$

List the f iles in the new directory

Type the following command at your unix prompt:

cold:~/stuff$ ls -a. ..

Huh? How can there be two f iles in a new directory? Not only that, but the names arejust dots. These are actually directories that are part of the unix f ile structure. Thesingle dot stands for the current directory, and the double dot stands for the previousdirectory. This allows us to cd back to the previous directory.

Type the following command at your unix prompt:

cold:~/stuff$ cd ..cold:~$

Copying and Removing Files

You can copy and remove f iles with cp and rm respect ively.

Type the following command at your unix prompt:

cold:~$ cp /etc/issue .

cold:~$ cp /etc/issue .

What this means is to copy the f ile named issue f rom the /etc directory into thecurrent directory (.).

Type the following command at your unix prompt:

cold:~$ lsissue stuff

Excellent . But we don't really need that f ile, so let 's remove it .

Type the following command at your unix prompt:

cold:~$ rm issuecold:~$ lsstuff

Logging Out

Now the f ile is gone again. That should be all we need to know for now. When you'redone in Unix mode just type exit and then click on the CodeRunner button at thebottom to get back.

Type the following command at your unix prompt:

cold:~$ exitlogout

Connection closed.

© Useractive, Inc. - 1998-2003.Useractive™, Coderunner™, and The Learning Sandbox™ are registered trademarks of Useractive, Inc. All rights reserved.

Lesson 2 -- Editing FilesEditing Files

In this course we will need to edit C f iles in the editor below and then switch to the unixprompt to run them and review the output. You can use CodeRunner to edit and saveyour f iles. You will learn how to do this in this lesson.

Editing Files with CodeRunner

Look at the lower half of this window. By now you've f igured out that it 's a text editorcalled CodeRunner. Since this is a course in the C programming language, you'll want touse the C/C++ mode. By default , CodeRunner starts out in HTML mode. To putCodeRunner into C/C++ mode click on the drop down menu that has "HTML" in it . Likethis:

Select C/C++

Notice at the bottom of the page, that there are a couple of radio buttons where youcan choose CGI or EXE. For this class we will be making executables and not CGIs somake sure the EXE is selected like this:

Select EXE

Now you are ready to t ry saving and retreiving some f iles. Erase the text in the editor'stextarea and type anything you want, maybe even write a story about yourself . Onceyou have some text writ ten, let 's save the f ile as "test ing.c".

There are two ways to save a f ile, you can select Save to Server f rom the f ile menu:

Select "Save to Server"

OR

Click the Save Button

AFter you've done this, you'll be prompted to name your f ile and save it :

Save your f ile as test ing.c

Once you've saved a f ile, you can use "quick save" to quickly save any changes to theserver without being prompted. To quick save simply click on the quick save button:

Click the Quick Save button to quickly save changes to the server as you work

Now, if you've saved a f ile and some t ime goes by and you need to retreive the f ile f romthe server, simply click on Open From Server

Click 'Open From Server'

OR

Click the Open Button

We've completed the introduct ion to CodeRunner for now. In a lat ter lesson we'lldiscuss using the Compile feature of CodeRunner to quickly compile your C programs.

See you at the next lesson...

© Useractive, Inc. - 1998-2003.Useractive™, Coderunner™, and The Learning Sandbox™ are registered trademarks of Useractive, Inc. All rights reserved.

Lesson 3 -- Introduction to C

That 's it for introductory stuf f , let 's get started with C shall we?

What is C?

C was derived from the B programming language, which was built f rom BCPL. It was f irstused at Bell Labs in 1972. Nowadays, C is used everywhere. For example, the Unixoperat ing system, the Apache web server, and even other programming languages (likePerl) are all writ ten in C.

C is what 's known as a high level language. What this means is that it 's a lit t le closer tothe f low of human understanding rather than what your computer understands.

There are a lot of dif ferent versions of C, most ly due to dif ferent operat ing systems(DOS, Windows, Linux, etc). You'll be learning C that uses glibc (The GNU C Libraries).For the most part , they are all the same with just a few lit t le dif ferences.

A basic C program

The easiest way to start learning C is to jump in head f irst and start doing someexamples. I'm going to give you a simple program that prints something to the screenand then I'll explain how it works. You'll need to type the whole thing in for it to work, butfor now, I only want you to pay at tent ion to the stuf f in blue.

Put CodeRunner in C/C++ mode then type the program exact ly as it is below:

Type the following code into your editor:

/* first.c */

#include <stdio.h>

int main(){

/* print statement */ printf("I've been programming C for 1 day.");

return(1);}

We are going to use the Compile but ton to compile this program. If you don't knowanything about compiling don't worry about it that 's why you're taking this class, we'll letyou know about compiling later. For now we just want to get a program working andsee what it does.

Once you have the above text typed into CodeRunner below, select the "EXE" buttonat the bottom. Once you've done this, click on the Compile C/C++ but ton:

After you get enter your username and password to login, you'll get a prompt tocompile your C program, that looks like this:

Simply click on Save and Compile

Now that we've "compiled" the program, we can use the program. For the t ime think ofcompiling as "gett ing the program ready".

As we ment ioned before, we are going to execute programs from within a Unix shell.Right now, click on the Unix but ton to enter your Unix shell. The button is at the bottom

of the page and looks like this:

You'll have to type your password in again to enter your shell.

Now that you're in your shell, be sure that the compiled program is in the same directorythat you're in right now. Type the unix list ing command to insure that the saved f ile andthe compiled f ile are in your directory. Type ls like this:

Type the following command at your unix prompt:

cold:~$ ls

You should see two f iles, one called f irst .c and another called f irst .exe. IF you don'tsee both f iles then you should use the cd command to enter the directory where youstored the f irst .c f ile.

The f irst .c f ile is the text f ile we created with the code in it , and f irst .exe is the binaryexecutable f ile that was "compiled" f rom the f irst .c f ile. The binary executable is thesoftware we created and that we can use. Of course, this sof tware doesn't do verymuch. In fact , let 's see what this sof tware actually does. In your unix prompt type thefollowing:

Type the following command at your unix prompt:

cold:~$ ./first.exe

Notice the ./ in f ront of the f ile name. That tells Unix not to look in standard places forcommand, and that the command we are execut ing (in this case "f irst .exe") is right here.TRY typing f irst .exe without the ./ and see what happens.

You should get the following output af ter you type the Enter but ton on your keyboard:

Observe the following:

I've been programming C for 1 day.

You've actually made a Unix Command. The command prints out "I've beenprogramming C for 1 day". Not a very useful command I'll admit , but we've madeprogress!!!

Let's analyze your f irst Program We've made a C program and executed it . Nowlet 's see what we actually did when we typed that stuf f . Take a look at the program

once again:

Observe the following:

/* first.c */

#include <stdio.h>

int main(){

/* print statement */ printf("I've been programming C for 1 day.");

return(1);}

The f irst line says /* f irst .c */, the /* and */ are telling the program to ignore everything inbetween them. They are called comments and we've commented out that line. We dothis to write ourselves notes about the program we are writ ing so that months f romnow if and when we look at it again, or if someone else looks at it again they'll knowwhat 's going on. In this case we just repeated the name of the f ile so we know what f ilewe are looking at .

The stuf f in red you'll see in every C program. For now you don't need to worry what itmeans. Just be sure and put the code you write in between; where the blue lines arenow. I promise I'll tell you later what that line does.

The f irst line in blue is just another example of a comment in C. Again, comments don'tdo anything, but it 's a good idea to include them to keep track of what each part ofyour program is doing. Think of them as notes you can write to yourself about theprogram. The start of the comment is marked with /* and the end is marked with */.Anything af ter /* and before */ is part of the comment.

The second blue line is the meat of the program. This line tells the computer what wewould like it to do. In this case, we want to print the message, "I've been programming Cfor 1 day." to the computer screen. The printf funct ion requires that you have theparenthesis and the quotat ions around the text you want to print . You also need tohave a semi-colon at the end of the printf funct ion.

That 's enough for now. See you at the next lesson.

© Useractive, Inc. - 1998-2003.Useractive™, Coderunner™, and The Learning Sandbox™ are registered trademarks of Useractive, Inc. All rights reserved.

Lesson 4 -- CompilingCompile?

Now let 's get a feeling for what it means to compile a program. There are two types ofprogramming languages: interpreted and compiled. Interpreted languages convert yourcode into instruct ions for the computer everyt ime it reads the f ile. This makes it fasterto test your program because you don't have to go through the step to compile it , butoverall, it 's going to run slower than a pre-compiled language like C. By compiling yourprogram, it 's turned into machine language (what your computer understands) beforeyou run it . Addit ionally, the compiler report syntax errors for you.

A compiler is a program that converts your text into the computer instruct ions given bybinary code (0's and 1's)

Before there were compilers people in the early days of computer's used to have toprogram with 0's and 1's. Now that we have languages like C and C compilers we have itmuch easier.

Common Compile-time Errors

Let 's t ry leaving of f the semicolon af ter the printf funct ion. Do this by re-opening thefirst.c f ile (if you don't have it open already) and removing the semicolon at the endof of the print f line. Let 's see if the compiler tells us we made a mistake. Make sure yourf ile looks like the one below:

Type the following code into your editor:

/* first.c */

#include <stdio.h>

int main(){

/* print statement */ /* printf("I've been programming C for 1 day."); */ printf("I've been programming C for 1 day.")

return(1);}

What we doing here is simply comment ing out the old print statement and put in a newone that 's missing a semicolon. Now save Compile your program again by clicking on theCompile C/C++.

Af ter you compile you should get the following message:

Instead of creat ing an executable f ile, we get an error message. Just in case yourprogram consisted of more than one .c f ile (we'll see this more later), it tells you theerror was in first.c. Then, as you can see, the error was inside of the main()funct ion. Next, compiler tells you that there's a syntax error before line 9. So if we gof ind line 9 of our code, we should not ice the missing semi-colon on the line before it . Putthe semi-colon back where it 's supposed to be.

NOTE: Even though we got errors and a new version of first wasn't created, the oldone st ill exists. You could st ill run the old executable f ile and it would st ill work. Youshould be careful to make sure there are no errors before t rying to run the program.That way you know for sure it 's the newer version.

Let 's look at another one. Try mispelling printf to print (I do this all the t ime).

Type the following code into your editor:

/* first.c */

#include <stdio.h>

int main(){

/* print statement */ /* printf("I've been programming C for 1 day."); */ print("I've been programming C for 1 day.");

return(1);}

This t ime we put the semicolon back, but we removed the let ter 'f ' f rom printf. Trycompiling it again by clicking on the Compile C/C++ but ton. You should see errors likethis:

Observe the following:

/tmp/ccguElHH.o: In function `main':/tmp/ccguElHH.o(.text+0x13): undefined reference to `print '

collect2: ld returned 1 exit status

Huh? What is all that stuf f? Okay, so gcc isn't always as helpful as we'd like it to be. Butthere's st ill a couple clues here. It tells you it 's in the main() funct ion again and it 's aproblem with print. That should be enough to help you f igure out the problem andcorrect your code. But what does the rest of that mean?

What Happens When You Compile

In broad terms, compiling your program converts it f rom the code you write intosomething your computer understands. The compiler collects all of the parts and putsthem together to make a single f ile that the computer can run. That 's really all you needto know about compiling to write programs in C.

You don't have to read the rest of this unless you're curious about what 's going on.YOU DON'T HAVE TO UNDERSTAND COMPILING IN MUCH DETAIL TO BE A GREATPROGRAMMER.

This doesn't have much to do with writ ing C, but I think it 's useful to understand It canhelp you debug your (and other people's) programs when they get more complicated.Every computer that you write C on, has a set of C libraries. The libraries are just abunch of C funct ions (like printf) that 've been put together so you don't have to doeverything yourself . However, you can't use a funct ion without f irst telling C about it . Sohow did we use printf? Simple, the f irst line of our code was the inclusion of a f ilecalled stdio.h. This is called a header file because it contains informat ion about thefunct ions in the library. There's a lot of funct ions you might use in C that we'll includeheader f iles for later on. Let 's quickly go over how this all t ies together.

When you compile a bunch of stuf f is going to happen. First , a preprocessor is going to

go through and add stuf f to your code where you told it to include stuf f . It 'll evenmodify it somet imes as well. Once all the code is ready, it 's actually compiled intomachine language. At this point it 's called object code. Not ice, in the second errorabove, the temporary object f ile /tmp/ccguElHH.o that was created. Next, thecompiler has ld link the object code to any C libraries that it 'll need to run. ld is aseparate ut ility called the linker. Finally, the compiler creates the executable f ile to berun later. This is the f ile that is used to see the actual code results.

A very loose analogy can be made by thinking about your lunch. I'm not kidding. Say youwant to make a sandwich. You decide what you want on it (bread, mayo, ham, cheese,let tuce, and tomato). The "program" you write, is deciding what order to put them onthe bread. You're not actually going to bake the bread or make the mayo from scratch,just like you aren't going to make all the funct ions you use from scratch. More likelyyou'll go to the fridge and get some mayo out of the jar. That 's just like (well, notexact ly) the compiler using print f f rom it 's library.

I hope this helps you understand a lit t le bit about compiling. We'll discuss this topic againin a later lesson when we go through command line compiling.

See you at the next lesson.

© Useractive, Inc. - 1998-2003.Useractive™, Coderunner™, and The Learning Sandbox™ are registered trademarks of Useractive, Inc. All rights reserved.

Lesson 5 -- Variables and Data TypesVariables

Alright , in the previous lessons we learned how to print out a line of text . That 's f ine andgood, but we need to be able to change things. In C, as in most languages, we storechanging informat ion in variables. It might be useful to think of a variable as a box. Youcan store stuf f in a box and you can change what 's in it as well. Before we can use avariable in C, we have to declare it . Essent ially we have to make a box that we'll putthings in later.

What we're going to do next is declare a variable named days. We'll use this variable tostore a number and then print it out .

Type the following code into your editor:

/* lesson5.c */#include <stdio.h>

int main(){ int days;

days = 1;

printf("I've been programming C for %i day(s)\n",days);

return(1);}

Save and Compilethis code by clicking on Compile C/C++ as lesson5.c Switch to Unixand run your program by typing ./lesson5.exe

You should see the same output as before.

Observe the following:

I've been programming C for 1 day.

Here we modif ied the f irst program to include some new code. Don't forget to includethe stuf f that was in red before like is shown. I'll go over the new stuf f one line at a t ime.

int days;

This is the declarat ion of the variable called days. We're creat ing the box to use later.The int stands for integer. C keeps track of what kind of data is in each variable(whether the box will store apples or oranges). We'll go over integers and other variabletypes in a lit t le bit . Note how the line ends in a semicolon, just like most statements in C.

days = 1;

This is a variable assignment. We're set t ing days equal to 1. Alright , so now we've gotan integer box with a 1 in it .

printf ("I've been programming C for %i day(s)\n",days);

This looks a lot more complicated than it really is. Since there isn't anything todist inguish a variable f rom any other word, we have to tell printf that we want toinclude the value of a variable in the output. The %i says that, "right here there will bean integer." So printf goes and looks at days to get the value.

Now let 's change the value of days.

Type the following code into your editor:

/* lesson5.c */#include <stdio.h>

int main(){ int days; days = 1;

printf("I've been programming C for %i day(s)\n",days);

days = days + 1;

printf("Tomorrow it will be %i day(s)\n",days);

return(1);}

Compile and try this code (you should know the rout ine by now). What output did youget? Can you f igure out what the code is doing? Try to look at the code and predictwhat it 's doing. Try CHANGING THE CODE ANYWAY YOU SEE FIT! Take some t ime toexperiment. You can't hurt anything.

Let 's break down the code...

days = days + 1;

This is simply another assignment operat ion. The only dif ference is the expressiondays + 1 will be evaluated before a new value is assigned. Since this isn't an argumentto print f , we don't have to do that %i stuf f this t ime. days is st ill equal to 1, so 1 + 1 = 2.Now the assignment takes place and days is 2.

Printing Multiple Variables

We're not limited to print ing one variable at a t ime either. printf allows us to printmult iple variables simply by adding more arguments to the statement.

Type the following code into your editor:

/* lesson5b.c */#include <stdio.h>

int main(){ int days=3; char mychar='C';

printf("I've been programming %c for %i days.\n",mychar,days);

return 1;}

Compile and test this code af ter saving it as lesson5b.c. As always, experiment withthe code a lit t le. Try to get it to print a few dif ferent things.

Observe the following:

I've been programming C for 3 days.

Characters are printed using %c. The variables given to printf should be in the sameorder that they appear in the output string. Play around with this a lit t le, t ry print ing 3 or4 variables at a t ime.

Data Types

C is very part icular about keeping track of what kind of data is stored in all of yourvariables. Also, each variable in C only keeps track of one thing. Dif ferent variable typesare like boxes designed for dif ferent kinds of objects. There are three main data typesthat we'll be using throughout this course: int, float, and char. Integers (int) canonly store numbers like: -12, 0, 43, 32589. They can't store decimals or f ract ions. If youneed to store numbers that have a decimal point , you better use a f loat ing pointvariable (float). That last of the three is for storing characters. The limitat ion of charvariables is that they can only store a single ASCII character; no words or strings. We'llget around this later with arrays. There are other variable types, but the only variat ionsare the maximum value of the data being stored.

NOTE: Integers seem a lit t le inferior, so why bother using them at all? Integers take upless memory than f loat ing point numbers and even though that 's not a big problem withtoday's computers, it 's st ill good programming pract ice to use them when a f loat ingpoint number isn't necessary.

More on Declaring Variables

In C, we have to declare what variables we want to use before we can use them. This isbecause C has to allocate some of the computer's memory for each variable we wantto store. Because of this, the f irst part of your C program should declare all thevariables. You can always add more variables to the top as you need them. When wedeclare a variable, all we're really doing is specifying what type of data will be stored and

what the variable name is.

We also need to assign values to our variables. We can either do that at the same t imewe declare them, or we can do it seperately. Look over the following example, and lateryou can use it as a reference if you need to.

Consider the following C code:

#include <stdio.h>

int main(){ /* variable declarations */ int a, b; float x; char mychar1;

/* variable declarations and assignment */ int c=5; char mychar2='d';

/* assigning values to variables */ a = 3; b = 4; x = -4.57; mychar2 = 'd';

return 1;}

In the f irst part of the example we're just declaring a few variables of dif ferent types.Convenient ly, we can use commas to separate addit ional variable names. That keepsus from having two separate lines for both a and b.

The second blue sect ion shows how we can give variables a value at the same t ime aswe delcare them. The equals sign is known as the assignment operator. The value onthe right side of the equals sign, is stored in the variable on the lef t side.

The last part simply shows how to assign values to a variable that has already beendeclared. Note that when assigning a character value we use single quotes. This is amust. Single quotes are used for single characters and double quotes are used forstrings that we'll use later.

© Useractive, Inc. - 1998-2003.Useractive™, Coderunner™, and The Learning Sandbox™ are registered trademarks of Useractive, Inc. All rights reserved.

Lesson 6 -- MathDoing Math

Yeah, I know. Math.. yuck. We've gotta do it eventually, so we might as well get it out ofthe way.

Arithmet ic in C follows basically the same rules as you've always used. If you have astring of numbers like this: 1 + 3 * 2. The numbers 3 and 2 will be mult iplied, and thenumber 1 will be added to the result to yield 7. Mult iplicat ion and division are donebefore addt ion and subtract ion. However if you have a string of numbers like this: (1 +3) * 2. The numbers 1 and 3 will be added, and the number 2 will be mult iplied by theresult to yield 8. You can use parenthesis to group things.

Type in the following example as a f ile called math.c. Remember, we're only looking atthe stuf f in blue so don't worry about what the rest of it means yet.

Type the following code into your editor:

/* math.c */#include <stdio.h>

int main(){ int a=1, b=2, c, d; float x=1.1, y=2.2, z;

c = a + b; z = (x + y) * b; d = b / x;

printf("a + b = %i\n",c); printf("(x + y) * b = %f\n",z); printf("b / x = %i\n",d);

return 1;}

Compile and run the program. If you don't remember how, go back to lesson 4 for areminder. The output should look like the following:

Observe the following:

a + b = 3(x + y) * b = 6.600000b / x = 1

Notice that the f irst thing we're doing in the program is declaring variables and values

that we'll be using later on. The variables a, b, c, and d are all integers while x, y, and zare f loat ing point numbers. We're assigning init ial values to some of the variables whenthey are declared and the others will be used to store results. To get the result of themath, we simply assign the math expression to a variable. The mathematical expressionis evaluated, and then the result is stored in the variable. Since a is equal to 1 and bequals 2, the value of c, af ter the addit ion and assignment, is 3.

Cool, huh? But let 's take a look at the last line of output. b is 2 and x is 1.1, so the resultof the division should be about 1.82. But we got 1... what 's going on? The result of thedivision, was indeed 1.82, however, we're t rying to assign that number (which has adecimal point) to a variable that is an integer. As a result , C just ignores everything af terthe decimal point and we get 1. You have to be very careful when you do math withboth integers and f loat ing point numbers.

This is all f ine and good if you want to add, subtract , mult iply, and divide, but that 's notgoing to get you very far in the world of a C programmer. There are more operatorsavailale to use besides +, -, *, and /. For example, there is an operator called themodulus (%). The modulus gives the remainder of a division operat ion. For example, 21divided by 2 equals 10 with a remainder of 1. If we want to know the value of thatremainder we'd use the modulus (%).

answer = 21 % 2;

After the modulus is taken, answer will be set to 1. This is really useful for f inding out ifa number is even or odd.

How about calculat ing 52? Well 5*5 works, but what if it was 520. I don't know aboutyou, but I'd rather not type that in 20 t imes! Lucky for us, there's a header f ile calledmath.h that def ines a lot of common math funct ions for us. Do you remember how toinclude a header f ile? (If not , go back to lesson 2 for a reminder.) Now we can use thepow() funct ion to do our calculat ion for us. It 's as simple as answer = pow(5,20);

Here's a list of other funct ions that are def ined in math.h:

Common Functions in math.hFunction Resultpow(x,y) xy

fabs(x) absolute value of xsqrt(x) square root of xexp(x) ex

log(x) natural log of xlog10(x) log base 10 of xceil(x) rounds up to the nearest integerf loor(x) rounds down to the nearest integercos(x) cosine of xsin(x) sine of xtan(x) tangent of x

All of the trigometric functions assume that you enter your angle in radians.

When you start doing math with large numbers you may exceed the bounds of thenormal data types. If this happens you can use double instead of float and longinstead of int. double and long are the same thing as their conterparts, except theytake up more memory and allow you to store larger numbers. If you exceed the boundsof a data type, C will either complain about an overf low, or print inf instead of thevalue you expected. (inf stands for inf inity)

See you in the next lesson:

© Useractive, Inc. - 1998-2003.Useractive™, Coderunner™, and The Learning Sandbox™ are registered trademarks of Useractive, Inc. All rights reserved.

Lesson 7 -- OutputPrintf

I'd say it 's about t ime I explain all of those printf statements I had you use in the lastlesson. As you may have already guessed, the printf statement is used to print"stuf f" to the screen. Print ing out just a string of text is very simple:

Consider the following C code:

printf("my line of text\n");

You're probably wondering what the \n is at the end of the string of text . The backlashcharacter is called the escape character. It tells C to t reat the next character dif ferent lythan normal. For example, \n, prints a new line. The escape character is also used if youwant to print special characters such as quotes or a backslash itself . Create a programfor the following example, save it as lesson7.c and run it .

Type the following code into your editor:

/* lesson7.c */#include <stdio.h>

int main(){

printf(" \" \\ hello\tthere \' \? \n");

return 1;}

You should see the following output when test ing it :

Observe the following:

" \ hello there ' ?

You can see how the backslash delimiter let 's you print out quotat ions and other specialcharacters that C would otherwise interpret as part of the syntax.

Printing Variables

We wouldn't get anywhere if all we could print was text , so obviously there has to be away to print out the values of our variables as well. We saw in a previous lesson how touse %i to print out variables with integer values. Recall the following statement:

Consider the following C code:

printf("Tomorrow it will be %i day(s)\n",days);

printf("Tomorrow it will be %i day(s)\n",days);

The %i tells printf that we want to print out the value of the variable c (an integer)to the screen. The second thing we gave printf was the variable we want to print .You can print out a bunch of variables at the same t ime as well.

Type the following code into your editor:

/* lesson7b.c */#include <stdio.h>

int main(){ int a=1; float x=2.345, y=-6.78; char chr1='p';

printf("%i %f %f %c\n",a,x,y,chr1);

return 1;}

Here, %f and %c are for print ing f loats and characters. The variables at the end are thein order they will be printed out. An integer, two f loats, and a character. Save this aslesson7b.c. Compile and run the example.

Observe the following:

1 2.345000 -6.780000 p

Notice that the f loat ing point numbers, when printed, are padded with zeros up to thesixth decimal place. That 's because f loat ing point numbers have a precision of 6 decimalplaces.

Formatting Output

Let 's say you've taken a bunch of data. They're all f loat ing point numbers that haveinformat ion out to the 6th decimal place. However, you don't need to be that accuratewhen print ing out a report of your data. For example, let 's take 123.456789 stored in avariable called mynum. So try this:

Type the following code into your editor:

/* lesson7c.c */#include <stdio.h>

int main(){ float mynum=123.456789;

printf("%10.2f\n",mynum);

return 1;}

Compile that and try to guess what happened before reading my explanat ion. This islesson7c.c

The f irst number, 10, is called the field width. What this means is that , if necessary, it willadd blank spaces before the number to make it take up 10 spots. You can also makethat a -10, and it will add spaces af ter the number. The .2 specif ies the precision. It willround up or down accordingly. The output would look like this:

Observe the following:

123.46

Four spaces were automat ically inserted to make the total length 10.

© Useractive, Inc. - 1998-2003.Useractive™, Coderunner™, and The Learning Sandbox™ are registered trademarks of Useractive, Inc. All rights reserved.

Lesson 8 -- InputScanf

Print ing stuf f is great, but it 's a lot more helpful to be able to do calculat ions based onactual input rather than hardcoded variables. That 's where scanf comes in. As you canprobably tell f rom the name, it works similarly to printf. Here's an example programthat reads in two numbers entered by the user when the program runs and mult ipliesthem together:

Type the following code into your editor:

/* lesson8.c */#include <stdio.h>

int main(){ float num1,num2,result;

printf("Please enter two numbers seperated by a space: ");

scanf("%f %f",&num1,&num2);

result = num1 * num2; printf("The result is %f\n",result);

return 1;}

We'll call this one lesson8.c to help keep track of them. Run this program to see how itworks.

Observe the following:

Please enter two numbers seperated by a space: 3.4 1.2The result is 4.080000

First we want to print out a line telling the user what we expect. Otherwise it would justsit there and they wouldn't have a clue what was going on. The space behind the colonis just there to make it look pret ty. So what about that scanf line? When you typestuf f in at the prompt and hit enter it goes into a standard input (STDIN) buffer (alsorefered to as a stream). It stays in the buffer unt il the program decides what to do withit . The f irst argument, "%f %f", tells scanf to look in the buffer for a couple f loat ingpoint numbers seperated by white space. Next, we need to tell scanf where to storethe two numbers. Remember that when you declare a variable, C allocates a spot inmemory to store the value. We need to tell scanf where that memory is. This can bedone by using the address operator, &. For now, just remember to use this in all of yourscanf statements. We'll learn more about it later.

Now the two f loat ing point numbers that the user gave us are stored in the variablesnum1 and num2. They can be used later in the program just as if we had assignedvalues for them ourselves.

NOTE: White space refers to any number of spaces, tabs, or newlines in a row. So, inessence, you could enter your f irst number, hit enter twenty t imes, and then enter yoursecond number. It 'd st ill work.

Normally it 's very important to test to make sure the input is valid, but since we don'tknow how to do that yet , we'll just assume that the user entered two f loat ing pointnumbers correct ly.

A very common error is forgett ing the address operator in the scanf statement. So ifyou're output doesn't make any sense you might want to check that f irst .

Getchar

Another very useful funct ion is called getchar. getchar is used to read input f romthe buffer just like scanf. The dif ference is that getchar only reads in one characterat a t ime and returns it as an integer. The following example illustrates this:

Type the following code into your editor:

/* lesson8b.c */#include <stdio.h>

int main(){ char a;

a = getchar(); printf("%c\n",a);

return 1;}

The getchar funct ion reads a single character f rom the input buffer and stores it in a.Save this program as lesson8b.c, then compile and test it out .

So what 's this business about getchar returning an integer? How are we comparingcharacter values if it returned an integer? Well, it 's about t ime I told you something.Every character corresponds to an integer value according to the ASCII chart . Basically,this is because your computer only understands numbers. It doesn't really matter inmost cases because the use of %c with printf displays a character for us.

The problem is that the characters 0-9 do not correspond with the integer values 0-9.The characters 0-9 are actually the integers 48-57. So if you plan on doing any mathwith the numbers you get f rom getchar you need a way to convert them to their realinteger values f irst . We can do this with a funct ion called atoi which is part ofstdlib.h. atio requires the use of the address operator, &, like scanf did.

Type the following code into your editor:

/* lesson8c.c */#include <stdio.h>#include <stdlib.h>

int main(){ char a; int i=0;

printf("Enter an integer between 0 and 9: "); a = getchar(); printf("%c\n",a);

i = atoi(&a); printf("%i\n",i);

return 1;}

Both of the print statements give you the same output to the screen, but a and i aredif ferent kinds of variables.

Save this program as lesson8c.c and test it out .

© Useractive, Inc. - 1998-2003.Useractive™, Coderunner™, and The Learning Sandbox™ are registered trademarks of Useractive, Inc. All rights reserved.

Lesson 9 -- Conditional StatementsIf Statements

Your programs will eventually need to make their own decisions. It will need to takedif ferent act ions depending on the value of the variables and it will need to do errorchecking to prevent possible bugs. This is accomplished using condit ional statements.There's two main ways to do this in C and we'll cover them both. The f irst type we'll lookat is called an if statement. Chances are, if you've programmed in any other language,you've seen if statements before. The basic format of an if statement is to test ifsomething is t rue, and if so, perform a series of commands. Let 's do an example to seethis in act ion.

Type the following code into your editor:

/* lesson9.c */#include <stdio.h>

int main(){ int var1;

printf("Enter an integer: "); scanf("%i",&var1);

/* test ing variable 1 */ if(var1 < 10){ printf("var1 is less than 10\n"); }

return 1;}

Save this as lesson9.c, then compile and try it out .

Observe the following:

Enter an integer: 3var1 is less than 10

The scanf statement reads in an integer f rom the user just like we read in two f loat ingpoint numbers in the previous lesson. I typed in 3 and it gave me 10.

The if statement checks the result of var1 < 10. If the result of that expression istrue, then the code inside the brackets is run. However, if the result is false, the code isskipped. For example, if var1 is 20, the expression is false and the program goes on tothe rest of the program after the closing bracket. However, if var1 is -2, the expressionis t rue. We display a line stat ing that var1 is less than 10.

The brackets aren't actually required if there's only one command to be run inside of theif statement, but I usually include them so I don't get confused.

The following table shows a list of test operators available C:

Test Operators< Less than> Greater than<= Less than or equal>= Greater than or equal== equal!= does not equal

NOTE: Be very careful not to confuse the equality operator, (==) with the assignmentoperator (=). Also, the exclamat ion mark is commonly used as the boolean NOT. All itreally does is reverse whether the statement is TRUE or FALSE. For example:if(!(var >= 2)) is the same thing as if(var < 2).

Type the following code into your editor:

/* lesson9b.c */#include <stdio.h>

int main(){ int var1;

printf("Enter an integer: "); scanf("%i",&var1);

if((var1 >= 1) && (var1 <= 10)){ printf("var1 is between 1 and 10\n"); }

return 1;}

Compile and test this one as well. You can keep calling it lesson9.c since we're justexpanding on the previous example. Play with it a lit t le to get a dif ferent range ofnumbers to check.

Observe the following:

Entry an integer: 6var1 is between 1 and 10

Here we're test ing to see if var1 is greater than or equal to 1 AND less than or equal to

10. We could do it with two separate statements, but it 's just as easy and requires lesscode to do it in one. This expression returns t rue only if both of the tests are t rue. Thetwo && stand for AND. Two vert ical lines (pipes), ||, stand for OR.

Type the following code into your editor:

/* lesson9.c */#include <stdio.h>

int main(){ int var1;

printf("Enter an integer: "); scanf("%i",&var1);

if((var1 < 1) || (var1 > 10)){ printf("var1 is not between 1 and 10\n"); }else{ printf("var1 is between 1 and 10\n"); }

return 1;}

After compiling you should test it out to get both of the possible outcomes.

The above statement illustrates the use of OR. The test cases are reversed as well, sowe get the same result . In addit ion to the if statement there's also an else. What theelse does is pret ty simple. If the condit ion in the if statement was FALSE, then thecode inside of the else is run. It 's the same thing as putt ing another if statement thathas the opposite condit ions.

You can also string together if /else statements as follows:

Type the following code into your editor:

/* lesson9.c */#include <stdio.h>

int main(){ int var1;

printf("Enter an integer: "); scanf("%i",&var1);

if((var1 >= 1) && (var1 <= 10)){ printf("var1 is between 1 and 10\n"); }else if((var1 > 10) && (var1 <=20)){ printf("var1 is between 10 and 20\n"); }else{

}else{ printf("var1 is not between 1 and 20\n"); }

return 1;}

We already know that stuf f inside of an else statement is executed when thecondit ion for the if is false. So what if the f irst thing af ter the else is another ifstatement? It 's really just allows for another possible set of condit ions. Using else ifis sort of like having a giant OR but the dif ferent condit ions result in dif ferent act ions.

Be sure to compile and test this example. Try it muliple t imes and get it to give you all ofthe dif ferent outputs.

NOTE: Compile t ime errors will start to get more complicated now. Forgett ing aparanthesis or bracket might not cause an error unt il much later in your program. Justback track unt il you f ind it . For example, removing the closing bracket, might cause gccto report a parse error at the end of input.

Embedded If 's and Indentation

Now suppose we have a situat ion where we only want to test for certain cases whenother cases are t rue or false. When this happens, we can get a bunch of if statementsembedded in other statements. Much like the following example:

Type the following code into your editor:

/* lesson9b.c */#include <stdio.h>

int main(){ int var1, var2, var3;

printf("Enter three integers (0, 1, or 2) separated by spaces: "); scanf("%i %i %i",&var1,&var2,&var3);

if(var1 == 1){ if(var2 == 1){ printf("var1 is 1 and var2 is 1\n"); }else{ if(var3 == 2){ printf("var1 is 1, var2 is not 1, and var3 is 2\n"); } } if(var2 == 0 ){ printf("var2 is 0\n"); } }

}}

Save this one as lesson9b.c. I colored the example to help you see which statementsgo with which brackets.

In this case, we only test var2 if var1 is 1. Also, we only test var3 if var1 is 1 andvar2 is not 1. Review this example very closely. Try switching things around and re-compiling it .

You may have not iced in the other code examples, like this one, some of the lines areindented farther than others. This is to help you keep track of which parts of yourprogram go with each other. The use of proper indentat ion while writ ing your programcan make debugging a lot easier. The next bit of code is exact ly the same as the oneabove as far as funct ionality, but not ice how improper indentat ion can make code a lotharder to read.

Consider the following C code:

if(var1 == 1){if(var2 == 1){ printf("var1 is 1 and var2 is 1\n"); }else{ if(var3 == 2) printf("var1 is 1, var2 is not 1, and var3 is 2\n");}if(var2 == 0 ){ printf("var2 is 0\n"); } }

Emacs Tip: If you're using emacs you can use the TAB key to correct the indentat ion.Place your cursor at the beginning of the incorrect code, hit TAB and the down arrow inrepeatedly in succession unt il the indentat ion is f ixed. When emacs is in C mode, itrecognizes the syntax and will t ry to correct ly indent it for you. You may have not iced itauto-indent some lines af ter you f inish typing them.

Let 's switch gears a lit t le. Instead of test ing a lot of dif ferent variables, we can test thesame one for a lot of dif ferent cases.

Consider the following C code:

if((var == 1) || (var == 2) || (var == 4) || (var == 8) || (var == 16)){ printf("var is either 1, 2, 4, 8, or 16.\n");}else if((var == 3) || (var == 5) || (var == 7)){ printf("var is either 3, 5, or 7.\n");}else if(var == 6){ printf("var is 6.\n");}else{ printf("var isn't any of those numbers.\n");

printf("var isn't any of those numbers.\n");}

You can see how this could be a pain. Especially if you need to test for more cases thanI show here. A better way to go about this is by using a switch statement.

Switch Statements

Switch statements are used to perform dif ferent operat ions depending on the value ofone variable or funct ion. The example below shows how to use switch and is theequivalent of the if statement above.

Type the following code into your editor:

/* lesson9c.c */#include <stdio.h>

int main(){ int var;

printf("Enter an integer: "); scanf("%i",&var);

switch(var){ case 1: case 2: case 4: case 8: case 16: printf("var is either 1, 2, 4, 8, or 16.\n"); break; case 3: case 5: case 7: printf("var is either 3, 5, or 7.\n"); break; case 6: printf("var is 6.\n"); break; default: printf("var isn't any of those numbers.\n"); break; }

return 1;}

Save this program as lesson9c.c. Test it out to make sure it does what you think it will.

At f irst this just seems longer to write out, but some people f ind it easier to read whenthere are a lot of cases. It all boils down to personal preference in the end. However,you should be familiar with how both if and switch work in case you f ind yourselfmodifying someone else's code.

The argument, var in this case, is the variable or funct ion that is tested in each case.Each instance of case is a test for equality with what we're test ing for. If one of thecases match, everything unt il the f irst occurance of break is executed. If none of thecases match, the default case is run. If you don't need a default, it can beommit ted.

© Useractive, Inc. - 1998-2003.Useractive™, Coderunner™, and The Learning Sandbox™ are registered trademarks of Useractive, Inc. All rights reserved.

Lesson 10 -- LoopsLoops

One of the most powerful programming tools are loops. The idea behind loops is tokeep doing the same thing over and over unt il a certain condit ion is met. Consider whathappens when you wash dishes by hand. You wash and dry a dish, then you go ontothe next one. The process is repeated, washing and drying, unt il there are no moredishes lef t . This is a dish washing loop.

I'm going to start by teaching you while loops because they are the most similar to theif statements we've already covered. Look at the following bit of code.

Consider the following C code:

dishes=0;if(dishes < 10){ printf("done ");}

That 's a simple enough if statement right? It just prints "done " if dishes is less than10. Now let 's replace the if with a while. (Do not t ry this yet)

Consider the following C code:

dishes=0;while(dishes < 10){ printf("done "); /* Do not try this code */}

The only dif ference is that an if will only execute once and a while will keep going aslong as the condit ion is t rue. You can use mult iple condit ions for a while just like youcan with if statements. That 's really all there is to while loops, but before I have youtry them I want to go over the very important topic of inf inite loops.

Inf inite Loops

Look again at the previous code example. Do you see what 's wrong? If dishes is lessthan 10, "done" will be printed to the screen unt il the value of dishes is no longer lessthan 10. But because the value of dishes never changes, the while will keeprunning... and running... and running. Forever. Forever and inf inite mean the same thing.That 's obviously not what we want, but it does happen (most ly by accident) and youneed to know what to do when it does. Lucky for us, Unix has a built in way to stop yourprogram. In an emergency like this you can always hit Ctrl+c (Control and c at thesame t ime), to stop your program from running.

NOTE: You only need to hit Ctrl+c once even though your program may appear tokeep running. What 's actually happening is that your inf inite loop will probably execute

thousands of t imes before you realize it and stop your program. Your terminal isn't fastenough to display everything as quickly as your program is writ ing to STDOUT. You justhave to wait a few seconds for it to catch up.

Avoiding Inf inite Loops

Avoiding inf inite loops isn't that hard, it 's all in how you use them. This t ime, let 's add 1to dishes every t ime we go through the loop. Essent ially we'll end up with a loop thatexecutes ten t imes. It 'll run once for each value of dishes f rom 0 to 9. I want you towrite a program that contains the following code and make sure you get the output youexpect:

Type the following code into your editor:

/* lesson10.c */

#include <stdio.h>

int main(){ int dishes;

dishes=0;

while(dishes < 10){ printf("done "); dishes++; }

printf("\nDarn, t ime to do the dishes again.\n");

return 1;}

Alright , now it 's safe to compile and test your f irst loop. :) Save the f ile as lesson10.cand go at it .

The line dishes++; that I used is just a shortcut for dishes = dishes + 1;. Thismeans that the value of dishes increases by 1 each t ime the while loop is repeated.The f irst t ime through the loop, the value of dishes is 0, the second t ime 1, the thirdt ime 2, all the way up unt il the tenth t ime when the value of dishes is equal to 9. At theend of the tenth t ime trhough the loop, the value of dishes is incremented so that itequals 10. At this point the eleventh t ime will be at tempted, however, because dishesis now equal to 10 and is no longer less than 10, so the loop terminates.

This is what you should get:

Observe the following:

cold:~$ ./while

cold:~$ ./whiledone done done done done done done done done doneDarn, t ime to do the dishes again.

Let 's do another example.

Type the following code into your editor:

/* lesson10b.c */

#include <stdio.h>

int main(){ int var=20,ans;

while(var < 26){

ans = var % 2; if(ans == 1){ printf("%i is odd\n",var); }else{ printf("%i is even\n",var); } var++; } return 1;}

Play with lesson10b.c a lit t le too and see what you can come up with.

Here we're using basically the same strategy as in the previous example. This t ime, varstarts at 20 and the loop cont inues while it 's less than 26. The modulus (%) is used toget the remainder of dividing var by 2. The remainder will either be 1 or 0 depending onwhether or not the number is even or odd. Don't forget to compile and test theexamples.

Observe the following:

cold:~$ ./while220 is even21 is odd22 is even23 is odd24 is even25 is odd

Do-While Loops

The only dif ferent between a do-while loop and a regular while loop, is that thedo-while will always be executed at least once.

Type the following code into your editor:

/* lesson10c.c */#include <stdio.h>

int main(){ int i=0;

do{ printf("%i ",i++); } while(i<10);

return 1;}

Save this one as lesson10c.c. What do you think the output will be? Try it out and seeif you're right .

Here, i++; is used inside of another funct ion. What happens is that 1 is added to iafter the printf runs. The f irst t ime through the loop, printf statement will output a0 before i is incremented to 1. You could also use ++i; to add 1 before printfexecutes. In this case, the f irst t ime through the loop, i will be incremented to 1 beforethe printf statement outputs it 's value.

For

Very of ten loops are used with a variable, such as i, that is incremented each t ime unt ila condit ion isn't met. As we've seen with the previous while loop examples. Thevariable needs an init ial value, a test it needs to pass, and a statement that incrementsit . for loops contain all of these things at the very beginning. This reduces the numberof lines of code required for simple loops.

Type the following code into your editor:

/* lesson10d.c */#include <stdio.h>

int main(){ int i;

for(i=0;i<10;i++){ printf("bye "); } return 1;}

I bet you couldn't guess this one would be lesson10d.c. :) Compile and run this example.

Not ice the semicolons between the three parts of the for loop. The f irst part init ializesi to 0, the second part tests i to make sure it 's less than 10, and the last partincreases i by one each t ime through the loop. The variable i will start at 0, andincrease by 1 each t ime through the loop unt il i equals 10.

Observe the following:

cold:~$ ./for bye bye bye bye bye bye bye bye bye bye

This simple example of a for loop is actually the most common way it 's used. In thenext lesson you'll see how this loop can make short work when traversing through anarray.

Stopping in the Middle of a Loop

There are two other C statements that allow you to alter the f low of loops: break andcontinue. Both are usually used for special cases that aren't covered by the normalcondit ions of the loop.

Consider the following C code:

var=0;while(var < 20){ printf("%i",var); var++; if(var < 10) continue; var++; }

The continue; statement forces to loop to go to the next iterat ion and skips anycode in the loop af ter it . The result is that we'll add 1 to var while it 's small, and 2 whenit gets bigger. Let 's say var is current ly 8. First , "8" is printed out, then var in increasedto 9. Since 9 is less than 10 the continue statement runs. Now we go back to thebeginning of the loop. var is less than 20 so we print it out , 9. Then we add one tomake var 10. It 's not less than 10 anymore, so we add one again to make it 11. Back tothe start again and we print out 11, 13, 15, 17, and 19 before stopping when var equals21. The break; command is used the same way, but it stops the loop altogetherinstead of cont inuing at the top. We saw break as part of a switch statement.

© Useractive, Inc. - 1998-2003.Useractive™, Coderunner™, and The Learning Sandbox™ are registered trademarks of Useractive, Inc. All rights reserved.

Lesson 11 -- ArraysArray Basics

Let 's say you want to remember something. You store that informat ion in your head.Then you use your memory to recall it later. When you declare a variable, like an integeror character, C allocates a single block of memory to store it in. An array is nothing morethan a series of consecut ive blocks in memory that all store the same type ofinformat ion. But why would we ever want to do that? The simplest reason is if you needto store a bunch of dif ferent numbers. It 's easier to remember the name of one array,rather than a bunch of separate variables. I'll use the following type of diagram toillustrate data stored in arrays throughout the rest of this course.

In the diagram, arrayname is the name of our array. Each box represents a block ofmemory and the number below each box is called the index. The index, or posit ion inthe array, always starts f rom zero.

Declaring Arrays

The declarat ion of an array is very similar to that of a normal variable. The dif ference isthat you either have to declare init ial values or a size for the array. Without values or asize, C doesn't know how much memory to allocate.

Consider the following C code:

int myarray[5];int array2[] = {10, 6, 8, 7, 9};

Putt ing a number inside of the brackets, as with the declarat ion of myarray, tells C wewant to allocate that number of memory blocks to store integers. The alternat ive way isto assign values at the same t ime as the declarat ion. By giving array2 values, the sizeis automat ically determined.

After init ializat ion, the two arrays look like this in memory:

Note: Even though we declare the size of the array as 5, the indices st ill go f rom 0 to 4.

Traversing Arrays

Now that we have our array we need to be able to change it 's values. To do this wehave to tell C the name of the array and the index of the posit ion that needs to bechanged.

Consider the following C code:

myarray[2] = 20;

The array now looks like this:

Here we are assigning the 3rd element of myarray the value of 20. Remember that wecount the index start ing at zero, that 's why the index of 2 is actually the 3rd element.Now we'll put this all together in an example I want you to t ry.

Type the following code into your editor:

/* lesson11.c */#include <stdio.h>

int main(){ int myarray[3]; char array2[] = {'a','b','c','d','e'};

myarray[0] = 700; myarray[1] = 800; myarray[2] = 900;

printf("index 0 of array2 is %c\n",array2[0]); printf("index 1 of array2 is %c\n",array2[1]); printf("index 2 of array2 is %c\n",array2[2]); printf("index 3 of array2 is %c\n",array2[3]); printf("index 4 of array2 is %c\n",array2[4]);

printf("index 0 of myarray is %i\n",myarray[0]); printf("index 1 of myarray is %i\n",myarray[1]); printf("index 2 of myarray is %i\n",myarray[2]);

return 1;}

Compile and try out this bit of code af ter saving it as lesson11.c.

The f irst thing we're doing here is set t ing up a three element integer array called

myarray. Next, we create a character array that contains f ive characters. Then wesimply give values to the elements in myarray. The three printf statements showwhat each element of myarray stores.

Type the following code into your editor:

/* lesson11b.c */

#include <stdio.h>

int main(){ int myarray[3]; char array2[] = {'a','b','c','d','e'}; int i;

myarray[0] = 700; myarray[1] = 800; myarray[2] = 900;

/* illustrat ing the usefulness of loops */ for(i=0;i<5;i++){ printf("index %i of array2 is %c\n",i,array2[i]); } for(i=0;i<3;i++){ printf("index %i of myarray is %i\n",i,myarray[i]); }

return 1;}

Here we have lesson11b.c. Compile and run your code. This example is not just toshow you how to use arrays, it also reinforces the power of loops. Imagine you want toprint out an array with a few hundred elements. It 's not hard to see that a simple loop isa lot easier to write than tons of print statements.

Here we have basically the same setup. However, instead of using a printf statementfor every element of the array, we have a for loop. The for loop is used to look ateach element of array2, one at a t ime. The f irst t ime through, i equals 0 which canalso be used as the index of the array. So the statement "index 0 of array2 is a" isprinted out. Then i equals 1 the next t ime through and so on.

Observe the following:

cold:~$ ./arrayindex 0 of array2 is aindex 1 of array2 is bindex 2 of array2 is cindex 3 of array2 is dindex 4 of array2 is eindex 0 of myarray is 700

index 0 of myarray is 700index 1 of myarray is 800index 2 of myarray is 900

The object ive for this lesson is your f inal project and then all that 's lef t is another shortlook at compiling. Congratulat ions! You're almost done!

© Useractive, Inc. - 1998-2003.Useractive™, Coderunner™, and The Learning Sandbox™ are registered trademarks of Useractive, Inc. All rights reserved.

Lesson 12 -- Compiling: Revisited

Take a moment to relax. You're almost done.

Compiling Revisited

We covered what happens when you compile in Lesson 4. So far you've just beensaving and compiling with CodeRunner by clicking on Compile C/C++. That works great,but if you go get a job somewhere they aren't going to have CodeRunner.

GCC

Let 's go back and look at first.c.

Consider the following C code:

/* first.c */

#include <stdio.h>

int main(){

/* print statement */ printf("I've been programming C for 1 day.");

return(1);}

If you're not already in CodeRunner's Unix Mode, switch to it now. Let 's make sure ourf ile is there.

Type the following command at your unix prompt:

cold:~$ ls first*

Observe the following:

first.c

Alright , excellent . To compile the program we'll use a command called gcc. GCC standsfor GNU C Compiler.

Type the following command at your unix prompt:

cold:~$ gcc first.c

If everything worked you won't init ially see any output of the gcc command. If you got

any errors, look at the code again to make sure it 's correct . Then try to compile it again.If it st ill doesn't work, look below for some common errors. Go back to Lesson 4 forsome common errors. If you did not have any errors, you should now have a f ile calleda.out in your directory.

Type the following command at your unix prompt:

cold:~$ ls a.out

Observe the following:

a.out

This is the name given to a compiled f ile, or executable, by gcc. I f ind it really boring andnot very descript ive. Also, gcc will overwrite a.out, if it already exists without asking.It 's not very useful if it keeps overwrit ing your previous programs. For these reasons, it isa good idea to give the compiled f ile a name other than a.out to use. We could do thisby creat ing a.out and then using cp to make a copy with a dif ferent name, but there'sa better way.

Type the following command at your unix prompt:

cold:~$ gcc first.c -o first

Notice that we added -o first to the compile command. The -o opt ion tells gccthat we want the output f ile to be named something other than a.out. The new name,first, follows the -o opt ion. Check to make sure you have a f ile called first.

Type the following command at your unix prompt:

cold:~$ ls

Observe the following:

a.out first first.c

Now run it .

Type the following command at your unix prompt:

cold:~$ ./first

Observe the following:

I've been programming C for 1 day.

Great! Now let 's put an error in the C code again so you can see how gcc reportserrors. Let 's t ry leaving of f the semicolon af ter the printf funct ion. Do this by re-opening first.c and removing the semicolon.

Type the following code into your editor:

/* first.c */

#include <stdio.h>

int main(){

/* print statement */ /* printf("I've been programming C for 1 day."); */ printf("I've been programming C for 1 day.")

return(1);}

What I did here was simply comment out the old print statement and put in a new onethat 's missing a semicolon. Now save your f ile and compile your program again.

Type the following command at your unix prompt:

cold:~$ gcc first.c -o first

Observe the following:

first.c: In function `main':first.c:10: parse error before `}'

Instead of creat ing an executable f ile, we get an error message. This is the same errormessage you saw in Lesson 4.

The -lm f lag

There is a special case when using the math.h library. Type in the following C program:

Type the following code into your editor:

/* pow.c */

#include <stdio.h>#include <math.h>

int main(){ float a=5.0, b=10.0, c;

c = pow(a,b);

printf("%f\n",c);

return 1;}

I talked about the pow() funct ion in Lesson 6. Let 's t ry to compile this program withgcc.

Type the following command at your unix prompt:

cold:~$ gcc pow.c -o pow/tmp/ccJextG3.o: In function `main':/tmp/ccJextG3.o(.text+0x27): undefined reference to `pow'collect2: ld returned 1 exit status

Wow... that sucks. There's nothing wrong with the code. Why is there an undef inedreference to pow? Hhmmm...

This is the special case I was talking about. When using math.h you have to use the -lm f lag with gcc. Here's how:

Type the following command at your unix prompt:

cold:~$ gcc -lm pow.c -o powcold:~$ ./pow9765625.000000

Excellent . The -lm f lag simply indicates the use of math.h.

That 's it for now. You've learned a lot and you should be really proud of yourself .Looking forward to seeing you in C, Part 2!!

© Useractive, Inc. - 1998-2003.Useractive™, Coderunner™, and The Learning Sandbox™ are registered trademarks of Useractive, Inc. All rights reserved.

Lesson 1 -- FunctionsCongratulat ions on f inishing the f irst C course. Remember that at any t ime you can goback and review the previous lessons.

What's a Function?

A funct ion is a self -contained sect ion of code that performs operat ions on some inputand returns the result . It sounds complicated, but you've been using one this whole t ime.Let 's look again at the very f irst program we wrote:

Consider the following C code:

#include <stdio.h>

int main(){

/* print statement */ printf("I\'ve been programming C for 1 day.");

return(1);}

main is a funct ion. It 's a special funct ion in that C always starts execut ing with main,and as a result , it always has to exist . Not ice that main is declared with a variable typeas well. This variable type tells C what kind of variable the funct ion will return. What thismeans is that when we call a funct ion we can get back a result . The result can beanything from the result of a math funct ion to simply an indicat ion that the funct ion ranokay. In this case, the return funct ion returns a 1 (TRUE). This is the same thing assaying that it exited successfully.

The parenthesis af ter the name of the funct ion is where you'd specify what type ofinput the funct ion is receiving. The input would be any informat ion that the funct ionneeds to manipulate to get a result . In this case, there isn't any input so we don't putanything in the parenthesis. We'll take a look at this more down below when we writeour own funct ion. The last thing you want to make sure of is to include the contents ofthe funct ion in brackets.

Why Functions?

There are three good reasons why you'd want to write your own funct ions. First , if youneed to do the same thing mult iple t imes throughout your code, but with dif ferentvariables, funct ions save a lot of typing and reduce clut ter. Secondly, the use of outsidefunct ions clean up main so the f low of the program is more easily understood whenlooking back. Without funct ions, main could get really long. Last ly, funct ions can be re-used in future programs. An excellent example of these is the pow funct ion Iintroduced in lesson 6 of the f irst C course. We could do the same thing with a loop, butit 's much easier to use pow. To prove this, let 's write our own version of pow thatwe'll call power. Save this in a f ile called main.c.

Type the following code into your editor:

/* c2-1.c */

#include <stdio.h>

int main(){ int var1, var2; double result; double power(int x, int y);

/* get input from the user */ printf("Please enter two integers seperated by a space: "); scanf("%i %i",&var1,&var2);

/* call our function and store the returned value in a variable */ result = power(var1,var2);

printf("result = %f\n",result);

}

double power(int x, int y){ int i; double answer=1;

/* mult iply by x, as many t imes as there are y */ for(i=0;i<y;i++){ answer = answer * x; } return answer;}

Save this example as c2-1.c then compile and run it to see it in act ion. If you don'tremember how to compile, click here.

In order to use a funct ion outside of main, we have to delare it like we would a variable.Unlike variables, we don't do this for the purpose of allocat ing memory, but C needs toknow what type of data the funct ion expects as input and what type it will return. In thiscase, we want the power funct ion to return a double. Also, inside the parenthesis wedef ine what type of input the funct ion is expect ing. (The actual variable names aren'trequired at this point , only the types, but I include them to keep things straight.)

The next blue sect ion is where we use the power funct ion to get a result . Not ice thatthe result variable is the same type as we expect the funct ion to return. In theparenthesis we have var1 and var2 which are the integer inputs that power isexpect ing.

Finally we have the power funct ion itself . The beginning of the funct ion looks exact lylike the declarat ion of it f rom inside of main. The dif ference is that now the variable

names (x and y in this case) are required. The variables x and y are allocated for use inthe power funct ion and they store the value of var1 and var2 respect ively. The nextcouple lines declare a few variables we'll need to make the calculat ion. Next, the forloop does the math and af ter that we return the answer. The answer that is returned,is stored into the result variable f rom main.

Observe the following:

Please enter two integers seperated by a space: 2 3result = 8.000000

Our power funct ion is a lit t le less powerful than the real pow because we're onlydealing with integers, but it gets the idea across.

NOTE: The reason I chose a double is, even though the result of our math will be aninteger, the number can be rather large depending on the input. A double can store amuch bigger number than an int , f loat , or even a long.

Separate .c and .h f iles

Let 's imagine we have a lot of extra funct ions that we've writ ten. The c2-1.c file isgetting a little big to work with and we'd like to break it up intomore than one file.

We need to create two new files, one called power.c and one calledpower.h.

Type the following code into your editor:

/* power.c */

double power(int x, int y){ int i; double answer=1;

/* mult iply by x, as many t imes as there are y */ for(i=0;i<y;i++){ answer = answer * x; } return answer;}

Save this as power.c.

Type the following code into your editor:

/* power.h */double power(int x, int y);

We'll save this one as power.h.

The next box shows, in red, the lines that we'll remove from the c2-1.c file and in blue the line that needs to be added.

Consider the following C code:

/* c2-1.c */

#include <stdio.h>#include <power.h>

int main(){ int var1, var2; double result; double power(int x, int y);

/* get input from the user */ printf("Please enter two integers seperated by a space: "); scanf("%i %i",&var1,&var2);

/* call our function and store the returned value in a variable */ result = power(var1,var2);

printf("result = %f",result);

}

double power(int x, int y){ int i; double answer=1;

/* mult iply by x, as many t imes as there are y */ for(i=0;i<y;i++){ answer = answer * x; } return answer;}

The new file looks like this:

Type the following code into your editor:

/* c2-2.c */

#include <stdio.h>#include <power.h>

int main(){ int var1, var2; double result;

/* get input from the user */ printf("Please enter two integers seperated by a space: "); scanf("%i %i",&var1,&var2);

/* call our function and store the returned value in a variable */ result = power(var1,var2);

printf("result = %f",result);

}

Save this as c2-2.c.

Notice how we replaced the declaration of the power function inmain by the inclusion of the power.h header file. The functions aredeclared in the header file. Instead of declaring all the functionsseparately we only have to include the one header file. The actualfunctions we took from c2-1.c are in power.c. So now we have threefiles: c2-2.c, power.c, and power.h. We have to do something specialto get them all to compile into one program. Use the followingcommand to compile it:

Type the following command at your unix prompt:

cold:~$ gcc -I./ c2-2.c power.c -o power

The -I./ option for gcc tells the compiler to look in the currentdirectory for header files as well as the normal system places.Without this we get an error saying that gcc can't find power.h:

Observe the following:

main.c:4: power.h: No such file or directory

The stdio.h file that we've been including this whole time declaresmany standard functions such as printf and scanf. There are manymore header files, some of which we'll look at as we progressfurther.

© UserActive, Inc. - 2000UserActive is a registered trademark of UserActive, Inc.

-- all rights reserved --

Lesson 2 -- Random NumbersRandom Numbers

At some point you may f ind yourself want ing to generate some random numbers.Perhaps you want to simulate the rolling of a six sided die for a game.

To generate a random number we'll use the rand() funct ion. This funct ion is declaredin stdlib.h, so we need to include that header f ile as well. It def ines a constant calledRAND_MAX. The rand() funct ion will return a number between 0 and RAND_MAX.RAND_MAX is an unchanging number that is def ined separately for each system. On a32bit computer, it 's usually over 2.1 billion.

Usually we don't desire numbers that large. We can use the modulus (%) to change therange of our random number. For example, rand() % 6 would produce a numberbetween 0 and 5. To simulate a six sided die, all we have to do it add one to that result .Let 's do a small example.

Type the following code into your editor:

/* c2-3.c */

#include <stdio.h>#include <stdlib.h>

int main(){ int result;

result = rand() % 6 + 1;

printf("%i",result);

return 1;}

Save this program as c2-3.c. Compile and run this several t imes. You should not icesomething a lit t le strange. You're gett ing the same number over and over. What? Ithought it was supposed to be random. Yeah, well, it 's not. You have to remember thatsince we're in the world of computers, nothing is ever going to be totally random. Whatrand() actually does is use a some strange math funct ion (that doesn't really matterto us) to generate numbers that appear to be random. The problem is that it alwaysstarts at the same place and gives the same sequence of "random" numbers. However,there is a solut ion.

srand

Another funct ion called srand can be used to make rand start f rom another place.The srand takes in a value called a seed. But if we give srand a constant integer as aseed, the only result is that we'll get a dif ferent sequence of the same random numbers.So we need a seed that will be dif ferent every t ime we run the program.

This is where we'll take advantage of your computer's clock. Your computer keeps trackof the t ime of day in seconds, so if we could use that number as our seed we'd begolden. We need to include the time.h header f ile and use the time funct ion. Here'show:

Type the following code into your editor:

/* c2-4.c */

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

int main(){ int result,i;

srand(time(NULL));

for(i=0;i<5;i++){ result = rand() % 6 + 1;

printf("%i\n",result); } return 1;}

Compile and run this one af ter saving it as c2-4.c.

We only need to use srand once at the beginning of the program. Then we cangenerate as many random numbers as we want.

If you run the program twice in a row fast enough you'll st ill get the same sequence ofnumbers (if a second hasn't gone by we'll get the same seed), but for the most part wecan ignore that.

NOTE: Theoret ically we could predict our random number sequence by picking a t imeof day, and trying to run our program at that exact same t ime.

Fractions

You may have not iced that the only thing we're gett ing f rom the random numbergenerator is integers. However, if you want to do anything involving percentages, orperhaps a stat ist ics simulat ion, you'll need random fract ions. The best way I've found todo this is to take full advantage of the RAND_MAX constant that already exists.

Consider the following C code:

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

int main(){ float result;

srand(time(NULL));

result = rand() / (float) RAND_MAX; /* gotta make sure we do the math with all floats or it won't work */

printf("%f\n",result);

return 1;}

By dividing a random number that goes from 0 to RAND_MAX, by RAND_MAX, we get afract ion f rom 0 to 1. Again, it 's not t ruly random because there's only a certain amountof accuracy you can get with your f ract ions. However, RAND_MAX is so large that youare actually limited by the 6 decimal place accuracy of the f loat ing point variable.

© UserActive, Inc. - 2000UserActive is a registered trademark of UserActive, Inc.

- - all rights reserved - -

Lesson 3 -- PointersWhat's a Pointer?

Sometimes in C, it becomes necessary to store the locat ion of a variable rather than it 'sactual value. Huh? Let me explain. Normally, when you declare a variable, say an integer,C allocates a specif ic block of memory to store the variable. The variable itselfrepresents the value stored in that memory block. Here's a picture showing an integervariable called num.

Here, num represents the number 12. Now suppose we have a pointer to a memoryblock. We'll represent that as follows:

pnt is a pointer to the memory storing the number 9. As a result , pnt does not storethe number 9, it stores a memory address, the locat ion of the number 9. However, wecan get at the data stored in memory by using an asterisk. The asterisk is called thedereference operator. So, in our program, *pnt would refer to the actual number 9.Pointers are weird unt il you get used to them, so don't worry if this makes absolutely nosense right now. That 's perfect ly normal.

Using Pointers

A pointer is declared almost the same way as a regular variable because C needs toknow what type of data the pointer is point ing to. We use the dereferencing operator(*) in the declarat ion as well, to indicate it 's a pointer and not a normal variable. Here's asmall but important example:

Type the following code into your editor:

/* c2-5.c */

#include <stdio.h>

int main(){ int num; int *pnt;

pnt = &num;

num = 1; printf("num is %i\n",num);

*pnt = 2;

*pnt = 2; printf("num is %i\n",num); printf("*pnt is %i\n",*pnt);

printf("pnt is %p\n",pnt);

}

Save as c2-5.c. Compile and run your code. You should get output similar to thefollowing:

Observe the following:

num is 1num is 2*pnt is 2pnt is 0xbffffa74

Declaring a pointer doesn't set up the memory locat ion it 's going to point to. As a result ,we have to assign an address to the pointer. On the second blue line we use theaddress operator (&) to get the address of num and store it in pnt . (Do you rememberthe address operator f rom when we learned scanf?) From this point on, pnt points tothe same memory block that num refers to.

Now the dereferencing operator allows us to use *pnt as essent ially the same thing asnum. When assigning a value of 2 to *pnt we change the value of num as well.Changing one changes the other.

The last line prints out the memory address that 's stored in pnt . You don't need toknow how to read this address, that 's what your computer is for. I just wanted to showyou that pnt as a variable, stores an address.

It might be useful to think of your mailbox as a variable, and your street address as apointer. You can either walk out to your mailbox and put something in it direct ly, or youcould mail it to your address. Either way, it ends up in the same place.

Not ice how the second t ime we printed out num, the value was 2.

NOTE: If you're t rying to use a pointer as a regular variable and you're gett ingsegmentat ion faults you might want to t ry putt ing parenthesis around the pointer andit 's dereferencer. For example, *j++; will not work correct ly because ++ has a higherprecedence than *. However, (*j)++; does work.

Pointers to Arrays

You may think that pointers to arrays would be trickier, but in fact , they're much easier.When you declare an array...

Consider the following C code:

char myarray[] = {'a','b','c'};

...the name, myarray is automat ically a pointer to the f irst element of the array.

Is actually..

Since the array is made up of consecut ive blocks of memory, the brackets ([ ]) act asthe dereferencer. The number inside the bracket just indicates which block of memory isbeing refered to. To prove this, t ry the following:

Type the following code into your editor:

/* c2-6.c */

#include <stdio.h>

int main(){ int myarray[] = {1,2,3,4,5,6,7,8,9,10};

printf("%i\n",*myarray); printf("%i\n",myarray[0]);}

Both of the print statements will give the same output. Both *myarray andmyarray[0] refer to the f irst element of the array. Compile and test the code tomake sure it works af ter saving it as c2-6.c.

But Why?

Pointers seem really complicated. Why on earth would we ever want to use them?Pointers are used to get around an important problem with funct ions. As you know, afunct ion can only return one value. That 's no good. What happens when you need afunct ion that returns more than one value? The answer lies with pointers. You cansetup the variables you need and then pass only the address of those variables to thefunct ion.

Let 's see how this all works.

Type the following code into your editor:

/* c2-7.c */

#include <stdio.h>

int main(){ int number1=10, number2=20; int addfive(int *num1, int num2);

printf("Before adding 5 we have %i and %i\n",number1, number2);

number2 = addfive(&number1, number2);

printf("After adding 5 to both we get %i and %i\n",number1, number2);} int addfive(int *num1, int num2){ *num1 += 5; num2 += 5;

return num2;}

Examine this code closely before compiling it . See if you can f igure out what 's going onbefore reading my explanat ion. Don't forget to save it as c2-7.c.

Before we use the funct ion we have to declare it . The addfive funct ion is going totake one pointer and one integer as input. What pointer will we give it if I didn't declareone? A pointer simply stores a memory address right? So when we pass a pointer toour funct ion we can just use the address operator and pass the address of the variabledirect ly.

We call the funct ion and give it our two inputs. The number1 variable will be changedby using a pointer to it 's memory locat ion and number2 will be assigned a new valuethat addfive returns.

Now comes the actual addfive funct ion. It takes an address and declares the pointer*num1 for it , while num2 stores the value of number2. Five is added to both ofthem and num2 is returned. number1 was changed at it 's memory locat ion by usingthe pointer.

Observe the following:

cold:~$ ./pointersBefore adding 5 we have 10 and 20After adding 5 to both we get 15 and 25

We can do the same thing as above with two pointers instead of one while having thefunct ion return nothing. The program turns out to be shorter by using pointers insteadof relying on the program to return a number.

Consider the following C code:

#include <stdio.h>

int main(){ int number1=10, number2=20; void addfive(int *num1, int *num2);

printf("Before adding 5 we have %i and %i\n",number1, number2);

addfive(&number1, &number2);

printf("After adding 5 to both we get %i and %i\n",number1, number2);

printf("After adding 5 to both we get %i and %i\n",number1, number2);} void addfive(int *num1, int *num2){ *num1 += 5; *num2 += 5;}

© UserActive, Inc. - 2000UserActive is a registered trademark of UserActive, Inc.

- - all rights reserved - -

Lesson 4 -- More PointersGiant Pointer Example

This lesson is just a larger example of using pointers with funct ions. It 's an importantconcept that deserves a lit t le extra t ime. This also helps to t ie together a lot of thestuf f you've learned so far.

Type the following code into your editor:

/* c2-8.c */

#include <stdio.h>

int main(){ int myarray[] = {1,2,3,4,5,6,7,8,9,10}; int size=10; float average; int getavg(int ary[], float *avg, int sz);

if(getavg(myarray,&average,size)){ printf("average is %f",average); }else{ printf("average gett ing function was unsuccessful"); }

}

int getavg(int ary[], float *avg, int sz){ int i=0,total=0; if(sz == 0){ /* array is empty, return failure */ return 0; }

while(i < sz){ total += ary[i]; i++; }

*avg = (float) total / (float) sz; return 1;}

Save as c2-8.c. Compile and run the program. The result should be 5.500000.

Let me point out a few things about the code. The reason we want the averagevariable to be a f loat ing point number is purely based on the math behind gett ing anaverage. Even though we'll be adding up integers and dividing by an integer, the result islikely to be a f ract ion.

The second blue line is declaring the funct ion we'll be using and what it expects as input.The getavg funct ion will return an integer value (success 1 or failure 0). As input, weneed to send it the address of an array, a pointer to the variable that will store ouraverage (essent ially the address of our average variable), and an integer giving thesize of the array. When we actually use the funct ion we don't need to use a separatepointer variable. Since a pointer simply stores the address of a variable, we can just passthat address to getavg.

The if statement checks to see if the getavg funct ion returns successfully or not. Asa result , the getavg funct ion executes inside of the if statement. This is strange thef irst t ime you see it . Think of the getavg funct ion just like you would any othercondit ional expression in an if statement. For example, if we had varname < 1. We'retest ing for TRUE (1) or FALSE (0). However, we can also just return a numerical value of1.

Back to the getavg funct ion. We pass the name of our array (it 's address), and we usethe address operator (&) to pass the address of the average variable, and then wesimply give it an integer storing the size of the array.

Inside of the getavg funct ion, the f irst thing we want to do is check and see if thearray is empty or not. If it 's empty, we're going to return zero indicat ing that the funct ionfailed to determine an average value.

Inside of the while loop you can see how we use the brackets to get each value of thearray and add up the total.

The last line stores the result in our average variable by using the pointer. The pointeris point ing to the memory address of average so when we change the pointer, thereal variable is changing as well.

But wait a second, what 's up with putt ing (float) in f ront of the variables? That 's gotnothing to do with pointers. It has to do with how C does math. total and sz are bothintegers, so C will t ry to return an integer as the answer. Putt ing (float) in f ront of avariable, tells C to t reat it like a f loat ing point number for the rest of that statement.Treat ing a variable as another type is called casting.

© UserActive, Inc. - 2000UserActive is a registered trademark of UserActive, Inc.

- - all rights reserved - -

Lesson 5 -- Character Arrays and StringsStrings

I ment ioned early on that strings and words couldn't be stored in a normal variable.However, with an array of characters, we have that power. The dif ference between justan array of characters and a string in C is the addit ion of a NULL character (\0) at theend. The use of NULL indicates where the end of the string is.

This is just a character array

This is a string

Declaring Strings

Strings can be delcared using the same method used to specify values in a characterarray or we can use a shortcut by including a string in double quotes. The NULLcharacter is automat ically added when we use double quotes.

Consider the following C code:

char string1[]={'y','o','\0'};char string2[]="hello";char string3[6];

The f irst string ends up being a three character array with the string "yo" stored inside.By using double quotes, as with string2, C automat ically adds a \0 at the end.string3 is essent ially just declared as an array of characters. In order for it to be astring, we have to remember to include the \0 at the end.

Using Strings

Alright , so let 's start using our strings.

Type the following code into your editor:

/* c2-9.c */

#include <stdio.h>#include <string.h>

int main(){ char string1[]={'y','o','\0'}; char string2[]="hello"; char string3[6];

char string3[6];

strcpy(string3,"there");

printf("%s ",string1); printf("%s ",string2); printf("%s\n",string3);

return 1;}

Compile and run this to see it in act ion. You should save it as c2-9.c.

Observe the following:

yo hello there

When using strings, the f irst thing we need to do is include an addit ional header f ilecalled string.h. This allows us to use many of the funct ions designed to work withstrings. The strcpy statement is a way to assign a value to a string. Unlike normalvariables, we can only use the assignment operator (=) when declaring a string. To set avalue later we have to use something like strcpy. strcpy can also be used to copyone string into another. In this case, we set string3 equal to "there" You have to keepin mind the size of the string so that it does not exceed the size of the array when aNULL character is added to the end.

It 's simple to print out strings using a %s. That way we don't have to worry aboutwhere the end of the string is.

NOTE: string.h isn't necessary on all plat forms, but it 's better to include it than try toremember which ones it 's needed for.

For the rest of this lesson I'll brief ly cover some of the funct ions most commonly usedwith strings. Compile and test all of the following string examples to get a feel forthem. Play around a bit and see what you can come up with.

strcat

The strcat funct ion, as with all of the funct ions I'll go over that start with "str," requiresthat you include string.h.

Type the following code into your editor:

/* c2-10.c */

#include <stdio.h>#include <string.h>

int main(){ char first[40] = "The first string "; char second[] = "and the second string.";

strcat(first,second); printf("%s",first);

return 1;}

We'll call this c2-10.c. The strcat funct ion appends the second string to the end ofthe f irst string. (They don't have to be called first and second, but it makes it easierto illustrate.) What about the NULL character at the end of the f irst string? Well, luckyfor us, strcat takes care of that by putt ing the f irst character of the second stringwhere the NULL used to be. The result is this:

Observe the following:

The first string and the second string.

We could also put strcat direct ly in the print statement.

Consider the following C code:

printf("%s",strcat(first,second));

This is because strcat returns a pointer to the f irst string which is exact ly the samething that the name first refers to.

strcmp

The strcmp funct ion is used to compare two strings. It then returns an integer valuebased on the result of the comparison. It returns less than 0 if the f irst string is less thanthe second, 0 if they are equal, and greater than 0 if the f irst is greater than the second.Wait a second. Less than and greater than? I thought we were talking about charactershere. We are, but remember, characters in C are represented by numbers as well.

Type the following code into your editor:

/* c2-11.c */

#include <stdio.h>#include <string.h>

int main(){ char one[] = "abcd"; char two[] = "abcz"; void compare(char *str1, char *str2);

compare(one, one); compare(one, two); compare(two, one);

return 1;

return 1;}

void compare(char *str1, char *str2){ int value; value = strcmp(str1,str2);

if(value < 0){ printf("%s is less than %s\n",str1,str2); }else if(value == 0) printf("%s is equal to %s\n",str1,str2); else if(value > 0){ printf("%s is greater than %s\n",str1,str2); }

}

Save this one as c2-11.c. Try this out to get a feel for what it does. Here I went an extrastep and wrote another funct ion to show all the dif ferent outcomes. The void type isused when we don't need the funct ion to return anything.

strlen

The strlen funct ion is used to f ind the length of a string. It reads through the string,count ing characters, unt il it sees the NULL character at the end. As a result , it 's veryimportant that NULL character is there. strlen is useful when you need to t raverse astring like an array, and you don't know how long it is.

Consider the following C code:

#include <stdio.h>#include <string.h>

int main(){ str[] = "Mary had a litt le lamb." int length;

length = strlen(str);

printf("The string is %i characters long.\n",length);

return 1;}

The NULL character is not counted in the length of the string. The result looks like this:

Observe the following:

The string is 23 characters long.

sprintf

The sprintf funct ion works almost exact ly the same as printf except that it prints toa string instead of standard output (STDOUT).

Type the following code into your editor:

/* c2-12.c */

#include <stdio.h>

int main(){ char str[50]; int bob = 3;

sprintf(str,"This is my new string and bob equals %i",bob);

printf("%s",str); return 1;}

Save this as c2-12.c before compiling and running it . The format for sprintf is exact lythe same except you have to give it the name of your string f irst .

NOTE: When working with strings you want to be very careful not to exceed the lengthof the string (one less than the size of the array). Writ ing into memory past the end of astring will commonly cause a lot of really weird errors.

sscanf

Just like we have sprintf, we've also got sscanf. This t ime, instead of reading fromstandard input (STDIN) it reads from, you guessed it , a string.

Type the following code into your editor:

/* c2-13.c */

#include <stdio.h>

int main(){ char str[] = "a b c"; char one,two,three;

sscanf(str,"%c %c %c",&one,&two,&three);

printf("the characters are: %c %c %c\n",three,two,one); return 1;}

As you can see, the format is exact ly the same except that you have to tell it the nameof your input string f irst . Save as c2-13.c.

gets

The gets funct ion reads from STDIN, just like scanf. However, the dif ference is thatgets keeps reading characters unt il a newline or end of f ile (EOF). It then stores thecharacters into a string. gets will automat ically append the NULL character to the endof the string as well.

Whenever you compile a program that uses gets you'll get an error saying that usinggets is dangerous. Ignore this warning for now, but if you want it to go away you'llneed to read the link below about programming strings more securely.

NOTE: The EOF (end of f ile) character is found at the end of f iles (as we'll see later) orat the end of an input stream.

Type the following code into your editor:

/* c2-14.c */

#include <stdio.h>

int main(){ char str[100];

gets(str);

printf("%s",str);

return 1;}

It 's just that simple. Try it out and see it in act ion af ter naming it c2-14.c.

© UserActive, Inc. - 2000UserActive is a registered trademark of UserActive, Inc.

- - all rights reserved - -

Lesson 6 -- StructuresWhat is a Structure?

A structure allows you to def ine your own data types. Usually it 's a collect ion of severalother types and by delcaring your new type, all of the other ones are automat ically declaredfor you. Structures are sort of like arrays, but all of the elements don't have to be the sametype. It 's easiest to do an example. First I'll go over three common ways of def ining a struct ,and then I'll cover how to use them.

Consider the following C code:

#include <stdio.h>

struct house{ char owner[30]; float size; float stories; int bedrooms; float bathrooms;};

int main(){ struct house bighouse; struct house smallhouse;

return 1;}

The f irst sect ion def ines the contents of a structure called house. Now, every housestructure we use will contain all of those elements. Inside of main we can then usestruct house to def ine a new house with all of it 's elements. As you can imagine, this isa lot faster than declaring variables for each individual element for every house.

Consider the following C code:

#include <stdio.h>

struct house{ char owner[30]; float size; float stories; int bedrooms; float bathrooms;};

typedef struct house House;

int main(){

int main(){ House bighouse; House smallhouse;

return 1;}

This piece of code illustrates the use of typedef. The only thing typedef does is make itso you can use a single name for variable declarat ion instead of the full struct house.

Consider the following C code:

#include <stdio.h>

typedef struct house{ char owner[30]; float size; float stories; int bedrooms; float bathrooms;} House;

int main(){ House bighouse; House smallhouse;

return 1;}

Here I've combined the structure def init ion and the typedef into one statement. This isusually how you'll see it . Now we have two houses declared... how do we use them?

Using Structures

To access each element of a structure, you have to give the structure's name, a period,and then the element name. The period is called the dot operator. For example, if we wantedto set the bedrooms element of the bighouse structure, we'd do the following:

Consider the following C code:

bighouse.bedrooms = 4;

A structure and element combinat ion acts just like a variable of the type specif ied in thestructure def init ion.

Type the following code into your editor:

/* c2-15.c */

#include <stdio.h>#include <string.h>

typedef struct house{ char owner[30]; float size; float stories; int bedrooms; float bathrooms;} House;

int main(){ House bighouse;

bighouse.size = 4; bighouse.stories = 2; strcpy(bighouse.owner,"John Doe");

printf("size is %.2f square feet.\n",bighouse.size); printf("There are %.1f stories.\n",bighouse.stories); printf("%s owns it.\n",bighouse.owner);

return 1;}

Save as c2-15.c. Compile and run it to get the following output:

Observe the following:

size is 4.00 square feet.There are 2.0 stories.John Doe owns it.

Here we're only using three elements of the structure: size, stories, and owner. Note theuse of strcpy to assign a value for the owner of the house. I've formatted the output tomake it look a lit t le nicer. Try assigning values for the other elements and print ing those outas well.

Pointers to Structures

Just like other variables, you can create a pointer to a structure. The only dif ference is howyou access them.

Type the following code into your editor:

/* c2-16.c */

#include <stdio.h>#include <string.h>

typedef struct house{ char owner[30]; float size; float stories;

float stories; int bedrooms; float bathrooms;} House;

int main(){ House bighouse; House *pnt2house;

pnt2house = &bighouse;

(*pnt2house).size = 4; pnt2house->stories = 2; strcpy(pnt2house->owner,"John Doe");

printf("size is %.2f square feet.\n",pnt2house->size); printf("There are %.1f stories.\n",pnt2house->stories); printf("%s owns it.\n",pnt2house->owner);

return 1;}

After compiling, you should get the same result as before. Remember to save it as c2-16.c.

We declare the pointer and assign it an address the same way as other variable types. Thetrick is that we have to dereference the pointer before we can access it 's elements. Thedot operator ( . ) has a higher priority than the dereferencer ( * ). So we have to putparentheses around the dereferencer and the pointer name. That 's kind of a pain. Luckily, Cprovides us with a shortcut called the arrow operator. It consists of a minus sign and agreater than sign ( -> ). The arrow operator does that same thing as dereferencing thepointer and using the dot operator, but it 's just a lit t le easier to read and use.

Now we'll use all of this to do a big example. Don't let the size of this scare you, it 's reallynot that bad. Just look at it in pieces.

Type the following code into your editor:

/* c2-17.c */

#include <stdio.h>#include <string.h>

/* Define our house structure */typedef struct house{ char owner[50]; float size; float stories; int bedrooms; float bathrooms;} House;

int main(){

int main(){ House house1; House house2; int benefits1=0,benefits2=0; void GetHouseInfo(House *tmphouse);

/* Get the data for each of the two houses */ printf("Now enter the information for the first house\n"); GetHouseInfo(&house1); printf("Now enter the information for the second house\n"); GetHouseInfo(&house2);

/* Compare all of the house elements and adjust the benefits accordingly */ if(house1.size > house2.size){ benefits1++; }else if(house2.size > house1.size){ benefits2++; }

if(house1.stories > house2.stories){ benefits1++; }else if(house2.stories > house1.stories){ benefits2++; }

if(house1.bedrooms > house2.bedrooms){ benefits1++; }else if(house2.bedrooms > house1.bedrooms){ benefits2++; }

if(house1.bathrooms > house2.bathrooms){ benefits1++; }else if(house2.bathrooms > house1.bathrooms){ benefits2++; }

/* Determine which house is better */ if(benefits1 > benefits2){ printf("The house owned by %s is better.\n",house1.owner); }else if(benefits2 > benefits1){ printf("The house owned by %s is better.\n",house2.owner); }else{ printf("Both houses are equally good.\n"); }

return 1;}

void GetHouseInfo(House *tmphouse){ printf("Enter the owners name: ");

printf("Enter the owners name: "); gets(tmphouse->owner);

/* This gets rid of stray newlines that could screw up "gets" */ while(strlen(tmphouse->owner) == 0){ gets(tmphouse->owner); }

printf("Enter the number of square feet: "); scanf("%f",&tmphouse->size);

printf("Enter the number of stories: "); scanf(" %f",&tmphouse->stories);

printf("Enter the number of bedrooms: "); scanf(" %i",&tmphouse->bedrooms);

printf("Enter the number of bathrooms: "); scanf(" %f",&tmphouse->bathrooms); printf("\n\n");

}

Try that out af ter saving it as c2-17.c.

We need to include string.h because we use strlen later on.

In the declarat ion of the GetHouseInfo funct ion, you can see how our def ined Housedata type is used just like int , char, or anything else.

We send the address of each of our house structures to the GetHouseInfo funct ion.This way, by using a pointer to the house structure, we only have to write the code toquery the user one t ime.

At the start of GetHouseInfo, we give the name of the pointer to a house structure as,tmphouse.

The while loop inside of GetHouseInfo helps get rid of stray newlines from the inputbuffer. This works because gets stops on a newlines. If the f irst thing encounted is anewline, the size of the input string will be zero.

© UserActive, Inc. - 2000UserActive is a registered trademark of UserActive, Inc.

- - all rights reserved - -

Lesson 7 -- Reading/Writing FilesOpening a File

In order to read or write to a f ile, you f irst have to open it . By opening a f ile you aresett ing up a pointer to that f ile f rom within C. To do this, C provides us with a data typefor f iles known as a f ile structure.

Type the following code into your editor:

/* c2-18.c */

#include <stdio.h>

int main(){ FILE *myfile;

myfile = fopen("coutput.dat","w"); if(myfile == NULL){ printf("Error opening file\n"); }else{ printf("File opened successfully.\n"); fclose(myfile); }

return 1;}

Save this as c2-18.c> Compile and test this code. Keep in mind that this programdoesn't test to see if the f ile exists before t rying to create it .

Here we can see that the f ile structure type, FILE, is used to declare a pointer. Now wehave to establish which f ile we want to point to. Using the fopen command, we canspecify the name of the f ile and which mode we want to open it in. (Modes areexplained below) If there is an error opening the f ile, fopen will return a NULL pointer.We should check for a NULL pointer because we don't want to cont inue trying to usethis f ile if it didn't open successfully. When we're done with the f ile we use fclose toclose it .

NOTE: Opening a f ile essent ially sets up a data stream for input and/or output just likestdin and stdout .

fopen Modes

When using fopen to open a f ile, you have to give it a mode. In the example above, weused w. The w mode opens a f ile for writ ing, and if it already exists, it 's originalcontents are removed. Two other basic modes are r and a. The r mode opens a f ile forjust reading, while the a mode opens it for appending. While appending, anything newthat 's writ ten to the f ile is put at the end.

Normal Modesr read from an exist ing f ilew create a new f ile for writ ing or clear out an exist ing onea writes to end of an exist ing f ile

There are also three addit ional modes that allow for reading and writ ing at the sametime: r+, w+, and a+.

Read/Write Modesr+ modify exist ing f ilew+ create new f ile or clear out exist ing onea+ reads normally, appends while writ ing

fprintf

Very similar to printf and sprintf, this funct ion is used to, you guessed it , print tof iles. The fprintf funct ion takes a f ile pointer as it 's f irst argument.

Type the following code into your editor:

/* c2-19.c */

#include <stdio.h>

int main(){ FILE *myfile;

myfile = fopen("coutput.dat","w"); if(myfile == NULL){ printf("Error opening file\n"); }else{ fprintf(myfile,"This is the contents of my file.\n"); fclose(myfile); }

return 1;}

Compile and test c2-19.c to make sure it works. After you've run it , use ls at the unixprompt to make sure the f ile exists. You can open the f ile in your editor to make sure it 'scorrect or use can use cat .

Observe the following:

cold:~$ gcc openfile.c -o openfilecold:~$ ./openfilecold:~$ ls

cold:~$ lsa.out* house.c math1.c~ pointer.c scanf* struct*coutput.dat house.c~ openfile* pointer.c~ scanf.c struct.cfile.c~ main.c openfile.c power* scanf.c~ struct.c~first.c* main.c~ pntfunc* power.c string* test*first.c~* math1* pntfunc.c power.c~ string.c test.chouse* math1.c pointer* power.h string.c~ test.c~cold:~$ cat coutput.datThis is the contents of my file.cold:~$

fscanf

I bet you didn't see this coming. :) Again, fscanf works much like scanf and sscanfexcept that you have to give it a f ile pointer f irst .

Consider the following C code:

fscanf(myfile,"%f %c",&myfloat,&mychar);

NOTE: Be careful when reading and writ ing a f ile at the same t ime. If you start reading,and then start writ ing, it will write over the characters at that posit ion in the f ile. This isbecause, one of the elements of the f ile structure stores the posit ion within the f ile.

EOF

EOF stands for end of file. There is an EOF marker at the end of every f ile. It allows youand other funct ions to check for the end of a data stream. C provides us with afunct ion called feof to facilitate this.

Type the following code into your editor:

/* c2-20.c */

#include <stdio.h>

int main(){ char blaa; FILE *myfile;

/* open the file for reading */ myfile = fopen("coutput.dat","r");

/* make sure the open was successful */ if(myfile == NULL){ printf("Error opening file\n"); return 0; }

/* read from the file, one character at a t ime */ /* and stop at the EOF */

/* and stop at the EOF */

fscanf(myfile,"%c",&blaa); while(!feof(myfile)){ printf("%c",blaa); fscanf(myfile,"%c",&blaa); }

fclose(myfile);

return 1;}

Save as c2-20.c. Compile and run this code. Make sure it displays the contents of thef ile correct ly.

Observe the following:

This is the contents of my file.

Here we're just reading in and print ing out one character at a t ime unt il we hit the end ofthe f ile. We scan in the f irst character of our f ile and then test for EOF. While we're notat the end of the f ile, we print out the character we scanned and get another one.

fgets

If you want to read strings f rom a f ile you can use the fgets funct ion. If you read theaside about more secure programming of strings f rom lesson 15 you'll remember it . Wehave to specify a f ile pointer as well as the maximum number of characters to read. Itwill read in up to one less than the number you specify (it saves room for the NULLcharacter it adds) or unt il it reaches a newline. Unlike gets that doesn't keep a t railingnewline as part of the string, fgets does. Another dif ference, is that gets alsoconsiders an EOF the end of a string, while fgets considers an EOF to be an error. If anerror occurs, fgets returns a NULL pointer. Here's an example:

Type the following code into your editor:

/* c2-21.c */

#include <stdio.h>

int main(){ char str[40]; int i=40; FILE *myfile;

/* open the file for reading */ myfile = fopen("coutput.dat","r");

/* make sure the open was successful */ if(myfile == NULL){ printf("Error opening file\n");

printf("Error opening file\n"); return 0; }

/* read a string from the file */ if(fgets(str,i,myfile) == NULL){ printf("read failed.\n"); return 0; }

printf("%s\n",str);

fclose(myfile);

return 1;}

Since the coutput.dat f ile st ill exists, we can read in the line f rom that f ile and print itout . Compile and test the above code af ter saving it as c2-21.c.

© UserActive, Inc. - 2000UserActive is a registered trademark of UserActive, Inc.

- - all rights reserved - -

Lesson 8 -- RecursionWhat is Recursion?

Recursion doesn't introduce any new funct ions in C, but it introduces a very importantconcept. The point of recursion is basically to have a funct ion that calls itself . It can callitself over and over unt il a certain condit ion is met (this condit ion is called the basecase). It 's sort of like one of those pictures you've probably seen of a f rame hanging ona wall with a picture of the wall in it .

(Sorry, I'm not an artist)

You can think of the base case as the point at which you can't draw any smaller.

Let 's start by making a recursive funct ion that doesn't really require recursion. I just wantto get down the basic concepts f irst .

Type the following code into your editor:

/* c2-22.c */

#include <stdio.h>

int main(){ int i=0,end; int numbers(int *j);

end = numbers(&i);

printf("end is %i\n",end); return 1;}

int numbers(int *j){ int tmp; if(*j == 3){ return 0; }

(*j)++;

(*j)++; tmp = *j;

return(numbers(j) + tmp);}

Save as c2-22.c. Try this code to get the following result :

Observe the following:

End is 6

The f irst blue sect ion in the numbers funct ion is our base case. Basically, this providesa stopping point . It 's essent ial that each t ime numbers runs that we make progresstowards the base case. Here we're just adding 1 to an integer unt il we get to 3. If wedon't make progress, it 's possible to get something that 's inf initely recursive and wedon't want that . When the integer equals 3, numbers just returns zero.

When the base case hasn't been reached, however, numbers returns the value ofanother run through numbers added to the value of the integer when it was called.Needless to say, this gets confusing.

Consider the change below, what do you think will be the output? Is it the same thing?All I'm doing is gett ing rid of the temporary integer.

Type the following code into your editor:

/* c2-23.c */

#include <stdio.h>

int main(){ int i=0,end; int numbers(int *j);

end = numbers(&i);

printf("end is %i\n",end); return 1;}

int numbers(int *j){ if(*j == 3){ return 0; } (*j)++;

return(numbers(j) + *j);}

Compile c2-23.c and try it out . Examine the output on your own and see if you canf igure out any dif ferences.

Be Careful and Why?

You have to be pret ty careful when using recursion. One of the most popular examplesof recursion involves the Fibonacci sequence. (If you're not familiar with the Fibonaccisequence, don't worry about it .) The Fibonacci recursive funct ion that is used to f indthe nth number of the series, calls itself twice. The result is exponent ial growth.Sometimes it 's better to use a while loop. (A while loop to f ind the 40th number of theseries took almost no t ime at all on the UserAct ive machines, while the recursive versiontook 18 seconds.)

If you go on and take a data structures course in C/C++, you'll see the real power ofrecursion.

© UserActive, Inc. - 2000UserActive is a registered trademark of UserActive, Inc.

- - all rights reserved - -