c programming - welcome to thyrdthyrd.org/mercurio/cclass/mercurio-c-slides.pdfc c programming...

446
C Programming UCSD Extension © 1995 Philip J. Mercurio 1 1 Introduction Introduction C C C Programming Introduction Phil Mercurio UCSD Extension [email protected] 2 Introduction Introduction C C Today’s Session Course Overview Introduction Fundamentals Writing a Program in C

Upload: lekhue

Post on 28-Jun-2018

231 views

Category:

Documents


4 download

TRANSCRIPT

C Programming UCSD Extension

© 1995 Philip J. Mercurio 1

11 IntroductionIntroduction

CC

C Programming

IntroductionPhil Mercurio

UCSD [email protected]

22 IntroductionIntroduction

CC Today’s Session

ä Course Overviewä Introductionä Fundamentalsä Writing a Program in C

C Programming UCSD Extension

© 1995 Philip J. Mercurio 2

33 IntroductionIntroduction

CC Course Overview: Texts

ä Required: Programming in ANSI C, RevisedEdition. Stephen G. Kochan, SAMS Publishing,1994. (PAC)

ä References (all Prentice-Hall):ä The C Programming Language. Kernighan & Ritchie,

1988ä The C Answer Book. Tondo & Gimpel, 1988ä C: A Reference Manual, Harbison & Steele, 1995ä The Standard C Library, PJ. Plauger, 1992

44 IntroductionIntroduction

CC Course Overview: Grading

ä Homework exercises from PAC assigned eachweekä Due the following week at start of classä Hand in only even-numbered exercises, check odd-

numbered exercises against answers in Appendix Fä Final grade based on homeworkä No midterm or final exams!ä All homework is to be your own work!ä Pass/Fail available

C Programming UCSD Extension

© 1995 Philip J. Mercurio 3

55 IntroductionIntroduction

CC Course Overview: Topics

ä Session 1ä Introduction [Chapter 1]ä Some Fundamentals [Chapter 2]

ä Programming, Higher-Level Languages & OperatingSystems

ä Compiling Programsä Writing a Program in C [Chapter 3]

ä Program Output

66 IntroductionIntroduction

CC Course Overview: Topics

ä Session 2ä Variables, Constants, Data Types, and Arithmetic

Expressions [Chapter 4]ä Program Looping [Chapter 5]

ä For, While, & Do Statementsä Program Input

ä Session 3ä Making Decisions [Chapter 6]

ä If, If-Else, & Switch Statementsä Conditional Expression Operator

C Programming UCSD Extension

© 1995 Philip J. Mercurio 4

77 IntroductionIntroduction

CC Course Overview: Topics

ä Session 4ä Arrays [Chapter 7]

ä Declaring & Initializing Arrays, Character Arraysä Multi-Dimensional Arrays

ä Common Programming Mistakes (So Far) [Appendix]

88 IntroductionIntroduction

CC Course Overview: Topics

ä Session 5ä Functions and Variables [Chapter 8]

ä Arguments & Local Variables, Returning FunctionResults

ä Functions Calling Functions, Functions & Arraysä Global, Automatic, & Static Variablesä Recursive Functions

C Programming UCSD Extension

© 1995 Philip J. Mercurio 5

99 IntroductionIntroduction

CC Course Overview: Topics

ä Session 6ä Structures [Chapter 9]

ä Initializing & Referencing Structures, Functions &Structures

ä Arrays of Structures, Nested Structures

1010 IntroductionIntroduction

CC Course Overview: Topics

ä Session 7ä Character Strings [Chapter 10]

ä Initializing & Displaying Character Strings, Testing forEquality

ä Inputting Character Strings, The Null Stringä Escape Characters, Character Conversions &

Arithmetic Operations

C Programming UCSD Extension

© 1995 Philip J. Mercurio 6

1111 IntroductionIntroduction

CC Course Overview: Topics

ä Session 8ä Pointers [Chapter 11]

ä Pointers & Structures, Pointers & Functions, Pointers& Arrays

ä Operations on Pointers, Pointers to Functions,Pointers & Memory Addresses

ä Session 9ä Operations on Bits [Chapter 12]

ä Bit Operators, Bit Fields

1212 IntroductionIntroduction

CC Course Overview: Topics

ä Session 9 (continued)ä The Preprocessor [Chapter 13]

ä#define, #include Statementsä Conditional Compilation (#ifdef, #endif, #else,#ifndef, #if, #undef)

ä More on Data Types [Chapter 14]ä Enumerated Data Types, Typedef Statementä Data Type Conversions

ä Common Programming Mistakes (Revisited) [Appendix]

C Programming UCSD Extension

© 1995 Philip J. Mercurio 7

1313 IntroductionIntroduction

CC Course Overview: Topics

ä Session 10ä Modularity [Chapter 15]

ä Separate Compilations, Communication BetweenModules

ä Input and Output [Chapter 16]ä Character I/O, Formatted I/O, File I/O

ä Miscellaneous Features and Advanced Topics [Chapter17]

ä Break, Continue, Goto, & Null Statementsä Unions, Command Line Arguments, Dynamic

Memory Allocation

1414 IntroductionIntroduction

CC Introduction

ä Why C?ä What is C?ä History of Cä What you will learn

C Programming UCSD Extension

© 1995 Philip J. Mercurio 8

1515 IntroductionIntroduction

CC Why C?

ä Most popular compiled languageä Available on many platformsä Concepts useful in most programming languagesä Stepping stone to

ä C++ä Objective C

ä Lingua franca of computing

1616 IntroductionIntroduction

CC What is C?

ä Structured, procedural, complied, high-levellanguage

ä Language: vocabulary and syntax for expressingsomethingä In this case, instructions for a computer

ä High-level: more human-oriented than machine’snative language

ä Compiled: converted to machine’s language once,before running

C Programming UCSD Extension

© 1995 Philip J. Mercurio 9

1717 IntroductionIntroduction

CC What is C? (continued)

ä Procedural: programmer specifies exact steps inexact order

ä Structured: build small pieces into larger whole

1818 IntroductionIntroduction

CC History of C

ä Written at AT&T Bell Labs in ‘70sä Mostly by Dennis Ritchieä Successor to BCPL

ä Simultaneous development with Unix operatingsystemä At the time, 90% of Unix written in Cä Together, both gained popularity in academia

ä First book, Kernighan and Ritchie, 1978ä Ambiguous, but first standardä Still referred to as “K&R”

C Programming UCSD Extension

© 1995 Philip J. Mercurio 10

1919 IntroductionIntroduction

CC History of C (continued)

ä American National Standards Institute beganformalizing ANSI C standard in early ‘80s

ä ANSI C code should be understandable to anyANSI-certified compiler on any platformä Doesn’t mean program will run correctly!ä Standard libraries make true portability possible

ä ANSI also made some small improvements in thelanguageä All our examples will be in ANSI Cä Differences wrt K&R will be discussed

2020 IntroductionIntroduction

CC What you will learn

ä Complete vocabulary and syntax of ANSI C (andK&R)

ä Some of the standard libraries for I/O, textmanipulation, etc.

ä Introduction to good C coding style and readabilityä Introduction to designing and building larger

programs

C Programming UCSD Extension

© 1995 Philip J. Mercurio 11

2121 IntroductionIntroduction

CC What you’ll need to learn on yourown

ä How to edit, compile, and run a program on yourcomputerä We’ll use Unix as an exampleä All other systems are similar or easier

ä The libraries on your computer forä Drawing graphicsä Creating user interfaces (windows, buttons, menus, etc.)ä Accessing other features of your computer like audio,

special devices, etc.

2222 IntroductionIntroduction

CC Fundamentals

ä Programmingä Higher-Level Languagesä Operating Systemsä Compiling Programs

C Programming UCSD Extension

© 1995 Philip J. Mercurio 12

2323 IntroductionIntroduction

CC Programming: Instruction sets

ä Computers deal only with binary numbersä A number may be interpreted in many different

waysä As a numerical valueä As a character of textä As the address of a location in memoryä As an instruction to the CPU to

ä Perform arithmeticä Change a location in memoryä etc.

2424 IntroductionIntroduction

CC Programming: Programs &Algorithms

ä A program is a sequence of instructions using theinstruction set of a particular computer to solve aspecific problem

ä An algorithm is a method or technique for solving aproblem

ä The act of programming consists ofä Designing an algorithm to solve the problem (called

analysis)ä Writing a program that implements that algorithm (called

coding)

C Programming UCSD Extension

© 1995 Philip J. Mercurio 13

2525 IntroductionIntroduction

CC Programming: Algorithm example

ä How do you get out of a maze?ä One solution that works for almost all mazes (but

isn’t very efficient) is to place one hand on a walland follow it, along every turn and cul-de-sac.Eventually you’ll end up outside.

ä Another way of viewing the same algorithm is“always keep a wall on your right”

2626 IntroductionIntroduction

CC Programming: Program example

ä Step 1: Look in front and to the right for wallsä Step 2: If there's no right wall, turn right and go

forwardä Step 3: If there's a right wall but none front, go

forwardä Step 4: If there's a right wall and a front wall, turn

leftä Step 5: If we’re still in the maze, go back to Step 1

C Programming UCSD Extension

© 1995 Philip J. Mercurio 14

2727 IntroductionIntroduction

CC Programming Languages: Assembly

ä The preceding example was expressed in a veryhigh-level language (English)

ä The lowest level language is machine language,the binary instructions understood directly by thecomputer

ä The next level up is assembly language, which is atextual code for the binary instructionsä Much easier for a human to type or read than numbersä Each assembly language instruction is translated to

exactly one machine instructionä Specific to one computer model, not portable

2828 IntroductionIntroduction

CC Higher-level languages

ä The first high-level language was FORTRAN(FORmula TRANslation) developed by JohnBackus around 1956

ä The statements in a HLL are closer to how ahuman expresses problems

ä A high-level language is not specific to a particularcomputer architecture

ä One statement in a HLL will get translated intomany machine instructions

C Programming UCSD Extension

© 1995 Philip J. Mercurio 15

2929 IntroductionIntroduction

CC Higher-level languages (continued)

ä By deciding on a standard for the syntax andvocabulary of a language, programs can be writtenwhich are truly machine independentä ANSI C is the standard for the C language

ä A program which translates the text of a HLL into afile containing binary instructions is called acompiler

3030 IntroductionIntroduction

CC Higher-level languages (continued)

ä A program which reads the statements of a HLLand executes them immediately is called aninterpreterä Interpreted programs run slower than compiled

programsä C interpreters exist, but are expensive and aren’t used

much

C Programming UCSD Extension

© 1995 Philip J. Mercurio 16

3131 IntroductionIntroduction

CC Operating Systems

ä Every model of computer has a program (or suiteor programs) which comprises the operatingsystem or OS

ä All input/output operations are performed by theOSä Reading the keyboard and mouseä Displaying on the screenä Reading and writing files from disk or tapeä Network communication

3232 IntroductionIntroduction

CC Operating Systems (continued)

ä OSs are usually specific to a particular computerarchitectureä DOS, Windows, OS/2 for IBM PC-compatiblesä MacOS for Macintoshes

ä UNIX is an OS available on a wide range ofcomputer hardware, including PCs and Macsä UNIX is written in C and can be as portable as C is

C Programming UCSD Extension

© 1995 Philip J. Mercurio 17

3333 IntroductionIntroduction

CC Operating Systems (continued)

ä Compilers are usually specific to one OS, as arethe binary programs they generateä Moving a program from one OS to another is called

portingä Cross-platform compilers run under one OS and create

binaries for another OS

3434 IntroductionIntroduction

CC Compiling Programs

ä Compilers are programs just like the ones we’llwriteä They read files from the disk as input and write different

files to the diskä They’re much more complex than anything we’ll write

ä Entire courses are taught on compiler writingä Many C compilers are written in C and can compile

themselves!

C Programming UCSD Extension

© 1995 Philip J. Mercurio 18

3535 IntroductionIntroduction

CC Edit-Compile-Test Cycle

ä Edit: a text editor is used to create a file containingthe C programä The file name should end in “.c”, for example:

“prog1.c”ä This file is called the source program or source code

ä Compile: the compiler is run with the source codeas the inputä Unix: cc prog1.cä MS-DOS: cl prog1.cä Windows/Mac: probably a menu item

3636 IntroductionIntroduction

CC Compiling: Phases

ä The “compiler” is usually a control program thatactually calls several other programs or phases

ä 1st phase: check the program for syntax andsemantic errorsä syntax error: unbalanced parenthesesä semantic error: using a variable that wasn’t defined

ä If there are errors, the compiler displays them andstops

ä If there are no errors, the compiler generatesassembly code equivalent to the C code

C Programming UCSD Extension

© 1995 Philip J. Mercurio 19

3737 IntroductionIntroduction

CC Compiling: Object code

ä 2nd phase: the assembler assembles theassembly code to produce object codeä object code is almost a program, it’s binary instructionsä object code is saved in a file ending in “.o”, e.g.

“prog1.o”ä the object file contains unresolved references to portions

of the program in other “.o” files

ä a library is a collection of “.o” files that havealready been compiled

3838 IntroductionIntroduction

CC Compiling: Libraries

ä Your compiler package will contain many librariescontaining compiled code toä Perform input/outputä Perform math operationsä Perform operations on textä Draw graphics, make sounds, etc.

ä Much important code is contained in the standardC library included in every program

C Programming UCSD Extension

© 1995 Philip J. Mercurio 20

3939 IntroductionIntroduction

CC Compilation Errors

ä Phases 1 and 2 convert a “.c” file into a “.o” fileä Many errors can be generated

ä You’ll need to fix all the errors before you get a “.o” fileä Most development environments contain a tool to show

exactly where each error occursä If not, the error message text will explain the errorä Error may have been caused by a mistake earlier in

the file

ä First cycle: edit-compile-edit-compile... untilsuccessful

4040 IntroductionIntroduction

CC Linking

ä Your program may consist of many “.c” files whichproduce many “.o” filesä Most of our examples will be only one “.c” file

ä 3rd phase: all of your “.o” files and the libraries youneed are processed by the linker to resolvereferences between filesä Even a program consisting of one “.c” file needs to be

linked with the standard C libraryä A reference may be unresolved simply because you

misspelled something

ä Linker usually run automatically by compiler

C Programming UCSD Extension

© 1995 Philip J. Mercurio 21

4141 IntroductionIntroduction

CC Executable

ä Second cycle: edit-compile-link-edit-compile-link...until all references resolved

ä The resulting file is an executable programä Default executable file name is either “a.out” (Unix) or

derived from “.c” file (e.g. “prog1.exe” in MS-DOS)

ä Typing the name of the executable loads theprogram into memory and starts it runningä If the program requires input, it usually comes from the

user via the keyboardä If the program generate output, it usually appears on the

terminal/screen

4242 IntroductionIntroduction

CC Debugging

ä Your program usually won’t do exactly what youintended the first time, it will contain bugs

ä Third cycle: edit-compile-link-test-edit-compile-link-test... until all of the (known) bugs are fixed

ä Most development environments will include adebugger, a program which helps you examine thestate of the program and see what your program isdoing at each step

C Programming UCSD Extension

© 1995 Philip J. Mercurio 22

4343 IntroductionIntroduction

CC Writing a Program in ANSI C

ä Let’s jump right in and look at several exampleprograms

ä We’ll brush over many issues in C programming,all of which will be discussed in depth insubsequent sessions.

4444 IntroductionIntroduction

CC Program 1-1

#include <stdio.h>

main(){

printf("Programming is fun.\n");}

Output:Output:

Programming is fun.

C Programming UCSD Extension

© 1995 Philip J. Mercurio 23

4545 IntroductionIntroduction

CC Typing in a program

ä Upper/lower case are distinctä FOO, foo, Foo, fOo are all different

ä Text can start anywhere on the lineä Exception: lines beginning with # (preprocessor lines)

must start in column 1ä White space: any number of spaces, tabs, or blank lines

can be used to separate two wordsä Use freely:

ä Tabs: show structure (like an outline)ä Blank lines: separate sections (like paragraphs)

4646 IntroductionIntroduction

CC #include <stdio.h>

ä Tells the compiler to include information about thestandard input/output (“stdio”) library

ä This is a command to the preprocessorä All of our programs will use the standard I/O

library, so this line needs to appear at thebeginning of every program

ä This is how you tie together your code with thecode in the library (added by the linker)ä In this case, this describes the printf() command

C Programming UCSD Extension

© 1995 Philip J. Mercurio 24

4747 IntroductionIntroduction

CC main()

ä Beginning of a function called “main”ä All C statements that do things are contained in

functions, also known as routines, subroutines, orprocedures

ä The body of a routine begins with { and ends with }(curly braces)

ä Every C program has one (and only one) routine namedmain()

ä The program starts with the first statement in main()ä When main() ends, the program exits

4848 IntroductionIntroduction

CC printf(“Programming is fun.\n”);

ä This is our first C statementä All C statements end with a semicolon ;ä This statement calls the routine printf()

ä printf() (which is in the stdio library) is enteredä The statements in printf() are executed, they may

call other routinesä When printf() is done, we return to main()

C Programming UCSD Extension

© 1995 Philip J. Mercurio 25

4949 IntroductionIntroduction

CC “Programming is fun.\n”

ä The contents of the ( ) are the parameters orarguments to the routine

ä In this case, we have one argument, a string ofcharactersä strings of characters are contained in double quotes “ “

ä This string contains a special code “\n” (backslashn) called the newline, it means go to a new line(like the carriage return on a typewriter)

5050 IntroductionIntroduction

CC Program 1-2

#include <stdio.h>

main(){

printf("Programming is fun.\n");printf("And programming in C is even more fun.\n");

}

Output:Output:

Programming is fun.And programming in C is even more fun.

C Programming UCSD Extension

© 1995 Philip J. Mercurio 26

5151 IntroductionIntroduction

CC Multiple statements vs. multiple lines

ä In program 1-2, we added a second call to theprintf() routine to print out a second line of text

ä Note that each statement ended with a semicolonä We could have any number of newlines between the

statements (even 0), only the semicolon punctuates theend of a statement

ä Using "\n", we can output more than one line withone printf() call

5252 IntroductionIntroduction

CC Program 1-3

#include <stdio.h>

main(){

printf("Testing...\n..1\n...2\n....3\n");}

Output:Output:

Testing...

..1

...2

....3

C Programming UCSD Extension

© 1995 Philip J. Mercurio 27

5353 IntroductionIntroduction

CC Other uses of printf()

ä printf() (print with format) is a very commonoutput routine

ä printf() can be used to print more than just textä a common use for printf() is to display the value of

variablesä a variable is a name for a numerical value

ä ... or the results of computationsä a computation is arithmetic performed on variables

(often with the result stored in a variable)

5454 IntroductionIntroduction

CC Program 1-4

#include <stdio.h>

main(){

int sum;

sum = 50 + 25;printf("The sum of 50 and 25 is %i.\n", sum);

}

Output:Output:

The sum of 50 and 25 is 75.

C Programming UCSD Extension

© 1995 Philip J. Mercurio 28

5555 IntroductionIntroduction

CC int sum;

ä This is a declaration statement, it performs noaction

ä It declares that there is a variable called sum, andthat the variable will hold an integer value (int)ä All variables must be declared before they can be

usedä int is the type of the variable, it means sum can

only hold integral values (3, -8, 0, 1003, 42, etc.)ä float is a type for floating point or real numbers

(3.14, -0.4, 98.6, etc.)

5656 IntroductionIntroduction

CC (blank line)

ä The next line is blank, it is ignored by the compilerä It could be left outä There could be 20 blank lines there

ä What it does do is make the program a little morereadableä In this case, it separates the declarations from the

executable statements which follow

C Programming UCSD Extension

© 1995 Philip J. Mercurio 29

5757 IntroductionIntroduction

CC sum = 50 + 25;

ä This is an assignment statementä The value on the right side of the equals sign is

computedä That value is stored in the variable on the left side,

replacing any previous value sum may have had

ä The computation, in this case, is addition, and theresult is the integer value 75

5858 IntroductionIntroduction

CC printf("The sum of 50 and25 is %i.\n",sum);

ä Now we see why this routine is called "print withformat"

ä This statement has two arguments, separated by acomma

ä The first argument to printf() is the formatstring, it contains the text to be printed plus specialformat codesä \n is a special code for "newline"ä %i is a special code for "print an integer"

ä The remaining arguments are the values for eachof the % codes, in order

C Programming UCSD Extension

© 1995 Philip J. Mercurio 30

5959 IntroductionIntroduction

CC Program 1-5

#include <stdio.h>

main(){

int value1, value2, sum;

value1 = 50;value2 = 25; sum = value1 + value2;printf("The sum of %i and %i is %i.\n", value1,

value2, sum);}

Output:Output:

The sum of 50 and 25 is 75.

6060 IntroductionIntroduction

CC int value1, value2, sum;

ä This declares three variables, all of which are intsä Exactly the same as

int value1;

int value2;

int sum;

ä Note how the three values are printed with oneprintf()call, by using a format with three %icodes

C Programming UCSD Extension

© 1995 Philip J. Mercurio 31

6161 IntroductionIntroduction

CC Program 1-6

/* * This program adds two integer values * and displays the results. */#include <stdio.h>

main(){

/* Declare variables */int value1, value2, sum;

/* Assign values and compute result */value1 = 50;value2 = 25; sum = value1 + value2;

/* Display result */printf("The sum of %i and %i is %i.\n", value1,

value2, sum);}

6262 IntroductionIntroduction

CC Comments

ä Anything between /* and */ is a comment, andis totally ignored by the compilerä The /* and */ codes are written without any intervening

spaces

ä Comments can fit on one line or extend to multiplelinesä The leading *s in the first comment are just decoration

ä Failing to close a comment is a common way togenerate weird syntax errors later

C Programming UCSD Extension

© 1995 Philip J. Mercurio 32

6363 IntroductionIntroduction

CC Why use comments?

ä Comments document a programä In a well-written program, the comments describe what

you're doing, at a high levelä You should be able to read only the comments and

understand the programä The code implements the comments

ä Comments capture extra informationä When you're coding, you have information in your head

as to why you're writing it that wayä The why information doesn't get expressed in the codeä Write it down while it's still fresh, it will help when

debugging

6464 IntroductionIntroduction

CC Exercises due next session

ä Read: Chapters 1, 2, and 3ä Exercises: Chapter 3

ä 1 (at least one program)ä 2, 3, 4, 5, 6

C Programming UCSD Extension

© 1995 Philip J. Mercurio 33

6565 IntroductionIntroduction

CC

C Programming

Variables & LoopsPhil Mercurio

UCSD [email protected]

6666 IntroductionIntroduction

CC Today’s Session

ä Variables, Constants, Data Types, and ArithmeticExpressions [Chapter 4]

ä Program Looping [Chapter 5]ä For, While, & Do Statementsä Program Input

C Programming UCSD Extension

© 1995 Philip J. Mercurio 34

6767 IntroductionIntroduction

CC Memory

ä All values that change are stored somewhere inmemory

ä In machine language, the programmer had to referto these values by giving their address in memory

0000 0202 0707 0909080806060505040403030101

aa bb jjiihhggffeeddcc

6868 IntroductionIntroduction

CC Variables

ä Higher-level languages allow us to assign symbolicvariable names to values stored in memory

ä Variable names attach meaning to values

the_athe_a value1value1

aa 5050value2value2 sumsum

75752525

C Programming UCSD Extension

© 1995 Philip J. Mercurio 35

6969 IntroductionIntroduction

CC C Variables

ä All variables in C must be declared before they canbe used

ä Variables can be declared to be one of any of anumber of types:ä charactersä integersä reals (floating point)ä pointers (addresses in memory)

7070 IntroductionIntroduction

CC Variable Names

ä Must begin with a letter or underscore _ä Valid characters:

ä letters (uppercase and lowercase)ä underscore _ä digits 0 1 2 3 4 5 6 7 8 9

ä Most compilers allow names to be up to 31characters longä Older K&R compilers may allow as few as 8

ä Upper/lower case are differentä Use descriptive, self-explanatory names

ä Don't be lazy! The extra typing is worth it, for readability.

C Programming UCSD Extension

© 1995 Philip J. Mercurio 36

7171 IntroductionIntroduction

CC Some valid variable names

sum

peace_flag

peaceFlag

i

J5x7

Number_of_moves

_sysflag

7272 IntroductionIntroduction

CC Some invalid variable names

sum$value

ä $ not a valid characterpeace flag

ä embedded spaces not permitted344Clinton3D

ä can't begin with a numberint

ä reserved word (see Appendix A)

C Programming UCSD Extension

© 1995 Philip J. Mercurio 37

7373 IntroductionIntroduction

CC Basic C Data Types

ä char 1 byte (8 bits), 1 characterä int an integer valueä float a floating point (real) valueä double a float with twice the precision

7474 IntroductionIntroduction

CC Constants

ä Any literal number, single character, or string is aconstant

ä A constant's value doesn't changeä Some compilers will optimize based on this

ä "Programming is fun.\n" is an example of a stringconstant

ä 128 + 7 - 17 is an example of a constantexpressionä Usually evaluated by the compiler

C Programming UCSD Extension

© 1995 Philip J. Mercurio 38

7575 IntroductionIntroduction

CC Type int

ä An int constant is a sequence of one or moredigits, optionally preceded by a minus sign:ä 42 -10 0 12000

ä No embedded spaces or commasä 12,000 is invalid

ä Leading plus sign can be used, but is usuallyavoided

ä By default, int constants are in decimal (base 10)ä printf() format code for decimal output is %d

or %iä %i is an ANSI innovation, K&R only had %d

7676 IntroductionIntroduction

CC Octal and hexadecimal ints

ä If the first digit is 0, it's interpreted as octal (base 8)ä 0177 (same as 127 in decimal)ä Only digits 0 1 2 3 4 5 6 7 validä printf() code is %o (%#o to print leading 0 too)

ä If the first digits are 0x, it's hexadecimal (base 16)ä 0x5EB (1515 decimal)ä Uses 0-9 A-F (or a-f)ä printf() code is %x (%#x to print leading 0x too)

ä Used when you need to deal with the individual bitsin a binary number (but there's no binary constantsyntax!)

C Programming UCSD Extension

© 1995 Philip J. Mercurio 39

7777 IntroductionIntroduction

CC Type float

ä Indicated by presence of a decimal pointä The digits before or after the decimal point can be

missing, but without the decimal point it's an integerä 3.14 3. -.0001 are all validä printf() code is %f

ä Can also be expressed in scientific notationä 1.7e4 means 1.7 x 104

ä Value before e is the mantissa, after is the exponent,either can have a sign

ä -2.76e-8 means -2.76 x 10-8

ä 10.86E15 and 1.3e+9 are also valid

7878 IntroductionIntroduction

CC Printing floats

ä printf() code for scientific notation is %eä %g can be used to let printf() decide whether the

number should be displayed in decimal or scientificnotationä if exponent is less than -4 or greater than 5, scientific

notation will be usedä otherwise, %f format is used

ä %g is usually the most aesthetically pleasingformat

C Programming UCSD Extension

© 1995 Philip J. Mercurio 40

7979 IntroductionIntroduction

CC Type double

ä Just like a float, but with double the precisionä IEEE-754 Example (Sun Sparc and 386-based PC)

mantissa(bits)

mantissa(digits)

minimumexponent

maximumexponent

float 24 7 -45 +38double 53 16 -324 +308

8080 IntroductionIntroduction

CC Type double (continued)

ä All floating-point constants are actually stored asdoubles

ä To force a constant to be a float, follow it with anf or Fä 12.5f

ä Use the same printf() codes for a double that youuse for a floatä %f, %e, and %g

C Programming UCSD Extension

© 1995 Philip J. Mercurio 41

8181 IntroductionIntroduction

CC Type char

ä Used to store a single character or byte (8 bits)ä A character constant is a character within single

quotesä 'a' ';' '0'

ä '0' is the ASCII character zero, not the same as thenumerical value zero

ä a character string is any number of characters in doublequotes " "

ä printf()code for a char is %c

8282 IntroductionIntroduction

CC Special char codes

ä The backslash \ can be used to enter specialcharacter codesä '\n' is the newline characterä '\07' is the character with octal value 7 (control-G)ä More on this in Session 7

C Programming UCSD Extension

© 1995 Philip J. Mercurio 42

8383 IntroductionIntroduction

CC Program 2-1

#include <stdio.h>

main(){

int integer_var = 100;float floating_var = 331.79;double double_var = 8.44e+11;char char_var = 'W';

printf("integer_var = %i\n", integer_var);printf("floating_var = %f\n", floating_var);printf("double_var = %e\n", double_var);printf("double_var = %g\n", double_var);printf("char_var = %c\n", char_var);

}

8484 IntroductionIntroduction

CC Program 2-1 Output

integer_var = 100floating_var = 331.790009double_var = 8.440000e+011double_var = 8.44e+011char_var = W

C Programming UCSD Extension

© 1995 Philip J. Mercurio 43

8585 IntroductionIntroduction

CC Notes on Program 2-1

ä Declaration statements can include an initial valuefor a variableä First line equivalent to:

int integer_var;

integer_var = 100;

ä Note that 331.79 is printed as 331.790009ä Due to the limitations in accuracy of floating point

numbersä floats are stored as binary fractions, which can't always

represent a decimal fraction exactlyä For example, 1/3 can't be expressed exactly in

decimal:0.333333333333333333333333333333...

8686 IntroductionIntroduction

CC float and double display

ä Unless told otherwise, %f displays 6 decimalplacesä We'll see how to change this later

ä %e also defaults to 6 decimal placesä %g not only picks the best-looking of %f or %e, but

also gets rid of trailing zerosä Also gets rid of decimal point if no digits follow

C Programming UCSD Extension

© 1995 Philip J. Mercurio 44

8787 IntroductionIntroduction

CC Qualifiers long, short, unsigned,and signed

ä The qualifier long before an int declarationdeclares a larger integerlong int factorial;

ä A long int is 32 bits (4 bytes), a value from -231 to231-1 (-2,147,483,648 to 2,147,483,647)

ä The qualifier short before an int declarationdeclares a shorter integershort int counter;

ä A short int is 16 bits (2 bytes), a value from -215 to 215-1 (-32,768 to 32,767)

8888 IntroductionIntroduction

CC So what's an int?

ä int was originally defined (in K&R) as the nativeword size of the computer

ä As a result, you can't be certain what int meansacross machinesä On 68000s, 8086s and 80286s (and older processors),

an int is 16 bitsä On 68020s, 80386s (and most newer processors) anint is 32 bits

ä Most people assume an int is the same as along int these days

ä To be portable, you should explicitly state long orshort if it's relevant

C Programming UCSD Extension

© 1995 Philip J. Mercurio 45

8989 IntroductionIntroduction

CC More on long

ä To declare a long constant, append a l or Lä long int points = 131071L;

ä Most compilers will automatically promote a constant tolong if it's too big, but it doesn't hurt to be explicit

ä printf() codes for long ints have an 'l' before the 'i','d', 'o', or 'x':ä %li %ld %lo %lx

9090 IntroductionIntroduction

CC long double

ä Some compilers support long double, moreprecision than a doublelong double nationalDebt =1.45678901234567890123e+10L

ä 'L' is used as the modifier in constants and printf()codes like %Lf

ä Check your compiler's documentation to see if itsupports it

C Programming UCSD Extension

© 1995 Philip J. Mercurio 46

9191 IntroductionIntroduction

CC short int

ä Regardless of what size an int is, ANSIguarantees thatä a short int is no less than 16 bitsä a long int is no less than 32 bits

ä There is no way to explicitly mark a constant asshort

ä printf() codes for short ints (very rarelyused) are %hi, %hd, %ho, and %hx

9292 IntroductionIntroduction

CC unsigned

ä By default, ints are signed (negative or positive)numbers

ä The unsigned qualifier declares that an int willhold only positive numbersä unsigned short int can hold a value from 0 to

65,535ä unsigned long int can hold a value from 0 to

4,294,967,295

ä Unsigned constants use the 'u' or 'U' modifier0x00ffU 200000UL

ä printf() code for unsigned ints is %u

C Programming UCSD Extension

© 1995 Philip J. Mercurio 47

9393 IntroductionIntroduction

CC More on unsigned and signed

ä You can omit the int (same with long andshort):unsigned counter;

long length;

ä variables can also be declared as signedä signed is used to indicate that a variable issignedä Primarily used with chars, which are usually unsigned

by defaultä All other types are signed by default

ä The use of these obscure types will be exploredmore in Session 9

9494 IntroductionIntroduction

CC Arithmetic expressions: binaryoperators

ä A binary operator operates on two values+ (plus) addition- (minus) subtraction* (asterisk) multiplication/ (slash) division

ä These are the same in almost all programminglanguages

ä Demonstrated by Program 2-2

C Programming UCSD Extension

© 1995 Philip J. Mercurio 48

9595 IntroductionIntroduction

CC Program 2-2

#include <stdio.h>

main(){

int a = 100;int b = 2;int c = 25;int d = 4;int result;

result = a - b; /* subtraction */printf("a - b = %i\n", result);

result = b * c; /* multiplication */printf("b * c = %i\n", result);

result = a / c; /* division */printf("a / c = %i\n", result);

result = a + b * c; /* precedence */printf("a + b * c = %i\n", result);

printf("a * b + c * d = %i\n", a * b + c * d);}

9696 IntroductionIntroduction

CC Program 2-2 Output

a - b = 98b * c = 50a / c = 4a + b * c = 150a * b + c * d = 300

C Programming UCSD Extension

© 1995 Philip J. Mercurio 49

9797 IntroductionIntroduction

CC Precedence and Associativity

ä Binary operators are ordered by precedence--determines which operation is performed first

ä In a + b * c, multiplication takes precedenceover addition, so b * c is performed first

ä Operators of the same precedence are performedeither left-to-right or right-to-left, depending on theirassociativityä Most common operators associate left-to-right

ä Appendix A contains a complete table (A.3) ofprecedences and associativities for all C operators

9898 IntroductionIntroduction

CC Arithmetic errors

ä It's possible to cause errors in arithmetic that can'tbe detected by the compilerä The program compiles correctly, but crashes when runä This is called a run-time error (vs. compile-time)

ä The most common run-time arithmetic error isdividing by zero

ä In Session 3 we'll learn how to make decisions sowe can check to make sure the denominator is notzero before dividing

C Programming UCSD Extension

© 1995 Philip J. Mercurio 50

9999 IntroductionIntroduction

CC Parentheses

ä What if, in a + b * c, we had intended for theaddition to be performed first?

ä We can explicitly control precedence withparentheses:(a + b) * c

ä Parentheses can be nested((a + b) - 6) * c

ä Execution starts with the innermost parentheses andworks outward

ä Use parens liberally, to aid readabilitya + (b * c)

100100 IntroductionIntroduction

CC Program 2-3

#include <stdio.h>

main(){

int a = 25;int b = 2;float c = 25.0;float d = 2.0;

printf("6 + a / 5 * b = %i\n", 6 + a / 5 * b);printf("a / b * b = %i\n", a / b * b);printf("c / d * d = %f\n", c / d * d);printf("-a = %i\n", -a);

}

C Programming UCSD Extension

© 1995 Philip J. Mercurio 51

101101 IntroductionIntroduction

CC Program 2-3 Output

6 + a / 5 * b = 16a / b * b = 24c / d * d = 25.000000-a = -25

102102 IntroductionIntroduction

CC Notes on 2-3

ä Note the use of tabs to line up the variable namesin the int and float declarations

ä Also note the use of spaces around the operatorsä Neither are needed, but help readability

ä Example of precedence:ä 6 + a / 5 * b is evaluated as 6 + ((a / 5) * b)

C Programming UCSD Extension

© 1995 Philip J. Mercurio 52

103103 IntroductionIntroduction

CC 25 / 2 * 2 = 24?

ä Why does (a / b) * b produce 24 instead of25?

ä a / b is performed using integer arithmetic, allfractional portions are lost

ä The intermediate result is 12, giving a final result of24

ä Operations on integers always produce integerresults, which are truncated, not roundedä 4 / 3 = 1.333 = 1 5 / 3 = 1.666 = 1

ä Next line uses float variables to obtain correctresult

104104 IntroductionIntroduction

CC More notes on 2-3

ä Integers are used for efficiency, when you knowyou won't have fractional results

ä If you do have fractions, you must use floats ordoublesä floats are more efficient on most machines

ä -a is an example of the unary minus operatorä unary minus and unary plus have very high precedence,

so -a * b is (-a) * b

C Programming UCSD Extension

© 1995 Philip J. Mercurio 53

105105 IntroductionIntroduction

CC Program 2-4

#include <stdio.h>

main(){

int a = 25, b = 5, c = 10, d = 7;

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

a / d * d + a % d);}

Output

a % b = 0 a % c = 5 a % d = 4 a / d * d + a % d = 25

106106 IntroductionIntroduction

CC Modolo operator

ä The modolo operator % produces the remainder ofthe first value divided by the second value

ä Note that we need to use %% to print a single %,because of the special meaning of % in a printf()format string

ä Note how the last line is continued on the next line,we can do this any time, except inside a characterstringä Note how the second part is indented as a visual cue

that it's a continuation

C Programming UCSD Extension

© 1995 Philip J. Mercurio 54

107107 IntroductionIntroduction

CC a / d * d + a % d

ä % has the same precedence as * and /ä Evaluated as ((a / d) * d) + (a % d)ä Note that it equals a

ä a / d loses the fractional remainderä (a / d) * d is the biggest multiple of d less than aä Adding the remainder (a % d) brings us back to a

108108 IntroductionIntroduction

CC Program 2-5

#include <stdio.h>

main(){

float f1 = 123.125, f2;int i1, i2 = -150;char c = 'a';

i1 = f1; /* floating to integer conversion*/printf("%f assigned to an int produces %i\n", f1, i1);

f1 = i2; /* integer to floating conversion */printf("%i assigned to a float produces %f\n",i2,f1);

f1 = i2 / 100; /* integer divided by integer */printf("%i divided by 100 produces %f\n", i2, f1);

f2 = i2 / 100.0; /* integer divided by a float */printf("%i divided by 100.0 produces %f\n", i2, f2);

}

C Programming UCSD Extension

© 1995 Philip J. Mercurio 55

109109 IntroductionIntroduction

CC Program 2-5 Output

123.125000 assigned to an int produces 123-150 assigned to a float produces -150.000000-150 divided by 100 produces -1.000000-150 divided by 100.0 produces -1.500000

110110 IntroductionIntroduction

CC Integer and Floating-PointConversions

ä float assigned to int causes truncation offractional portion

ä int assigned to float promotes int to float,no change in value

ä int divided by int loses fractional part, evenwhen assigned to float

ä if either operand is float, all ints promoted tofloat, so int divided by float gives floatresult

C Programming UCSD Extension

© 1995 Philip J. Mercurio 56

111111 IntroductionIntroduction

CC Program Looping

ä Problem: compute the nth triangular numberä This is a diagram of the 5th triangular number

ä Number of dots is 1 + 2 + 3 + 4 + 5 = 15ä In general, the nth triangular number is the sum 1 + 2 +

... + n

112112 IntroductionIntroduction

CC Program 2-6

/* Compute the 8th triangular number */#include <stdio.h>

main(){

int triangular_number;

triangular_number = 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8;

printf("The eighth triangular number is %i\n",triangular_number);

}

Output

The eighth triangular number is 36

C Programming UCSD Extension

© 1995 Philip J. Mercurio 57

113113 IntroductionIntroduction

CC Looping

ä Program 2-6 is fine as a solution to the 8thtriangular number problem, but what about the200th?

ä We need to loop, execute a set of statementsrepeatedly

ä In this case, we need to loop 200 times, adding thenext integer to a variable (triangular_number)

114114 IntroductionIntroduction

CC Program 2-7

/* Compute the 200th triangular number */#include <stdio.h>

main(){

int n, triNum;

triNum = 0;

for(n = 1; n <= 200; n = n + 1)triNum = triNum + n;

printf("The 200th triangular number is %i\n",triNum);

}

Output

The 200th triangular number is 20100

C Programming UCSD Extension

© 1995 Philip J. Mercurio 58

115115 IntroductionIntroduction

CC The for statement

ä The format of the for statement:for(init_expression; loop_condition; loop_expression)

statement

ä The three expressions inside the ( ) set up theloop environment

ä The statement is the body of the loop, and isexecuted as many times as the for parametersdefine

116116 IntroductionIntroduction

CC init_expression

ä The first of the three for expressionsä Sets up the initial values before the loop begins

ä Executed once and only once

ä In this case, we initialize n to 1ä n is called the index variable

ä Any valid C statement can be used here (alwayswith a ; at the end)ä This will almost always be an assignment statement

C Programming UCSD Extension

© 1995 Philip J. Mercurio 59

117117 IntroductionIntroduction

CC loop_condition

ä The second of the three for expressionsä Specifies the condition necessary for the loop to

continueä Evaluated at the start of each pass through the loopä If true, the loop continues, if false, we stop loopingä If false at the beginning, loop body is never executed

ä In this case, n <= 200 compares n to 200ä It's true if n is less than or equal to 200ä It's false if n is greater than 200

118118 IntroductionIntroduction

CC Relational Operators

ä C has six relational operators:

Operator Meaning Example== Equal to count == 10

!= Not equal to flag != DONE

< Less than a < b

<= Less than or equal to low <= high

> Greater than pointer > endOfList

>= Greater than or equal to j >= 0

C Programming UCSD Extension

© 1995 Philip J. Mercurio 60

119119 IntroductionIntroduction

CC Relational Operators (continued)

ä Lower precedence than all arithmetic operatorsä a < b + c evaluated as a < (b + c)ä Almost always what you intended

ä Be careful with == (equals to)ä Not the same as = (assignment)ä Some compilers will warn you

ä We could have used n < 201 rather than n <=200ä n <= 200 makes more sense since 200 is a parameter

of the problem as stated

120120 IntroductionIntroduction

CC loop_expression

ä The third for parameterä Note the lack of a final semicolon ;

ä Specifies a statement to be executed at the end ofeach pass through the loopä Almost always adding or subtracting from the index

variableä Can be any valid C statement

ä Executed after the statements in the bodyä The next thing to happen is the next evaluation of the

loop_condition

C Programming UCSD Extension

© 1995 Philip J. Mercurio 61

121121 IntroductionIntroduction

CC for statement flowchart

init_expression

body

loop_expression

next statement

loopcondition TRUEFALSE

122122 IntroductionIntroduction

CC Program 2-8

/* Compute a table of triangular numbers */#include <stdio.h>

main(){

int n, triNum;

printf("TABLE OF TRIANGULAR NUMBERS\n\n");printf(" n \tSum from 1 to n\n");printf("---\t---------------\n");

triNum = 0;

for(n = 1; n <= 10; n++) {triNum = triNum + n;printf("%i\t%i\n",n,triNum);

}}

C Programming UCSD Extension

© 1995 Philip J. Mercurio 62

123123 IntroductionIntroduction

CC Program 2-8 Output

TABLE OF TRIANGULAR NUMBERS

n Sum from 1 to n--- ---------------1 12 33 64 105 156 217 288 369 4510 55

124124 IntroductionIntroduction

CC Notes on Program 2-8

ä Computes and displays each triangular number ina loop

ä Note printf() statements at beginning todisplay header for tableä \t is the printf() code for a tab (lines things up

easier than spaces)

C Programming UCSD Extension

© 1995 Philip J. Mercurio 63

125125 IntroductionIntroduction

CC Blocks

ä We need to execute two statements in the body ofthe loopä First increment triNumä Then display the current n and triNum

ä Anywhere we can put one statement, we can putmultiple statements in a blockä A block begins with { and ends with } (curly braces)ä Blocks are usually indentedä Different programmers have different styles

126126 IntroductionIntroduction

CC Increment & Decrement Operators

ä ++ is a unary operator that adds 1ä n++ is identical to n = n + 1

ä -- is also providedä n-- is identical to n = n - 1

ä The increment and decrement operators areunique to Cä May seem less readableä Such a common operation that it's worth learning the

extra syntax

ä ++n and n++ are almost identical, we'll use thelatter

C Programming UCSD Extension

© 1995 Philip J. Mercurio 64

127127 IntroductionIntroduction

CC Field Width Specification

ä The numbers in the output of Program 2-8 don'tline up nicelyä We'd prefer them right-justified

ä printf("%2i\t%8i\n",n,triNum); producesthe output on the next slideä %2i specifies an integer right-justified in a field 2

characters wideä %8i specifies a field 8 characters wideä Leading spaces are inserted by printf() to line things

up

128128 IntroductionIntroduction

CC Program 2-8a Output

TABLE OF TRIANGULAR NUMBERS

n Sum from 1 to n--- --------------- 1 1 2 3 3 6 4 10 5 15 6 21 7 28 8 36 9 4510 55

C Programming UCSD Extension

© 1995 Philip J. Mercurio 65

129129 IntroductionIntroduction

CC Program Input

ä How can we convert Program 2-7 into one that cancompute any triangular number, not just the 200th?

ä We could change the 200 and recompile each timeä A better solution is to ask the user what number

they want to triangulateä Our first interactive program!

130130 IntroductionIntroduction

CC Program 2-9

/* Compute the nth triangular number */#include <stdio.h>

main(){

int n, number, triNum;

printf("What triangular number do you want? ");scanf("%i", &number);

triNum = 0;

for(n = 1; n <= number; n = n + 1)triNum = triNum + n;

printf("Triangular number %i is %i\n",number,triNum);

}

C Programming UCSD Extension

© 1995 Philip J. Mercurio 66

131131 IntroductionIntroduction

CC Program 2-9 Output

What triangular number do you want? 100Triangular number 100 is 5050

132132 IntroductionIntroduction

CC scanf()

ä scanf()(scan with format) is the input companionto printf()

ä scanf() uses the same format codes asprintf()ä %i means "read an integer value from the user"

ä The second argument tells scanf()where toplace the valueä The & (ampersand) character is necessary!ä Don't forget the &, or strange things will happenä & is actually an operator in C, we'll discuss it in Session

8

C Programming UCSD Extension

© 1995 Philip J. Mercurio 67

133133 IntroductionIntroduction

CC Nested for loops

ä What if we want to calculate 5 triangular numbers,each entered by the user?

ä We could run the program five timesä A better solution is to wrap our existing code inside

another for loopä This is called nesting, and we can go as deep as we

want

134134 IntroductionIntroduction

CC Program 2-10

/* Compute 5 triangular numbers */#include <stdio.h>

main(){

int n, number, triNum, counter;

for(counter = 1; counter <= 5; counter++) {printf("What triangular number do you want? ");scanf("%i", &number);

triNum = 0;

for(n = 1; n <= number; n = n + 1)triNum = triNum + n;

printf("Triangular number %i is %i\n",number,triNum);

}}

C Programming UCSD Extension

© 1995 Philip J. Mercurio 68

135135 IntroductionIntroduction

CC Program 2-10 Output

What triangular number do you want? 12Triangular number 12 is 78What triangular number do you want? 25Triangular number 25 is 325What triangular number do you want? 50Triangular number 50 is 1275What triangular number do you want? 75Triangular number 75 is 2850What triangular number do you want? 83Triangular number 83 is 3486

136136 IntroductionIntroduction

CC Notes on Program 2-10

ä The newly added text is in boldfor(counter = 1; counter <= 5;counter++)

ä A loop that executes exactly 5 timesä The body of the loop contains all the executable

statements from Program 2-9, wrapped in { }ä Note that counter isn't used anywhere inside the loop

C Programming UCSD Extension

© 1995 Philip J. Mercurio 69

137137 IntroductionIntroduction

CC for Loop Variants

ä Inside the for parens is one place you can't use {} to include multiple statementsä What if you need two index variables in one loop?

for(i = 0, j = 10; i < 10; i++, j--)

ä Commas can be used to separate multiple statements infor loops (elsewhere too)

ä This loop counts i up, from 0 to 9, while counting jdown from 10 to 1

138138 IntroductionIntroduction

CC Omitting for expressions

ä Any of the three for expressions can be omitted ifnot neededä You still need the semicolons!

for( ; j != 100; j++)

ä Assumes j has already been initializedfor(;;)

ä No init, no condition, no increment: this loop never stopsä Commonly called a forever loopä Usually include some other code to get out somewhere

in the body

C Programming UCSD Extension

© 1995 Philip J. Mercurio 70

139139 IntroductionIntroduction

CC The while statement

ä A simpler looping construct is the while statementwhile ( expression )

body (a statement or block of statements)

ä First the expression is evaluatedä If true, the statement(s) in the body are executedä If false, the body is skipped

ä This is repeated for as long as the expression istrue

ä The following two programs do the same thing

140140 IntroductionIntroduction

CC Program 2-11

/* Introducing the while statement */#include <stdio.h>

main(){

int count = 1;

while(count <= 5) {printf("%i\n", count);count++;

}}

Output1 2 3 4 5

C Programming UCSD Extension

© 1995 Philip J. Mercurio 71

141141 IntroductionIntroduction

CC Program 2-12

/* for equivalent to Program 2-11 */#include <stdio.h>

main(){

int count;

for(count = 1; count <= 5; count++)printf("%i\n", count);

}

Output1 2 3 4 5

142142 IntroductionIntroduction

CC

i = 0;while(i < 10) {

/* body */i++;

}

for(i = 0; i < 10; i++) {/* body */

}

Comparing the for and whilestatements

ä A for loop can be looked at as a shortcut for awhile loop

C Programming UCSD Extension

© 1995 Philip J. Mercurio 72

143143 IntroductionIntroduction

CCfor(i = 0; i < 10; i++) {

/* body */}

Comparing the for and whilestatements (continued)

ä Note that the for version makes it clearer what'shappening to i, the index variable

initialization

condition

increment or decrement

one or more statements i = 0;while(i < 10) {

/* body */i++;

}

144144 IntroductionIntroduction

CC Which is better?

ä If the initialization, condition, and loop expressionare all related (such as using the same variable),the for loop is more readable

ä There are many cases where the condition isseparate, in which case the while makes moresense

C Programming UCSD Extension

© 1995 Philip J. Mercurio 73

145145 IntroductionIntroduction

CC Greatest Common Divisor

ä The GCD of two numbers is the largest integerthan evenly divides both numbersä The GCD of 10 and 15 is 5

ä Here's an algorithm for the GCD of two non-negative numbers u and vä Step 1: If v equals 0, we're done and the GCD is uä Step 2: Calculate temp = u % v, u = v, v = temp and go

back to Step 1

ä This algorithm is naturally expressed as a whileloop

146146 IntroductionIntroduction

CC Program 2-13

/* Find the GCD of two nonnegative numbers */#include <stdio.h>

main(){

int u, v, temp;

printf("Please type in two nonnegative numbers: ");scanf("%i%i", &u, &v);

while(v != 0) {temp = u % v;u = v;v = temp;

}

printf("Their GCD is %i\n",u);}

OutputPlease type in two nonnegative numbers: 1026 405Their GCD is 27

C Programming UCSD Extension

© 1995 Philip J. Mercurio 74

147147 IntroductionIntroduction

CC Notes on Program 2-13

ä scanf("%i%i",&u,&v); causes two integers tobe readä They can be separated by spaces, tabs, newlines (but

not commas!)

ä The expression in the while loop is Step 1 of thealgorithm

ä The body of the while loop is Step 2

148148 IntroductionIntroduction

CC Reversing the digits of a number

ä Given a number like 1234, we want to output 4321ä Elements of the algorithm:

ä n % 10 will give us the rightmost digitä n / 10 (integer division) will chop off the rightmost

digit and throw it awayä As long as n is not zero, we're not done yet

ä Let's go from here straight to the code

C Programming UCSD Extension

© 1995 Philip J. Mercurio 75

149149 IntroductionIntroduction

CC Program 2-14

/* Reverse the digits of a number */#include <stdio.h>

main(){

int number, rightDigit;

printf("Please enter a number: ");scanf("%i", &number);

while(number != 0) {rightDigit = number % 10;printf("%i", rightDigit);number = number / 10;

}

printf("\n");}

OutputPlease enter a number: 1234554321

150150 IntroductionIntroduction

CC Notes on Program 2-14

ä In some cases, you can go from pieces of thealgorithm directly to coding, without expressing thealgorithm in some intermediate form

ä Note that we printed each digit out without anewline, then printed the newline in a separateprintf() statement outside the loop

C Programming UCSD Extension

© 1995 Philip J. Mercurio 76

151151 IntroductionIntroduction

CC The do statement

ä Both the for and while statements test thecondition before entering the body

ä What happens if we run 2-14 with an input of 0?ä The while statement fails immediately, and we never

print anything except the newlinedo

body

while ( condition );ä Executes body first, then condition

ä Continues until condition is falseä Always executes body at least once

152152 IntroductionIntroduction

CC Program 2-15

/* Reverse the digits of a number (correctly) */#include <stdio.h>

main(){

int number, rightDigit;

printf("Please enter a number: ");scanf("%i", &number);

do {rightDigit = number % 10;printf("%i", rightDigit);number = number / 10;

} while(number != 0);

printf("\n");}

OutputPlease enter a number: 00

C Programming UCSD Extension

© 1995 Philip J. Mercurio 77

153153 IntroductionIntroduction

CC The break and continue statements

break;ä Exits immediately from a loop (for, while, or do)ä Can be executed anywhere in the bodyä If nested, exits only the inner loop

continue;ä Like break, but only jumps to end of bodyä The next thing to execute will be the loop expression,

then the condition

ä We'll need the if statement to use these, we'llcover that in the next session

154154 IntroductionIntroduction

CC Exercises due next session

ä Readä Chapters 4 and 5 (optional: first 11 pages of Chapter 16)

ä Exercises: Chapter 4ä 2, 3, 4, 5, 6, 7ä Ex. 4: Use doublesä Ex. 6: Equation is 3x3 - 5x2 + 6

ä Exercises: Chapter 5ä 3, 4, 5, 8, 9, 11 (use longs)

C Programming UCSD Extension

© 1995 Philip J. Mercurio 78

155155 IntroductionIntroduction

CC

C Programming

DecisionsPhil Mercurio

UCSD [email protected]

156156 IntroductionIntroduction

CC Today’s Session

ä Making Decisions [Chapter 6]ä if, if-else, and switch statementsä Conditional Expression Operator

C Programming UCSD Extension

© 1995 Philip J. Mercurio 79

157157 IntroductionIntroduction

CC Making Decisions

ä Last session discussed one fundamental ability ofa computer: to execute a task repeatedly

ä Another ability is that of making decisions basedon data

ä We've already seen this in the conditions used inthe looping statementsä Without the ability to decide when to stop, a loop

becomes an infinite loop

158158 IntroductionIntroduction

CC The if statement

ä if ( condition )ä body statement(s)

ä Basic form of the if statementä The body statement (or block enclosed in {}) will

be executed if the condition is trueä If the condition is false, body is ignored

C Programming UCSD Extension

© 1995 Philip J. Mercurio 80

159159 IntroductionIntroduction

CC Sample if statement

ä For example, here's how we'd print a warningmessage if a counter exceeded its limit:if(count >= COUNT_LIMIT)

printf("Count limit exceeded\n");

ä If count is less than the limit, nothing is printed

160160 IntroductionIntroduction

CC Program 3-1

/* Calculate the absolute value of an integer */#include <stdio.h>

main(){

int number;

printf("Type in your number: ");scanf("%i", &number);

if(number < 0)number = -number;

printf("The absolute value is %i\n", number);}

C Programming UCSD Extension

© 1995 Philip J. Mercurio 81

161161 IntroductionIntroduction

CC Program 3-1 Output

Type in your number: -100The absolute value is 100

Type in your number: 2000The absolute value is 2000

162162 IntroductionIntroduction

CC Notes on Program 3-1

ä We ran it twice to test each possible outcome ofthe if statementä Higher confidence would require testing with even more

values

ä The user is prompted for a numberä If the number is negative, we negate it

ä Otherwise, we need to do nothing

ä Let's look at another example:ä List of grades that we need to averageä We also need count of failing grades (under 65)

C Programming UCSD Extension

© 1995 Philip J. Mercurio 82

163163 IntroductionIntroduction

CC Program 3-2

/* Average grades and count failing grades */#include <stdio.h>

main(){

int numGrades, i, grade;int gradeTotal = 0;int failureCount = 0;float average;

printf("How many grades will you be entering? ");scanf("%i", &numGrades);

164164 IntroductionIntroduction

CC Program 3-2 (continued)

for(i = 1; i <= numGrades; i++) {printf("Enter grade #%i: ", i);scanf("%i", &grade);

gradeTotal = gradeTotal + grade;

if(grade < 65)failureCount++;

}

average = (float) gradeTotal / numGrades;

printf("\nGrade average = %.2f\n", average);printf("Number of failures = %i\n", failureCount);

}

C Programming UCSD Extension

© 1995 Philip J. Mercurio 83

165165 IntroductionIntroduction

CC Program 3-2 Output

How many grades will you be entering? 7Enter grade #1: 93Enter grade #2: 63Enter grade #3: 87Enter grade #4: 65Enter grade #5: 62Enter grade #6: 88Enter grade #7: 76

Grade average = 76.29Number of failures = 2

166166 IntroductionIntroduction

CC Notes on Program 3-2

ä Our totals are initialized to 0ä average is declared as a floatä Loop on user-supplied loop limit (numGrades)

ä Ask user for gradeä Add to totalä If failing, increment failureTotal

ä Compute and display average and failure total

C Programming UCSD Extension

© 1995 Philip J. Mercurio 84

167167 IntroductionIntroduction

CC What about that (float)?

ä Although gradeTotal and numGrades are ints,the average could have a fractional portionä Can't use integer division

ä We could make gradeTotal or numGrades afloat

ä Wasteful of storageä Obscures their real use

ä (float) is a unary operator that type-castsgradeTotal to a floatä gradeTotal is not permanently changedä gradeTotal treated as float for this calculation

168168 IntroductionIntroduction

CC Type casts

ä Any type can be used in a type castä The type cast operator has a higher precedence

than all the arithmetic operators (except unary -and +)ä (int) 29.55 + (int) -21.99 is evaluated as 29+ (-21)

ä In Program 3-2, since one of the operands in thedivision is float, floating point division is performedä average = (float) gradeTotal / (float)numGrades; would have worked too

C Programming UCSD Extension

© 1995 Philip J. Mercurio 85

169169 IntroductionIntroduction

CC Precision modifier

ä We've already seen the width modifier (%2i) forprinting integers

ä The printf() codes for floats can be modified tolimit the number of digits after the decimal pointä In this case, %.2f gives us two digits for average

ä The two can be combined: %10.2f prints a float ina 10-character-wide field, with 2 decimal digits

170170 IntroductionIntroduction

CC The if-else construct

ä To determine if a number is even or odd, we cantake its remainder when divided by 2ä If the remainder is 0, the number is evenä If the remainder is not 0, the number is odd

ä Let's write a program to compute this:

C Programming UCSD Extension

© 1995 Philip J. Mercurio 86

171171 IntroductionIntroduction

CC Program 3-3

/* Determine if a number is even or odd */#include <stdio.h>

main(){

int number, remainder;

printf("Please enter a number: ");scanf("%i", &number);

remainder = number % 2;

if(remainder == 0)printf("The number is even.\n");

if(remainder != 0)printf("The number is odd.\n");

}

172172 IntroductionIntroduction

CC Program 3-3 Output

Please enter a number: 2455The number is odd.

Please enter a number: 1210The number is even.

C Programming UCSD Extension

© 1995 Philip J. Mercurio 87

173173 IntroductionIntroduction

CC Notes on Program 3-3

ä User is prompted for numberä Remainder is calculatedä The first if statement tests remainder == 0,

and prints evenä The second if statement tests remainder != 0,

and prints oddä If the first succeeds, the second must fail, and vice

versaä In English: if the remainder is 0, the number is

even, else it is odd

174174 IntroductionIntroduction

CC The if-else statement

if ( condition )statement 1

else

statement 2

ä If the condition is true, only statement 1 isexecuted

ä If the condition is false, only statement 2 isexecuted

ä There's no way for both to be executed

C Programming UCSD Extension

© 1995 Philip J. Mercurio 88

175175 IntroductionIntroduction

CC Program 3-4

/* Determine if a number is even or odd (Ver. 2) */#include <stdio.h>

main(){

int number, remainder;

printf("Please enter a number: ");scanf("%i", &number);

remainder = number % 2;

if(remainder == 0)printf("The number is even.\n");

elseprintf("The number is odd.\n");

}

176176 IntroductionIntroduction

CC Program 3-4 Output

Please enter a number: 1234The number is even.

Please enter a number: 6551The number is odd.

C Programming UCSD Extension

© 1995 Philip J. Mercurio 89

177177 IntroductionIntroduction

CC Compound Relational Tests

ä Suppose, in Program 3-2, we need a count ofgrades between 70 and 79 (Cs)

ä This is a compound relational test: one or moretests joined byä && logical ANDä || logical OR

if(grade >= 70 && grade <= 79)gradeCs++;

ä Increments gradeCs if the grade is greater than orequal to 70 and less than or equal to 79ä If less than 70 or greater than 79, condition is false

178178 IntroductionIntroduction

CC Compound Relational Tests(continued)

if(index < 0 || index > 99)printf("Error: index out of range\n");

ä Very common idiom for guaranteeing a value iswithin a rangeä If index is either too low or too high, warning is printed

ä Compound relations can get complexä && and || have lower precedence than arithmetic and

relational operatorsä Use parens and spaces for readability

C Programming UCSD Extension

© 1995 Philip J. Mercurio 90

179179 IntroductionIntroduction

CC Leap Year Program

ä A year is a leap year ifä evenly divisible by 4ä not divisible by 100, unless divisible by 400

ä Rephrase:ä divisible by 4 and not 100, orä divisible by 400

ä Code:ä (rem4 == 0 && rem100 != 0) || rem400 == 0

ä && has higher precedence than ||ä parens not needed, but big aid to readability

180180 IntroductionIntroduction

CC Program 3-5

/* Determine if a year is a leap year */#include <stdio.h>

main(){

int year, rem4, rem100, rem400;

printf("Enter the year to be tested: ");scanf("%i", &year);

rem4 = year % 4;rem100 = year % 100;rem400 = year % 400;

if((rem4 == 0 && rem100 != 0) || rem400 == 0)printf("Yup, it's a leap year.\n");

elseprintf("Nope, it's not a leap year.\n");

}

C Programming UCSD Extension

© 1995 Philip J. Mercurio 91

181181 IntroductionIntroduction

CC Program 3-5 Output

Enter the year to be tested: 1955Nope, it's not a leap year.

Enter the year to be tested: 1900Nope, it's not a leap year.

Enter the year to be tested: 2000Yup, it's a leap year.

182182 IntroductionIntroduction

CC Notes on Program 3-5

ä Note that, once we figured out the correctcondition, the rest of the program was easy

ä We didn't need to pre-compute the remaindersif( (year % 4 == 0 && year % 100 != 0)|| year % 400 == 0 )ä Remember that && and || have very low precedence,

no need to paren arithmetic or relational operatorsä Might be more readable with parens, but you'll see it

written this way most often

C Programming UCSD Extension

© 1995 Philip J. Mercurio 92

183183 IntroductionIntroduction

CC Nested if statements

ä The body statement in an if can be another if(it can be any statement)

if(gameOver == 0)if(playerToMove == YOU)

printf("Your Move\n");

ä Same asif(gameOver == 0 && playerToMove ==YOU)printf("Your Move\n");

184184 IntroductionIntroduction

CC Nested if statements (betterexample)

if(gameOver == 0)if(playerToMove == YOU)

printf("Your Move\n");

else

printf("My Move\n");

ä If gameOver is not zero, nothing printed, elsecorrect move prompt printed

ä Note how indentation helps make this readableä else belongs to last if without an else

C Programming UCSD Extension

© 1995 Philip J. Mercurio 93

185185 IntroductionIntroduction

CC Nested if statements (completeexample)

if(gameOver == 0)if(playerToMove == YOU)

printf("Your Move\n");

else

printf("My Move\n");

elseprintf("Game Over, Dude!\n");

ä Would be unreadable without indentation, butindentation is ignored by compiler

186186 IntroductionIntroduction

CC Nested if statements (badexample)

if(gameOver == 0)if(playerToMove == YOU)

printf("Your Move\n");

elseprintf("Game Over, Dude!\n");

ä In spite of indentation, the else really belongs tothe if(playerToMove == YOU) statement

C Programming UCSD Extension

© 1995 Philip J. Mercurio 94

187187 IntroductionIntroduction

CC Nested if statements (fixedexample)

if(gameOver == 0) {if(playerToMove == YOU)

printf("Your Move\n");

}

elseprintf("Game Over, Dude!\n");

ä {} are necessary here to properly expressprogram logicä Usually a good idea, even if not necessary

188188 IntroductionIntroduction

CC The else if Construct

ä Not all tests are two-wayä sign function: print -1 if a number is less than 0, 0 if

equal to 0, 1 if greater than 0ä Need to add if to our else clauseif ( condition1 )

statement 1else

if ( condition2 )statement2

else

statement3

C Programming UCSD Extension

© 1995 Philip J. Mercurio 95

189189 IntroductionIntroduction

CC The else if Construct (commonidiom)

if ( condition1 )statement 1

else if ( condition2 )statement2

else

statement3

ä All we've done is removed a newline and sometabsä Actually more readable than the "correct" indentationä Easily extended to n-way decisions

190190 IntroductionIntroduction

CC Program 3-6

/* Implement the sign function */#include <stdio.h>

main(){

int number, sign;

printf("Please type a number: ");scanf("%i", &number);

if(number < 0)sign = -1;

else if(number == 0)sign = 0;

elsesign = 1;

printf("Sign = %i\n", sign);}

C Programming UCSD Extension

© 1995 Philip J. Mercurio 96

191191 IntroductionIntroduction

CC Program 3-6 Output

Please type a number: 1121Sign = 1

Please type a number: -158Sign = -1

Please type a number: 0Sign = 0

192192 IntroductionIntroduction

CC Characterizing a character

ä The next example characterizes a character asalphabetic, digit, or special

ä We rely on the ASCII character set, which has allthe letters in orderä (c >= 'a' && c <= 'z') is true if c is a lowercase

letterä (c >= 'A' && c <= 'Z') is true if c is an

uppercase letterä (c >= '0' && c <= '9') is true if c is a digit

ä Note we're comparing against the characters '0' and'9', not the values 0 and 9

C Programming UCSD Extension

© 1995 Philip J. Mercurio 97

193193 IntroductionIntroduction

CC Program 3-7

/* Characterize a single character */#include <stdio.h>

main(){

char c;

printf("Please enter a single character: ");scanf("%c", &c);

if((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))printf("It's an alphabetic character.\n");

else if(c >= '0' && c <= '9')printf("It's a digit.\n");

elseprintf("It's a special character.\n");

}

194194 IntroductionIntroduction

CC Program 3-7 Output

Please enter a single character: &It's a special character.

Please enter a single character: 8It's a digit.

Please enter a single character: CIt's an alphabetic character.

C Programming UCSD Extension

© 1995 Philip J. Mercurio 98

195195 IntroductionIntroduction

CC Notes on Program 3-7

ä Note again that, once the conditions have beenfigured out, the code is easy to write

ä Even when reading a single character, scanf()still requires that the RETURN key be pressedä Getting a C program to respond immediately to each

character typed is actually quite tricky and is specific tothe operating system

196196 IntroductionIntroduction

CC Simple calculator

ä Let's write a program to calculate typed-inexpressions of the formä number operator number

ä We'll support + - * and /, and floating pointnumbers

C Programming UCSD Extension

© 1995 Philip J. Mercurio 99

197197 IntroductionIntroduction

CC Program 3-8

/* Simple number operator number calculator */#include <stdio.h>

main(){

float value1, value2;char operator;

printf("Type in your expression: ");scanf("%f %c %f", &value1, &operator, &value2);

if(operator == '+')printf("%.2f\n", value1 + value2);

else if(operator == '-')printf("%.2f\n", value1 - value2);

else if(operator == '*')printf("%.2f\n", value1 * value2);

else if(operator == '/')printf("%.2f\n", value1 / value2);

}

198198 IntroductionIntroduction

CC Program 3-8 Output

Type in your expression: 123.5 + 59.3182.80

Type in your expression: 198.7 / 267.64

Type in your expression: 89.3 * 2.5223.25

C Programming UCSD Extension

© 1995 Philip J. Mercurio 100

199199 IntroductionIntroduction

CC Notes on Program 3-8

ä The blank spaces in the scanf() format "%f %c%f" are importantä They tell scanf() to expect a float, any number of

spaces, a character, any number of spaces, and afloat

ä "%f%c%f" would not allow spaces, any space typedafter the first float would satisfy the %c code!

ä Leading spaces before numbers are always ignored, so"%f %c%f" would have worked too

200200 IntroductionIntroduction

CC Problems with Program 3-8

ä There are two bugs in Program 3-8!ä If the operator typed is not + - * or /, none of theifs match and nothing happensä This is called falling throughä Any else-if sequence without a final else clause is

suspect

ä It's possible to enter an expression like "16 / 0",which would cause a divide-by-zero error

C Programming UCSD Extension

© 1995 Philip J. Mercurio 101

201201 IntroductionIntroduction

CC Program 3-8a

...printf("Type in your expression: ");scanf("%f %c %f", &value1, &operator, &value2);

if(operator == '+')printf("%.2f\n", value1 + value2);

else if(operator == '-')printf("%.2f\n", value1 - value2);

else if(operator == '*')printf("%.2f\n", value1 * value2);

else if(operator == '/') {if(value2 == 0)

printf("Division by zero.\n");else

printf("%.2f\n", value1 / value2);}

elseprintf("Unknown operator.\n");

}

202202 IntroductionIntroduction

CC Program 3-8a Output

Type in your expression: 123.5 + 59.3182.80

Type in your expression: 198.7 / 0Division by zero.

Type in your expression: 125 $ 28Unknown operator.

C Programming UCSD Extension

© 1995 Philip J. Mercurio 102

203203 IntroductionIntroduction

CC The switch statement

ä Comparing the same expression against multiplevalues is so common that C has a specialconstruct for it

switch ( expression ) {case value1:

statements ...break;

case value2:statements ...break;

...default:

statements ...break;

}

204204 IntroductionIntroduction

CC The switch statement (continued)

ä The expression is compared against each of thevalues in the case statements

ä When the value matches, all of the statementsbetween the case and the break; are executedä No need to enclose them in {}

ä If the value of the expression doesn't match any ofthe case values, the default block is executed

ä Only one of the blocks is executed

C Programming UCSD Extension

© 1995 Philip J. Mercurio 103

205205 IntroductionIntroduction

CC The switch statement (continued)

ä If there's no default and nothing matches,nothing happens

ä If there's no break, execution falls through to thenext caseä You rarely want this to happen

206206 IntroductionIntroduction

CC Program 3-9

...switch(operator) {

case '+':printf("%.2f\n", value1 + value2);break;

case '-':printf("%.2f\n", value1 - value2);break;

case '*':printf("%.2f\n", value1 * value2);break;

case '/':if(value2 == 0)

printf("Division by zero.\n");else

printf("%.2f\n", value1 / value2);break;

default:printf("Unknown operator.\n");break;

}}

C Programming UCSD Extension

© 1995 Philip J. Mercurio 104

207207 IntroductionIntroduction

CC Notes on Program 3-9

ä The break in the default block is unnecessary,but it's a good habit

ä No two case values can be the sameä But you can have two cases execute the same

code:...

case '*':

case 'x':printf("%.2f\n", value1 * value2);

break;

...

208208 IntroductionIntroduction

CC Flags

ä Problem: generate a table of prime numbers(numbers divisible only by themselves and 1)ä 2 3 5 7 11 13 17 19 23 ...

ä Simplest way to generate the table, for a smallnumber of entries, is to test each number p fordivisibility by each integer from 2 to p-1

C Programming UCSD Extension

© 1995 Philip J. Mercurio 105

209209 IntroductionIntroduction

CC Program 3-10

/* Very simple prime number generator */#include <stdio.h>

main(){

int p, isPrime, d;

for(p = 2; p <= 50; p++) {isPrime = 1;

for(d = 2; d < p; d++)if(p % d == 0)

isPrime = 0;

if(isPrime != 0)printf("%i ", p);

}

printf("\n");}

210210 IntroductionIntroduction

CC Program 3-10 Output

2 3 5 7 11 13 17 19 23 29 31 37 41 43 47

C Programming UCSD Extension

© 1995 Philip J. Mercurio 106

211211 IntroductionIntroduction

CC Notes on Program 3-10

ä Outermost loop cycles p from 2 through 50ä isPrime is a flag, a variable that indicates a true or

false conditionä We'll use 1 for true and 0 for false

ä Each pass through the loop weä Start with the assumption the number is primeä Loop on all the possible divisors, setting flag to false if

we find oneä Test the final state of the flag to determine what to print

212212 IntroductionIntroduction

CC What is truth?

ä The choice of 1 for true and 0 for false is notarbitrary

ä In C, an expression is true if it evaluates tosomething nonzeroä false is 0ä true is usually 1 (-1 on some machines)

if(100)printf("This will always be printed.\n");

ä The condition is nonzero, so it will always be trueä if(isPrime)is the same as if(isPrime !=0)

ä The first form is more common when isPrime is a flag

C Programming UCSD Extension

© 1995 Philip J. Mercurio 107

213213 IntroductionIntroduction

CC More on truth

ä All conditional expressions are really evaluated toa numeric valueä printf("%i\n", 42 == 42); will print 1

ä The logical negation operator ! (read not) invertsthe logic of an expressionä if(!isPrime) to test if isPrime is falseä myMove = !myMove; flips value of a flag

ä ! is a unary operator with high precedence, parensare often necessaryä ! (x < y) tests if x is not less than y (logically

equivalent to x >= y)

214214 IntroductionIntroduction

CC The Conditional Operator

ä The most unusual operator in C is the conditionaloperatorä Not unary or binary, it's actually ternary (3 operands)

condition ? expression1 : expression2ä The entire expression gets evaluated to a value

ä If condition is true, expression1 gets evaluated and itsvalue becomes the value of the entire conditionalexpression

ä If condition is false, expression2 gets evaluated

ä Precedence is the lowest of all operatorsä For readability, we usually put the condition in parens

C Programming UCSD Extension

© 1995 Philip J. Mercurio 108

215215 IntroductionIntroduction

CC Conditional Operator Examples

s = (x < 0) ? -1 : x * x;ä Assigns -1 to s if x is negative, else assigns x2 to s

max = (a > b) ? a : b;ä Assigns the maximum of a and b to max

sign = (n < 0) ? -1 : ((n == 0)? 0 : 1)

ä Complete implementation of the sign operation fromProgram 3-6

ä Associates right-to-left, so second set of parensunnecessary, but pretty unreadable without them

ä Can be used anywhere, not just assignmentstatements

216216 IntroductionIntroduction

CC Exercises due next session

ä Read: Chapter 6ä Exercises: Chapter 6

ä 4, 5, 6, 7ä Don't use any features (like arrays) that we haven't

covered yet

C Programming UCSD Extension

© 1995 Philip J. Mercurio 109

217217 IntroductionIntroduction

CC

C Programming

ArraysPhil Mercurio

UCSD [email protected]

218218 IntroductionIntroduction

CC Today's Session

ä Arrays [Chapter 7]ä Declaring & Initializing Arraysä Multi-Dimensional Arrays

ä Common Programming Mistakes [Appendix D]

C Programming UCSD Extension

© 1995 Philip J. Mercurio 110

219219 IntroductionIntroduction

CC Arrays

ä Up to now we've dealt with variables one at a timeä Each variable had a separate name

ä C allows us to define an ordered set of data items,an array

ä Today's session will discuss how arrays arecreated and manipulated

ä Later sessions will show how they fit in with otherfeatures

220220 IntroductionIntroduction

CC Back to School

ä Let's go back to the problem of processing a set ofgradesä In Program 3-2 we processed each grade as it was

typed in

ä What if we want to do things likeä Rank them in ascending orderä Find the median or other stats

ä We need to be able to perform our calculationsafter all the grades have been enteredä We could have separate variables (grade1, grade2 ...)

but this gets unmanageable quickly

C Programming UCSD Extension

© 1995 Philip J. Mercurio 111

221221 IntroductionIntroduction

CC Arrays to the rescue

ä We can define an array of grades which is anordered set

ä The array has one name (grades)ä Each element of the array can be referenced by a

number called an index or subscriptä In math, the ith x is xi

ä In C, the ith x is x[i] (read x sub i)

ä grades[5] is element 5 in the array gradesä Array indices in C begin with 0, so the first element

is grades[0]

222222 IntroductionIntroduction

CC Array elements

ä An array element can be used anywhere a singlevariable is usedg = grades[50];

ä Copies element 50 of grades to ggrades[100] = 95;

ä Stores a 95 in the array grades at element 100

ä Array indices can be any expressioni = 7;

g = grades[i];

ä Copies element 7 from grades to g

C Programming UCSD Extension

© 1995 Philip J. Mercurio 112

223223 IntroductionIntroduction

CC Arrays and Loops

ä Arrays work well with loopsfor(i = 0; i < 100; i++)

sum = sum + grades[i];

ä Since the first element is [0], the last index is thesize of the array minus 1

ä for loops like this one are very commonä Index starts at 0ä Condition is less than (not <=) array size

224224 IntroductionIntroduction

CC Array indices can be any expression

nextValue = sortedData[(low+high) / 2];

ä First (low+high) / 2 is evaluatedä The integer result is used to index into the arrayä Any integer expression can be used as an indexä Including another array referenceg = grades[students[5]];

ä First students[5] is evaluatedä Then grades[] is indexed by that value

C Programming UCSD Extension

© 1995 Philip J. Mercurio 113

225225 IntroductionIntroduction

CC Declaring Arrays

ä Two things need to be specifiedä The data type of the elements of the arrayä The number of elements in the array

int grades[100];

ä Declares 100 integersä First is grades[0], last is grades[99]

ä The compiler does no boundary checking!ä grades[150] = 99; would pass the compiler, but

would cause an unpredictable error at run-time

226226 IntroductionIntroduction

CC More array declarations

float averages[200];ä Allocates memory for 200 floats

char name[20];

ä Allocates memory for 20 charactersä We'll see later that this is exactly what a string is

int values[10];

ä Allocates 10 integersä Let's look at a diagram of this memory

C Programming UCSD Extension

© 1995 Philip J. Mercurio 114

227227 IntroductionIntroduction

CC int values[10];

values[0]

values[3]

values[6]

values[8]

values[2]

values[9]

values[4]

values[7]

values[1]

values[5]

228228 IntroductionIntroduction

CC Storing values in an array

int values[10];

values[0] = 197;

values[2] = -100;

values[5] = 350;

values[3] = values[0] + values[5];

values[9] = values[5] / 10;

values[2]--;

C Programming UCSD Extension

© 1995 Philip J. Mercurio 115

229229 IntroductionIntroduction

CC Updated values[]

values[0]

values[3]

values[6]

values[8]

values[2]

values[9]

values[4]

values[7]

values[1]

values[5]

197

-101

350

35

547

230230 IntroductionIntroduction

CC Program 4-1

#include <stdio.h>

main(){

int values[10];int index;

values[0] = 197;values[2] = -100;values[5] = 350;values[3] = values[0] + values[5];values[9] = values[5] / 10;values[2]--;

for(index = 0; index < 10; index++)printf("values[%i] = %i\n", index,

values[index]);}

C Programming UCSD Extension

© 1995 Philip J. Mercurio 116

231231 IntroductionIntroduction

CC Program 4-1 Output

values[0] = 197values[1] = 0values[2] = -101values[3] = 547values[4] = 0values[5] = 350values[6] = 3values[7] = -268439300values[8] = 4values[9] = 35

232232 IntroductionIntroduction

CC Notes on Program 4-1

ä Note that the values for the array elements 1, 4, 6,7, and 8 are weirdä Since we never assigned anything to these elements,

they contain whatever happened to be lying around inmemory

ä Never assume values or array elements are initialized to0

C Programming UCSD Extension

© 1995 Philip J. Mercurio 117

233233 IntroductionIntroduction

CC TV Ratings Problem

ä 5,000 people were asked to rate a TV show from 1to 10

ä The results are 5,000 numbers that we need toanalyzeä We need to know how many rated it a 1, how many 2,

etc.

ä We could set up 10 different counters rating1,rating2, ...

ä An array called ratingCounters[] is moreelegant

ä We'll only process 20 responses instead of 5,000

234234 IntroductionIntroduction

CC Program 4-2

/* Ratings tally program */#include <stdio.h>

main(){

int ratingCounters[11], i, response;

for(i = 1; i <= 10; i++)ratingCounters[i] = 0;

printf("Enter your responses\n");

for(i = 1; i <= 20; i++) {scanf("%i", &response);

if(response < 1 || response > 10)printf("Bad response: %i\n", response);

elseratingCounters[response]++;

}

C Programming UCSD Extension

© 1995 Philip J. Mercurio 118

235235 IntroductionIntroduction

CC Program 4-2 (continued)

printf("\n\nRating\tNumber of Responses\n");printf("------\t-------------------\n");

for(i = 1; i <= 10; i++)printf("%4i\t%9i\n", i, ratingCounters[i]);

}

236236 IntroductionIntroduction

CC Program 4-2 Input

Enter your responses6583965715Bad response: 15551741056896

C Programming UCSD Extension

© 1995 Philip J. Mercurio 119

237237 IntroductionIntroduction

CC Program 4-2 Output

Rating Number of Responses------ ------------------- 1 1 2 0 3 1 4 1 5 5 6 4 7 2 8 2 9 2 10 1

238238 IntroductionIntroduction

CC Notes on Program 4-2

ä Why int ratingCounters[11] when there areonly 10 ratings?

ä Allows us to use ratings number (1..10) as indexä We just ignore ratingCounters[0]

ä We could have allocated only 10 elements andsubtracted 1 from the rating to get the indexä Sacrificing 1 integer's worth of memory for readability is

a good trade

C Programming UCSD Extension

© 1995 Philip J. Mercurio 120

239239 IntroductionIntroduction

CC Fibonacci Numbers

ä The first two Fibonacci numbers, F0 and F1, aredefined to be 0 and 1, respectively

ä Each successive Fi is defined as Fi-2 + Fi-1

ä Fibonacci numbers have lots of applications inmath, computer science, even biology

240240 IntroductionIntroduction

CC Program 4-3

/* Generate the first 15 Fibonacci numbers */#include <stdio.h>

main(){

int Fibonacci[15], i;

Fibonacci[0] = 0; /* by definition */Fibonacci[1] = 1; /* ditto */

for(i = 2; i < 15; i++)Fibonacci[i] = Fibonacci[i-2] + Fibonacci[i-1];

for(i = 0; i < 15; i++)printf("%i\n", Fibonacci[i]);

}

C Programming UCSD Extension

© 1995 Philip J. Mercurio 121

241241 IntroductionIntroduction

CC Program 4-3 Output

01123581321345589144233377

242242 IntroductionIntroduction

CC Notes on Program 4-3

ä Since the values we're computing depend onprevious values, an array is the logical choice

ä We could have gotten by with just two variables(one for Fi-2 and one for Fi-1) and a lot of copyingback and forthä This might be a better solution if we had to generate a

really large number of Fibonacci numbers

C Programming UCSD Extension

© 1995 Philip J. Mercurio 122

243243 IntroductionIntroduction

CC Prime time again

ä Let's make an even more efficient prime numbergenerator than the one in Program 3-10 (and theenhancements from exercise 7)

ä First, we only have to check other primes asdivisorsä Good reason to store our primes in an array as we

generate them

ä Second, we only have to check up to the squareroot of the number being testedä p / primes[i] >= primes[i] is used as loop

condition, will fail when primes[i] exceeds square root

244244 IntroductionIntroduction

CC Program 4-4

/* Modified prime number generator */#include <stdio.h>

main(){

int p, isPrime, i, primes[50], primeIndex = 2;

primes[0] = 2;primes[1] = 3;

for(p = 5; p <= 50; p = p + 2) {isPrime = 1;

for(i = 1; isPrime && p/primes[i] >= primes[i]; i++)

if(p % primes[i] == 0)isPrime = 0;

if(isPrime) {primes[primeIndex] = p;primeIndex++;

}}

C Programming UCSD Extension

© 1995 Philip J. Mercurio 123

245245 IntroductionIntroduction

CC Program 4-4 (continued)

for(i = 0; i < primeIndex; i++)printf("%i ", primes[i]);

printf("\n");}

246246 IntroductionIntroduction

CC Program 4-4 Output

2 3 5 7 11 13 17 19 23 29 31 37 41 43 47

C Programming UCSD Extension

© 1995 Philip J. Mercurio 124

247247 IntroductionIntroduction

CC Notes on Program 4-4

ä We store 2 and 3 explicitly, start our loop with 5,and increment by 2 (odd numbers only)ä A little bit of optimizing using existing knowledge

ä The primes array is allocated for 50 (more thanenough room) and primeIndex is set to 2 (firstavailable slot)

ä In the inner loop, we start with index 1, sincethere's no need to check for divisibility byprimes[0] (2)ä We exit the loop as soon as a divisor is found (isPrime== 0)--no need to check any higher values

248248 IntroductionIntroduction

CC Notes on Program 4-4 (continued)

ä At the bottom of the outer loop, we add p to theprimes array if it's still prime

C Programming UCSD Extension

© 1995 Philip J. Mercurio 125

249249 IntroductionIntroduction

CC Initializing Array Elements

ä Arrays can be initialized as they are declared bygiving a list of items in {} separated by commas

int counters[5] = {0, 0, 0, 0, 0};

ä initializes 5 counters to 0int integers[5] = {0, 1, 2, 3, 4};

ä integers[0] = 0, integers[1] = 1, etc.

char letters[5] = {'a', 'b', 'c', 'd','e'};

ä Example using charactersfloat data[500] = {1.0, 30.0, 500.5};

ä Sets first 3 values, rest initialized to 0.0

250250 IntroductionIntroduction

CC Program 4-5

/* Examples of array initialization */#include <stdio.h>

main(){

int squares[10] = {0, 1, 4, 9, 16};int i;

for(i = 5; i < 10; i++)squares[i] = i * i;

for(i = 0; i < 10; i++)printf("squares[%i] = %i\n", i, squares[i]);

}

C Programming UCSD Extension

© 1995 Philip J. Mercurio 126

251251 IntroductionIntroduction

CC Program 4-5 Output

squares[0] = 0squares[1] = 1squares[2] = 4squares[3] = 9squares[4] = 16squares[5] = 25squares[6] = 36squares[7] = 49squares[8] = 64squares[9] = 81

252252 IntroductionIntroduction

CC Notes on Program 4-5

ä The first five squares are initialized in thedeclaration

ä The last five are initialized in a for loop

C Programming UCSD Extension

© 1995 Philip J. Mercurio 127

253253 IntroductionIntroduction

CC Program 4-6

/* Character array example */#include <stdio.h>

main(){

char word[] = {'H', 'e', 'l', 'l', 'o', '!'};int i;

for(i = 0; i < 6; i++)printf("%c", word[i]);

printf("\n");}

Hello!

OutputOutput

254254 IntroductionIntroduction

CC Notes on Program 4-6

ä Note that we didn't set an array size for wordä The compiler counted the number of items in the

initialization list and set the array size

ä This only works if we initialize every item, if weneed an array bigger than the initialization list wehave to be explicit

C Programming UCSD Extension

© 1995 Philip J. Mercurio 128

255255 IntroductionIntroduction

CC Base Conversion

ä Problem: Convert a base-10 number to any basebetween 2 and 16

ä Algorithm: Similar to 2-14ä number % base gives rightmost digitä number / base chops off rightmost digit

ä Concerns:ä digits will be generated in wrong orderä need to display digit values for 10..15

256256 IntroductionIntroduction

CC Program 4-7

/* Convert a positive integer to another base */#include <stdio.h>

main(){

char baseDigits[16] ={'0', '1', '2', '3', '4', '5', '6', '7','8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};

int convertedNumber[64];long int numberToConvert;int nextDigit, base, index = 0;

/* Get the number and the base */printf("Number to be converted? ");scanf("%li", &numberToConvert);printf("Base? ");scanf("%i", &base);

C Programming UCSD Extension

© 1995 Philip J. Mercurio 129

257257 IntroductionIntroduction

CC Program 4-7 (continued)

/* Do the conversion */do {

convertedNumber[index] = numberToConvert %base;

index++;numberToConvert = numberToConvert / base;

} while(numberToConvert != 0);

/* Display results, reversing order */printf("Converted number = ");

for(index--; index >= 0; index--) {nextDigit = convertedNumber[index];printf("%c", baseDigits[nextDigit]);

}

printf("\n");}

258258 IntroductionIntroduction

CC Program 4-7 Output

Number to be converted? 10Base? 2Converted number = 1010

Number to be converted? 128362Base? 16Converted number = 1F56A

C Programming UCSD Extension

© 1995 Philip J. Mercurio 130

259259 IntroductionIntroduction

CC Notes on Program 4-7

ä baseDigits is indexed by a digit value 0..15 andcontains the character to display for that valueä This is called a lookup table

ä convertedNumber is used to store the digits inthe order they're generated

ä After the do loop, index will be the number ofdigits in convertedNumberä We need to decrement it when starting the for loopä Remember that arrays indices start with 0!

260260 IntroductionIntroduction

CC Notes on Program 4-7 (continued)

ä convertedNumber is indexed from the end backto 0

ä Each digit is looked up in baseDigits to get thecharacter

C Programming UCSD Extension

© 1995 Philip J. Mercurio 131

261261 IntroductionIntroduction

CC Problems in Program 4-7

ä If 0 entered as base, divide by zero error occursä If 1 entered as base, numberToConvert never

becomes 0 and program loops foreverä If base > 16 given, we exceed boundaries ofbaseDigits array

ä We'll fix these next session

262262 IntroductionIntroduction

CC Multidimensional Arrays

ä All of our arrays up to now have been linear orone-dimensional arrays

ä C can support arrays of any dimensionä Consider this 4x5 two-dimensional matrix:

10 5 -3 17 82

9 0 0 8 -7

32 20 1 0 14

0 0 8 7 6

C Programming UCSD Extension

© 1995 Philip J. Mercurio 132

263263 IntroductionIntroduction

CC Rows & Columns

ä The preceding matrix has 4 rows and 5 columnsä In math, we might call the matrix M and refer to

elements in the matrix using two indicesä i the row index, ranging from 1 to 4ä j the column index, ranging from 1 to 5

ä An element would be referred to as Mi,jä M3,2 would be the element 20ä M4,5 would be the element 6

ä We do the same in C, but starting at 0

264264 IntroductionIntroduction

CC Matrix M in C

Row(i) Column(j)

0 1 2 3 4

0 10 5 -3 17 821 9 0 0 8 -72 32 20 1 0 143 0 0 8 7 6

C Programming UCSD Extension

© 1995 Philip J. Mercurio 133

265265 IntroductionIntroduction

CC C matrix notation

ä Mi,j in C is written M[i][j]ä The first index is the row, the second is the columnä sum = M[0][2] + M[2][4]; would add the -3

to the 14 to produce 11ä int M[4][5]; declares a 2-D array of 4 rows

and 5 columns

266266 IntroductionIntroduction

CC Initializing 2-D arrays

ä Each row is listed in {}, the rows are then listed in{}

int M[4][5] = {{ 10, 5, -3, 17, 82 },

{ 9, 0, 0, 8, -7 },

{ 32, 20, 1, 0, 14 },

{ 0, 0, 8, 7, 6 }

};

ä Note that there's no comma after the last row!

C Programming UCSD Extension

© 1995 Philip J. Mercurio 134

267267 IntroductionIntroduction

CC More initializing 2-D arrays

ä The inner braces are not really necessaryint M[4][5] = {10, 5, -3, 17, 82, 9, 0,0, 8, -7, 32, 20, 1, 0, 14, 0, 0, 8,7, 6};

ä This is highly unreadable

268268 IntroductionIntroduction

CC Partial initialization

int M[4][5] = {{ 10, 5, -3 },

{ 9, 0, 0 },

{ 32, 20, 1 },

{ 0, 0, 8 }

}

ä Fills in first 3 values of each row, rest are 0ä Inner braces are required

C Programming UCSD Extension

© 1995 Philip J. Mercurio 135

269269 IntroductionIntroduction

CC Common Programming Mistakes

ä Let's look at some common programmingmistakes, using the portion of C we've studied sofar

ä This is not an exhaustive list, but includes many ofthe most common mistakes

ä In general, when the compiler reports an error themistake is at that line or somewhere aboveä Some mistakes don't trigger a compiler for many. many

lines

ä Many mistakes will not generate error messages atall, such as:

270270 IntroductionIntroduction

CC Misplacing a semicolon

if(j == 100) ;j = 0;

ä A semicolon by itself is a valid C statement (it doesnothing)ä In this case, it's the body of the ifä j = 0; will always be executed

ä This is syntactically correct, so no error message!

C Programming UCSD Extension

© 1995 Philip J. Mercurio 136

271271 IntroductionIntroduction

CC Confusing = with ==

if(a = 2)printf("Your turn\n");

ä The assignment statement is a valid expressionä It's value, in this case, is 2ä 2 is nonzero, so it's true

ä This causes two problemsä It changes a to 2 (probably didn't mean to change it)ä It always prints "Your turn"

272272 IntroductionIntroduction

CC Using the wrong bounds for an array

int a[100], i, sum = 0;

for(i = 1; i <= 100; i++)sum += a[i];

ä Valid indices for a[] are 0..99ä References a[100], which is invalidä Doesn't include a[0] in sum

C Programming UCSD Extension

© 1995 Philip J. Mercurio 137

273273 IntroductionIntroduction

CC Omitting the & in scanf() calls

int number;

scanf("%i", number);

ä Except for pointer arguments (which we haven'tcovered yet), all arguments in a scanf() callmust be preceded by an &

ä However, this is still syntactically correct.

274274 IntroductionIntroduction

CC Omitting the break at the end of acase

ä In a switch statement, any case block without abreak falls through to the next case block

ä Sometimes you mean to do this--I insert acomment/* falls thru ... */

where the break would have been so it's obvious thatit's intentional

C Programming UCSD Extension

© 1995 Philip J. Mercurio 138

275275 IntroductionIntroduction

CC Forgetting to close a comment

/* comment

code block 1/* comment */

code block 2ä This is syntactically correct, all the code in code

block 1 gets included in the comment (and ignored)ä This might compile just fine, orä It might generate an error around code block 2

(while the error is really up by code block 1)

276276 IntroductionIntroduction

CC Exercises due next session

ä Read: Chapter 7ä Exercises: Chapter 6

ä 6 (Use array(s) this time)

ä Exercises: Chapter 7ä 3, 4, 5 and 6

ä Ex. 6: Bad typo, just initialize array P to all 0s. n is150.

C Programming UCSD Extension

© 1995 Philip J. Mercurio 139

277277 IntroductionIntroduction

CC

C Programming

FunctionsPhil Mercurio

UCSD [email protected]

278278 IntroductionIntroduction

CC Today's Session

ä Functions and Variables [Chapter 8]ä Arguments & Local Variables, Returning Function

Resultsä Functions Calling Functions, Functions & Arraysä Global, Automatic, & Static Variablesä Recursive Functions

C Programming UCSD Extension

© 1995 Philip J. Mercurio 140

279279 IntroductionIntroduction

CC Functions

ä Functions (AKA routines, subroutines, procedures)are what make C a structured language

ä A function is a bunch of code with a nameä We can use the name to call that same code many

timesä Naming pieces of our programs means we can

build programs up out of smaller partsä We've already used functions in every program

we've writtenä printf() and scanf() are functionsä main() is a function

280280 IntroductionIntroduction

CC Back to the beginning

ä Our first program consisted of one function,main()main()

{

printf("Programming is fun.\n");

}

ä Here's a function that does the same thingvoid printMessage(void)

{

printf("Programming is fun.\n");

}

C Programming UCSD Extension

© 1995 Philip J. Mercurio 141

281281 IntroductionIntroduction

CC Beginning a function

ä The first line of a function tells the compiler 4things about the function:ä Its nameä The type of value it returnsä The arguments it takesä Who can call it (discussed in Session 10)

ä This function is named "printMessage", it returnsno value (the first void) and takes no arguments(the second void)ä Naming a function is just like naming a variable--use

something meaningful

282282 IntroductionIntroduction

CC A function is not a program

ä A C program must always have exactly onefunction called main()

ä Execution of the program begins with the first lineof main() and ends when main() ends

ä We can turn printMessage() into a program byadding a main() which calls it

C Programming UCSD Extension

© 1995 Philip J. Mercurio 142

283283 IntroductionIntroduction

CC Program 5-1

#include <stdio.h>

void printMessage(void){

printf("Programming is fun.\n");}

main(){

printMessage();}

Programming is fun.

OutputOutput

284284 IntroductionIntroduction

CC Notes on Program 5-1

ä There are two functions, main() andprintMessage()

ä The () after printMessage indicates that we'recalling a function with no argumentsä Consistent with how printMessage() is defined above

ä When printMessage(); is encountered,execution proceeds with the first line ofprintMessage()

ä printMessage() then calls printf() to print amessage

C Programming UCSD Extension

© 1995 Philip J. Mercurio 143

285285 IntroductionIntroduction

CC More Notes on Program 5-1

ä At the end (the closing }) it returns to main()ä Execution continues in main(), with the next

statement after the function call

286286 IntroductionIntroduction

CC Program 5-2

#include <stdio.h>

void printMessage(void){

printf("Programming is fun.\n");}

main(){

printMessage();printMessage();

}

OutputOutput

Programming is fun.Programming is fun.

C Programming UCSD Extension

© 1995 Philip J. Mercurio 144

287287 IntroductionIntroduction

CC Notes on Program 5-2

ä Execution begins with main()ä Proceeds to printMessage()ä Returns to main()ä Proceeds to printMessage() againä Returns to main()ä Exits

288288 IntroductionIntroduction

CC Program 5-3

#include <stdio.h>

void printMessage(void){

printf("Programming is fun.\n");}

main(){

int i;

for(i=1; i <= 5; i++)printMessage();

}

OutputOutputProgramming is fun.Programming is fun.Programming is fun.Programming is fun.Programming is fun.

C Programming UCSD Extension

© 1995 Philip J. Mercurio 145

289289 IntroductionIntroduction

CC Arguments and Local Variables

ä printf() is an example of a function that takesargumentsä It performs differently based on the arguments we give it

ä Let's take the code from Session 2 and make afunction which calculates a triangular numberä We'll give the function one argument, what number to

calculateä The function will display the result for us

290290 IntroductionIntroduction

CC Program 5-4

/* Function to calculate the nth triangular number */#include <stdio.h>

void calculateTriangularNumber(int n){

int i, triNum = 0;

for(i = 1; i <= n; i++)triNum = triNum + i;

printf("Triangular number %i is %i\n", n, triNum);}

main(){

calculateTriangularNumber(10);calculateTriangularNumber(20);calculateTriangularNumber(50);

}

C Programming UCSD Extension

© 1995 Philip J. Mercurio 146

291291 IntroductionIntroduction

CC Program 5-4 Output

Triangular number 10 is 55Triangular number 20 is 210Triangular number 50 is 1275

292292 IntroductionIntroduction

CC Notes on Program 5-4

void calculateTriangularNumber(int n)

ä This is a function prototype declarationä It states the name of the functionä The function returns nothing (void)ä And takes a single argument n which is an int

ä Argument names and function names follow thesame rules as those for variables (Session 2)

C Programming UCSD Extension

© 1995 Philip J. Mercurio 147

293293 IntroductionIntroduction

CC Formal Parameter Names

ä An argument name is its formal parameter nameä Once defined, the formal parameter name can be

used anywhere inside the functionä Outside the function, that name has no meaning

ä Or it can have a different meaning in a different function

294294 IntroductionIntroduction

CC Automatic Local Variables

ä The first line ofcalculateTriangularNumber() defines twovariables

ä These are automatic local variablesä They're automatically created each time the function is

calledä They're local to the function

ä Initialized local variables are initialized again eachtime the function is called

ä auto int i, triNum = 0; would be theformal declaration

C Programming UCSD Extension

© 1995 Philip J. Mercurio 148

295295 IntroductionIntroduction

CC Back to Program 5-4

ä Inside main(),calculateTriangularNumber() is called with10 as the argument

ä 10 becomes the value of n during this invocation ofcalculateTriangularNumber()

ä After the 10th triangular number is calculated,main() calls it again with 20 as argument

ä Now n is set to 20, triNum is reset to 0, and thecalculation is performed again

ä Finally, one last invocation with 50 as the argument

296296 IntroductionIntroduction

CC Program 5-5

/* Function to calculate GCD */#include <stdio.h>

void gcd(int u, int v){

int temp;

printf("The GCD of %i and %i is ", u, v);

while(v != 0) {temp = u % v;u = v;v = temp;

}

printf("%i\n", u);}

main(){

gcd(150, 35);gcd(1026, 405);gcd(83, 240);

}

C Programming UCSD Extension

© 1995 Philip J. Mercurio 149

297297 IntroductionIntroduction

CC Program 5-5 Output

The GCD of 150 and 35 is 5The GCD of 1026 and 405 is 27The GCD of 83 and 240 is 1

298298 IntroductionIntroduction

CC Notes on Program 5-5

ä gcd() takes two integer arguments and computesthe GCD

ä Note that we have to print the first part out beforewe modified u and v.ä We could also have saved u and v in other variables

and printed everything out at the end

C Programming UCSD Extension

© 1995 Philip J. Mercurio 150

299299 IntroductionIntroduction

CC Returning Function Results

ä Each of the calculation functions we've looked atprinted their resultsä What if we don't like how that function prints?ä What if we didn't want anything printed at all?

ä A more useful function would be one thatperformed the calculations and gave back theresultsä The caller decides what to do with the resultä This is the essence of reusability--designing functions so

they can be used by a number of programs

300300 IntroductionIntroduction

CC return();

ä Inside a function return(expression); is used toreturn a value to the calling functionä Execution of the function stops immediatelyä There can be more than one return in a function

C Programming UCSD Extension

© 1995 Philip J. Mercurio 151

301301 IntroductionIntroduction

CC Returning Function Results(continued)

ä The function also needs to be declared asreturning the correct typeä Up to now, all our functions have returned void

(nothing)float kmh_to_mph(float km_speed)

ä Declares a function which takes one float as anargument and returns a float

int gcd(int u, int v)ä Takes two int arguments and returns an int

302302 IntroductionIntroduction

CC Program 5-6

/* Function to calculate GCD */#include <stdio.h>

int gcd(int u, int v){

int temp;

while(v != 0) {temp = u % v;u = v;v = temp;

}

return(u);}

C Programming UCSD Extension

© 1995 Philip J. Mercurio 152

303303 IntroductionIntroduction

CC Program 5-6 (continued)

main(){

int result;

result = gcd(150, 35);printf("The GCD of 150 and 35 is %i\n", result);

result = gcd(1026, 405);printf("The GCD of 1026 and 405 is %i\n", result);

printf("The GCD of 83 and 240 is %i\n", gcd(83, 240));}

304304 IntroductionIntroduction

CC Program 5-6 Output

The GCD of 150 and 35 is 5The GCD of 1026 and 405 is 27The GCD of 83 and 240 is 1

C Programming UCSD Extension

© 1995 Philip J. Mercurio 153

305305 IntroductionIntroduction

CC Notes on Program 5-6

ä Once the calculation is complete, return(u);does two thingsä It exits the function gcd()ä It returns the value of u

ä The function call can be treated like any otherexpressionresult = gcd(150, 35);

printf("...", gcd(83, 240));

x = gcd(150, 35) * gcd(150, 45);

306306 IntroductionIntroduction

CC Return Values

ä Only one value can be returnedä Other languages distinguish between procedures

(no return value) and functions (returns something)ä In C, the syntax is the sameä A procedure is just a function that returns void

ä If not specified, a C function is assumed to returnint

ä You should always explicitly specify the return valueä You'll probably see lots of old code where this is violated

(void wasn't a part of K&R)

C Programming UCSD Extension

© 1995 Philip J. Mercurio 154

307307 IntroductionIntroduction

CC The Void

ä Functions declared as returning void tell thecompiler that no value will be returnedä You can't attempt to return a value with areturn(value); statement

ä You can't attempt to use the function call as anexpression

void nothing() { ... }

x = nothing();

ä Will cause the compiler to generate an error message

308308 IntroductionIntroduction

CC Program 5-7

/* Absolute value function */#include <stdio.h>

float absoluteValue(float x){

if(x < 0)x = -x;

return(x);}

main(){

float f1 = -15.5, f2 = 20.0, f3 = -5.0;int i1 = -716;float result;

C Programming UCSD Extension

© 1995 Philip J. Mercurio 155

309309 IntroductionIntroduction

CC Program 5-7 (continued)

result = absoluteValue(f1);printf("result = %.2f\n", result);printf("f1 = %.2f\n", f1);

result = absoluteValue(f2) + absoluteValue(f3);printf("result = %.2f\n", result);

result = absoluteValue( (float) i1 );printf("result = %.2f\n", result);

result = absoluteValue(i1);printf("result = %.2f\n", result);

printf("%.2f\n", absoluteValue(-6.0) / 4);}

310310 IntroductionIntroduction

CC Program 5-7 Output

result = 15.50f1 = -15.50result = 25.00result = 716.00result = 716.001.50

C Programming UCSD Extension

© 1995 Philip J. Mercurio 156

311311 IntroductionIntroduction

CC Notes on Program 5-7

ä In the first invocation of absoluteValue(), f1 ispassed as an argumentä In the function, that value is assigned to xä x is then negated

ä Note that f1 itself was not changedä x is a copy of f1, not another name for it

ä A function can never change any of itsarguments, only copies of them

ä The next two calls demonstrate that the result of afunction call can be used as an expression

312312 IntroductionIntroduction

CC Automatic type conversion

ä In the fourth call to absoluteValue() we havean integer we need to supply as an argumentä We explicitly type-cast the int to a float

ä In the fifth call, we forget the type-cast and end uppassing an integer to a function expecting a floatä Since the compiler knows the argument should be afloat, it makes the conversion for us

ä It's always better to be explicit

C Programming UCSD Extension

© 1995 Philip J. Mercurio 157

313313 IntroductionIntroduction

CC Functions really are like any othervalue

ä The final call demonstrates that the rules forarithmetic expressions apply to function returnvaluesä Since absoluteValue() returns a float,absoluteValue(-6.0) / 4 is performed usingfloating point arithmetic

314314 IntroductionIntroduction

CC Functions Calling Functions Calling...

ä Let's use our absoluteValue() function insideanother function

ä Problem: compute square roots using the Newton-Raphson methodä Start with a guess at the square root of xä Divide x by the guess and add guessä Divide this by 2 and make it the new guessä Keep going until we get within a limit (epsilon) of the

correct answerä Test: if |guess2 - x| < epsilon, we're done

C Programming UCSD Extension

© 1995 Philip J. Mercurio 158

315315 IntroductionIntroduction

CC Program 5-8

/* Newton-Raphson square root approximation */

#include <stdio.h>

/* * Return the absolute value of x */float absVal(float x){

if(x < 0)x = -x;

return(x);}

316316 IntroductionIntroduction

CC Program 5-8 (continued)

/* * Return the square root of x using Newton-Raphson. * * The result will only be correct within epsilon, * and the input should be positive (this is not checked). */float squareRoot(float x){

float epsilon = 0.00001;float guess = 1.0;

while(absVal(guess*guess - x) >= epsilon)guess = (x/guess + guess) / 2.0;

return(guess);}

C Programming UCSD Extension

© 1995 Philip J. Mercurio 159

317317 IntroductionIntroduction

CC Program 5-8 (continued)

main(){

printf("squareRoot(2.0) = %f\n", squareRoot(2.0));printf("squareRoot(144.0) = %f\n", squareRoot(144.0));printf("squareRoot(17.5) = %f\n", squareRoot(17.5));

}

318318 IntroductionIntroduction

CC Program 5-8 Output

squareRoot(2.0) = 1.414216squareRoot(144.0) = 12.000000squareRoot(17.5) = 4.183300

C Programming UCSD Extension

© 1995 Philip J. Mercurio 160

319319 IntroductionIntroduction

CC Note the new comment structure

ä Every function should have a comment describingitsä inputsä outputsä algorithmä limitations, if any

ä Ideally, someone should be able to read just thecomment and fully understand what the functiondoesä They should only need to read the code if they need to

know the details

320320 IntroductionIntroduction

CC Notes on Program 5-8

ä First we define absVal()ä Then we define squareRoot()

ä Two local variables are declared and initializedä The while loop implements the test

äguess*guess - x is computedä This is passed as the argument to absVal()äabsVal() returns the absolute valueä which is then compared against epsilon

C Programming UCSD Extension

© 1995 Philip J. Mercurio 161

321321 IntroductionIntroduction

CC Scope

ä Note that both absVal() and squareRoot()have arguments called xä The compiler doesn't get confused

ä A function's arguments and local variables arenames known only to that functionä It is said that the scope of the names is the function that

defines them

ä Outside the scope of the function, that name canbe reused by any other functionä For example, main() and absVal() could both

declare local variables called guess that would bedistinct from the one in squareRoot()

322322 IntroductionIntroduction

CC Declaring Return Types andArgument Types

ä When the compiler encounters a call to a function,it assumes the function returns int unlessä The function has been defined in the program earlierä The value returned by the function has been declared

earlier

ä In Program 5-8, absVal() is defined before it'sused in squareRoot()ä If it came after, its use in squareRoot() would have

caused the assumption that it returns intä Later, when the definition of absVal() was

encountered, the compiler would notice that it returnedfloat and complain about the inconsistency

C Programming UCSD Extension

© 1995 Philip J. Mercurio 162

323323 IntroductionIntroduction

CC Declaring Return Types andArgument Types (continued)

ä If we want to define absVal() later (or maybe inanother file--Session 10) we need to declare itbefore its used

ä A declaration is the header of a function withoutthe body

ä It can be declaredä inside squareRoot(), orä outside of all functions (usually at the beginning of the

file)

ä The declaration tells both the return type and theargument types

324324 IntroductionIntroduction

CC Declaration Examples

float absVal(float);ä Declares that there is a function called absVal(),ä it will return a float, andä it takes a single float argument

ä Note the need for a semicolonä Note the lack of a variable name

ä float absVal(float x); is valid, but the name x isignored

ä In fact, the variable name doesn't have to be the sameas used in the real function definition

ä Dummy variable names in a declaration can be an aid toremembering how to use the function

C Programming UCSD Extension

© 1995 Philip J. Mercurio 163

325325 IntroductionIntroduction

CC More Declarations

ä A foolproof way to write a declaration is to copy theheader of the function and add a semicolon

ä If there are no arguments, use voidä int getTime(void); for a function that returns the

time by reading the internal clock

ä If there is no return value, use voidvoid

ä void printTime(int time); for a function thatprints the time

326326 IntroductionIntroduction

CC Why Declarations

ä The compiler will convert arguments to the correcttype only if you provide declarations with types

ä It's a good idea to declare all functions, even ifthey're defined before being usedä It's good documentationä You might move the definition later

C Programming UCSD Extension

© 1995 Philip J. Mercurio 164

327327 IntroductionIntroduction

CC Variable arguments

ä If there are a variable number of arguments, usethe ellipsis

int printf(char *format, ...);

ä Declares one argument explicitly (a pointer argument,we'll cover these later) and that that will be followed by 0or more arguments of unknown type

ä Both printf() and scanf() are declared in a specialfile stdio.h

ä #include <stdio.h> includes the contents of this filein your program, so printf() and scanf() getdefined properly

328328 IntroductionIntroduction

CC Compiler's Assumptions

ä If not specified, a function is assumed to be intfunction(...);ä Returns intä No clue as to how many arguments or what types

C Programming UCSD Extension

© 1995 Philip J. Mercurio 165

329329 IntroductionIntroduction

CC Checking Function Arguments

ä If passed a negative argument, the Newton-Raphson algorithm never convergesä squareRoot() goes into an infinite loop

ä The comment helps, but this puts the burden onthe calling function

ä A better solution is to make sure your function issafe: if given a bad argument, it shouldä print an error messageä return an out-of-range answer

ä This is another important aspect of makingreusable functions

330330 IntroductionIntroduction

CC Revised square root function

/* * Return the square root of x using Newton-Raphson. * The result will only be correct within epsilon. * * If x is negative, an error message is displayed and * -1.0 is returned. */float squareRoot(float x){

float epsilon = 0.00001;float guess = 1.0;float absVal(float x);

if(x < 0) {printf("Bad argument to squareRoot(): %f\n",

x);return(-1.0);

}

while(absVal(guess*guess - x) >= epsilon)guess = (x/guess + guess) / 2.0;

return(guess);}

C Programming UCSD Extension

© 1995 Philip J. Mercurio 166

331331 IntroductionIntroduction

CC Notes on revised squareRoot()

ä Note that the comment has been updated toexplain what happens upon bad input

ä The declaration for absVal() has been includedä The bad value is printed as part of the error

message (might help debugging)ä Note that we can have more than one return();

in a functionä Whenever a return is encountered, the control returns

to the calling function immediatelyä return; can be used to exit early from a function

returning void

332332 IntroductionIntroduction

CC Top-Down Programming

ä Structured programming allows us to solve aproblem from the top downä We start with generalities and break the task into smaller

piecesä We then break those pieces into even smaller pieces, ...ä Until we get down to pieces that are easy to code

ä Let's look again at the problem of Program 5-8,from a top-down approach

ä Problem: compute and print the square roots ofthree numbers

C Programming UCSD Extension

© 1995 Philip J. Mercurio 167

333333 IntroductionIntroduction

CC Top-Down Programming (continued)

ä Top-level (main()main()): For each numberä call printf() to print the text andä call float squareRoot(float x); to compute the

square root

ä We don't have to define squareRoot() at thispoint, we just need to decideä How it's going to be calledä What it will do

ä Notice that this is the same info that we saidshould belong in the comment at the beginning ofthe function

334334 IntroductionIntroduction

CC Top-Down Programming (continued)

ä Now we proceed down a level to writesquareRoot()

ä As we're developing the algorithm, we realize we needto calculate absolute values

ä We decide that there will be a function floatabsVal(float x);

ä Again, we don't need to write absVal() yetä We might find it already written, in a library

ä It's all about how we manage all the detailsnecessary in writing a program

C Programming UCSD Extension

© 1995 Philip J. Mercurio 168

335335 IntroductionIntroduction

CC Functions and Arrays

result = squareRoot(averages[i]);

ä Example of passing a single value from an array to afunction

ä No special handling needed inside squareRoot(), it'sjust another value

ä To pass an entire array, we only give the name ofthe array, with no subscripts

int gradeScores[100]; ...

minimum(gradeScores);ä Calls the function minimum() with the array

gradeScores

336336 IntroductionIntroduction

CC Function with array argument

ä minimum() must be written to expect an array asits argument

int minimum(int values[100])

{...

return(minimumValue);

}

ä All of the 100 values in gradeScores[] areavailable to minimum()ä A reference to values[4], for example, gets the value

stored in gradeScores[4]

C Programming UCSD Extension

© 1995 Philip J. Mercurio 169

337337 IntroductionIntroduction

CC Program 5-9

/* Array minimum example */#include <stdio.h>

int minimum(int values[10]);

main(){

int scores[10], i, minScore;

printf("Enter 10 scores\n");

for(i = 0; i < 10; i++)scanf("%i", &scores[i]);

minScore = minimum(scores);printf("\nMinimum score is %i\n", minScore);

}

338338 IntroductionIntroduction

CC Program 5-9 (continued)

/* * Return the minimum value from an array of 10 ints */int minimum(int values[10]){

int min, i;

min = values[0];

for(i = 1; i < 10; i++)if(values[i] < min)

min = values[i];

return(min);}

C Programming UCSD Extension

© 1995 Philip J. Mercurio 170

339339 IntroductionIntroduction

CC Program 5-9 Output

Enter 10 scores69976587698678679290

Minimum score is 65

340340 IntroductionIntroduction

CC Notes on Program 5-9

ä Note the declaration for minimum() outside allfunctions, at the beginning of the fileä This is a good place for declarations

ä The user is prompted for 10 values, which arestored in scores[]

ä scores[] is passed to minimum()ä It allocates some local variablesä Makes the assumption that values[0] is the minimumä Then compares values[1]..[9] against the

minimum, storing a new minimum if foundä The result is the true minimum, which is returned

C Programming UCSD Extension

© 1995 Philip J. Mercurio 171

341341 IntroductionIntroduction

CC Generality

ä We now have a general-purpose function whichcan find the minimum of any array of 10 integers

ä We could easily define other functions to computeother stats, like maximum, mean, etc.

ä On top of that we might build a statistics()routine that takes an array and performs severalstatistical analyses on it

342342 IntroductionIntroduction

CC Bottom-Up Design

ä If we were going to start a project which we knewwas going to require a lot of stats, we might beginby writing a number of utility functions likeminimum()

ä This is called bottom-up design: figuring out whatlow-level tools are needed, then building on top ofthem until you've got a tool to solve the problem

ä Most projects can benefit from both top-down andbottom-up design

ä The art of software engineering is knowing when touse top-down and when to use bottom-up

C Programming UCSD Extension

© 1995 Philip J. Mercurio 172

343343 IntroductionIntroduction

CC True Generality

ä minimum() isn't really all that general, it can onlyhandle arrays of exactly 10 integers

ä We can add a second argument with the size ofthe array

ä In fact, the compiler ignores the size given in theargument list for the functionä All it really wants to know is that it's an array, and of

which type

344344 IntroductionIntroduction

CC Program 5-10

/* Array minimum example */#include <stdio.h>

int minimum(int values[], int nElements);

main(){

int array1[5] = {157, -28, -37, 26, 10};int array2[7] = {12, 45, 1, 10, 5, 3, 22};

printf("array1 minimum is %i\n", minimum(array1,5));printf("array2 minimum is %i\n", minimum(array2,7));

}

C Programming UCSD Extension

© 1995 Philip J. Mercurio 173

345345 IntroductionIntroduction

CC Program 5-10 (continued)

/* * Return the minimum value from an array of ints. * nElements is the size of the array. */int minimum(int values[], int nElements){

int min, i;

min = values[0];

for(i = 1; i < nElements; i++)if(values[i] < min)

min = values[i];

return(min);}

346346 IntroductionIntroduction

CC Program 5-10 Output

array1 minimum is -37array2 minimum is 1

C Programming UCSD Extension

© 1995 Philip J. Mercurio 174

347347 IntroductionIntroduction

CC Notes on Program 5-10

ä The [] in the declaration and definition ofminimum() states that values is an arrayä The compiler really doesn't care how big it is

ä Note that the only change to the code inminimum() is to replace the 10 in the for loop withthe argument nElementsä Remember that the condition has to be i <nElements, since the last element isvalues[nElements - 1]

348348 IntroductionIntroduction

CC More Notes on Program 5-10

ä The arguments passed to minimum() have tomatch (array1[] and 5, array2[] and 7)ä minimum() has no way to check that the size is

accurate, so it can never be totally safe

C Programming UCSD Extension

© 1995 Philip J. Mercurio 175

349349 IntroductionIntroduction

CC Assignment Operators

ä C provides operators to make it easier to expressstatements of the formx = x operator y

counter += 5;ä Adds 5 to counter (same as counter = counter +5;)

array[i] *= 2;ä Same as array[i] = array[i] * 2;

a /= b + c

ä The expression on the right is evaluated firstä This is equivalent to a = a / (b + c);

350350 IntroductionIntroduction

CC Program 5-11

/* Array manipulation example */#include <stdio.h>

void multiplyByTwo(float array[], int n);

main(){

float floatValues[4] = {1.2, -3.7, 6.2, 8.55};int i;

multiplyByTwo(floatValues, 4);

for(i = 0; i < 4; i++)printf("%.2f ", floatValues[i]);

printf("\n");}

C Programming UCSD Extension

© 1995 Philip J. Mercurio 176

351351 IntroductionIntroduction

CC Program 5-11 (continued)

/* * Multiply each of the elements of a float array * by 2. n is the number of elements in the array. */void multiplyByTwo(float array[], int n){

int i;

for(i = 0; i < n; i++)array[i] *= 2;

}

352352 IntroductionIntroduction

CC Program 5-11 Output

2.40 -7.40 12.40 17.10

C Programming UCSD Extension

© 1995 Philip J. Mercurio 177

353353 IntroductionIntroduction

CC Notes on Program 5-11

ä array[i] *= 2 is the interesting thing hereä It demonstrates how the C operator-equals operators

can both save typing and make something morereadable

ä Here's another example:Board[row + col - 5] = Board[row + col - 5]- 10;

Board[row + col - 5] -= 10;

ä The second version is not only shorter and morereadable, it prevents calculating row + col - 5twice

354354 IntroductionIntroduction

CC We lied

ä Earlier we said that a function couldn't permanentlymodify its arguments

ä Yet multiplyByTwo() modifies thefloatValues[] array!

ä When an array is passed to a function, theindividual elements are not copiedä Instead, only the location where the array begins is

copiedä This is why the size is ignored, the function only knows

where the array starts in memoryä The function can use this information to retrieve and

modify the elements in the array

C Programming UCSD Extension

© 1995 Philip J. Mercurio 178

355355 IntroductionIntroduction

CC OK, we didn't lie

ä In fact, the location of the start of the array,ä the only thing passed to the function as an argument,ä is what we'll call a pointer, andä is a copy of the location, the original isn't modified

ä So you really can't modify argumentsä In the case of arrays, the argument tells you where

the elements are so you can modify themä This applies only to whole arrays, not to individual

elementsä If you pass array[4] to a function, the function still

gets a copy

356356 IntroductionIntroduction

CC Foreshadowing

ä For now, just remember that this always applies toarrays and never to anything elseä We'll go into much more detail in Session 8: Pointers

C Programming UCSD Extension

© 1995 Philip J. Mercurio 179

357357 IntroductionIntroduction

CC Sorting an array

ä To demonstrate modifying an array further, let'swrite a function to sort the elements of an array inascending order

ä The sorting algorithm in PAC is very inefficientä It's also harder to explain and to code than what we'll

use

ä There are many, many sorting algorithmsä It's an important field of study in computer science, since

sorting is done often

ä We'll look at an algorithm called Bubble Sortä It's not very efficient, but it's more fun

358358 IntroductionIntroduction

CC Bubble Sort

ä For each element ai in the array (except the lastone)ä Compare ai to ai+1

ä If they're in the wrong order (ai > ai+1), swap them andset a flag indicating that you did a swap

ä Keep on performing the loop described above,clearing the flag and starting at the beginning eachtimeä If you make a pass through the array without doing any

swaps, you're done!

ä It's called Bubble Sort because the lower valuesbubble up to the top of the array

C Programming UCSD Extension

© 1995 Philip J. Mercurio 180

359359 IntroductionIntroduction

CC Program 5-12: main()

/* Bubble sort some arrays */#include <stdio.h>

void printArray(int a[], int n);void bubbleSort(int a[], int n);int bSortPass(int a[], int n);

main(){

int array[16] = { 34, -5, 6, 0, 12, 100, 56, 22,44, -3, -9, 12, 17, 22, 6, 11};

printf("The array before the sort: \n");printArray(array, 16);

bubbleSort(array, 16);

printf("The array after the sort: \n");printArray(array, 16);

}

360360 IntroductionIntroduction

CC Program 5-12: printArray()

/* * Print an array of ints, of size n. * The whole array is printed on one line. */void printArray(int a[], int n){

int i;

for(i = 0; i < n; i++)printf("%i ", a[i]);

printf("\n");}

C Programming UCSD Extension

© 1995 Philip J. Mercurio 181

361361 IntroductionIntroduction

CC Program 5-12: bubbleSort()

/* * Using the Bubble Sort algorithm, sort the * integers in an array of size n. * * Most of the work is done by bSortPass(), we just call * it until it's done. */void bubbleSort(int a[], int n){

int swapped;

do {swapped = bSortPass(a, n);

} while(swapped);}

362362 IntroductionIntroduction

CC Program 5-12: bSortPass()

/* * Perform one Bubble Sort pass over the array a[], of * size n. We start at the beginning and swap any pairs * that are out of order. If we did a swap, we return 1 * (true). If we didn't do any swaps, we return 0 (false). */int bSortPass(int a[], int n){

int swapped = 0;int i;int temp;

for(i = 0; i < n - 1; i++)if(a[i] > a[i+1]) { /* out of order, swap */

temp = a[i];a[i] = a[i+1];a[i+1] = temp;

swapped = 1;}

return(swapped);}

C Programming UCSD Extension

© 1995 Philip J. Mercurio 182

363363 IntroductionIntroduction

CC Program 5-12 Output

The array before the sort:34 -5 6 0 12 100 56 22 44 -3 -9 12 17 22 6 11The array after the sort:-9 -5 -3 0 6 6 11 12 12 17 22 22 34 44 56 100

364364 IntroductionIntroduction

CC Notes on Program 5-12

ä PAC's version did all the printing in main()ä Anytime you do something more than once, consider

making it a function

ä Note how top-down design makes each functioneasily understandable

ä bSortPass() is an example of a function thatreturns a flag value (true or false)ä It's very common for functions to return whether or not

they succeeded

C Programming UCSD Extension

© 1995 Philip J. Mercurio 183

365365 IntroductionIntroduction

CC More Notes on Program 5-12

ä Note the need to use a temporary variable to swapa[i] and a[i+1]

ä i < n - 1 needed in order to not process thelast elementä if i == n - 1 then i + 1 is out of bounds

366366 IntroductionIntroduction

CC Multidimensional Arrays

ä A multidimensional array element can be passedlike any other valueä squareRoot(matrix[i][j]); passes the value

stored at Mi,j to the squareRoot() function

ä An entire multidimensional array can be passedjust like a 1-D array

ä scalarMultiply(matrix, n) could be used toinvoke a function which multiplies each element ofa 2-D matrix by n

C Programming UCSD Extension

© 1995 Philip J. Mercurio 184

367367 IntroductionIntroduction

CC Multidimensional Arrays (continued)

ä In the argument list for scalarMultiply()ä the matrix can be sized explicitly: int mat[100][50]ä or just the number of columns: int mat[][50]

ä Similar to how a function doesn't need to know thesize of a 1-D array, it doesn't need to know thenumber of rows of a 2-D array

ä int mat[][] and int mat[100][] are bothinvalid

368368 IntroductionIntroduction

CC Program 5-13

/* Multidimensional arrays example */#include <stdio.h>

void scalarMultiply(int matrix[3][5], int scalar);void displayMatrix(int matrix[3][5]);

main(){

int sampleMatrix[3][5] = {{ 7, 16, 55, 13, 12 },{ 12, 10, 52, 0, 7 },{ -2, 1, 2, 4, 9 }};

printf("Original matrix:\n");displayMatrix(sampleMatrix);

scalarMultiply(sampleMatrix,2);

printf("\nMultiplied by 2:\n");displayMatrix(sampleMatrix);

scalarMultiply(sampleMatrix,-1);

C Programming UCSD Extension

© 1995 Philip J. Mercurio 185

369369 IntroductionIntroduction

CC Program 5-13 (continued)

printf("\nMultiplied by -1:\n");displayMatrix(sampleMatrix);

}

/* * Multiply a 3x5 matrix by a scalar */voidscalarMultiply(int mat[3][5], int scalar){

int row, column;

for(row = 0; row < 3; row++)for(column = 0; column < 5; column++)

mat[row][column] *= scalar;}

370370 IntroductionIntroduction

CC Program 5-13 (continued)

/* * Print a 3x5 matrix */voiddisplayMatrix(int mat[3][5]){

int row, column;

for(row = 0; row < 3; row++) {for(column = 0; column < 5; column++)

printf("%5i", mat[row][column]);

printf("\n");}

}

C Programming UCSD Extension

© 1995 Philip J. Mercurio 186

371371 IntroductionIntroduction

CC Program 5-13 Output

Original matrix: 7 16 55 13 12 12 10 52 0 7 -2 1 2 4 9

Multiplied by 2: 14 32 110 26 24 24 20 104 0 14 -4 2 4 8 18

Multiplied by -1: -14 -32 -110 -26 -24 -24 -20 -104 0 -14 4 -2 -4 -8 -18

372372 IntroductionIntroduction

CC Notes on Program 5-13

ä We use a custom printing function, just like in 5-12ä Note the nested for loops, the outer loop sequences

through the rows while the inner loop does the columnsä After each pass through the inner loop (one row), a

newline is printedä This prints the matrix out in the order we're used to

seeing it inä The %5i makes everything line up nicely

C Programming UCSD Extension

© 1995 Philip J. Mercurio 187

373373 IntroductionIntroduction

CC More Notes on Program 5-13

ä The first call to scalarMultiply() scales thematrix by 2ä The following displayMatrix() demonstrates that the

matrix values were changed

ä The second call to scalarMultiply()demonstrates the same thing

374374 IntroductionIntroduction

CC Global Variables

ä Variables defined inside a function are localvariablesä Their names are only valid within their function

ä Variables defined outside of all functions are globalä They're valid anywhere in all the functions after their

declarationä There's only one copy of each global variable, all

functions which access it are accessing the samevariable

ä Global and local are two types of scopeä All variables declared outside of functions are

automatically global

C Programming UCSD Extension

© 1995 Philip J. Mercurio 188

375375 IntroductionIntroduction

CC Fixing Program 4-7

ä Let's re-write Program 4-7 (converts a number toanother base) using functionsä We'll fix the problems we noticed beforeä We'll use global variables to communicate between

functions

ä getNumberAndBase() will get the user input,rejecting a bad base value

ä convertNumber() will do the conversionä displayConvertedNumber() will display the

number (correcting the order of the digits)

376376 IntroductionIntroduction

CC/* Convert a positive integer to a base between 2 and 16 */

/* Global variables */int convertedNumber[64];long int numberToConvert;int base;int index = 0;

/* * Get the number and base from the user */void getNumberAndBase(void){

printf("Number to be converted? ");scanf("%li", &numberToConvert);

printf("Base? ");scanf("%i", &base);

if(base < 2 || base > 16) {printf("Bad base, must be between 2 and 16\n");base = 10;

}}

Program 5-14:getNumberAndBase()

C Programming UCSD Extension

© 1995 Philip J. Mercurio 189

377377 IntroductionIntroduction

CC Program 5-14: convertNumber()

/* * Convert the number to the given base, assembling the * digits in reverse order in convertedNumber[]. */void convertNumber(void){

do {convertedNumber[index] = numberToConvert %

base;index++;numberToConvert /= base;

} while(numberToConvert != 0);}

378378 IntroductionIntroduction

CC Program 5-14:displayConvertedNumber()

/* * Display the converted number (reversing the digits) */void displayConvertedNumber(void){

char baseDigits[16] = {'0', '1', '2', '3', '4', '5', '6', '7','8', '9', 'A', 'B', 'C', 'D', 'E', 'F'

};int nextDigit;

printf("Converted number = ");

for(index--; index >= 0; index--) {nextDigit = convertedNumber[index];printf("%c", baseDigits[nextDigit]);

}

printf("\n");}

C Programming UCSD Extension

© 1995 Philip J. Mercurio 190

379379 IntroductionIntroduction

CC Program 5-14: main()

main(){

void getNumberAndBase(void), convertNumber(void),displayConvertedNumber(void);

getNumberAndBase();convertNumber();displayConvertedNumber();

}

380380 IntroductionIntroduction

CC Program 5-14 Output

Number to be converted? 100Base? 8Converted number = 144

Number to be converted? 1983Base? 0Bad base, must be between 2 and 16Converted number = 1983

C Programming UCSD Extension

© 1995 Philip J. Mercurio 191

381381 IntroductionIntroduction

CC Notes on Program 5-14

ä getNumberAndBase() forces a valid value whena bad base is entered, so the rest of thecomputation can proceedä Another approach would be to havegetNumberAndBase() return a flag indicating if it wassuccessful

ä main() could check the flag and not continue ifgetNumberAndBase() failed

ä Note how descriptive function names make themain() routine more obvious

382382 IntroductionIntroduction

CC More on globals

ä Globals are most useful when many functions haveto access the same variable

ä The functions in Program 5-14 are not reusable,because they require the global variables to bepresentä Versions that took arguments instead would be more

flexible

ä Global variables are always initialized to 0ä Local variables are not initializedä It's still a good idea to explicitly initialize variables

C Programming UCSD Extension

© 1995 Philip J. Mercurio 192

383383 IntroductionIntroduction

CC Automatic Variables

ä By default, local variables are automaticä They're created each time the function is enteredä They're destroyed when the function returnsä If initialized, they're initialized again each time the

function is calledä The values in automatic local variables are lost between

calls to the function

384384 IntroductionIntroduction

CC Static Variables

ä The opposite of automatic is staticä static variables are created once and survive for the life

of the programä When a function with static variables exits and gets

called again, the static variables still have the samevalue

ä static variables with initializations are initialized once,regardless of how many times the function is called

ä The scope of a static variable is still local--it can't bereferenced outside the function it's defined in

C Programming UCSD Extension

© 1995 Philip J. Mercurio 193

385385 IntroductionIntroduction

CC Using static variables

void test(void) {static int counter = 100;

....

counter--;

}

ä counter gets initialized to 100 once, when theprogram starts

ä Each time test() is called, counter will bedecremented

ä For example, if(counter == 0) would tell youif test had been called 100 times

386386 IntroductionIntroduction

CC Program 5-15

/* Illustrate static and auto variables */

void autoStatic(void){

int autoVar = 1;static int staticVar = 1;

printf("automatic = %i, static = %i\n",autoVar, staticVar);

autoVar++;staticVar++;

}

main(){

int i;void autoStatic(void);

for(i = 0; i < 5; i++)autoStatic();

}

C Programming UCSD Extension

© 1995 Philip J. Mercurio 194

387387 IntroductionIntroduction

CC Program 5-15 Output

automatic = 1, static = 1automatic = 1, static = 2automatic = 1, static = 3automatic = 1, static = 4automatic = 1, static = 5

388388 IntroductionIntroduction

CC Notes on Program 5-15

ä main() calls autoStatic() 5 timesä Since autoVar is automatic, it gets reinitialized to

1 each timeä staticVar is initialized to 1 once

C Programming UCSD Extension

© 1995 Philip J. Mercurio 195

389389 IntroductionIntroduction

CC When to use static variables

ä If you need to maintain a value across calls to afunction, static variables are the best way to go

ä statics can also be useful if a function needs avalue that will never changeä It avoids recreating the variable each time the function is

calledä If the initialization is big (like initializing an array), it helps

to do that only once

390390 IntroductionIntroduction

CC Recursion Defined

re-cur-sion \ri-'ker-zhen\ n1. See recursion

C Programming UCSD Extension

© 1995 Philip J. Mercurio 196

391391 IntroductionIntroduction

CC Recursive Functions

ä C allows us to create recursive functions, orfunctions which call themselves

ä Recursive functions are handy for problems wherethe solution can be expressed by successivelyapplying the solution to subsets of the problemä Evaluating expressions with nested parenthesesä Various searching and sorting operationsä Factorials in mathematics

392392 IntroductionIntroduction

CC Factorials

ä The factorial of n, written n!, is the product of theintegers from 1 to nä 5! = 5 x 4 x 3 x 2 x 1 = 120ä 6! = 6 x 5 x 4 x 3 x 2 x 1 = 720ä 0! = 1 (by definition)

ä One way of expressing factorials is to say thatä n! = n x (n-1)!

ä This is a recursive definition, since factorial isbeing defined in terms of another factorial

C Programming UCSD Extension

© 1995 Philip J. Mercurio 197

393393 IntroductionIntroduction

CC Program 5-16

/* Factorial program */#include <stdio.h>

main(){

int j;long int factorial(long int n);

for(j = 0; j <= 10; j++)printf("%2i! = %li\n", j, factorial(j));

}

394394 IntroductionIntroduction

CC Program 5-16 (continued)

/* * Recursive factorial function */long int factorial(long int n){

long int result;

if(n == 0)result = 1;

elseresult = n * factorial(n - 1);

return(result);}

C Programming UCSD Extension

© 1995 Philip J. Mercurio 198

395395 IntroductionIntroduction

CC Program 5-16 Output

0! = 1 1! = 1 2! = 2 3! = 6 4! = 24 5! = 120 6! = 720 7! = 5040 8! = 40320 9! = 36288010! = 3628800

396396 IntroductionIntroduction

CC Notes on Program 5-16

ä main() just calls factorial() 10 times andprints the result

ä factorial() consists of one if statementä if n is 0, we know the answer (1) and return itä otherwise, we call factorial(n-1), multiply the result

by n, and return it

ä A recursive function must have a way out!ä There must be a path through the function that does not

call itself

C Programming UCSD Extension

© 1995 Philip J. Mercurio 199

397397 IntroductionIntroduction

CC More Notes on Program 5-16

ä Each time a function is called, it gets its own localvariablesä Even though factorial() is calling itself, each

invocation gets its own result

398398 IntroductionIntroduction

CC factorial(2)

ä factorial(2)ä calls factorial(1)

ä calls factorial(0)ä returns 1

ä sets result = 1 * 1 = 1ä returns 1

ä sets result = 2 * 1 = 2ä returns 2

C Programming UCSD Extension

© 1995 Philip J. Mercurio 200

399399 IntroductionIntroduction

CC Factorial Animation #1

main()

400400 IntroductionIntroduction

CC Factorial Animation #2

main()

factorial(3)

C Programming UCSD Extension

© 1995 Philip J. Mercurio 201

401401 IntroductionIntroduction

CC Factorial Animation #3

n = 3

main()

factorial(n)

factorial(3)

402402 IntroductionIntroduction

CC Factorial Animation #4

n = 2

n = 3

3 x

main()

factorial(n)

factorial(3)

C Programming UCSD Extension

© 1995 Philip J. Mercurio 202

403403 IntroductionIntroduction

CC Factorial Animation #5

n = 1

n = 2

n = 3

3 x 2 x

main()

factorial(n)

factorial(3)

404404 IntroductionIntroduction

CC Factorial Animation #6

n = 0

n = 1

n = 2

n = 3

3 x 2 x 1 x

main()

factorial(n)

factorial(3)

C Programming UCSD Extension

© 1995 Philip J. Mercurio 203

405405 IntroductionIntroduction

CC Factorial Animation #7

n = 0

1

n = 1

n = 2

n = 3

3 x 2 x 1 x

main()

factorial(n)

factorial(3)

406406 IntroductionIntroduction

CC Factorial Animation #8

n = 0

1

n = 1

n = 2

n = 3

3 x 2 x 1 x

1

main()

factorial(n)

factorial(3)

C Programming UCSD Extension

© 1995 Philip J. Mercurio 204

407407 IntroductionIntroduction

CC Factorial Animation #9

n = 0

1

n = 1

n = 2

n = 3

3 x 2 x 1 x

1

1main()

factorial(n)

factorial(3)

408408 IntroductionIntroduction

CC Factorial Animation #10

n = 0

1

n = 1

n = 2

n = 3

3 x 2 x 1 x

1

2

1main()

factorial(n)

factorial(3)

C Programming UCSD Extension

© 1995 Philip J. Mercurio 205

409409 IntroductionIntroduction

CC Factorial Animation #11

n = 0

1

n = 1

n = 2

n = 3

3 x 2 x 1 x

1

62

1main()

factorial(n)

factorial(3)

410410 IntroductionIntroduction

CC Factorial Animation #12

n = 0

1

n = 1

n = 2

n = 3

3 x 2 x 1 x

1

62

1main()

factorial(n)

6

factorial(3)

C Programming UCSD Extension

© 1995 Philip J. Mercurio 206

411411 IntroductionIntroduction

CC Exercises due next session

ä Read: Chapter 8ä Exercises: Chapter 8

ä 8: Be sure to use double everywhereä 11, 12, 13, 15, 16

ä Exercises: Chapter 6ä 6: Redo using a recursive function to print the results

2a

-b ± √ b2 - 4ac

413413 IntroductionIntroduction

CC

C Programming

StructuresPhil Mercurio

UCSD [email protected]

C Programming UCSD Extension

© 1995 Philip J. Mercurio 207

414414 IntroductionIntroduction

CC Today's Session

ä Structures [Chapter 9]ä Initializing and Referencing Structuresä Functions & Structuresä Arrays of Structuresä Nested Structures

415415 IntroductionIntroduction

CC Structures

ä In Session 4 we introduced the array, which lets usgroup elements of the same type into a singlelogical entity

ä C also provides a tool for grouping elements ofdifferent types, called the structure

ä Structures are very useful for modeling data as itappears in the real world

ä Structures and functions work together well

C Programming UCSD Extension

© 1995 Philip J. Mercurio 208

416416 IntroductionIntroduction

CC Storing Dates

ä One natural way to store today's date:int month = 8, day = 16, year = 1995;

ä But what if we need another date, like date ofpurchase?int month_of_purchase, day_of_purchase,year_of_purchase; ?

ä The three elements of a date are logically related,and they apply to all datesä One could say that the structure of a date is three

numbers

417417 IntroductionIntroduction

CC struct date

struct date {int month;

int day;

int year;

};

ä Defines a structure called date with 3 intmembers month, day, and year

ä We've actually just defined a new data type, whichwe can use in variable declarationsä The ability to create our own functions and our own data

types is what makes C extensible

C Programming UCSD Extension

© 1995 Philip J. Mercurio 209

418418 IntroductionIntroduction

CC Using struct date

struct date today;ä Declares a date structure called today

struct date today, purchaseDate;ä Declares two date structures, one called today and

one called purchaseDate.

419419 IntroductionIntroduction

CC Using struct date (continued)

ä To access a member within a struct, you statethe struct variable name, followed by a period,followed by the member nameä today.day = 21; sets the day member of the today

structure to 21ä today.year = 1993; set today's year to 1993if(today.month == 12)

nextMonth = 1;

ä tests today's month to see if it's equal to 12

C Programming UCSD Extension

© 1995 Philip J. Mercurio 210

420420 IntroductionIntroduction

CC Program 6-1/* Illustrate structure use */#include <stdio.h>

void main(){

struct date {int month;int day;int year;

};

struct date today;

today.month = 8;today.day = 16;today.year = 1993;

printf("Today's date is %i/%i/%i.\n",today.month, today.day, today.year % 100);

}

Today's date is 8/16/93.

Output

421421 IntroductionIntroduction

CC Notes on Program 6-1

ä The first use of struct defines the datestructure, but doesn't allocate any memory

ä The struct date today; line allocates a datestructure called todayä This is an important distinction!

ä Note that we take the year modolo 100 to get thelast two digits

C Programming UCSD Extension

© 1995 Philip J. Mercurio 211

422422 IntroductionIntroduction

CC Diagram of struct date: Definition

date

.month

.day

.year

struct date { int month, day, year; };

423423 IntroductionIntroduction

CC Diagram of struct date: Declaration

datetoday

.month

.day

.year

struct date { int month, day, year; };

struct date today;

C Programming UCSD Extension

© 1995 Philip J. Mercurio 212

424424 IntroductionIntroduction

CC Tomorrow's date

ä Problem: given today's date, compute tomorrow'sä We can't just add one to the day

ä What if today is the end of the month?ä What if today is the end of the year?

ä We'll need a lookup table of the number of days ineach monthint daysPerMonth[12] = {31, 28, 31, 30, 31,

30, 31, 31, 30, 31, 30, 31};

ä For a given month i, daysPerMonth[i-1] is thenumber of days in that month

425425 IntroductionIntroduction

CC Program 6-2

/* Program to determine tomorrow's date */#include <stdio.h>

main(){

struct date {int month;int day;int year;};

struct date today, tomorrow;

int daysPerMonth[12] = {31, 28, 31, 30, 31, 30,31, 31, 30, 31, 30, 31};

printf("Enter today's date (mm dd yyyy): ");scanf("%i%i%i", &today.month, &today.day,

&today.year);

C Programming UCSD Extension

© 1995 Philip J. Mercurio 213

426426 IntroductionIntroduction

CC Program 6-2 (continued)

if(today.day != daysPerMonth[today.month-1]) {tomorrow.day = today.day + 1;tomorrow.month = today.month;tomorrow.year = today.year;

}else if(today.month == 12) { /* end of year */

tomorrow.day = 1;tomorrow.month = 1;tomorrow.year = today.year + 1;

}else { /* end of month */

tomorrow.day = 1;tomorrow.month = today.month + 1;tomorrow.year = today.year;

}

printf("Tomorrow's date is %i/%i/%i.\n",tomorrow.month, tomorrow.day, tomorrow.year);

}

427427 IntroductionIntroduction

CC Program 6-2 Output

Enter today's date (mm dd yyyy): 8 16 1995Tomorrow's date is 8/17/1995.

Enter today's date (mm dd yyyy): 12 31 1995Tomorrow's date is 1/1/1996.

C Programming UCSD Extension

© 1995 Philip J. Mercurio 214

428428 IntroductionIntroduction

CC Notes on Program 6-2

ä Note the (mm dd yyyy) in the input prompt, tellingthe user how to enter the date correctly

ä First we test for end of monthä If that fails, just increment the day

ä If it is the end of month, we then test for end ofyear

ä Note that this program is correct, except for leapyears!

429429 IntroductionIntroduction

CC Functions and Structures

ä We need to incorporate the leap year calculation inour program

ä One good way is to create a function callednumberOfDays() to determine the number ofdays in a monthä It would check for leap year and use the lookup table to

give the correct resultä Only requires a small change to main()

ä Just have to replacedaysPerMonth[today.month-1] withnumberOfDays(today)

C Programming UCSD Extension

© 1995 Philip J. Mercurio 215

430430 IntroductionIntroduction

CC Program 6-3

/* Program to determine tomorrow's date */#include <stdio.h>

struct date {int month;int day;int year;};

main(){

struct date today, tomorrow;int numberOfDays(struct date d);

printf("Enter today's date (mm dd yyyy): ");scanf("%i%i%i", &today.month, &today.day,

&today.year);

431431 IntroductionIntroduction

CC Program 6-3 (continued)

if(today.day != numberOfDays(today)) {tomorrow.day = today.day + 1;tomorrow.month = today.month;tomorrow.year = today.year;

}else if(today.month == 12) { /* end of year */

tomorrow.day = 1;tomorrow.month = 1;tomorrow.year = today.year + 1;

}else { /* end of month */

tomorrow.day = 1;tomorrow.month = today.month + 1;tomorrow.year = today.year;

}

printf("Tomorrow's date is %i/%i/%i.\n",tomorrow.month, tomorrow.day, tomorrow.year);

}

C Programming UCSD Extension

© 1995 Philip J. Mercurio 216

432432 IntroductionIntroduction

CC Program 6-3 (continued)

/* * Return the number of days in a month, for the given date */int numberOfDays(struct date d){

int isLeapYear(struct date d);int daysPerMonth[12] = {31, 28, 31, 30, 31, 30,

31, 31, 30, 31, 30, 31};

if(isLeapYear(d) && d.month == 2)return(29);

elsereturn(daysPerMonth[d.month - 1]);

}

433433 IntroductionIntroduction

CC Program 6-3 (continued)

/* * Return 1 if the date is a leap year, 0 otherwise */int isLeapYear(struct date d){

if( (d.year % 4 == 0 && d.year % 100 != 0) ||d.year % 400 == 0 )return(1);

elsereturn(0);

}

C Programming UCSD Extension

© 1995 Philip J. Mercurio 217

434434 IntroductionIntroduction

CC Program 6-3 Output

Enter today's date (mm dd yyyy): 8 16 1995Tomorrow's date is 8/17/1995.

Enter today's date (mm dd yyyy): 2 28 1996Tomorrow's date is 2/29/1996.

435435 IntroductionIntroduction

CC Notes on Program 6-3

ä Note that struct date is now defined outside ofmain()

ä Structure definitions, like variables, have scopeä A structure defined within a function can only be used

within that functionä Structures defined outside all functions are global, and

can be used anywhere

C Programming UCSD Extension

© 1995 Philip J. Mercurio 218

436436 IntroductionIntroduction

CC More Notes on Program 6-3

int numberOfDays(struct date d);ä Declares an integer function that will take a structdate as an argument

ä This argument is filled in when main() callsnumberOfDays(today)

ä Just like with ordinary variables, structures are copiedwhen passed as arguments

ä The original today structure can't be changed bynumberOfDays()

437437 IntroductionIntroduction

CC More Notes on Program 6-3

ä isLeapYear() is a function that returns a flagvalue, 1 for true, 0 for falseä We test it directly in if(isLeapYear(d) ...)

ä No need to compare it against 1ä Note how the name of the function reads well in an if

statement

ä How about making this better structured bycreating a function which, given a date struct,returns another date struct containing the nextday?

C Programming UCSD Extension

© 1995 Philip J. Mercurio 219

438438 IntroductionIntroduction

CC Program 6-4

/* Program to determine tomorrow's date */#include <stdio.h>

struct date {int month;int day;int year;};

/* * Given a date structure, return another containing the * next day */struct date nextDay(struct date today){

struct date tomorrow;int numberOfDays(struct date d);

439439 IntroductionIntroduction

CC Program 6-4 (continued)

if(today.day != numberOfDays(today)) {tomorrow.day = today.day + 1;tomorrow.month = today.month;tomorrow.year = today.year;

}else if(today.month == 12) { /* end of year */

tomorrow.day = 1;tomorrow.month = 1;tomorrow.year = today.year + 1;

}else { /* end of month */

tomorrow.day = 1;tomorrow.month = today.month + 1;tomorrow.year = today.year;

}

return(tomorrow);}

C Programming UCSD Extension

© 1995 Philip J. Mercurio 220

440440 IntroductionIntroduction

CC Program 6-4 (continued)

/* * Return the number of days in a month, for the given date */int numberOfDays(struct date d){

int isLeapYear(struct date d);int daysPerMonth[12] = {31, 28, 31, 30, 31, 30,

31, 31, 30, 31, 30, 31};

if(isLeapYear(d) && d.month == 2)return(29);

elsereturn(daysPerMonth[d.month - 1]);

}

441441 IntroductionIntroduction

CC Program 6-4 (continued)

/* * Return 1 if the date is a leap year, 0 otherwise */int isLeapYear(struct date d){

if( (d.year % 4 == 0 && d.year % 100 != 0) ||d.year % 400 == 0 )return(1);

elsereturn(0);

}

C Programming UCSD Extension

© 1995 Philip J. Mercurio 221

442442 IntroductionIntroduction

CC Program 6-4 (continued)

/* * Main routine */main(){

struct date nextDay(struct date d);struct date today, tomorrow;

printf("Enter today's date (mm dd yyyy): ");scanf("%i%i%i", &today.month, &today.day,

&today.year);

tomorrow = nextDay(today);

printf("Tomorrow's date is %i/%i/%i.\n",tomorrow.month, tomorrow.day, tomorrow.year);

}

443443 IntroductionIntroduction

CC Program 6-4 Output

Enter today's date (mm dd yyyy): 2 28 2000Tomorrow's date is 2/29/2000.

C Programming UCSD Extension

© 1995 Philip J. Mercurio 222

444444 IntroductionIntroduction

CC Notes on Program 6-4

ä tomorrow = nextDay(today); shows thatyou can both pass a structure as an argument andreturn one as a value

ä nextDay() is almost identical to the code frommain in Program 6-3ä The printf()s and scanf()s were removed, they're

in the new main()

445445 IntroductionIntroduction

CC Time

ä Let's create a structure for holding the time of day:struct time {

int hour; /* 24 hour clock */

int minutes;

int seconds;

};

ä Let's write a function to increment the time by 1second

C Programming UCSD Extension

© 1995 Philip J. Mercurio 223

446446 IntroductionIntroduction

CC Program 6-5/* Program to update the time by one second */#include <stdio.h>

struct time {int hour;int minutes;int seconds;};

main(){

struct time timeUpdate(struct time now);struct time currentTime, nextTime;

printf("Enter the time (hh:mm:ss): ");scanf("%i:%i:%i", &currentTime.hour,

&currentTime.minutes, &currentTime.seconds);

nextTime = timeUpdate(currentTime);

printf("Updated time is %.2i:%.2i:%.2i\n",nextTime.hour,nextTime.minutes, nextTime.seconds);

}

447447 IntroductionIntroduction

CC Program 6-5 (continued)

/* * Return a time updated by one second */struct time timeUpdate(struct time now){

now.seconds++;

if(now.seconds == 60) { /* next minute */now.seconds = 0;now.minutes++;

if(now.minutes == 60) { /* next hour */now.minutes = 0;now.hour++;

if(now.hour == 24) /* midnight */now.hour = 0;

}}

return(now);}

C Programming UCSD Extension

© 1995 Philip J. Mercurio 224

448448 IntroductionIntroduction

CC Program 6-5 Output

Enter the time (hh:mm:ss): 12:59:59Updated time is 13:00:00

449449 IntroductionIntroduction

CC Notes on Program 6-5

ä The "%i:%i:%i" scanf() format tells scanf()to expect 3 integers with colons in betweenä We'll see later how to tell if the input matches scanf()'s

format

ä The time is entered and stored in currentTime,which is passed to timeUpdate()

C Programming UCSD Extension

© 1995 Philip J. Mercurio 225

450450 IntroductionIntroduction

CC More Notes on Program 6-5

ä timeUpdate() handles bumping up the minutes ifthe seconds go over 60, and bumping up the hourif the minutes overflowä It also handles the hour overflowing at midnight

ä timeUpdate() then returns now, which is copiedinto main()'s nextTime and printed

451451 IntroductionIntroduction

CC Initializing Structures

ä Initializing structures is just like initializing arrays,the elements are listed in order in {}

ä struct date today = { 8, 16, 1995};

ä Sets a date structure to August 16th, 1995ä struct time rightNow = { 19, 29, 55 };

ä Sets a time to 7:29:55 pmä struct time partTime = { 12, 10 };

ä Initializes hour to 12 and minutes to 10, but leavesseconds undefined

C Programming UCSD Extension

© 1995 Philip J. Mercurio 226

452452 IntroductionIntroduction

CC Arrays of Structures

ä When we declare a structure, we're defining a newdata type that can be used just like the built-intypes int, char, float, etc.

ä In fact, we can make arrays of structures:struct time experiments[10];

ä Declares an array containing 10 time structuresstruct date birthdays[15];

ä Declares an array of 15 dates

453453 IntroductionIntroduction

CC Referencing an element of an arrayof structures

ä To set the second birthday in the array toNovember 2, 1958:birthdays[1].month = 11;

birthdays[1].day = 2;

birthdays[1].year = 1958;

ä To pass one the time from the first experiment totimeUpdate():timeUpdate(experiment[0]);

C Programming UCSD Extension

© 1995 Philip J. Mercurio 227

454454 IntroductionIntroduction

CC Initializing Arrays of Structures

ä Initializing arrays of structures is just like initializingmulti-dimensional arraysstruct time runTimes[5] =

{ {12, 0, 0}, {12, 30, 0}, {13, 15, 0} };

ä Sets the first three times in runTimes[] to 12:00:00,12:30:00, and 13:15:00

ä The rest of the runTimes[] elements are uninitialized

ä You can leave out the inner {}s, but it becomesquite unreadable

455455 IntroductionIntroduction

CC Program 6-6

/* Program to illustrate arrays of structures */#include <stdio.h>

struct time {int hour;int minutes;int seconds;};

main(){

struct time timeUpdate(struct time now);struct time testTimes[5] = {

{11, 59, 59}, {12, 0, 0}, {1, 29, 59},{23, 59, 59}, {19, 12, 27} };

int i;

C Programming UCSD Extension

© 1995 Philip J. Mercurio 228

456456 IntroductionIntroduction

CC Program 6-6 (continued)

for(i=0; i < 5; i++) {printf("Time is %.2i:%.2i:%.2i",

testTimes[i].hour,testTimes[i].minutes,testTimes[i].seconds);

testTimes[i] = timeUpdate(testTimes[i]);

printf(" ...one second later it's"" %.2i:%.2i:%.2i\n",testTimes[i].hour,testTimes[i].minutes,testTimes[i].seconds);

}}

457457 IntroductionIntroduction

CC Program 6-6 (continued)

/* * Return a time updated by one second */struct time timeUpdate(struct time now){

now.seconds++;

if(now.seconds == 60) { /* next minute */now.seconds = 0;now.minutes++;

if(now.minutes == 60) { /* next hour */now.minutes = 0;now.hour++;

if(now.hour == 24) /* midnight */now.hour = 0;

}}

return(now);}

C Programming UCSD Extension

© 1995 Philip J. Mercurio 229

458458 IntroductionIntroduction

CC Program 6-6 Output

Time is 11:59:59 ...one second later it's 12:00:00Time is 12:00:00 ...one second later it's 12:00:01Time is 01:29:59 ...one second later it's 01:30:00Time is 23:59:59 ...one second later it's 00:00:00Time is 19:12:27 ...one second later it's 19:12:28

459459 IntroductionIntroduction

CC Diagram of testTimes[]

.seconds

.seconds

.seconds

.minutes

.minutes

.seconds

.hour

.hour

.hour

.minutes

.hour

.minutestestTimes[0]{testTimes[1]{testTimes[2]{testTimes[3]{

11595912 0 0 12959235959

C Programming UCSD Extension

© 1995 Philip J. Mercurio 230

460460 IntroductionIntroduction

CC Structures Within Structures

ä Any C data type can be used inside a structure,including arrays and other structures

ä Let's create a data type for storing a date and timetogether

struct dateAndTime {struct date Date;

struct time Time;

};

461461 IntroductionIntroduction

CC More Structures Within Structures

struct dateAndTime event;ä Declares a dateAndTime structure called event

event.Dateä Refers to the date structure within event

event.Date = dateUpdate(event.Date);ä Calls dateUpdate() on the date portion of event and

stores the result thereevent.Time = timeUpdate(event.Time);

ä Updates the Time portion of event

C Programming UCSD Extension

© 1995 Philip J. Mercurio 231

462462 IntroductionIntroduction

CC Elements Within Structures WithinStructures

event.Date.month = 10;ä Sets the month element of the date portion of event

event.Time.seconds++;ä Increments the seconds element of the time withinevent

struct dateAndTime event = {{2, 15, 1992}, {16, 0, 0} };

ä Initializes event to February 15th, 1992, 4:00:00 pm

463463 IntroductionIntroduction

CC Diagram of dateAndTime

.year

.seconds

.minutes

.hour

.month

.day.Date{.Time{

215

199216 0 0

event{

C Programming UCSD Extension

© 1995 Philip J. Mercurio 232

464464 IntroductionIntroduction

CC Arrays of Structures ContainingStructures

struct dateAndTime events[100];ä Creates an array of 100 dateAndTime structures

events[24].Date =dateUpdate(events[24].Date);ä Updates the 25th event

for(i=0; i < 100; i++) {events[i].Time.hour = 12;

events[i].Time.minutes = 0;

events[i].Time.seconds = 0;

}

ä Sets all the events' times to noon

465465 IntroductionIntroduction

CC Structures Containing Arrays

ä Structures can contain any data type, includingarrays

struct month {int numDays;

char name[3];

};

ä Declares a structure containing information about amonthä numDays contains the number of days in the monthä name[] contains the three characters of the month's

abbreviation

C Programming UCSD Extension

© 1995 Philip J. Mercurio 233

466466 IntroductionIntroduction

CC More Structures Containing Arrays

struct month aMonth;

ä Creates a month structureaMonth.numDays = 31;

aMonth.name[0] = 'J';

aMonth.name[1] = 'a';

aMonth.name[2] = 'n';ä Sets the fields for a month representing January

struct month aMonth = { 31, {'J', 'a','n'} };

ä Same thing done as an initialization

467467 IntroductionIntroduction

CC Program 6-7

* Program to illustrate structures and arrays */#include <stdio.h>

main(){

int i;

struct month {int numDays;char name[3];

};

struct month months[12] = {{31, {'J', 'a', 'n'} }, {28, {'F', 'e', 'b'} },{31, {'M', 'a', 'r'} }, {30, {'A', 'p', 'r'} },{31, {'M', 'a', 'y'} }, {30, {'J', 'u', 'n'} },{31, {'J', 'u', 'l'} }, {31, {'A', 'u', 'g'} },{30, {'S', 'e', 'p'} }, {31, {'O', 'c', 't'} },{30, {'N', 'o', 'v'} }, {31, {'D', 'e', 'c'} }};

C Programming UCSD Extension

© 1995 Philip J. Mercurio 234

468468 IntroductionIntroduction

CC Program 6-7 (continued)

printf("Month\tNumber of Days\n");printf("=====\t==============\n");

for(i = 0; i < 12; i++) printf(" %c%c%c\t%8i\n", months[i].name[0], months[i].name[1], months[i].name[2], months[i].numDays);

}

469469 IntroductionIntroduction

CC Program 6-7 Output

Month Number of Days===== ============== Jan 31 Feb 28 Mar 31 Apr 30 May 31 Jun 30 Jul 31 Aug 31 Sep 30 Oct 31 Nov 30 Dec 31

C Programming UCSD Extension

© 1995 Philip J. Mercurio 235

470470 IntroductionIntroduction

CC Notes on Program 6-7

struct month months[12];ä Creates an array of 12 months

month[0].numDaysä Is the numDays field of the first element of the array,

type int

month[0].nameä Is the name array from the first element, type array ofchar

month[0].name[0]ä Is the first char in that array, 'J'

471471 IntroductionIntroduction

CC Diagram of months array

.name[2]

[0][1]{ 'J'

'a''n'

{.numDays

months[0]

31

.name[2]

[0][1]{ 'F'

'e''b'

{.numDays

months[1]

28

.name[2]

[0][1]{ 'M'

'a''r'

{.numDays

months[2]

30

C Programming UCSD Extension

© 1995 Philip J. Mercurio 236

472472 IntroductionIntroduction

CC Structure Variants

ä We can define a structure and declare somevariables of that type at the same time:

struct date {int month, day, year;

} todaysDate, purchaseDate;

ä Both defines the struct date and creates two ofthem, todaysDate and purchaseDate

473473 IntroductionIntroduction

CC More Structure Variants

struct date {int month, day, year;

} todaysDate = {8, 16, 1995};

ä Defines date, creates one called todaysDate,and initializes it to August 16th, 1995

C Programming UCSD Extension

© 1995 Philip J. Mercurio 237

474474 IntroductionIntroduction

CC Unnamed Structures

struct {int month, day, year;

} dates[100];

ä Defines an unnamed structure similar to structdate, and creates an array of 100 of them

ä The only name defined by this declaration is dates,an array of 100 structures containing 3 ints.

ä This is bad usage, we can't create another identicalstructure without restating the contents (int month,day, year;)

ä Always give your structures a name

475475 IntroductionIntroduction

CC Exercises due next session

ä Read: Chapter 9ä Exercises: Chapter 9

ä Typo: numbers are misplacedä 2 & 3 together make up the text for Ex. 2ä 4 is really Ex. 3ä 5 & 6 together make up the text for Ex. 4ä 7 is Ex. 5

C Programming UCSD Extension

© 1995 Philip J. Mercurio 238

476476 IntroductionIntroduction

CC Exercises due next session

ä Do Ex. 2 & 4ä Test input for 2:

ä 1/1/1970 - 2/14/1988ä 12/7/1944 - 5/7/1959ä 4/22/1953 - 4/22/1993

ä Test input for 4:ä 2/9/1988ä 1/1/1970ä 12/24/2000

477477 IntroductionIntroduction

CC

C Programming

StringsPhil Mercurio

UCSD [email protected]

C Programming UCSD Extension

© 1995 Philip J. Mercurio 239

478478 IntroductionIntroduction

CC Today's Session

ä Character Strings [Chapter 10]ä Initializing and Displaying Character Stringsä Testing for Equalityä Inputting Character Stringsä The Null Stringä Escape Charactersä The Standard Strings Library

479479 IntroductionIntroduction

CC Character Strings

ä C deals with text in the form of strings ofcharacters

ä "Programming in C is fun.\n"

ä Our first string, encountered in our first program

ä A string is not a primitive data type in C, it'sactually an array of chars

ä Most of C's string handling is done using thestandard strings libraryä We'll be writing functions similar to those in the strings

library to help us learn about strings

C Programming UCSD Extension

© 1995 Philip J. Mercurio 240

480480 IntroductionIntroduction

CC String and Char Constants

char plusSign = '+';

ä A character constant begins and ends with a singlequote '

ä It may contain any 8-bit valueä printable ASCII characters (letters, numbers,

punctuation) typed directlyä Special characters typed using backslash \

"Programming in C is fun.\n"

ä A string constant begins and ends with a doublequote "ä Same rules as for single chars

481481 IntroductionIntroduction

CC Array of chars

ä In Program 4-6 we defined an array of chars:static char word[] = {'H', 'e', 'l','l', 'o', '!'};

ä Allocates exactly six characters:

word[2]word[2]

word[4]word[4]word[5]word[5]

word[0]word[0]

word[3]word[3]

word[1]word[1]'H''H''e''e''l''l''l''l''o''o''!''!'

C Programming UCSD Extension

© 1995 Philip J. Mercurio 241

482482 IntroductionIntroduction

CC More char Arrays

ä To print out this array, we indexed through thearray and printed each char with %c

ä There are many other useful things we might wantto do to strings:ä Copying one to anotherä Combining two together (concatenation)ä Extracting a portion (substring)ä Testing for equalityä etc.

483483 IntroductionIntroduction

CC concat()

ä Let's write a function to concatenate two strings:concat(result, str1, n1, str2, n2);

ä result is a char array that will contain the charactersfrom str1 followed by the characters from str2

ä n1 is the number of characters in str1ä n2 is the number of characters in str2

ä This makes concat() flexible enough to handle anystrings

C Programming UCSD Extension

© 1995 Philip J. Mercurio 242

484484 IntroductionIntroduction

CC Program 7-1

/* Function to concat two character arrays */#include <stdio.h>

void concat(char result[], char str1[], int n1,char str2[], int n2)

{int i, j;

/* Copy str1 to result */for(i = 0; i < n1; i++)

result[i] = str1[i];

/* Copy str2 to result */for(j = 0; j < n2; j++)

result[n1 + j] = str2[j];}

485485 IntroductionIntroduction

CC Program 7-1 (continued)

main(){

void concat(char result[], char str1[], int n1,char str2[], int n2);

char s1[5] = {'T', 'e', 's', 't', ' '};char s2[6] = {'w', 'o', 'r', 'k', 's', '.'};char s3[11];int i;

concat(s3, s1, 5, s2, 6);

for(i = 0; i < 11; i++)printf("%c", s3[i]);

printf("\n");}

Test works.

OutputOutput

C Programming UCSD Extension

© 1995 Philip J. Mercurio 243

486486 IntroductionIntroduction

CC Notes on Program 7-1

ä The first for loop in concat() copies chars fromstr1 to result

ä The second for loop copies from str2 to result,starting at n1ä After copying n1 characters into result, the next

available slot is n1ä For example, after copying 0 characters, the next slot is

0

ä Note that main() has to make sure s3 is bigenough to hold the contents of s1 and s2ä Otherwise we'll exceed the bounds of the array

487487 IntroductionIntroduction

CC Variable Length Strings

ä If we stored all strings like Program 7-1 does, we'dalways have to keep track of the size of each string

ä We can establish a convention to mark the end ofa string with a special characterä A convention is an agreed-upon method for doing

somethingä All the libraries deal with variable length strings this way

by convention

C Programming UCSD Extension

© 1995 Philip J. Mercurio 244

488488 IntroductionIntroduction

CC The Null

ä In C, the end of a string is marked by the nullcharacter, ASCII 0

ä Portions of the ASCII table:

Binary Hex ASCII

00000000 0 NULL00000001 1 Ctrl-A00000010 2 Ctrl-B

00101111 2F /00110000 30 0 (zero)00110001 31 1 (one)

Binary Hex ASCII

01001110 4E N01001111 4F O (oh)01010000 50 P

01101110 6E n01101111 6F o01110000 70 p

489489 IntroductionIntroduction

CC More Null

ä In C, the null is written '\0'ä This is a character constant with the numerical value

zero, 8 bits:ä00000000

ä 0 is an integer constant with the numerical value zero,16 bits (or maybe 32):

ä0000000000000000

ä Many programmers use 0 instead of '\0'

C Programming UCSD Extension

© 1995 Philip J. Mercurio 245

490490 IntroductionIntroduction

CC Using Null

char word[] = {'H', 'e', 'l', 'l', 'o','!', '\0'};

ä Declares a seven-char array:

word[2]word[2]

word[4]word[4]word[5]word[5]

word[0]word[0]

word[3]word[3]

word[1]word[1]'H''H''e''e''l''l''l''l''o''o''!''!'

word[6]word[6] '\0''\0'

491491 IntroductionIntroduction

CC String Length

ä Let's create a function to return the length of astring terminated by a nullä The first argument will be the character arrayä The return value will be the length

ä The length of a string is defined as the number ofcharacters, not counting the nullä char pet[] = { 'c', 'a', 't', '\0' };

ä stringLength(pet); should return 3

C Programming UCSD Extension

© 1995 Philip J. Mercurio 246

492492 IntroductionIntroduction

CC Program 7-2

/* Function to count the number of characters in a string */#include <stdio.h>

int stringLength(char string[]){

int count = 0;

while(string[count] != '\0')count++;

return(count);}

main(){

int stringLength(char string[]);char word1[] = {'a', 's', 't', 'e', 'r', '\0'};char word2[] = {'a', 't', '\0'};char word3[] = {'a', 'w', 'e', '\0'};

printf("%i %i %i\n", stringLength(word1),stringLength(word2), stringLength(word3));

}

493493 IntroductionIntroduction

CC Program 7-2 Output

5 2 3

C Programming UCSD Extension

© 1995 Philip J. Mercurio 247

494494 IntroductionIntroduction

CC Notes on Program 7-2

ä In stringLength(), count is first initialized to 0ä In the loop we increment count until we come to

the nullä count is now the number of characters preceding

the nullä Trace through the function to convince yourself this is

always true

00 11count = count =

'c''c' 'a''a' 't''t'

22

'\0''\0'

33

495495 IntroductionIntroduction

CC Initializing Character Strings

ä C string constants are stored with null terminatorsä A character array can be initialized using a string

constantä char word[] = { "Hello!" }; is the same asä char word[] = { 'H', 'e', 'l', 'l', 'o','!', '\0' };

ä The null is always present at the end of a stringconstantä Both allocations use 7 charsä char word[6] = { "Hello!" }; leaves no place to

store the null

C Programming UCSD Extension

© 1995 Philip J. Mercurio 248

496496 IntroductionIntroduction

CC Displaying Character Strings

ä printf("Programming is fun\n");

ä printf() uses the null to identify the end of itsformat string

ä printf("The secret word is: %s\n",word);

ä %s can be used within a format to specify a stringargument

497497 IntroductionIntroduction

CC Another Way to Skin a concat()

ä concat() needs to be updated to handle variablelength strings

ä concat(char result[], char s1[], chars2[]);

ä No length arguments needed

C Programming UCSD Extension

© 1995 Philip J. Mercurio 249

498498 IntroductionIntroduction

CC Program 7-3

/* Function to concatenate two variable length strings */#include <stdio.h>

main(){

void concat(char result[], char str1[],char str2[]);

char s1[] = { "Test " };char s2[] = { "works." };char s3[20];

concat(s3, s1, s2);

printf("%s\n", s3);}

499499 IntroductionIntroduction

CC Program 7-3

void concat(char result[], char str1[], char str2[]){

int i, j;

/* Copy str1 to result */for(i = 0; str1[i] != '\0'; i++)

result[i] = str1[i];

/* Copy str2 to result */for(j = 0; str2[j] != '\0'; j++)

result[i + j] = str2[j];

/* Terminate the result string */result[i + j] = '\0';

}

Test works

OutputOutput

C Programming UCSD Extension

© 1995 Philip J. Mercurio 250

500500 IntroductionIntroduction

CC Notes on Program 7-3

ä The first loop copies chars from str1 to result untila null is reachedä When done, i is the number of characters (excluding

the null) in str1[]

ä The second loop fills from result[i] on withchars from str2[]ä When done, j is the string length of str2[]ä i + j is the string length of result[]

ä Always remember to terminate strings whenbuilding them by hand!

501501 IntroductionIntroduction

CC More Notes on Program 7-3

ä General rule:ä char string[];

ä string[ stringLength(string) ] is where thenull belongs

ä Note that, in main(), we declare s3[] to be largerthan it needs to beä The extra chars after the null are ignored

C Programming UCSD Extension

© 1995 Philip J. Mercurio 251

502502 IntroductionIntroduction

CC Testing Strings for Equality

ä The == operator only works on primitive data typeslike chars, ints, floats and doublesä Can't be applied to structures or arrays

ä We can't sayä if(string1 == string2) ...

ä We have to compare each pair of characters inturnä If we make it to the end of both strings at the same time,

they matchä If any pair doesn't match or one string runs out, they're

not the same

ä Our function will return 1 (true) if the strings areequal

503503 IntroductionIntroduction

CC Program 7-4

/* Function to determine if two strings are equal */#include <stdio.h>

int equalStrings(char s1[], char s2[]){

int i = 0;

/* Step through the strings matching pairs */while(s1[i] == s2[i] && s1[i] != '\0' && s2[i] != '\0')

i++;

/* If we're at the end of both strings, they match */if(s1[i] == '\0' && s2[i] == '\0')

return(1);else

return(0);}

C Programming UCSD Extension

© 1995 Philip J. Mercurio 252

504504 IntroductionIntroduction

CC Program 7-4

main(){

int equalStrings(char s1[], char s2[]);char a[] = "string compare test";char b[] = "string";

printf("%i\n",equalStrings(a,b));printf("%i\n",equalStrings(a,a));printf("%i\n",equalStrings(b,"string"));

}

011

OutputOutput

505505 IntroductionIntroduction

CC Notes on Program 7-4

ä The loop indexes through both stringsä Continues as long as the strings are still equal (s1[i]== s2[i])

ä and as long as we haven't reached the end (s1[i] !='\0' && s2[i] != '\0')

ä At some point, the while loop will exitä If we're at the end of both stings, they were equalä Otherwise, we exited either because of a mismatch or

because one string ended early, so they don't match

ä The test if(s1[i] == s2[i]) would also workä If they're the same but not == '\0', we wouldn't have

exited the while loop yet

C Programming UCSD Extension

© 1995 Philip J. Mercurio 253

506506 IntroductionIntroduction

CC More Notes on Program 7-4

ä Note the last invocation of equalStrings():equalStrings(b, "string")

ä We can use a string constant in place of a characterarray

ä Internally, a string constant is stored as a characterarray

äequalStrings() doesn't know the differenceä We'll see more about how this works in the next session

507507 IntroductionIntroduction

CC Inputting Strings

ä %s can be used to read a string with scanf()ä Reads all the input characters up to the next space, tab,

or newlinechar string[81];

scanf("%s", string);

ä Note that string is not preceded by an &ä We'll see why next sessionä For now, just remember that the & isn't used when

reading strings

C Programming UCSD Extension

© 1995 Philip J. Mercurio 254

508508 IntroductionIntroduction

CC More on Inputting Strings

ä If the text Sheryl were typed, the string "Sheryl"would be stored in the string[] arrayä The string is automatically terminated with a null

ä If the text Sheryl Crow were typed, just the word"Sheryl" would be read

ä If we then did another scanf("%s", string);the string would now contain "Crow"ä scanf() always picks up where the previous one left

offä The spaces separating strings (or ints, or floats ...)

are thrown away

509509 IntroductionIntroduction

CC Inputting Multiple Strings

ä If we call scanf("%s%s%s", s1, s2, s3);and type James Earl Jonesä s1 would contain "James", s2 "Earl", s3 "Jones"

ä If instead we typed Darth Vaderä s1 would contain "Darth", s2 "Vader"ä Since scanf() is still looking for a third string, it would

wait for more input to be typed

C Programming UCSD Extension

© 1995 Philip J. Mercurio 255

510510 IntroductionIntroduction

CC Program 7-5

/* Program to illustrate %s in scanf() */#include <stdio.h>

main(){

char s1[81], s2[81], s3[81];

printf("Enter text:\n");scanf("%s%s%s", s1, s2, s3);printf("\ns1 = %s\ns2 = %s\ns3 = %s\n", s1, s2, s3);

}

Enter text:C ProgrammingClass

s1 = Cs2 = Programmings3 = Class

OutputOutput

511511 IntroductionIntroduction

CC Notes on Program 7-5

ä Note that the strings were allocated to be 81chars longä Long enough for 80 input chars plus the null terminator

ä Since scanf() doesn't know how large yourarrays are, if you typed more than 80 charactersfor a string, it would overflow

ä You can tell scanf() how many chars to read viaä scanf("%80s%80s%80s", s1, s2, s3);

ä No more than 80 chars will be read for each stringä Left-over chars will go in the next string

C Programming UCSD Extension

© 1995 Philip J. Mercurio 256

512512 IntroductionIntroduction

CC Single-Character Input

ä The function getchar() can be used to read asingle character from the input

ä If we call getchar() 5 times and typeabc<RETURN>ä The first 3 chars will be 'a', 'b', and 'c'ä The fourth char will contain the newline '\n'ä The fifth call will cause it to wait for more input

513513 IntroductionIntroduction

CC Single-Character Input (continued)

ä getchar() takes no arguments and returns thecharacter enteredä c = getchar();

ä Simpler than scanf("%c",...), and it readsspaces, tabs, and newlines just like any otherchars

C Programming UCSD Extension

© 1995 Philip J. Mercurio 257

514514 IntroductionIntroduction

CC Buffered Input

ä Input to a C program is usually bufferedä The program doesn't get the chars until a full line has

been typed (after the newline)ä Even if you're reading chars using getchar(), you

don't get each char as it is typedä This allows you to correct input with the backspace key

ä Turning input buffering off is specific to youroperating systemä It's usually handled by some library callsä Sometimes it's handled outside your program

ä Usually by calling another program first

515515 IntroductionIntroduction

CC Inputting Lines

ä A line of text (the whole input buffer) can be readusing the gets() functionä "gets" stands for "get string"

ä Let's write a similar function using getchar()ä It'll take one char array as an argument

ä All the input chars, up to but not including the newline,will be placed in this array

ä We can't use scanf("%s",...) to do the samethingä scanf() will stop at the first space or tabä scanf() also throws out extra spaces and tabs

C Programming UCSD Extension

© 1995 Philip J. Mercurio 258

516516 IntroductionIntroduction

CC Program 7-6

/* readLine() function, similar to gets() library function*/#include <stdio.h>

main(){

int i;char line[81];void readLine(char buffer[]);

for(i = 0; i < 3; i++) {readLine(line);printf("%s\n\n", line);

}}

517517 IntroductionIntroduction

CC Program 7-6

/* * Read a line of text, up to a newline. * The newline will not be in the buffer. */void readLine(char buffer[]){

char c;int i = 0;

do {c = getchar();buffer[i] = c;

i++;} while(c != '\n');

buffer[i - 1] = '\0';}

C Programming UCSD Extension

© 1995 Philip J. Mercurio 259

518518 IntroductionIntroduction

CC Program 7-6 Output

This is a sample line of text.This is a sample line of text.

abcdefghijlkmnopqrstuvwxyzabcdefghijlkmnopqrstuvwxyz

519519 IntroductionIntroduction

CC Notes on Program 7-6

ä Each char returned by getchar() is stored inthe next element of buffer[]

ä When we get a newline, we stopä i is now referring to the next available element inbuffer[]ä the char after the newline

ä buffer[i - 1] = '\0'; overwrites thenewline with a null, terminating the string

C Programming UCSD Extension

© 1995 Philip J. Mercurio 260

520520 IntroductionIntroduction

CC More Notes on Program 7-6

ä Our readLine() doesn't know how big the bufferis, so it could overflow if we typed in more than 80charsä It would be a good idea to add a second argument

containing the size of the buffer

521521 IntroductionIntroduction

CC Operations on Characters

ä Character constants are turned into integer values,according to the ASCII code (or some other code,on some OS's)

ä 'a' is the same as the integer value 97, 'b' is98, etc.

ä c >= 'a' && c <= 'z' is the same as c >=97 && c <= 122

ä Tests whether c is a lowercase alphabetic charä Works because the ASCII alphabetic chars are in order

C Programming UCSD Extension

© 1995 Philip J. Mercurio 261

522522 IntroductionIntroduction

CC More Character Operations

ä printf("%i\n", c); will print the ASCII valueof a charä printf("%i\n", 'a'); will print 97

ä printf("%c\n", 'a' + 1); would print bä We can use this to convert a digit into a numerical

valueä '0' is the value 48, '1' is 49, etcä '1' - '0' is 1, '7' - '0' is 7, etc.ä If c is one of the digit chars ('0', '1', ... '9'), c -'0' is its numerical value

ä We can use this to convert a string into an integer

523523 IntroductionIntroduction

CC Program 7-7

/* Function to convert a string into an integer */#include <stdio.h>

int stringToInteger(char string[]){

int i, value, result = 0;

for(i = 0; string[i] >= '0' && string[i] <= '9'; i++) {value = string[i] - '0';result = result * 10 + value;

}

return(result);}

main(){

int stringToInteger(char string[]);

printf("%i\n", stringToInteger("245"));printf("%i\n", stringToInteger("100") + 25);printf("%i\n", stringToInteger("13x5"));

}

C Programming UCSD Extension

© 1995 Philip J. Mercurio 262

524524 IntroductionIntroduction

CC Program 7-7 Output

24512513

525525 IntroductionIntroduction

CC Notes on Program 7-7

ä The for loop runs as long as the current characteris a digit

ä The value of each digit is gotten via string[i] -'0'

ä Multiplying result by 10 shifts all the digits to theleft

ä Adding value inserts the new rightmost digitä Improvements possible

ä Handling negative numbersä Reporting when the input contains no number at all

C Programming UCSD Extension

© 1995 Philip J. Mercurio 263

526526 IntroductionIntroduction

CC Counting Words

ä Let's create a program to count the number ofwords in a stringä A word will be defined as a string of one or more

alphabetic characters (a-z, A-Z)ä Words will be separated by any non-alphabetic character

ä countWords() will take the string as anargument, and return the number of words as anint

ä alphabetic() will take a char as an argumentand return true if it's an alphabetic character

527527 IntroductionIntroduction

CC Program 7-8

/* Count the words in strings */#include <stdio.h>

/* * Return true (1) if the char is alphabetic */int alphabetic(char c){

if( (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') )return(1);

elsereturn(0);

}

C Programming UCSD Extension

© 1995 Philip J. Mercurio 264

528528 IntroductionIntroduction

CC Program 7-8 (continued)

/* * Return the number of words in the string */int countWords(char string[]){

int i, lookingForWord = 1, wordCount = 0;int alphabetic(char c);

for(i = 0; string[i] != '\0'; i++)if(alphabetic(string[i])) {

if(lookingForWord) {wordCount++;lookingForWord = 0;

}}else

lookingForWord = 1;

return(wordCount);}

529529 IntroductionIntroduction

CC Program 7-8 & Output

main(){

char text1[] = "Well, here goes.";char text2[] = "And here we go... again.";int countWords(char string[]);

printf("%s\t<%d words>\n", text1, countWords(text1));printf("%s\t<%d words>\n", text2, countWords(text2));

}

Well, here goes. <3 words>And here we go... again. <5 words>

OutputOutput

C Programming UCSD Extension

© 1995 Philip J. Mercurio 265

530530 IntroductionIntroduction

CC Notes on Program 7-8

ä alphabetic() works because we know theASCII chars a-z and A-Z are in order

ä in countWords(), lookingForWord is a flag,initialized to trueä If true, we're looking for the beginning of a word (an

alphabetic char)ä If false, we're already in a word, and we're looking for the

end (any non-alphabetic char)

ä The for loop uses i as an index variable to scanthrough the string

531531 IntroductionIntroduction

CC countWords()

ä For each char in the stringä If it's alphabetic

ä If we're looking for a word, we just found oneä Increment the word countä Set lookingForWord to false

ä If we're not looking for a word, we're still in one, so donothing

ä If it's not alphabeticä Then we're looking for a word, set flag to true

C Programming UCSD Extension

© 1995 Philip J. Mercurio 266

532532 IntroductionIntroduction

CC Table of countWord() values

i string[i] count looking0 1

0 ‘W’ 1 01 ‘e’ 1 02 ‘l’ 1 03 ‘l’ 1 04 ‘,’ 1 15 ‘ ‘ 1 16 ‘h’ 2 07 ‘e’ 2 08 ‘r’ 2 09 ‘e’ 2 0

i string[i] count looking10 ‘ ‘ 2 111 ‘g’ 3 012 ‘o’ 3 013 ‘e’ 3 014 ‘s’ 3 015 ‘.’ 3 116 ‘\’0’ 3 1

533533 IntroductionIntroduction

CC The Null String

ä Let's combine 7-6 and 7-8 to produce a program tocount words in typed input

ä We need a way to know when the user hasstopped typing: the Null String

ä The null string contains nothing but the terminatorä It's a char array with the null in the first elementstring[0] = '\0';

C Programming UCSD Extension

© 1995 Philip J. Mercurio 267

534534 IntroductionIntroduction

CC The Null String (continued)

ä The null string constant is written with two doublequotes, nothing in betweenchar buffer[100] = "";

ä If you type a RETURN by itself to the readLine()function, it'll return the null string

535535 IntroductionIntroduction

CC Program 7-9/* Count the words in strings */#include <stdio.h>

main(){

char text[81];int endOfText = 0, totalWords = 0;int countWords(char string[]);void readLine(char buffer[]);

printf("Type in your text.\n");printf("When you are done, press <RETURN>.\n\n");

while(!endOfText) {readLine(text);

if(text[0] == '\0')endOfText = 1;

elsetotalWords += countWords(text);

}

printf("\nThere are %i words in the above text.\n",totalWords);

}

C Programming UCSD Extension

© 1995 Philip J. Mercurio 268

536536 IntroductionIntroduction

CC Program 7-9 (continued)

/* * Return true (1) if the char is alphabetic */int alphabetic(char c){

if( (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') )return(1);

elsereturn(0);

}

537537 IntroductionIntroduction

CC Program 7-9 (continued)

/* * Return the number of words in the string */int countWords(char string[]){

int i, lookingForWord = 1, wordCount = 0;int alphabetic(char c);

for(i = 0; string[i] != '\0'; i++)if(alphabetic(string[i])) {

if(lookingForWord) {wordCount++;lookingForWord = 0;

}}else

lookingForWord = 1;

return(wordCount);}

C Programming UCSD Extension

© 1995 Philip J. Mercurio 269

538538 IntroductionIntroduction

CC Program 7-9 (continued)

/* * Read a line of text, up to a newline. * The newline will not be in the buffer. */void readLine(char buffer[]){

char c;int i = 0;

do {c = getchar();buffer[i] = c;

i++;} while(c != '\n');

buffer[i - 1] = '\0';}

539539 IntroductionIntroduction

CC Program 7-9 Output

Type in your text.When you are done, press <RETURN>.

'Twas brillig, and the slithy tovesDid gyre and gimble in the wabe:All mimsy were the borogoves,And the mome raths outgrabe.

There are 23 words in the above text.

C Programming UCSD Extension

© 1995 Philip J. Mercurio 270

540540 IntroductionIntroduction

CC Notes on Program 7-9

ä while(!endOfText) ("while not endOfText") isthe same as while(endOfText != 0)ä ! is a unary operator which turns true to false and false

to trueä !endOfText is more readable

ä Loop is executed as long as endOfText is falseä endOfTest is set true when we encounter a null string

if(text[0] == '\0')

ä Otherwise, we count the words and add them tototalWords

541541 IntroductionIntroduction

CC Escape Codes

ä There are many escape codes like '\n':ä Backslash is called the escape character

Code Meaning\a audible alert\b backspace\f form feed\n newline\r carriage return\t horizontal tab\v vertical tab

Code Meaning\\ backslash\” double quote\’ single quote\? question mark\nnn octal value nnn\xnn hex value nn

C Programming UCSD Extension

© 1995 Philip J. Mercurio 271

542542 IntroductionIntroduction

CC Using Escape Codes

printf("\aDanger! Danger!!!\n");

ä Will ring the bell and print the text, on most machinesä If no bell, at least the text will be printed

printf("This is the symbol for null:0\b/\n");ä You can use \b to backspace over a characterä Used for doing overstriking on a printer, not that useful

otherwiseprintf("%i\t%i\t%i\n", a, b, c);

ä Displays 3 numbers with tabs in between

543543 IntroductionIntroduction

CC More Escape Codes

printf("\\t is the horizontal tabcharacter\n");ä Use \\ to print one backslash

ä printf("\"Hello\", he said.\n"); prints"Hello", he said.

ä You need to escape double quotes inside strings

char c = '\'';ä Assigns a single quote char to c

ä \? has to do with trigraphs, see PAC Appendix A

C Programming UCSD Extension

© 1995 Philip J. Mercurio 272

544544 IntroductionIntroduction

CC Numerical Characters

ä The exact 8-bit value of a character can beexpressedä Use \nnn to express it in octalä Use \xnn to express it in hexadecimal

ä For example, the ASCII escape code, octal 33:ä '\033' orä '\x1B'

545545 IntroductionIntroduction

CC Back to Null

ä We've already been using '\0' to express theASCII null

ä Since this is the numerical value 0, a lot of codedealing with strings will use something likeä if(string[count]) rather than if(string[count]!= '\0')

ä Remember that all escape codes translate to only1 character in the string

C Programming UCSD Extension

© 1995 Philip J. Mercurio 273

546546 IntroductionIntroduction

CC Continuing Strings

ä A string can be continued by putting a \ at the veryend of the line

ä Any leading spaces on the next line get included inthe string!

char letters[] ={"abcdefghijklmnopqrstuvwxyz\

ABCDEFGHIJKLMNOPQRSTUVWXYZ"};

547547 IntroductionIntroduction

CC Continuing Strings (continued)

ä You can also split it up into more than one stringchar letters[] ={"abcdefghijklmnopqrstuvwxyz""ABCDEFGHIJKLMNOPQRSTUVWXYZ"};

ä Adjacent strings with no intervening punctuation(except spaces, tabs, or newlines) areconcatenated into one string by the compilerä Not in K&R, ANSI only

C Programming UCSD Extension

© 1995 Philip J. Mercurio 274

548548 IntroductionIntroduction

CC Strings, Structures, and Arrays

ä Let's write a dictionary programä We'll type in a word, and it will reply with its definition

ä We'll need to represent an entry in the dictionary:ä struct entry {

ächar word[10];

ächar definition[50];

ä };

ä Each entry holds two strings, a word and its definitionä struct entry word1 = {"blob", "anamorphous mass"};

ä struct entry dictionary[100];

549549 IntroductionIntroduction

CC lookup()

ä We'll need a function to look up an entry in thedictionary

ä If we find the entry, return the entry number (indexinto dictionary[])

ä Otherwise, return -1ä We'll pass the dictionary array, the search string,

and the number of entries in the dictionary asargumentsWe'll borrow equalStrings() from Prog7-4 forcomparing strings

C Programming UCSD Extension

© 1995 Philip J. Mercurio 275

550550 IntroductionIntroduction

CC Program 7-10

/* Dictionary lookup program */#include <stdio.h>

/* * The structure of one entry in the dictionary */struct entry {

char word[10];char definition[50];

};

551551 IntroductionIntroduction

CC Program 7-10 (continued)

/* * Return true if two strings are equal */int equalStrings(char s1[], char s2[]){

int i = 0;

/* Step thru the strings matching pairs */while(s1[i] == s2[i] && s1[i] != '\0' && s2[i] != '\0')

i++;

/* If we're at the end of both strings, they match */if(s1[i] == '\0' && s2[i] == '\0')

return(1);else

return(0);}

C Programming UCSD Extension

© 1995 Philip J. Mercurio 276

552552 IntroductionIntroduction

CC Program 7-10 (continued)

/* * Return the index of a word in the dictionary, or * -1 if it's not found */int lookup(struct entry dictionary[], char search[],

int entries){

int i, equalStrings(char s1[], char s2[]);

for(i = 0; i < entries; i++)if(equalStrings(search,dictionary[i].word))

return(i);

return(-1);}

553553 IntroductionIntroduction

CC Program 7-10 (continued)

main(){

struct entry dictionary[100] = {{"aardvark", "a burrowing African mammal"},{"abyss", "a bottomless pit"},{"acumen", "mentally sharp, keen"},{"addle", "to become confused"},{"aerie", "a high nest"},{"affix", "to append; attach"},{"agar", "a jelly made from seaweed"},{"ahoy", "a nautical call of greeting"},{"aigrette", "an ornamental cluster"

" of feathers"},{"ajar", "partially opened"} };

C Programming UCSD Extension

© 1995 Philip J. Mercurio 277

554554 IntroductionIntroduction

CC Program 7-10 & Output

char word[10];int entries = 10;int entryNumber;int lookup(struct entry d[], char s[], int e);

printf("Enter word: ");scanf("%9s", word);entryNumber = lookup(dictionary, word, entries);

if(entryNumber != -1)printf("%s\n", dictionary[entryNumber].definition);

elseprintf("Sorry, I don't know that word\n");

}

Enter word: agara jelly made from seaweed

OutputOutput

555555 IntroductionIntroduction

CC Notes on Program 7-10

ä lookup() steps through each entry in thedictionary, comparing that entry's .word fieldagainst the search stringä When it finds a match, it returns the index

ä If we make it out of the for loop without returning,we must not have matchedä We return -1 to indicate no match

C Programming UCSD Extension

© 1995 Philip J. Mercurio 278

556556 IntroductionIntroduction

CC Better Searching

ä lookup() is inefficient, in that it looks at everyentry in the dictionary every time

ä Because our dictionary is sorted alphabetically, wecan optimize the searching

ä One optimization would be to quit when we go toofar in the dictionaryä When searching for "active", we can stop when we come

to a dictionary entry that would come after it, like"acumen"

ä This only helps a little, and only with words not in thedictionary

557557 IntroductionIntroduction

CC Binary Searching

ä Binary searching works by picking the word in themiddle of the dictionary and comparing it againstthe search stringä We then narrow our search to either the lower or higher

half of the dictionaryä Repeat until we find it

ä Analogous example: guessing a number between1 and 99ä For each guess, I'll tell you if you're correct, too high, or

too low

C Programming UCSD Extension

© 1995 Philip J. Mercurio 279

558558 IntroductionIntroduction

CC Binary Search Algorithm

ä Searching for x in array M, size n:ä Step 1: Set low to 0, high to n - 1ä Step 2: If low > high, x is not in M at all; we're

doneä Step 3: Set mid to (low + high) / 2ä Step 4: If M[mid] == x, return mid, we're doneä Step 5: If M[mid] < x, set low to mid + 1 and

go to Step 2ä Step 6: If M[mid] > x, set high to mid - 1 and

go to Step 2

559559 IntroductionIntroduction

CC compareStrings()

ä To implement a binary search in lookup(), we'llneed a function like equalStrings(), but whichalso tells if we're too high or low

ä int compareStrings(char s1[], chars2[]) returnsä -1 if s1 precedes s2 lexicographicallyä 0 if s1 and s2 matchä +1 if s1 follows s2 lexicographically

ä compareStrings("alpha", "beta") returns -1ä compareStrings("zeta", "gamma") returns 1

C Programming UCSD Extension

© 1995 Philip J. Mercurio 280

560560 IntroductionIntroduction

CC More compareStrings()

ä compareStrings() has the same exact whileloop as equalStrings()

ä When the loop is doneä If s1[i] < s2[i], then s1 precedes s2, return -1ä If s1[i] == s2[i] then s1 equals s2, return 0ä Otherwise, s1 follows s2, return 1

ä What if s1 is the prefix of s2? ("foo" and"foobar")ä At the end of the loop, s1[i] will be '\0', and s2[i]

will be 'b'ä Since null is less than any other value, -1 will be

returned

561561 IntroductionIntroduction

CC Program 7-11

/* Dictionary lookup program, binary sort */#include <stdio.h>

/* * The structure of one entry in the dictionary */struct entry {

char word[10];char definition[50];

};

C Programming UCSD Extension

© 1995 Philip J. Mercurio 281

562562 IntroductionIntroduction

CC Program 7-11 (continued)

/* * Compare two strings, returning -1 if s1 precedes s2, * 0 if they're equal, and 1 if s1 follows s2 */int compareStrings(char s1[], char s2[]){

int i = 0;

/* Step thru the strings matching pairs */while(s1[i] == s2[i] && s1[i] != '\0' && s2[i] != '\0')

i++;

if(s1[i] < s2[i]) /* s1 < s2 */return(-1);

else if(s1[i] == s2[i]) /* s1 == s2 */return(0);

else /* s1 > s2 */return(1);

}

563563 IntroductionIntroduction

CC Program 7-11 (continued)

/* * Return the index of a word in the dictionary, or * -1 if it's not found. * * Binary search version */int lookup(struct entry dictionary[], char search[],

int entries){

int low = 0;int high = entries - 1;int mid, result;int compareStrings(char s1[], char s2[]);

while(low <= high) {mid = (low + high) / 2;result = compareStrings(dictionary[mid].word,

search);

C Programming UCSD Extension

© 1995 Philip J. Mercurio 282

564564 IntroductionIntroduction

CC Program 7-11 (continued)

switch(result) {case -1:

low = mid + 1;break;

case 1:high = mid - 1;break;

case 0: /* found it! */return(mid);

}}

return(-1); /* not found */}

565565 IntroductionIntroduction

CC Program 7-11 (continued)

main(){

struct entry dictionary[100] = {{"aardvark", "a burrowing African mammal"},{"abyss", "a bottomless pit"},{"acumen", "mentally sharp, keen"},{"addle", "to become confused"},{"aerie", "a high nest"},{"affix", "to append; attach"},{"agar", "a jelly made from seaweed"},{"ahoy", "a nautical call of greeting"},{"aigrette", "an ornamental cluster"

" of feathers"},{"ajar", "partially opened"} };

C Programming UCSD Extension

© 1995 Philip J. Mercurio 283

566566 IntroductionIntroduction

CC Program 7-11 (continued)

char word[10];int entries = 10;int entryNumber;int lookup(struct entry d[], char s[], int e);

printf("Enter word: ");scanf("%9s", word);entryNumber = lookup(dictionary, word, entries);

if(entryNumber != -1)printf("%s\n",dictionary[entryNumber].definition);

elseprintf("Sorry, I don't know that word\n");

}

567567 IntroductionIntroduction

CC Program 7-11 Output

Enter word: aigrettean ornamental cluster of feathers

Enter word: acerbSorry, I don't know that word

C Programming UCSD Extension

© 1995 Philip J. Mercurio 284

568568 IntroductionIntroduction

CC Notes on Program 7-11

ä Reintroduction of the switch statementä Shows the structure of the algorithm (one of three

different things done each step through the loop,depending on result) better than if-elses would

ä Note that main() is identical to the version inprog7-10ä As long as lookup() takes the same arguments and

returns an int we can change the internal algorithm asmuch as we want

ä We started with a cheap prototype then improved it

569569 IntroductionIntroduction

CC Standard String Library

ä The ANSI standard includes a library of functionsto deal with variable length strings

ä To use this library, we have to add #include<string.h> to the beginning of our file

ä Most of the functions we've just written are alreadyin the string library

ä Important string library functions are listed inAppendix B

ä Sneak Preview: char *string; is another wayof saying char string[];

C Programming UCSD Extension

© 1995 Philip J. Mercurio 285

570570 IntroductionIntroduction

CC #include <string.h>

int strlen(char *s)ä Returns the length of s, excluding the null

char *strcpy(char *s1, char *s2)ä Copies s2 to s1, returning s1

char *strncpy(char *s1, char *s2, int n)ä Copies no more than n chars from s2 to s1, returns s1

571571 IntroductionIntroduction

CC More #include <string.h>

char *strcat(char *s1, char *s2)ä Concatenates s2 onto the end of s1, returns s1

char *strncat(char *s1, char *s2, int n)ä Like strcat(), but copies no more than n chars froms2

int strcmp(char *s1, char *s2)ä Compares s1 and s2, returns same ascompareStrings()

int strncmp(char *s1, char *s2, int n)ä Like strcmp(), but only compares first n characters

C Programming UCSD Extension

© 1995 Philip J. Mercurio 286

572572 IntroductionIntroduction

CC More #include <string.h>

char *strchr(char *s, char c)ä Searches for the first char c in the string s. If found,

returns a pointer to where c is in s, else returns null

char *strrchr(char *s, char c)ä Same as strchr(), but searches from the end of the

string backwards

char *strstr(char *s1, char *s2)ä Searches s1 for the first occurrence of s2. If found,

returns a pointer to where s2 begins in s1, else returnsnull

573573 IntroductionIntroduction

CC Exercises due next session

ä Read: Chapter 10ä Exercises: Chapter 10

ä 2, 3, 4, 5, 6, 7, 8, 12 (use doubles)ä You can combine all the functions into one program, with

a main() to test themä Note: in the answer to 10-5 (PAC Appendix F),foundit needs to be initialized to 0

C Programming UCSD Extension

© 1995 Philip J. Mercurio 287

574574 IntroductionIntroduction

CC

C Programming

PointersPhil Mercurio

UCSD [email protected]

575575 IntroductionIntroduction

CC Today's Session

ä Pointers [Chapter 11]ä Pointers & Structuresä Pointers & Functionsä Pointers & Arraysä Operations on Pointersä Pointers to Functionsä Pointers & Memory Addresses

C Programming UCSD Extension

© 1995 Philip J. Mercurio 288

576576 IntroductionIntroduction

CC Pointers

ä Every location in memory has a numerical addressä On a 32-bit computer, there are 232 (~4 billion) memory

locations, each of which stores a byte

ä By storing, in memory, the address of anotherlocation in memory, we can access that secondlocation indirectly

0000 0202 0707 0909080806060505040403030101

104576342

223232-1-1

4

223232-2-2223232-3-3223232-4-4223232-5-5223232-6-6223232-7-7223232-8-8223232-9-9223232-10-10

577577 IntroductionIntroduction

CC Example of Indirection

ä Let's say you're planning to get a group of friendstogether to eat in Old Town tomorrow night

ä Jane knows of a great restaurant, but she can'tremember the name or where it isä She can find out by tomorrow night, though

ä Everyone knows where the Old Town MexicanCafe is

ä You plan to meet at the Cafe, from there you'll walkto the other restaurant

C Programming UCSD Extension

© 1995 Philip J. Mercurio 289

578578 IntroductionIntroduction

CC Indirection continued

ä You've specified the location of the greatrestaurant indirectly, by "storing" that location atthe Cafe (in Jane's head)

ä The Cafe is a pointer to the other restaurantä This example shows a little of why we use pointers

ä It has a lot to do with sharing information (amongdifferent parts of your program)

ä and dealing with information that will be filled in at a latertime

579579 IntroductionIntroduction

CC Variables & Pointers

ä Low-level languages deal only with addresses, andcan do indirection easily

ä High-level languages deal with variables, namesfor locations in memoryä This protects us from addresses, but makes indirection

impossible

ä C bridges the gap by still providing variables, and:ä A way of declaring a pointer: a variable that will contain

an addressä An operator to get the value at an address (pointer)ä An operator to get the address represented by a variable

C Programming UCSD Extension

© 1995 Philip J. Mercurio 290

580580 IntroductionIntroduction

CC Pointers

int count = 10;ä Declares an integer called count, and initializes it to 10

int *intPtr;ä Declares a variable called intPtr, of type pointer toint

ä C now knows that intPtr is a pointer (stores a locationin memory)

ä It also knows that what type of data to expect at thatlocation in memory

ä Because C pointers have a type associated withthem, they are much more powerful thanaddresses in assembly language

581581 IntroductionIntroduction

CC More Pointers

ä All pointer variables are the same size (32 bits on a32-bit OS), regardless of what type they'repointing to

ä & is the address operatorä intPtr = &count; stores the address of count in the

pointer intPtr

ä * is the indirection operatorä int x = *intPtr; takes the address in intPtr, gets

the value stored there, and copies that value into x

C Programming UCSD Extension

© 1995 Philip J. Mercurio 291

582582 IntroductionIntroduction

CC Program 8-1 & Output

/* Program to illustrate pointers */#include <stdio.h>

main(){

int x, count = 10;int *intPtr;

intPtr = &count;x = *intPtr;

printf("count = %i, x = %i\n", count, x);}

count = 10, x = 10

OutputOutput

583583 IntroductionIntroduction

CC Program 8-1 Animation #1

int x x

C Programming UCSD Extension

© 1995 Philip J. Mercurio 292

584584 IntroductionIntroduction

CC Program 8-1 Animation #2

int x,count = 10;

10

count

x

585585 IntroductionIntroduction

CC Program 8-1 Animation #3

int x,count = 10;

int *intPtr;

10

count

intPtr

x

C Programming UCSD Extension

© 1995 Philip J. Mercurio 293

586586 IntroductionIntroduction

CC Program 8-1 Animation #4

int x,count = 10;

int *intPtr;

intPtr = &count;

10

count

&count

intPtr

x

587587 IntroductionIntroduction

CC Program 8-1 Animation #5

int x,count = 10;

int *intPtr;

intPtr = &count;

x = *intPtr;

10

count

&count

intPtr

x

C Programming UCSD Extension

© 1995 Philip J. Mercurio 294

588588 IntroductionIntroduction

CC Program 8-1 Animation #6

int x,count = 10;

int *intPtr;

intPtr = &count;

x = *intPtr;

10

10

count

&count

intPtr

x

589589 IntroductionIntroduction

CC Notes on Program 8-1

int x, count = 10, *intPtr;

ä Another valid way to do declarations

ä intPtr is of type pointer to intä *intPtr is of type intä x = *intPtr; copies that int to x

C Programming UCSD Extension

© 1995 Philip J. Mercurio 295

590590 IntroductionIntroduction

CC Program 8-2 & Output

/* Program to further illustrate pointers */#include <stdio.h>

main(){

char c = 'Q';char *charPtr = &c;

printf("%c %c\n", c, *charPtr);

c = '/';printf("%c %c\n", c, *charPtr);

*charPtr = '(';printf("%c %c\n", c, *charPtr);

}

Q Q/ /( (

OutputOutput

591591 IntroductionIntroduction

CC Program 8-2 Animation #1

char c = 'Q';

Q

c

C Programming UCSD Extension

© 1995 Philip J. Mercurio 296

592592 IntroductionIntroduction

CC Program 8-2 Animation #2

char c = 'Q';

char *charPtr = &c;

Q

c

&c

charPtr

593593 IntroductionIntroduction

CC Program 8-2 Animation #3

char c = 'Q';

char *charPtr = &c;

c = '/';

/

c

&c

charPtr

/

C Programming UCSD Extension

© 1995 Philip J. Mercurio 297

594594 IntroductionIntroduction

CC Program 8-2 Animation #4

char c = 'Q';

char *charPtr = &c;

c = '/';

*charPtr = '(';(

c

&c

(

charPtr

595595 IntroductionIntroduction

CC Notes on Program 8-2

ä Once c has been defined, it's OK to use it in apointer initialization

ä char *charPtr = &c; is the same asä char *charPtr;

ä charPtr = &c;

ä Not the same as:ä *charPtr = &c;

ä This expression has a char * on the right and a charon the left, not valid

ä The value of a pointer is meaningless until it is setto something

C Programming UCSD Extension

© 1995 Philip J. Mercurio 298

596596 IntroductionIntroduction

CC More Notes on Program 8-2

ä As long as charPtr contains the address of c:ä c and *charPtr are two different ways of

referring to the same byte in memoryä printf("%c %c\n, c, *charPtr); prints that byte

twiceä c = '/'; and *charPtr = '('; each store a

character in that byte

597597 IntroductionIntroduction

CC Program 8-3 & Output

/* More pointers */#include <stdio.h>

main(){

int i1, i2;int *p1, *p2;

i1 = 5;p1 = &i1;

i2 = *p1 / 2 + 10;p2 = p1;

printf("i1 = %i, i2 = %i, *p1 = %i, *p2 = %i\n",i1, i2, *p1, *p2);

}

i1 = 5, i2 = 12, *p1 = 5, *p2 = 5

OutputOutput

C Programming UCSD Extension

© 1995 Philip J. Mercurio 299

598598 IntroductionIntroduction

CC Notes on Program 8-3

ä p1 = &i1; sets p1 to point to i1ä i2 = *p1 / 2 + 10; retrieves the value at *p1

(5) and uses it in the expressionä * has higher precedence than division, no parens

neededä Since *p1 is an int, integer division is performedä Identical to using i1 in this expression

ä p2 = p1; sets p2 to point to the same thing p1points toä Both contain &i1ä *p2 == *p1 == i1 == 5

599599 IntroductionIntroduction

CC Pointers and Structures

ä Pointers can be declared to point to any primitivedata typeä chars, ints, floats, doubles, etc.

ä Pointers can also point to user-defined structuresstruct date {

int month, day, year;

};

ä struct date today; creates a date structurecalled today

ä struct date *datePtr; creates a pointer to adate structure

C Programming UCSD Extension

© 1995 Philip J. Mercurio 300

600600 IntroductionIntroduction

CC More Pointers and Structures

ä datePtr = &today; sets datePtr to point totoday

ä *datePtr is now another way of saying todayä (*datePtr).day = 21; sets today's day field

to 21ä Note that . has higher precedence than *ä We need the parens

ä datePtr->day = 21; another way of saying thesame thingä -> is the pointer operatorä x->y is the same as (*x).y

601601 IntroductionIntroduction

CC Program 8-4 & Output

/* Structure pointers */#include <stdio.h>

main(){

struct date {int month, day, year;

} today, *datePtr;

datePtr = &today;datePtr->month = 8;datePtr->day = 30;datePtr->year = 1995;

printf("Today's date is %i/%i/%i.\n",datePtr->month, datePtr->day, datePtr->year%100);

}

Today's date is 8/30/95.

OutputOutput

C Programming UCSD Extension

© 1995 Philip J. Mercurio 301

602602 IntroductionIntroduction

CCdate

Program 8-4 Animation #1

struct date { int month, day, year; };

.month

.day

.year

603603 IntroductionIntroduction

CCdate

Program 8-4 Animation #2

struct date { int month, day, year; };

struct date today; today

.month

.day

.year

C Programming UCSD Extension

© 1995 Philip J. Mercurio 302

604604 IntroductionIntroduction

CCdate

Program 8-4 Animation #3

struct date { int month, day, year; };

struct date today;

struct date *datePtr;

today

datePtr

.month

.day

.year

605605 IntroductionIntroduction

CC Program 8-4 Animation #4

struct date { int month, day, year; };

struct date today;

struct date *datePtr;

datePtr = &today;

&today

datePtr

datetoday

.month

.day

.year

C Programming UCSD Extension

© 1995 Philip J. Mercurio 303

606606 IntroductionIntroduction

CCdate

Program 8-4 Animation #5

struct date { int month, day, year; };

struct date today;

struct date *datePtr;

datePtr = &today;

today

&today

datePtr

.month

.day

.yeardatePtr->month = 8;

8

607607 IntroductionIntroduction

CCdate

Program 8-4 Animation #6

struct date { int month, day, year; };

struct date today;

struct date *datePtr;

datePtr = &today;

today

&today

datePtr

.month

.day

.yeardatePtr->month = 8;

datePtr->day = 30;

830

C Programming UCSD Extension

© 1995 Philip J. Mercurio 304

608608 IntroductionIntroduction

CCdate

Program 8-4 Animation #7

struct date { int month, day, year; };

struct date today;

struct date *datePtr;

datePtr = &today;

today

&today

datePtr

.month

.day

.yeardatePtr->month = 8;

datePtr->day = 30;

datePtr->year = 1995;

830

1995

609609 IntroductionIntroduction

CC Notes on Program 8-4

ä A structure can be thought of as a framework forviewing an area of memory

ä Declaring a pointer to the structure dateä Creates a pointer-sized (32 bits) variable in memoryä Tells the compiler that the memory following this pointer

will be viewed as a date: 3 ints in the order .month,.day, and .year

C Programming UCSD Extension

© 1995 Philip J. Mercurio 305

610610 IntroductionIntroduction

CC Structures Containing Pointers

ä Structures can contain pointersstruct intPointers {

int *p1, *p2;

};

ä Defines a structure containing two pointers to intsstruct intPointers pointers;

ä Creates an intPointers structure: two pointersto ints

611611 IntroductionIntroduction

CC Program 8-5

/* Structures containing pointers */#include <stdio.h>

main(){

struct intPointers {int *p1;int *p2;

};

struct intPointers pointers;int i1 = 100, i2;

pointers.p1 = &i1;pointers.p2 = &i2;*pointers.p2 = -97;

printf("i1 = %i, *pointers.p1 = %i\n", i1,*pointers.p1);

printf("i2 = %i, *pointers.p2 = %i\n", i2,*pointers.p2);

}

C Programming UCSD Extension

© 1995 Philip J. Mercurio 306

612612 IntroductionIntroduction

CC Program 8-5 Output

i1 = 100, *pointers.p1 = 100i2 = -97, *pointers.p2 = -97

613613 IntroductionIntroduction

CC

.p2

intPointers

Program 8-5 Animation #1

struct intPointers { int *p1, *p2; };

.p1

C Programming UCSD Extension

© 1995 Philip J. Mercurio 307

614614 IntroductionIntroduction

CC

.p2

intPointers

Program 8-5 Animation #2

struct intPointers { int *p1, *p2; };

struct intPointers pointers;pointers

.p1

615615 IntroductionIntroduction

CC

.p2

intPointers

Program 8-5 Animation #3

struct intPointers { int *p1, *p2; };

struct intPointers pointers;

int i1 = 100, i2;pointers

.p1

i2

100

i1

C Programming UCSD Extension

© 1995 Philip J. Mercurio 308

616616 IntroductionIntroduction

CC

.p2

intPointers

Program 8-5 Animation #4

struct intPointers { int *p1, *p2; };

struct intPointers pointers;

int i1 = 100, i2;

pointers.p1 = &i1;

pointers

.p1 &i1

i2

100

i1

617617 IntroductionIntroduction

CC

.p2

intPointers

Program 8-5 Animation #5

struct intPointers { int *p1, *p2; };

struct intPointers pointers;

int i1 = 100, i2;

pointers.p1 = &i1;

pointers

.p1

pointers.p2 = &i2

&i1&i2

i2

100

i1

C Programming UCSD Extension

© 1995 Philip J. Mercurio 309

618618 IntroductionIntroduction

CC

.p2

intPointers

Program 8-5 Animation #6

struct intPointers { int *p1, *p2; };

struct intPointers pointers;

int i1 = 100, i2;

pointers.p1 = &i1;

pointers

-97

.p1

pointers.p2 = &i2

*pointers.p2 = -97;

&i1&i2

i2

100

i1

619619 IntroductionIntroduction

CC Linked Lists

ä We can combine structures and pointers to createsophisticated data structures like linked lists,doubly-linked lists, and trees

struct entry {int value;

struct entry *next;

};

ä Defines a structure entry containingä An integerä A pointer to another entry structure

C Programming UCSD Extension

© 1995 Philip J. Mercurio 310

620620 IntroductionIntroduction

CC Linked List Diagram

struct entry {

int value;

struct entry *next;

};

.next

entry

.value

621621 IntroductionIntroduction

CC Program 8-6/* Linked List traversal */#include <stdio.h>

main(){

struct entry {int value;struct entry *next;

};

struct entry n1, n2, n3;

n1.value = 100;n2.value = 200;n3.value = 300;

n1.next = &n2;n2.next = &n3;n3.next = 0;

printf("%i %i %i\n",n1.value,n1.next->value,n1.next->next->value);

}

C Programming UCSD Extension

© 1995 Philip J. Mercurio 311

622622 IntroductionIntroduction

CC Program 8-6 Output

100 200 300

623623 IntroductionIntroduction

CC Program 8-6 Animation #1

struct entry n1

.next

entry

.value

n1

C Programming UCSD Extension

© 1995 Philip J. Mercurio 312

624624 IntroductionIntroduction

CC Program 8-6 Animation #2

struct entry n1, n2

.next

entry

.value

n1

.next

entry

.value

n2

625625 IntroductionIntroduction

CC Program 8-6 Animation #3

struct entry n1, n2, n3;

.next

entry

.value

n1

.next

entry

.value

n2

.next

entry

.value

n3

C Programming UCSD Extension

© 1995 Philip J. Mercurio 313

626626 IntroductionIntroduction

CC Program 8-6 Animation #4

struct entry n1, n2, n3;

n1.value = 100;.next

entry

.value 100

n1

.next

entry

.value

n2

.next

entry

.value

n3

627627 IntroductionIntroduction

CC Program 8-6 Animation #5

struct entry n1, n2, n3;

n1.value = 100;

n2.value = 200;.next

entry

.value 100

n1

.next

entry

.value 200

n2

.next

entry

.value

n3

C Programming UCSD Extension

© 1995 Philip J. Mercurio 314

628628 IntroductionIntroduction

CC Program 8-6 Animation #6

struct entry n1, n2, n3;

n1.value = 100;

n2.value = 200;

n3.value = 300;

.next

entry

.value 100

n1

.next

entry

.value 200

n2

.next

entry

.value 300

n3

629629 IntroductionIntroduction

CC Program 8-6 Animation #7

struct entry n1, n2, n3;

n1.value = 100;

n2.value = 200;

n3.value = 300;

.next

entry

.value 100

&n2

n1

.next

entry

.value 200

n2

.next

entry

.value 300

n3

n1.next = &n2;

C Programming UCSD Extension

© 1995 Philip J. Mercurio 315

630630 IntroductionIntroduction

CC Program 8-6 Animation #8

struct entry n1, n2, n3;

n1.value = 100;

n2.value = 200;

n3.value = 300;

.next

entry

.value 100

&n2

n1

.next

entry

.value 200

&n3

n2

.next

entry

.value 300

n3

n1.next = &n2;

n2.next = &n3;

631631 IntroductionIntroduction

CC Program 8-6 Animation #9

struct entry n1, n2, n3;

n1.value = 100;

n2.value = 200;

n3.value = 300;

.next

entry

.value 100

&n2

n1

.next

entry

.value 200

&n3

n2

.next

entry

.value 300

0

n3

n1.next = &n2;

n2.next = &n3;

n3.next = 0;

C Programming UCSD Extension

© 1995 Philip J. Mercurio 316

632632 IntroductionIntroduction

CC Notes on Program 8-6

ä Note that the entry structure refers to itselfä A structure can't contain a copy of itselfä But it can contain a pointer to itself

ä Each entry points to its successorn1.next = &n2;

n2.next = &n3;

n3.next = 0; (no successor)

633633 IntroductionIntroduction

CC More Notes on Program 8-6

ä n1->value refers to the value in the first entryä n1.next->value is the value in the successor

ä (n1.next)->value . and -> have same precedence,evaluated left-to-right

ä Same as n2->value

ä n1.next->next->value is the third value

C Programming UCSD Extension

© 1995 Philip J. Mercurio 317

634634 IntroductionIntroduction

CC Editing Linked Lists

ä Linked lists make it easy to add or remove itemsfrom the listä With arrays you have to copy elements to make holes to

add new elements, or to fill in holes left by removingelements

ä By moving pointers around in a linked list, you canä Insert new elements between two existing elementsä Delete an element and join the preceding and following

elements to each other

635635 IntroductionIntroduction

CC Deletion

n1.next = &n3;

ä To remove an entry (n2) from the linked listä Make the entry before (n1) point to the entry after (n3)

ä n1.next = n1.next->next;

ä Expresses the same thing, but from the point of view ofn1

ä Points n1 at the entry following the one it was pointingto

C Programming UCSD Extension

© 1995 Philip J. Mercurio 318

636636 IntroductionIntroduction

CC Deletion: Before

n1.next = &n3;

.next

entry

.value 100

&n2

n1

.next

entry

.value 200

&n3

n2

.next

entry

.value 300

0

n3

100 200 300

n1.next = n1.next->next;

637637 IntroductionIntroduction

CC Deletion: After

n1.next = &n3;

.next

entry

.value 100

&n3

n1

.next

entry

.value 200

&n3

n2

.next

entry

.value 300

0

n3

100 300

n1.next = n1.next->next;

C Programming UCSD Extension

© 1995 Philip J. Mercurio 319

638638 IntroductionIntroduction

CC Insertion

n4.next = n2.next;

n2.next = &n4;

ä To insert n4 after n2ä Note that these have to be done in this order!

639639 IntroductionIntroduction

CC Insertion: Before

n4.next = n2.next;

.next

entry

.value 100

&n2

n1

.next

entry

.value 200

&n3

n2

.next

entry

.value 300

0

n3

100 200 300

n2.next = &n4;

.next

entry

.value 250

n4

C Programming UCSD Extension

© 1995 Philip J. Mercurio 320

640640 IntroductionIntroduction

CC Insertion: During

n4.next = n2.next;

.next

entry

.value 100

&n2

n1

.next

entry

.value 200

&n3

n2

.next

entry

.value 300

0

n3

100 200 300

n2.next = &n4;

.next

entry

.value 250

&n3

n4

641641 IntroductionIntroduction

CC Insertion: After

n4.next = n2.next;

.next

entry

.value 100

&n2

n1

.next

entry

.value 200

&n4

n2

.next

entry

.value 300

0

n3

100 200 250 300

n2.next = &n4;

.next

entry

.value 250

&n3

n4

C Programming UCSD Extension

© 1995 Philip J. Mercurio 321

642642 IntroductionIntroduction

CC List Pointers

ä To fully deal with lists, we need toä struct entry *head; keep a pointer to the firstentry (the head of the list)

ä struct entry *ptr, *p, *q; declare one ormore pointers to be used when processing the list(usually very short names)

ä n3.next = 0; use null (0) to terminate the list

643643 IntroductionIntroduction

CC Program 8-7/* Linked List traversal */#include <stdio.h>

main(){

struct entry {int value;struct entry *next;

};

struct entry n1, n2, n3; struct entry *head; struct entry *p;

/* Fill the list with values */n1.value = 100;n2.value = 200;n3.value = 300;

C Programming UCSD Extension

© 1995 Philip J. Mercurio 322

644644 IntroductionIntroduction

CC Program 8-7 & Output/* Sew up the list */head = &n1;n1.next = &n2;n2.next = &n3;n3.next = 0;

/* Traverse the list */ for(p = head; p != 0; p = p->next)

printf("%i\n", p->value);}

100200300

OutputOutput

645645 IntroductionIntroduction

CC Program 8-7 Animation #1

.next

entry

.value 100

&n2

n1

.next

entry

.value 200

&n3

n2

.next

entry

.value 300

0

n3

p

head

C Programming UCSD Extension

© 1995 Philip J. Mercurio 323

646646 IntroductionIntroduction

CC Program 8-7 Animation #2

.next

entry

.value 100

&n2

n1

.next

entry

.value 200

&n3

n2

.next

entry

.value 300

0

n3

p

&n1

head

647647 IntroductionIntroduction

CC Program 8-7 Animation #3

.next

entry

.value 100

&n2

n1

.next

entry

.value 200

&n3

n2

.next

entry

.value 300

0

n3

&n1

p

&n1

head

C Programming UCSD Extension

© 1995 Philip J. Mercurio 324

648648 IntroductionIntroduction

CC Program 8-7 Animation #4

.next

entry

.value 100

&n2

n1

.next

entry

.value 200

&n3

n2

.next

entry

.value 300

0

n3

100

&n1

p

&n1

head

649649 IntroductionIntroduction

CC Program 8-7 Animation #5

.next

entry

.value 100

&n2

n1

.next

entry

.value 200

&n3

n2

.next

entry

.value 300

0

n3

100 200

&n2

p

&n1

head

C Programming UCSD Extension

© 1995 Philip J. Mercurio 325

650650 IntroductionIntroduction

CC Program 8-7 Animation #6

.next

entry

.value 100

&n2

n1

.next

entry

.value 200

&n3

n2

.next

entry

.value 300

0

n3

100 200 300

&n3

p

&n1

head

651651 IntroductionIntroduction

CC Program 8-7 Animation #7

.next

entry

.value 100

&n2

n1

.next

entry

.value 200

&n3

n2

.next

entry

.value 300

0

n3

100 200 300

0

p

&n1

head

C Programming UCSD Extension

© 1995 Philip J. Mercurio 326

652652 IntroductionIntroduction

CC Notes on Program 8-7

ä p = p->next inches p ahead onto the next link inthe chain

for(p = head; p != 0; p = p->next)

ä A very common idiom for stepping through a linked listä Shows off the for statement nicely

ä Null terminating a linked list is as important as nullterminating a stringä Otherwise you fall off the end

653653 IntroductionIntroduction

CC Pointers and Functions

ä Pointers can be passed as function arguments andreturned as function return values

ä printList(p); calls a function on the pointer pfrom Program 8-7

void printList(struct entry *ptr)

{

...

}

ä Declares such a function

C Programming UCSD Extension

© 1995 Philip J. Mercurio 327

654654 IntroductionIntroduction

CC Changing Arguments

ä Just like any other primitive or user-defined datatype, pointers are copied when passed as anargument to a function

ä The function can't modify an argument, even if it'sa pointer

ä BUT it can use the pointer to modify the thing itpoints to

655655 IntroductionIntroduction

CC Program 8-8 & Output/* Pointers and functions */#include <stdio.h>

void test(int *ptr){

*ptr = 100;}

main(){

void test(int *ptr);int i = 50, *p = &i;

printf("i before the call to test() = %i\n", i);

test(p);

printf("i after the call to test() = %i\n", i);}

i before the call to test() = 50i after the call to test() = 100

OutputOutput

C Programming UCSD Extension

© 1995 Philip J. Mercurio 328

656656 IntroductionIntroduction

CC Notes on Program 8-8

ä The variable i is private to the main() routineä main() can't lend the variable to test() so it

can be modifiedä Instead, main() tells test() where the variable

is located in memoryä test() uses the * operator to indirectly modifymain()'s variable i

ä You need to use indirection whenever you want afunction to modify a private variable for you

657657 IntroductionIntroduction

CC Program 8-9/* More Pointers and functions */#include <stdio.h>

void exchange(int *a, int *b){

int temp;

temp = *a;*a = *b;*b = temp;

}

C Programming UCSD Extension

© 1995 Philip J. Mercurio 329

658658 IntroductionIntroduction

CC Program 8-9 (continued)main(){

void exchange(int *a, int *b);int i1 = -5, i2 = 66;int *p1 = &i1, *p2 = &i2;

printf("Before the call to exchange(): i1 = %i ""i2 = %i\n",i1, i2);

exchange(p1, p2);

printf("After the first call to exchange(): i1 = %i "" i2 = %i\n",i1, i2);

exchange(&i1, &i2);

printf("After the second call to exchange(): i1 = %i "" i2 = %i\n",i1, i2);

}

659659 IntroductionIntroduction

CC Program 8-9 & OutputBefore the call to exchange(): i1 = -5 i2 = 66After the first call to exchange(): i1 = 66 i2 = -5After the second call to exchange(): i1 = -5 i2 = 66

C Programming UCSD Extension

© 1995 Philip J. Mercurio 330

660660 IntroductionIntroduction

CC Notes on Program 8-9

ä exchange(p1, p2); passes the two pointers toexchange()

ä exchange() uses the temp variable to swap thevalues pointed to by its two arguments

ä exchange(&i1, &i2); avoids the p1 and p2variables and generates the pointers on the fly

ä There's no other way we could have written anexchange function

661661 IntroductionIntroduction

CC Functions Returning Pointers

ä Functions can return pointer valuesä Let's create a function which searches our linked

list of entrys for a valueä We'll return a pointer to the entry containing the valueä or 0, if we can't find it

C Programming UCSD Extension

© 1995 Philip J. Mercurio 331

662662 IntroductionIntroduction

CC Program 8-10/* Linked List search */#include <stdio.h>

struct entry {int value;struct entry *next;

};

/* * Search a linked list for a value, * returning a pointer to the entry * or null. */struct entry* findEntry(struct entry *p, int target){

for( ; p != 0; p = p->next)if(p->value == target)

return(p);

return(0); /* failed */}

663663 IntroductionIntroduction

CC Program 8-10 (continued)main(){

struct entry *findEntry(struct entry *list, int target);struct entry n1, n2, n3;

struct entry *head; struct entry *p; int search;

/* Fill the list with values */n1.value = 100;n2.value = 200;n3.value = 300;

/* Sew up the list */head = &n1;n1.next = &n2;n2.next = &n3;n3.next = 0;

C Programming UCSD Extension

© 1995 Philip J. Mercurio 332

664664 IntroductionIntroduction

CC Program 8-10 & Output

Enter value to locate: 200Found 200

Enter value to locate: 400Not found

/* Get the value and search for it */printf("Enter value to locate: ");scanf("%i", &search);

p = findEntry(head, search);

if(p)printf("Found %i\n", p->value);

elseprintf("Not found\n");

}

OutputOutput

665665 IntroductionIntroduction

CC Notes on Program 8-10

ä findEntry() is general-purpose because it takesthe list to search as an argument

ä The pointer returned isn't really used for muchhere, but it might be used to access other fields ofthe entry

ä For example, we could use a modified version offindEntry() to search a dictionary constructedas a linked listä The pointer for the matching entry would be used to

access the definitionä This would give us a dictionary we can easily grow or

shrink

C Programming UCSD Extension

© 1995 Philip J. Mercurio 333

666666 IntroductionIntroduction

CC Other Data Structures

ä While a linked list is good for editing a dictionary, itwouldn't be very good for searchingä Have to examine each entryä Can't use a binary search algorithm because we can't

access any random entry directly

ä A better data structure would be a treeä Trees, doubly-linked lists and other advanced data

structures are beyond the scope of this courseä References:

ä Knuth, The Art of Computer Programming, Volume 1ä Sedgewick, Algorithms in C

667667 IntroductionIntroduction

CC Pointers and Arrays

ä Arrays and pointers are intimately relatedä A pointer can be a handy way to refer to an

element of an arrayä char text[50], *p;

ä p = &text[29]; sets p to point to the 30th char intext

ä The name of an array is really a pointer to thebeginning of the arrayä p = &text[0]; can also be expressed as p = text;

C Programming UCSD Extension

© 1995 Philip J. Mercurio 334

668668 IntroductionIntroduction

CC Array Animation #1

values

100[0]

110[1]

120[2]

130[3]

140[4]

150[5]

160[6]

170[7]

180[8]

int values[9]

669669 IntroductionIntroduction

CC Array Animation #2

values

ptr

100[0]

110[1]

120[2]

130[3]

140[4]

150[5]

160[6]

170[7]

180[8]

int values[9], *ptr;

C Programming UCSD Extension

© 1995 Philip J. Mercurio 335

670670 IntroductionIntroduction

CC Array Animation #3

values

100

*ptr

values

ptr

100[0]

110[1]

120[2]

130[3]

140[4]

150[5]

160[6]

170[7]

180[8]

int values[9], *ptr;

ptr = values;

671671 IntroductionIntroduction

CC Array Animation #4

values

130

*ptr

values + 3

ptr

100[0]

110[1]

120[2]

130[3]

140[4]

150[5]

160[6]

170[7]

180[8]

int values[9], *ptr;

ptr = values;

ptr = values + 3;

C Programming UCSD Extension

© 1995 Philip J. Mercurio 336

672672 IntroductionIntroduction

CC Array Animation #5

values

150

*(ptr + 2)

values + 3

ptr

100[0]

110[1]

120[2]

130[3]

140[4]

150[5]

160[6]

170[7]

180[8]

int values[9], *ptr;

ptr = values;

ptr = values + 3;

*(ptr + 2)

673673 IntroductionIntroduction

CC Pointer Arithmetic

ä If ptr == values, then *(ptr + i) is thesame as values[i]

ä type *ptr;ä ptr++; will move a pointer ahead in memory by 1

typeä Regardless of what type is!

ä If ptr is a char *, ptr++ increases the addressby 1 byte

ä If ptr is an int *, ptr++ increases the addressby 4 bytes (the size of an int)

ä This is what makes C pointers so powerful!

C Programming UCSD Extension

© 1995 Philip J. Mercurio 337

674674 IntroductionIntroduction

CC More Pointer Arithmetic

int values[9], *ptr = values;

ä *(ptr + i) ptr[i] *(values + i)values[i] are all valid ways of referring tovalues[i]

ä The array name is just like a real pointer, exceptyou can't change itä values = &table[8]; will not compileä Think of the array name as a constant pointer

ä ptr[i] can be thought of as a shorthand for*(ptr + i)

675675 IntroductionIntroduction

CC Even More Pointer Arithmetic

ä ptr += n; advances by n of whatever type ptrpoints to

ä ptr--; retreats by 1 unitä Comparisons work too

ä (ptr == values) true if ptr is pointing at the start ofthe array

ä (ptr > &values[8]) true if ptr is pointing tosomeplace after the end of values[]

ä Could also be written (ptr > values + 8)ä Or even (ptr - values > 8)

ä Only addition and subtraction allowed,multiplication doesn't make sense

C Programming UCSD Extension

© 1995 Philip J. Mercurio 338

676676 IntroductionIntroduction

CC Program 8-11 & Output/* Sum the elements of an int array */#include <stdio.h>

int arraySum(int array[], int n){

int sum = 0, *ptr;int *end = array + n;

for(ptr = array; ptr < end; ptr++)sum += *ptr;

return(sum);}

main(){

int arraySum(int array[], int n);int values[10] = {3, 7, -9, 3, 6, -1, 7, 9, 1, -5};

printf("The sum is %i\n", arraySum(values, 10));}

The sum is 21OutputOutput

677677 IntroductionIntroduction

CC Optimization with Pointers

ä Indirection through a pointer is faster than arrayindexing

ä for(i = 0; i < n; i++)ä sum += values[i];

ä Each time through the loopä Add 1 to iä Find values[i] by

ä Multiplying i by 4 bytesä Adding that to values to get (values + i)ä Getting the value *(values + i)

ä Add that value to sum

C Programming UCSD Extension

© 1995 Philip J. Mercurio 339

678678 IntroductionIntroduction

CC More Optimization

for(p = values; p < end; p++)

sum += *p;

ä Each time through the loopä Get the value *pä Add that to sumä Add 4 bytes to p

ä No multiplication needed!

679679 IntroductionIntroduction

CC Even More Optimization

ä Why end = &values[n]; for(... p < end;...)ä Instead of for(... p < &values[n]; ...) ?

ä The loop condition has to be evaluated each timethrough the loop tooä p < &values[n] requires that &values[n] be

recomputed each time

ä These optimizations don't amount to much in smallprograms, but are significant when dealing withlarge arrays

C Programming UCSD Extension

© 1995 Philip J. Mercurio 340

680680 IntroductionIntroduction

CC Passing Arrays as Arguments

ä When we pass an array as an argument, we'rereally passing a pointer to the first element of thearrayä This is why we can modify the values inside an array

from a function

ä int array[]; and int *array; are the samething

ä Most people use int *array; in functionarguments

681681 IntroductionIntroduction

CC Passing Arrays as Arguments(continued)

ä Some people use int array[]; when thearray is going to be accessed with an indexvariable, int *array; when it's going to betreated like a pointer

C Programming UCSD Extension

© 1995 Philip J. Mercurio 341

682682 IntroductionIntroduction

CC/* Sum the elements of an int array (modified) */#include <stdio.h>

int arraySum(int *array, int n){

int sum = 0;int *end = array + n;

for( ; array < end; array++)sum += *array;

return(sum);}

main(){

int arraySum(int array[], int n);int values[10] = {3, 7, -9, 3, 6, -1, 7, 9, 1, -5};

printf("The sum is %i\n", arraySum(values, 10));}

Program 8-12 & Output

The sum is 21OutputOutput

683683 IntroductionIntroduction

CC Notes on Program 8-12

ä int *array; is used to specify the argumentpassed in as values

ä Since array is a copy of the values pointer, wecan use it to step through the arrayä We don't have to set it back to the beginning, it gets

thrown away when the function exits

C Programming UCSD Extension

© 1995 Philip J. Mercurio 342

684684 IntroductionIntroduction

CC Pointers to Strings

ä Pointers are naturals for dealing with characterstrings

ä Here's the copyString() function rewritten usingpointers

685685 IntroductionIntroduction

CC/* copyString() with pointers */#include <stdio.h>

void copyString(char *to, char *from){

for( ; *from != '\0'; from++, to++)*to = *from;

*to = '\0';}

main(){

void copyString(char *to, char *from);char string1[] = "A string to be copied.";char string2[50];

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

copyString(string2, "So is this.");printf("%s\n", string2);

}

Program 8-13

C Programming UCSD Extension

© 1995 Philip J. Mercurio 343

686686 IntroductionIntroduction

CCA string to be copied.So is this.

Program 8-13 Output

687687 IntroductionIntroduction

CC Notes on Program 8-13

ä Note that the new copyString() is moresuccinct

ä Since we increment to and from in lockstep,when from gets to the null terminator to points towhere the null belongs in the duplicate string

ä The second invocation of copyString() passesa string constant as an argument

C Programming UCSD Extension

© 1995 Philip J. Mercurio 344

688688 IntroductionIntroduction

CC Constant Strings and Pointers

ä copyString(string2, "So is this.");

ä A constant string is an array of characters, apointer to the beginning is getting passed as theargument

ä char *textPtr; creates a pointer to a charä textPtr = "A character string";

allocates a character array somewhere, returns apointer to the start of the array, and assigns that totextPtr

689689 IntroductionIntroduction

CC Constant Strings and Pointers(continued)

ä char text[80]; creates an array of charswith the name text

ä text = "This won't work."; is invalid,text is an array name and can't be changed topoint somewhere else

C Programming UCSD Extension

© 1995 Philip J. Mercurio 345

690690 IntroductionIntroduction

CC Initializing Strings and Pointers

ä char text[80] = "This is okay.";ä Allocates an 80-char array and initializes it with "Thisis okay."

ä Same as char text[80] = { "This is okay."};

ä Also same as char text[80] = {'T', 'h',.....'\0'};

ä char *ptr = "This is okay.";ä Allocates room for "This is okay." somewhereä Allocates a char pointer and initializes it to this location

691691 IntroductionIntroduction

CC Array of Strings

ä char *days[] = {"Sun", "Mon", "Tue","Wed", "Thu", "Fri", "Sat"};

days

[0]

[1]

[2]

[3]

[4]

[5]

[6]

'S' 'u' 'n' '\0'

'M' 'o' 'n' '\0'

'T' 'u' 'e' '\0'

'W' 'e' 'd' '\0'

'T' 'h' 'u' '\0'

'F' 'r' 'i' '\0'

'S' 'a' 't' '\0'

C Programming UCSD Extension

© 1995 Philip J. Mercurio 346

692692 IntroductionIntroduction

CC ++ and -- Revisited

ä ++i; and --i; are examples of the pre-incrementand pre-decrement operators

ä i++; and i--; are examples of the post-increment and post-decrement operators

ä By themselves, it never matters whether we usethe pre- or post- formä This is also true in the loop expression of a for

statement

ä It does matter in more complicated expressions

693693 IntroductionIntroduction

CC Pre- vs. Post-

ä The pre- versions increment/decrement thevariable, then use it in the rest of the expression

ä The post- versions use the variable first, thenincrement/decrement it

ä The post- versions are very common in code usingpointers

C Programming UCSD Extension

© 1995 Philip J. Mercurio 347

694694 IntroductionIntroduction

CC Assignment Comparison

int i = 0, j;

j = ++i;

ä Translates to:i = i + 1;

j = i;

ä Results:i = 1;

j = 1;

int i = 0, j;

j = i++;

ä Translates to:j = i;

i = i + 1;

ä Results:i = 1;

j = 0;

695695 IntroductionIntroduction

CC Pointer Comparison

char *p = "1234";

while(*p)printf("%c ", *++p);

ä Prints:ä 2 3 4

char *p = "1234";

while(*p)printf("%c ", *p++);

ä Prints:ä 1 2 3 4

C Programming UCSD Extension

© 1995 Philip J. Mercurio 348

696696 IntroductionIntroduction

CC/* copyString() with pointers, version 2 */#include <stdio.h>

void copyString(char *to, char *from){

while(*from)*to++ = *from++;

*to = '\0';}

main(){

void copyString(char *to, char *from);char string1[] = "A string to be copied.";char string2[50];

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

copyString(string2, "So is this.");printf("%s\n", string2);

}

Program 8-14

697697 IntroductionIntroduction

CCA string to be copied.So is this.

Program 8-14 Output

C Programming UCSD Extension

© 1995 Philip J. Mercurio 349

698698 IntroductionIntroduction

CC Notes on Program 8-14

ä *to++ = *from++; is a very common idiomused when copying data from one pointer toanother

ä Translates to:ä *to = *from;

ä to++;

ä from++;

699699 IntroductionIntroduction

CC Operations on Pointers

ä The only valid operations you can perform onpointers are:ä Adding or subtracting an integerä Comparing two pointers for equality (==) and order (<>)

ä Subtracting two pointers to get the number of elementsbetween them

C Programming UCSD Extension

© 1995 Philip J. Mercurio 350

700700 IntroductionIntroduction

CC Subtracting Pointers

float *a, *b, array[100];

ä a - b is an integerä It's the number of floats between b and aa = &array[55]; b = &array[35];

ä a - b would be 20ä a - array would be 55

701701 IntroductionIntroduction

CC/* pointer version of stringLength() */#include <stdio.h>

int stringLength(char *string){

char *p = string;

while(*p) p++;

/* p now points to the null */return(p - string);

}

main(){

int stringLength(char *string);

printf("%i ", stringLength("string length test"));printf("%i ", stringLength(""));printf("%i\n", stringLength("complete"));

}

Program 8-15

18 0 8

OutputOutput

C Programming UCSD Extension

© 1995 Philip J. Mercurio 351

702702 IntroductionIntroduction

CC Pointers to Functions

ä You can declare a pointer which points to afunction

ä You can then use the pointer to call the functionä The tricky part is declaring a pointer to a function

ä Both the function's return type and the types of itsarguments have to be specified

703703 IntroductionIntroduction

CC More Pointers to Functions

int (*funcPtr) (int n, char c);

ä Declares a pointer variable funcPträ funcPtr points to a function which

ä Returns an intä Takes an int and a char as arguments

ä Note that the parens are important!ä With out them, you're declaring a function which returns

an int pointer

C Programming UCSD Extension

© 1995 Philip J. Mercurio 352

704704 IntroductionIntroduction

CC Using Function Pointers

int func(int n, char c) { return(c + n);}

int (*funcPtr) (int n, char c);

ä funcPtr = func; points funcPtr at funcä answer = funcPtr(3,'t'); calls func() with

the arguments 3 and 't'ä You can use the & and * if you want to

funcPtr = &func;

answer = (*funcPtr)();

705705 IntroductionIntroduction

CC Why Function Pointers?

ä Functions pointers are used to pass around blocksof instructions (functions) within your program

ä One use is to supply a function you wrote for useby a library function

ä For example, qsort() is an implementation of theQuicksort algorithm included in the standard Clibrary

ä qsort() can sort an array of any data type foo(including pointers and structures)

C Programming UCSD Extension

© 1995 Philip J. Mercurio 353

706706 IntroductionIntroduction

CC Why Function Pointers? (continued)

ä The only thing qsort() doesn't know is how to dois to compare two elements from your array--itdoesn't know what a foo is

ä You provide pointer to a function that comparestwo foos a and b, returning -1 if a < b, 0 if a ==b, and 1 if a > b

707707 IntroductionIntroduction

CC Callbacks

ä Function pointers used to be obscure but are nowbecoming more popular because of windowsystems (graphical user interfaces), in the form ofcallbacks

ä Most GUI programs have two stagesä First you call library functions to create all the windows,

buttons, menus, etc.ä Then you call a special library function which "runs" your

window (often called an event manager)ä The event manager runs until you close the window (exit

the program)

C Programming UCSD Extension

© 1995 Philip J. Mercurio 354

708708 IntroductionIntroduction

CC A Button Is Pressed

ä For example, the event manager would notice thatyou moved the mouse over a button and clicked

ä The event manager needs to know what you wantthis button to do

ä You must provide a pointer to a function (thecallback function) when you create the button

ä Most GUI libraries use callbacks extensively

709709 IntroductionIntroduction

CC Void Pointers

ä void *ptr; declares a generic pointer, onewhose type is not specified

ä Before it can be used, it must be type-cast to pointto some real data type

ä *(char *)ptr treats ptr like a pointer to achar, then gets the value of the byte at thatlocation

C Programming UCSD Extension

© 1995 Philip J. Mercurio 355

710710 IntroductionIntroduction

CC/* Demo of the void pointer */#include <stdio.h>

main(){

void *p;long int i;

printf("Please enter a number in decimal: ");scanf("%li", &i);

printf("Your number in hex is %08lx\n", i);

p = (void *) &i;

printf("The 1st byte is %02x\n", *(unsigned char *)p);printf("The 2nd byte is %02x\n", *((unsigned char *)p+1));printf("The 3rd byte is %02x\n", *((unsigned char *)p+2));printf("The 4th byte is %02x\n", *((unsigned char *)p+3));

}

Program 8-16

711711 IntroductionIntroduction

CCPlease enter a number in decimal: 1234567Your number in hex is 0012d687The 1st byte is 87The 2nd byte is d6The 3rd byte is 12The 4th byte is 00

Program 8-16 Output

C Programming UCSD Extension

© 1995 Philip J. Mercurio 356

712712 IntroductionIntroduction

CC Notes on Program 8-16

ä p = (void *) &i; When assigning a pointer toa void*, it should be cast as one

ä * (char *)p gets the first charä (char *)p + 1 refers to the address 1 byte afterp

ä *((char *) p + 1) retrieves the char storedat the location after p

713713 IntroductionIntroduction

CC Pointers to Pointers

ä You can even declare pointers to pointers, andpointers to pointers to pointers

ä These are beyond the scope of this course, but arelogical extensions of how the * and & operatorsoperate

C Programming UCSD Extension

© 1995 Philip J. Mercurio 357

714714 IntroductionIntroduction

CC Exercises due next session

ä Read: Chapter 11ä Exercises: Chapter 11

ä 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12ä 4: Make sure to check for attempt to delete an entry

that's not in the listä 6: Your test program must demonstrate insertion and

deletion of first, middle, and last entries.ä 8: Use pointers!ä Feel free to combine multiple exercises in one program

715715 IntroductionIntroduction

CC

C Programming

PreprocessorPhil Mercurio

UCSD [email protected]

C Programming UCSD Extension

© 1995 Philip J. Mercurio 358

716716 IntroductionIntroduction

CC Today's Session

ä Operations on Bits [Ch. 12]ä Bit Operatorsä Bit Fields

ä The Preprocessor [Ch. 13]ä #define, #includeä Conditional Compilation

ä More Data Types [Ch. 14]ä Enumerated Types, Typedefä Data Type Conversions

ä More Common Programming Mistakes

717717 IntroductionIntroduction

CC Operations On Bits

ä Unlike most high-level languages, C allows us tooperate on the individual bits in a char or int

ä This is handy whenä Interacting directly with hardware: input and output

devices are often controlled by setting or clearingindividual bits

ä Drawing graphics: screen pixel colors are controlled bybits in memory

ä Storing flags: 8 flag values can be stored in one char

C Programming UCSD Extension

© 1995 Philip J. Mercurio 359

718718 IntroductionIntroduction

CC Chunks of Bits

ä We usually use unsigned variables when dealingwith bitsä We break them up into nybbles (4-bits)ä A nybble is one digit in hex

unsigned char

unsigned short

unsigned long1111 11111111 1111 8 bits

1111 1111 1111 11111111 1111 1111 1111 16 bits

1111 1111 1111 1111 1111 1111 1111 11111111 1111 1111 1111 1111 1111 1111 1111 32 bits

27

215

231

20

719719 IntroductionIntroduction

CC Handy Hex Table

000000000 000100011 001000102 001100113

010001004 010101015 011001106 011101117

100010008 100110019 10101010A 10111011B

11001100C 11011101D 11101110E 11111111F

C Programming UCSD Extension

© 1995 Philip J. Mercurio 360

720720 IntroductionIntroduction

CC Bit Operators

Symbol Operation

& Bitwise AND

| Bitwise Inclusive-OR

^ Bitwise Exclusive-OR

~ Ones Complement

<< Left Shift

>> Right Shift

721721 IntroductionIntroduction

CC & Bitwise AND

0110 11000110 1100

c = a & b;

1111 10101111 1010

0110 10000110 1000

aa

bb

cc

C Programming UCSD Extension

© 1995 Philip J. Mercurio 361

722722 IntroductionIntroduction

CC | Bitwise Inclusive-OR

0110 11000110 1100

c = a | b;

1111 10101111 1010

1111 11101111 1110

aa

bb

cc

723723 IntroductionIntroduction

CC ^ Bitwise Exclusive-OR

0110 11000110 1100

c = a ^ b;

1111 10101111 1010

1001 01101001 0110

aa

bb

cc

C Programming UCSD Extension

© 1995 Philip J. Mercurio 362

724724 IntroductionIntroduction

CC And, Or, and Xor

ä & | and ^ are each binary operators, just like + -* /

ä c = a & 0xFE; copies a to c, but shuts off thelow-order bitä This is called masking

ä b |= 0x07; same as b = b | 0x07;ä Works with all the binary bit operatorsä Has the effect of turning on the lower three bits of b,

leaving the rest alone

ä a ^ b ^ b = a interesting property ofexclusive-OR

725725 IntroductionIntroduction

CC ~ Ones-Complement

0110 11000110 1100

b = ~a;

1001 00111001 0011

aa

bb

0110 11000110 1100cc

c = ~b;

C Programming UCSD Extension

© 1995 Philip J. Mercurio 363

726726 IntroductionIntroduction

CC Ones-Complement

ä ~ is a unary operator, just like -ä Let's say we want to create a mask with all the bits

set, except the rightmostä If we need a char-sized mask, we know 0xFE will

workä If we need an int, we may not know if we need 16

or 32 bitsä 0xFFFE or 0xFFFFFFFEä ~1 is guaranteed to be correct

727727 IntroductionIntroduction

CC << Left Shift

0110 11000110 1100b = a << 1;

1101 10001101 1000

aa

bb

1011 00001011 0000cc

c = a << 2;

d = a << 3;

e = a << 4; 0110 00000110 0000dd

C Programming UCSD Extension

© 1995 Philip J. Mercurio 364

728728 IntroductionIntroduction

CC >> Right Shift

0110 11000110 1100b = a >> 1;

0011 01100011 0110

aa

bb

0001 10110001 1011cc

c = a >> 2;

d = a >> 3;

e = a >> 4; 0000 11010000 1101dd

729729 IntroductionIntroduction

CC The Shift Operators

ä << and >> are binary operatorsä a << n shifts the bits in a to the left by n bitsä a <<= 3; is the same as a = a << 3;ä a >> n shifts the bits in a to the right by n bits

C Programming UCSD Extension

© 1995 Philip J. Mercurio 365

730730 IntroductionIntroduction

CC Signed Shifts

ä << always shifts in 0s on the rightä >> always shifts in 0s on the left, if the variable is

unsignedä Signed numbers that are negative have the

leftmost bit (the sign bit) setä On a signed number, >> shifts in 1s if the sign bit is 1ä Positive numbers stay positive, negative stay negative

1110 11001110 1100

signed char a;

-20

1111 01101111 0110

a >> 1;

-10

731731 IntroductionIntroduction

CC Shifts and Arithmetic

ä Shifting an integer left by 1 bit is the same asmultiplying it by 2ä Think of the analogy with decimal numbers, where

adding a 0 at the end multiplies by 10

ä Shifting right is the same as dividing by 2 (integerdivision)ä Shifting in 0's is called a logical right shiftä Special-handling the sign bit for signed ints is called

an arithmetic right shift

ä Most compilers will optimize using thisä a *= 4; would be replaced with a <<= 2;

C Programming UCSD Extension

© 1995 Philip J. Mercurio 366

732732 IntroductionIntroduction

CC Bit Fields

ä Let's say we need a large array of a structurecontainingä 3 flags: f1, f2, f3ä a type code, which will be between 1 and 12ä an index, between 0 and 500

ä We could define a struct with 3 chars and 2ints, using at least 7 bytes

ä Or we could pack everything into 1 short (2 bytes):f1

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

f2 f3 type index

733733 IntroductionIntroduction

CC More Bit Fields

ä We could use the bit operators to manipulate thefields within this packed structureä See PAC Chapter 12 for an example

ä C provides a way to specify bit fields in a structure:struct packedStruct {

unsigned int f1:1;

unsigned int f2:1;

unsigned int f3:1;

unsigned int type:4;

unsigned int index:9;

} data;

C Programming UCSD Extension

© 1995 Philip J. Mercurio 367

734734 IntroductionIntroduction

CC Even More Bit Fields

ä The :number modifier after the field namesspecifies the number of bits

ä Bit fields are accessed just like normal structurefields:ä data.type = 6; if(data.f1) ...

ä You can have normal fields in the same structureä Keep all the bit fields together, C won't move them

around to pack them in tightly

ä Don't assume where the bit fields will end up inmemoryä Might be in a different order or packed differently

735735 IntroductionIntroduction

CC The C Preprocessor

ä In Session 1 we discussed the various phases ofthe compilerä compiling, assembling, linking

ä In fact, there's a 0th phase that happens before allof the others: the preprocessor

ä The preprocessor is an entirely different languageä All preprocessor commands begin with a # in column 1ä It just processes text, performing substitutions,

insertions, and deletions (like a macro processor)ä The text the compiler sees has had all preprocessor

commands processed and removed

C Programming UCSD Extension

© 1995 Philip J. Mercurio 368

736736 IntroductionIntroduction

CC C Preprocessor Syntax

ä # in column 1, followed by commandä Most preprocessors accept spaces between the # and the

command, but some don't

ä command may include one or more arguments,separated by spaces or tabs

ä No semicolon at the end!ä The entire command must be on one line

ä To continue a preprocessor command, put a backslash \at the end of the line

737737 IntroductionIntroduction

CC The #include statement

ä #include fileä Inserts a copy of the file at that point in your C fileä The file is usually a header file

ä Contains variable and structure definitions,ä And other preprocessor commandsä Usually ends in .hä Rarely contains functions, but that's allowed

C Programming UCSD Extension

© 1995 Philip J. Mercurio 369

738738 IntroductionIntroduction

CC Header Files

ä Your system will come with directories (folders)filled with many .h filesä These correspond to the libraries that come with your

compilerä #include <stdio.h>

ä Tells the preprocessor to look first in the systemdirectories for stdio.h

ä #include "myHeader.h"

ä Tells the preprocessor to look first in your local directoryfor myHeader.h

ä Searches system directories if not found

739739 IntroductionIntroduction

CC The #define Statement

#define macro expansionä Causes macro to be replaced with expansion wherever it

appears#define TRUE 1

#define FALSE 0ä Defines TRUE to be a macro for 1, FALSE for 0ä Macros are usually all upper-case by conventionä Everywhere TRUE appears, a 1 will be inserted. TRUE

will not appear in the text the compiler seesä Macros are not expanded when in double quotes ""

(string constants)

C Programming UCSD Extension

© 1995 Philip J. Mercurio 370

740740 IntroductionIntroduction

CC #define Scope

ä Unlike variable declarations, #define macroshave no scope

ä Once a #define line is encountered, the macro isdefined for the rest of the file, inside and outside offunctionsä If you attempt to #define the same macro again, you'll

get a warning from the compiler

ä #undef macroä Undefines the macro, for the rest of the file

741741 IntroductionIntroduction

CC #define Examples

ä gameOver = TRUE; expands to gameOver =1;

ä FALSE = 6; Invalid!!! This gets expanded toä 0 = 6;

ä return(TRUE); returns the value 1ä #define PI 3.141592654 defines a handy

constant for πä printf("TRUE"); prints TRUE, macros are not

expanded in strings

C Programming UCSD Extension

© 1995 Philip J. Mercurio 371

742742 IntroductionIntroduction

CC NULL

#define NULL 0

ä Defines a handy synonym for zeroä Already defined in stddef.h (which is included bystdio.h)

*p = NULL;

ä Terminate a stringwhile(ptr != NULL) ...

ä Loop until a null pointer

743743 IntroductionIntroduction

CC More #defines

ä The expansion can be anything, including variablesand expressions

#define CM centimeters

ä Defines an abbreviation for a long variable name#define SUM value1 + value2

ä Expands to value1 + value2ä x = 2 * SUM;

ä x = 2 * value1 + value2 = (2 * value1) +value2;

ä Probably not what you intended

C Programming UCSD Extension

© 1995 Philip J. Mercurio 372

744744 IntroductionIntroduction

CC Safe Macros

ä #define SUM (value1 + value2)ä Guarantees that SUM is always treated as a whole

expressionä Some programmers always use parens around the

expansion, just in caseä I think this helps readability a bit too

745745 IntroductionIntroduction

CC Redefining C

#define AND &&

#define OR ||

#define EQUALS ==

if(a EQUALS b OR c EQUALS d) ...

ä We could use the preprocessor to define alanguage that doesn't look much like C

ä This is strongly advised against--other people needto be able to read your code too

C Programming UCSD Extension

© 1995 Philip J. Mercurio 373

746746 IntroductionIntroduction

CC #includes and #defines

ä #defines are often found in #include filesä Multiple C files can include the same header file and

share the same definitions

ä Consider a file metric.h with the followingcontents:

/* Metric system conversions */

#define INCHES_PER_CM 0.394#define CM_PER_INCH 1 / INCHES_PER_CM

#define QUARTS_PER_LITER 1.057#define LITERS_PER_QUART 1 / QUARTS_PER_LITER

#define OUNCES_PER_GRAM 0.035#define GRAMS_PER_OUNCE 1 / OUNCES_PER_GRAM

747747 IntroductionIntroduction

CC Program 9-1 & Output

/* Gallons to liters converter */#include <stdio.h>#include "metric.h"

main(){

float liters, gallons;

printf("Enter gallons: ");scanf("%f", &gallons);

liters = gallons * 4 * LITERS_PER_QUART;printf("That's %.2f liters\n", liters);

}

Enter gallons: 14That's 52.98 liters

OutputOutput

C Programming UCSD Extension

© 1995 Philip J. Mercurio 374

748748 IntroductionIntroduction

CC Notes on Program 9-1

ä Any of a number of metric/English conversionprograms could make use of metric.h

ä The expansion portion of a macro can be anything,including another macroä Expansion continues until there's nothing left to expand

liters = gallons * 4 * LITERS_PER_QUART;

liters = gallons * 4 * 1 /QUARTS_PER_LITER;

liters = gallons * 4 * 1 / 1.057;

liters = gallons * 3.784;

749749 IntroductionIntroduction

CC System Include Files

ä stddef.h

ä Standard definitions, including NULLä stdio.h

ä Standard input/output libraryä math.h

ä Math library (square root, trig functions, lots more)ä limits.h

ä System-dependent info on sizes of character and integerdata types

ä float.h

ä System-dependent info on floats (largest float, precision)

C Programming UCSD Extension

© 1995 Philip J. Mercurio 375

750750 IntroductionIntroduction

CC Macro Arguments

ä #define macro(arg1, arg2, ...) expansionä A macro may contain arguments

ä The arguments can be used in the expansion, as placeholders for the arguments given when the macro is used

ä The ( must always come right after the macro nameä If defined with n arguments, the macro must always be

used with n argumentsä There's no notion of types for macro arguments

ä It's all just chunks of text being copied around

751751 IntroductionIntroduction

CC Arguments Examples

#define ALPHA(c) (c >= 'a' && c <= 'z')

char a;

ä ALPHA(a) evaluates to true if a is a lowercasealphabetic characterä Expands to (a >= 'a' && a <= 'z')

#define MAX(a,b) ( (a > b) ? a : b )

ä Uses the conditional operator to make a handy maxfunction

ä Note that this macro can be used on anything that canbe compared: chars, ints, floats, ...

C Programming UCSD Extension

© 1995 Philip J. Mercurio 376

752752 IntroductionIntroduction

CC More Safe Macros

ä #define SQUARE(x) (x * x) works fine ininstances like y = SQUARE(v);

ä What about y = SQUARE(v + 1); ?ä y = (v + 1 * v + 1) = v + v + 1

ä #define SQUARE(x) ( (x) * (x) ) fixes theproblem

ä To be safe, always wrap args in parens, and wrapentire expansion in parens

#define MAX(a,b) (((a) > (b)) ? (a):(b))ä Correct version of MAX(a,b)

753753 IntroductionIntroduction

CC The Weird # and ## Operators

ä # and ## are strange operators added to thepreprocessor by ANSI

ä They're only valid in the expansion portion of a#define macro

ä They allow you to construct what the compiler seesin weird ways

ä Very useful for certain tricky situations

C Programming UCSD Extension

© 1995 Philip J. Mercurio 377

754754 IntroductionIntroduction

CC The # Operator

ä In a macro expansion, #arg causes the argumentto be turned into a string

ä #define STR(x) #x

ä STR(test) is expanded to "test"ä Special characters and quotes are preserved

ä STR(foo bar\n) is expanded to "foo bar\n"ä STR("hello") is expanded to "\"hello\""

755755 IntroductionIntroduction

CC Using #

ä One of the best uses for # is to create a macro toprint a variable and its name

#define printInt(var) printf("%s =%i\n", #var, var)

ä Note the lack of a semicolon at the end

ä printInt(count); expands to printf("%s =%i\n", "count", count);ä Prints "count = " followed by the value of count

C Programming UCSD Extension

© 1995 Philip J. Mercurio 378

756756 IntroductionIntroduction

CC The ## Operator

ä ## joins two tokens together into one tokenä You can think of it as deleting the spaces

#define JOIN(a,b) a ## b

ä JOIN(foo,bar) is expanded to foobarä Lets say we have a group of variables x1, x2, x3 ...x100

#define printX(n) printf("The %ith x is%i\n", n, x##n)

ä printX(20); expands to printf("The %ith xis %i\n", 20, x20);ä Prints "The 20th x is " followed by the value of x20

757757 IntroductionIntroduction

CC Conditional Compilation

ä You often need to maintain slightly differentversions of your codeä Different versions for different operating systemsä Different versions for different compilersä Different versions with different features

ä A demo version with some features turned offä A debugging version with extra print statements

C Programming UCSD Extension

© 1995 Philip J. Mercurio 379

758758 IntroductionIntroduction

CC More Conditional Compilation

ä The preprocessor gives us if-else statements towrap around sections of code

ä They test the values of #defines which areä Automatically defined by the compilerä In your code or files #includedä Specified by you at compile time

759759 IntroductionIntroduction

CC #ifdef, #endif, #else, and#ifndef

ä #ifdef macroä lines of textä #endif

ä If macro is #defined, the lines of text are includedä If not, the compiler never sees the lines of text

ä #ifndef macroä Tests if macro is not defined

ä #elseä Alternate clause for #ifdef or #ifndef

C Programming UCSD Extension

© 1995 Philip J. Mercurio 380

760760 IntroductionIntroduction

CC Conditional Compilation Example

#ifdef __STDC__printf("%i\n", j);

#elseprintf("%d\n", j);

#endif

ä If __STDC__ is defined, we use %i, else we use %dä #define __STDC__ 1 or even just #define__STDC__ is sufficient

ä In fact, __STDC__ is automatically defined by anANSI compiler

761761 IntroductionIntroduction

CC Different OSs

#ifdef UNIX

#define DATADIR "/home/pjm/data"

#else

#define DATADIR "c:\data"

#endif

ä This example #defines DATADIR to one of twodifferent values depending on the UNIX #define

ä This might be defined by you at compile time:ä cc -DUNIX program.c is just like adding #defineUNIX to your code

C Programming UCSD Extension

© 1995 Philip J. Mercurio 381

762762 IntroductionIntroduction

CC Demo Version

void saveGame() {

#ifndef DEMOwriteGameToDisk();

#endif

}

ä If you #define DEMO, the saveGame() functionwill do nothing

763763 IntroductionIntroduction

CC Debugging

#ifdef DEBUGprintf("player is %i\n", player);

#endif

ä Prints out the value of player only if DEBUG isdefinedä You might have statements like these scattered all

throughout your code

ä You might turn on debugging everywhere by cc-DDEBUG, or you might use #define DEBUG and#undef DEBUG to turn debugging on and off invarious locations throughout your code

C Programming UCSD Extension

© 1995 Philip J. Mercurio 382

764764 IntroductionIntroduction

CC #if and #elif

ä #ifdef just tests a macro to see if it's definedä It doesn't care what it is defined as

ä #if expression tests an expression to see if it'snonzeroä All of C's relational operators are available

ä! < > == && || etc.ä #elif expression extends test with an else-if

ä #if defined(name) is the same as #ifdefname

765765 IntroductionIntroduction

CC Multiple OSs

#if OS == 1 /* MacOS */...

#elif OS == 2 /* Windows */...

#elif OS == 3 /* Unix */...

#else...

#endif

Compile for Unix with: cc -DOS=3 program.c

C Programming UCSD Extension

© 1995 Philip J. Mercurio 383

766766 IntroductionIntroduction

CC Complicated Relationals

#if defined(MSDOS) || defined(OS2)

#define HOME "c:\"

#else

#define HOME "/home"

#endif

ä #if tests for either MSDOS or OS2

767767 IntroductionIntroduction

CC More On Data Types

ä Three more topics on data types:ä The Enumerated Data Typeä The Typedef Statementä Data Type Conversion Rules

C Programming UCSD Extension

© 1995 Philip J. Mercurio 384

768768 IntroductionIntroduction

CC Why Enumerated Types

ä When we deal with flags we usually:#define TRUE 1

#define FALSE 0

int flag1, flag2;

ä Declaring our flags as int hides their meaningä We'd rather have a flag type

ä There's nothing to prevent us from using valuesother than 1 or 0ä We could set a flag to a value that's not equal to eitherTRUE or FALSE

769769 IntroductionIntroduction

CC Enumerated Types

enum flag { false, true };ä Defines a new type, enum flagä Variables of this type can only be set to true or falseä false and true are defined as integer constants, in

this case 0 and 1

ä enum flag flag1; creates an enum flagä flag1 = true; sets flag1ä if(flag1 == false) ... tests flag1

C Programming UCSD Extension

© 1995 Philip J. Mercurio 385

770770 IntroductionIntroduction

CC Enumerated Identifiers

ä The names inside the {} in the definition aredefined as integer constants

ä If not specified otherwise, the first is 0, the second1, etc.

ä An enumerated type for month names:ä enum month { jan, feb, mar, apr, may,jun, jul, aug, sep, oct, nov, dec };

ä You can specify a value, the rest followä enum month { jan = 1, feb, mar, ...

771771 IntroductionIntroduction

CC Program 9-2

/* enum Example */#include <stdio.h>

main(){

enum month { jan=1, feb, mar, apr, may, jun, jul,aug, sep, oct, nov, dec };

enum month m;int days = 0;

printf("Enter month number: ");scanf("%i", &m);

C Programming UCSD Extension

© 1995 Philip J. Mercurio 386

772772 IntroductionIntroduction

CC Program 9-2 (continued)

switch(m) {case jan: case mar: case may: case jul:case aug: case oct: case dec:

days = 31;break;

case apr: case jun: case sep: case nov:days = 30;break;

case feb:days = 28;break;

default:days = 0;printf("Bad month number, must be "

"[%i..%i]\n",jan, dec);

break;}

773773 IntroductionIntroduction

CC Program 9-2 & Output

if(days != 0)printf("Number of days is %i\n", days);

if(m == feb)printf("...or 29 if it's a leap year\n");

}

Enter month number: 11Number of days is 30

Enter month number: 2Number of days is 28...or 29 if it's a leap year

OutputOutput

C Programming UCSD Extension

© 1995 Philip J. Mercurio 387

774774 IntroductionIntroduction

CC Notes on Program 9-2

ä If we didn't set jan = 1, we would have had tosubtract 1 from the number entered by the userä Easier to adjust the numbering once than deal with the

"off by one" problem several places in the codeä PAC doesn't do this and ends up with a bug

ä Note that enumerated constants are just likeinteger constants, and can be used in casestatements

775775 IntroductionIntroduction

CC More Enumerated Constants

enum direction {up, down, left=10,right};

ä You can add an initialization anywhere in the list,subsequent values will increase by 1

ä up == 0 down == 1 left == 10 right == 11

enum boolean { no=0, false=0, yes=1,true=1 };

ä The same value can be used more than once

enum { east, west, south, north }compassPoint;ä Defines a nameless enum (just like a nameless struct)ä Creates one called compassPoint

C Programming UCSD Extension

© 1995 Philip J. Mercurio 388

776776 IntroductionIntroduction

CC Using Enumerated Types

ä enums have scope, just like structures andvariablesä Local if inside a functionä Global if outside all functions

ä Make sure the enumerated identifiers don't conflictwith other variable or function names

ä You can set an enum variable to an integer valueusing a type castä m = (enum month) 6;

ä Try not to treat enums as integers, it defeats theirpurpose

777777 IntroductionIntroduction

CC The typedef Statement

typedef type name;ä Declares a new name for a type

typedef int Counter;ä Defines a new type name Counter, which is the same

as an int

typedef unsigned short int UInt;

ä Can be used to abbreviate long typesä You might use #ifdef to define UInt differently on

different machines, then use UInt everywhereä Avoids lots of #ifdefs

C Programming UCSD Extension

© 1995 Philip J. Mercurio 389

778778 IntroductionIntroduction

CC How To Write a typedef

ä There's a simple rule for writing a typedefdeclaration, no matter how complicated the type is:ä Write the declaration as if you were declaring a variable

of the type you wantä In place of the variable name, put the new type nameä Place the keyword typedef in front of everything

779779 IntroductionIntroduction

CC typedef and #define

ä Why not just #define Counter int ?ä Consider:

ä #define CharPtr char * vs.ä typedef char *CharPtr;

CharPtr a,b;ä If #define used, is expanded to char * a, b;ä typedef generates the equivalent of char *a, *b;

C Programming UCSD Extension

© 1995 Philip J. Mercurio 390

780780 IntroductionIntroduction

CC More typedef Examples

typedef char String[81];ä Defines a new type String, an array of 81 charsä String a,b; is the same as char a[81], b[81];

typedef struct date Date;ä Defines a new type Date, equivalent to struct date

Date today, tomorrow;ä Creates two Dates

781781 IntroductionIntroduction

CC Typedef'ing Nameless Structs

ä Many programmers never use named structs,they use typedefs instead

typedef struct {int month, day, year;

} Date;

ä Defines a nameless struct and then creates atypedef Date for it

Date birthdays[100];ä Creates an array of 100 Dates

Date *datePtr;ä Creates a pointer to a Date

C Programming UCSD Extension

© 1995 Philip J. Mercurio 391

782782 IntroductionIntroduction

CC Back to Linked Lists

typedef struct entry_struct {int value;

struct entry_struct *next;

} Entry;

ä The typedef for Entry isn't defined yet inside thestruct definitionä Can't say Entry *next;

ä If a struct has to refer to itself, you have to name itä You'll never need to use the structure name

(struct entry_struct) again,ä Everywhere else can use Entry

783783 IntroductionIntroduction

CC C Tongue Twisters

ä Try to declare a two-dimensional (8 x 8) array ofpointers to functions which return pointers to astruct piece and take two ints as argumentsä This might appear in a chess program, for exampleä It might represent a chess board, with each location

containing a function which returns a structurerepresenting a chess piece

ä The only sane way to do this is to break it downusing typedefsä You'll probably need to use the sub types in other

declarations too

C Programming UCSD Extension

© 1995 Philip J. Mercurio 392

784784 IntroductionIntroduction

CC Tongue Twister Breakdown

typedef struct piece Piece;

typedef Piece *PiecePtr;

ä The structure representing a chess piece, and a pointertypedef PiecePtr (*PieceFunc)(int x,int y);

ä The function pointertypedef PieceFunc[8][8] Board;

ä Finally, the array

785785 IntroductionIntroduction

CC Data Type Conversions

ä We've discussed explicit data type conversions(type casts) and some of the implicit ones (floatvs. integer division)

ä There are strict rules the compiler follows whendetermining the type of an expression

ä As each binary operator is processed, the types ofthe two operands are looked at

ä The type of the expression is the type of the higherorder operand

ä The other operand is converted to this type

C Programming UCSD Extension

© 1995 Philip J. Mercurio 393

786786 IntroductionIntroduction

CC Operand Conversion

If either operand is of type: The type of the expression is:

long double

No

Yeslong double

double

No

Yesdouble

float

No

Yesfloat

char, short,bit field, enum

No

Yes

convert operand to int

787787 IntroductionIntroduction

CC Operand Conversion (continued)

If either operand is of type: The type of the expression is:

long int

No

Yeslong int

int

C Programming UCSD Extension

© 1995 Philip J. Mercurio 394

788788 IntroductionIntroduction

CC Operand Conversion Example

float f; int i; long l; short s;

f * i + l / s

ä f * i gets converted to two floatsl / s

ä s gets converted to intä s gets converted again to long intä long int division is performed

ä float + longä The long expression gets converted to float,ä but the fractional portion was already lost in the divisionä The result is a float

789789 IntroductionIntroduction

CC More Operand Conversion

ä If we wanted to avoid the integer division in f * i+ l / sä We have to type cast either l or s to (float)

ä This isn't the full story, it gets more complicatedwhen unsigned are involvedä See Appendix A in PAC

C Programming UCSD Extension

© 1995 Philip J. Mercurio 395

790790 IntroductionIntroduction

CC Sign Extension

ä When a signed char or int is converted to alarger int, the sign bit is extended all the way tothe left

0001 01000001 0100 20 0000 0000 0001 01000000 0000 0001 0100 20

1110 11001110 1100-20 1111 1111 1110 11001111 1111 1110 1100-20

char c; short int i = c;

1110 11001110 1100236 0000 0000 1110 11000000 0000 1110 1100236

unsigned char c; unsigned short int i = c;

791791 IntroductionIntroduction

CC unsigned char

ä char is signed by default, on most machinesä This is fine for dealing with ASCII, which never goes

over +127

ä When dealing with chars as 8 bit bytes, you oftenwant to deal with them as unsigned chars

ä typedef unsigned char byte; is a commontype definition

C Programming UCSD Extension

© 1995 Philip J. Mercurio 396

792792 IntroductionIntroduction

CC Argument Conversion

ä C will perform type conversions on arguments tofunctions

ä It can only do this if it's seenä The function itself orä a prototype for the function

ä Without info on a functionä It's assumed to return intä The arguments have to be converted according to K&R,

for compatibility

ä K&R promotes char or short arguments to ints,and floats to doubles

793793 IntroductionIntroduction

CC Conversion Example

float x,y;

y = absoluteValue(x);

ä If no prototype for absoluteValue() has beenseenä The x will get promoted to a doubleä The function will be assumed to return int

ä If, in fact, float absoluteValue(float v);all hell breaks looseä Your program will either behave strangely or crash

ä Always use prototypes!

C Programming UCSD Extension

© 1995 Philip J. Mercurio 397

794794 IntroductionIntroduction

CC Common Programming MistakesRevisited

ä Let's return to the list of common programmingmistakes, now that we've seen almost all of C

ä The first new item on our list is:ä Omitting Prototype Declarations

ä We just saw how this can confuse a computer

795795 IntroductionIntroduction

CC Confusing Operator Precedences

while( c = getchar() != EOF ) ..

ä Assignment has low precedenceä Evaluated as c = (getchar() != EOF), c will be equal to 1

or 0

if(x & 0xF == y) ...

ä Bitwise operators have low precedenceä Evaluated as x & (0xF == y), x is ANDed with 1 or 0

ä If in doubt, use parentheses!

C Programming UCSD Extension

© 1995 Philip J. Mercurio 398

796796 IntroductionIntroduction

CC Confusing char constants and strings

char text = 'a';

char *text = "a";

ä Remember that a character constant is a numericalvalue, while a string constant is a pointer to wherethe characters are stored (null-terminated)

797797 IntroductionIntroduction

CC Forgetting to Leave Room for theNull

ä Character arrays have to have room for the nullterminator

ä If a string is n chars long, you need n+1 chars tostore it

C Programming UCSD Extension

© 1995 Philip J. Mercurio 399

798798 IntroductionIntroduction

CC Confusing -> with .

ä Remember that . is used with structure variablesä -> is used with pointers to structuresä The compiler won't let you make a mistake, but you

may have to decipher long expressions filled with ->and . to find the error

799799 IntroductionIntroduction

CC Using a pointer before initializing it

char *ptr;

*ptr = 'X';

ä ptr doesn't point to anything yet, so it doesn'tmake sense to store something there

ä This stores an 'X' in some random location inmemory, and will probably crash your program

C Programming UCSD Extension

© 1995 Philip J. Mercurio 400

800800 IntroductionIntroduction

CC Ending a #define with a ;

#define END_OF_DATA 999;

ä if(value == END_OF_DATA)... wouldexpand to if(value == 999;)

ä This would generate a syntax error that may be alittle tricky to find

801801 IntroductionIntroduction

CC Omitting Parens In MacroExpansions

#define reciprocal(x) 1 / x

ä w = reciprocal(a + b); is expanded as 1 /a + b and computed as (1/a) + b

ä #define square(x) x * x

ä w = 1 / square(v); is expanded as 1 / v *v and computed as (1/v) * v == 1

C Programming UCSD Extension

© 1995 Philip J. Mercurio 401

802802 IntroductionIntroduction

CC Leaving a Blank After a Macro Name

#define MIN (a,b) ( ((a) < (b)) ? (a): (b) )

ä This defines a macro called MIN with noarguments that expands to "(a,b) ( ((a) <(b)) ? (a) : (b) )"

ä Another confusing syntax error

803803 IntroductionIntroduction

CC Using an Expression with Side-Effects in a Macro

#define square(x) ((x) * (x))

ä w = square(v++); expands to ((v++) *(v++))

ä First v * v is assigned to wä Then v is incremented twiceä If v starts as 3, after this statement

ä w == 9

ä v == 5

C Programming UCSD Extension

© 1995 Philip J. Mercurio 402

804804 IntroductionIntroduction

CC Exercises due next session

ä Read: Chapters 12, 13, and 14ä Exercises: Chapter 12

ä 2, 3, 4, 5, 6, 7, 8ä Ex. 6 & 7: Use the int_size() function from Ex. 3ä Ex. 6 Test input:

bit_search( 0xE1F4, 0x5, 3 )

bit_search( 0xE1F4, 0xFF, 6 )

bit_search( 0xE1F4, 0xF3, 4 )

ä Ex. 7: Initialize x to 0xFFFF

805805 IntroductionIntroduction

CC Exercises due next session

ä Exercises: Chapter 13ä 3, 4, 5, 6, 7, 8, 9

ä Exercises: Chapter 14ä 1, 2, 3

ä *** Extra Credit: ***ä Exercises: Chapter 16

ä 3, 4, 5, 6

C Programming UCSD Extension

© 1995 Philip J. Mercurio 403

806806 IntroductionIntroduction

CC

C Programming

Modularity & I/OPhil Mercurio

UCSD [email protected]

807807 IntroductionIntroduction

CC Today's Session

ä Input and Output [Chapter 16]ä Character I/O, Formatted I/O, File I/O

ä Miscellaneous Features and Advanced Topics[Chapter 17]ä Break, Continue, Goto, & Null Statementsä Unions, Command Line Arguments, Dynamic Memory

Allocation

ä Modularity [Chapter 15]ä Separate Compilations, Communication Between

Modules

C Programming UCSD Extension

© 1995 Philip J. Mercurio 404

808808 IntroductionIntroduction

CC Input/Output

ä Unlike other languages, C does not have built-insupport for I/O

ä All I/O is performed by library function callsä We've been using the stdio library which is

included in the standard C libraryä #include <stdio.h>

ä Includes the header file describing the contents of thestdio library

809809 IntroductionIntroduction

CC Files

ä stdio deals with input and output in terms of filesä A file is a stream of characters that can be read or

written one or more characters at a timeä Files containing text are usually read or written a line at

a time

ä Files can contain any arbitrary binary data and canbe read/written in chunks of any size

C Programming UCSD Extension

© 1995 Philip J. Mercurio 405

810810 IntroductionIntroduction

CC Buffering

ä stdio buffers the input and outputä Reading a single character causes a whole buffer

(probably around 1K) to be read from diskä Next time you read a character, it comes from the buffer

(in memory)ä Writing is buffered too

811811 IntroductionIntroduction

CC FILE

ä stdio.h defines a data structure called FILEä FILE contains all the information about an open

file:ä Where the file lives on diskä Whether it's being read or written toä A buffer used to read/write the fileä A representation of the current location in the file (how

much we've read or written)

ä We never need to look at the inside of the FILEstructure, we only need to deal with pointers toFILEs (FILE*)

C Programming UCSD Extension

© 1995 Philip J. Mercurio 406

812812 IntroductionIntroduction

CC Opening Files

FILE *fopen(char *name, char *mode)

ä Returns a pointer to a FILE structure representingan open fileä Returns NULL if unsuccessful

ä name is a character string containing the file nameä mode is a string:

ä "r" to open a file for readingä "w" to open a file for writing (creates or erases file)ä "a" to open an existing file to write additional stuff at the

end (append)ä Other codes for other modes

813813 IntroductionIntroduction

CC fopen() example

FILE *in, *out;

ä Declares two file pointersin = fopen("data", "r");

ä Opens the file "data" for readingif(in == NULL) printf("Unable to openfile: data\n");

ä Checks to see if we successfully opened the fileä Always check the result of fopen() to make sure it

worked!

C Programming UCSD Extension

© 1995 Philip J. Mercurio 407

814814 IntroductionIntroduction

CC fopen() example (continued)

out = fopen("output", "w");

ä Opens an output filefclose(in);

ä Closes the file in

815815 IntroductionIntroduction

CC stdin, stdout, stderr

ä The C library automatically opens three FILE*s foryouä stdin The standard input

ä Usually the keyboardäscanf() reads from stdin

ä stdout The standard outputä Usually the screenäprintf() writes to stdout

ä stderr The standard error outputä Also the screen

C Programming UCSD Extension

© 1995 Philip J. Mercurio 408

816816 IntroductionIntroduction

CC Redirecting I/O

ä In Unix and MS-DOS, you can take the input to aprogram from a file:program < file1

ä When the program reads from stdin, it reads fromfile1 rather than the keyboard

ä You can also direct the output to a fileprogram > file2

ä Anything written to stdout goes to file2ä stderr output still appears on the screen, so you can

see error messages

ä You can also do both at onceprogram < file1 > file2

817817 IntroductionIntroduction

CC Character Input and EOF

int getc(FILE *fp)

ä Reads a character from the file pointer fpä Returns the value of the characterä At the end of the input, the special code EOF is

returnedä EOF is #defined in stdio.h (usually as -1)ä getc() returns an int so we can distinguish EOF from

any possible character

C Programming UCSD Extension

© 1995 Philip J. Mercurio 409

818818 IntroductionIntroduction

CC Character Input and EOF

ä If the input is a file, EOF is returned when the entirefile has been read

ä If the user is typing the input, EOF is returned whenthey type a special code like ^D or ^Z

ä int feof(FILE *fp)ä Returns true if the file fp is at the end, false otherwise

819819 IntroductionIntroduction

CC Character Output and Macros

int putc(int c, FILE *fp)ä Write a character to the file pointer fpä Returns the value of the character written, or EOF if

something went wrongä We rarely check the return value

ä Since C promotes chars to ints, we can use a charas the first argument

ä getchar() is #defined to be the same asgetc(stdin)

ä putchar(c) is #defined to be the same asputc(c, stdout)

C Programming UCSD Extension

© 1995 Philip J. Mercurio 410

820820 IntroductionIntroduction

CC Program 10-1 & Output

/* Copy stdin to stdout */#include <stdio.h>

main(){

int c;

while((c = getchar()) != EOF)putchar(c);

}

abcdefgabcdefghijklmnhijklmn

OutputOutput

821821 IntroductionIntroduction

CC Notes on Program 10-1

ä while((c = getchar()) != EOF)

ä First gets a character from the inputä Assigns the character value to the int cä Compares c against EOF

ä prog10-1 < file1

ä Copies file to the screenä prog10-1 > file2

ä Reads input from the user up to a ^D or ^Zä Copies that text to file2

C Programming UCSD Extension

© 1995 Philip J. Mercurio 411

822822 IntroductionIntroduction

CC Program 10-2

/* Copy foo to bar */#include <stdio.h>#include <stdlib.h>

main(){

FILE *in;FILE *out;int c;

in = fopen("foo", "r");if(in == NULL) {

printf("Unable to open input file \"foo\"\n");exit(EXIT_FAILURE);

}

out = fopen("bar", "w");if(out == NULL) {

printf("Unable to open output file \"bar\"\n");exit(EXIT_FAILURE);

}

823823 IntroductionIntroduction

CC Program 10-2 (continued)

while((c = getc(in)) != EOF)putc(c, out);

fclose(in);fclose(out);exit(EXIT_SUCCESS);

}

C Programming UCSD Extension

© 1995 Philip J. Mercurio 412

824824 IntroductionIntroduction

CC Notes on Program 10-2

ä The names of the input and output files areexplicitly expressed in the fopen() calls

ä Note that the loop itself is pretty much the sameä Always check the result of fopen()!ä If we aren't able to open one of the files, we exit

the program immediately with exit()

825825 IntroductionIntroduction

CC exit()

void exit(int status)

ä Exits your program immediatelyä Returns a status value to the operating system

ä Unix and MS-DOS can use this in a shell script or batchfile

ä EXIT_FAILURE and EXIT_SUCCESS are defined instdlib.h

ä exit() is just like return()ing from main()ä Except that any function can call exit()

ä exit() cleans up, closing all open files andfreeing all memory

C Programming UCSD Extension

© 1995 Philip J. Mercurio 413

826826 IntroductionIntroduction

CC Reading Lines

char* fgets(char *buffer, int n, FILE*fp)ä Reads a line of input from fp, storing the chars inbuffer

ä Includes newline in bufferä Won't read more than n-1 chars (n is the size of buffer)ä Returns buffer if successful, NULL if error or end of file

char* gets(char *buffer)ä Reads a line from stdin into bufferä Does not include newline in bufferä A good size for buffer is BUFSIZ

827827 IntroductionIntroduction

CC Writing Lines

int fputs(char *buffer, FILE *fp)ä Writes buffer to the file fpä buffer should already have a newline at the endä Returns number of chars written, or EOF if failure

int puts(char *buffer)ä Writes buffer to stdoutä Always appends a newline

C Programming UCSD Extension

© 1995 Philip J. Mercurio 414

828828 IntroductionIntroduction

CC Formatted Input

int scanf(char *format, ...)ä Reads stdin for the input described by the formatä Stores the input in the locations pointed to by the argsä Returns the number of codes in format that were

satisfiedä Or EOF if no input left

int fscanf(FILE* fp, char *format, ...)ä Same as scanf(), but reads from any open file pointer

int sscanf(char *buffer, char * format,...)

ä Reads from a character array rather than a file

829829 IntroductionIntroduction

CC Formatted Output

int printf(char* format, ...)ä Writes stdout using the format and argsä Returns the number of chars printed, or a negative

value if an error occurred

int fprintf(FILE *fp, char *format,...)ä Same as printf(), but writes to any file pointer

int sprintf(char *buffer, char *format,...)

ä Writes to a character array, rather than a file

C Programming UCSD Extension

© 1995 Philip J. Mercurio 415

830830 IntroductionIntroduction

CC Binary Files

ä Reading and writing binary files is done withfread() and fwrite()

ä You may need to use a special fopen() mode like"rb" to read a binary fileä This is primarily true on MS-DOS and Windows

ä In addition to reading and writing characters, theycan be used to read and writeä Raw ints, floats, and doublesä The contents of structures

ä Beyond the scope of this course, see a book onadvanced C

831831 IntroductionIntroduction

CC Miscellaneous Features

ä We'll briefly cover some miscellaneous topicsä Infrequently used featuresä Advanced Topics

ä We'll also provide some rules of thumbä General guidelines for more readable programs�Marked like this

C Programming UCSD Extension

© 1995 Philip J. Mercurio 416

832832 IntroductionIntroduction

CC The goto statement

ä You can label a place in a function with:ä label: a = b;

ä The label can be any valid C nameä To jump to this location from somewhere else in

the same function:ä goto label;

ä Using goto's makes it hard to follow the flow ofyour program

ä Sometimes a goto is the best way to get out ofnested loops�Never more than 1 or 2 labels per function

833833 IntroductionIntroduction

CC Null statement

ä ; is a valid C statement, it does nothingä Handy when a while or for statement doesn't need a

bodyfor(count = 0; getchar() != EOF;count++)/* null body */ ;

ä Counts all the characters in the input�When you use a null statement, use a comment

C Programming UCSD Extension

© 1995 Philip J. Mercurio 417

834834 IntroductionIntroduction

CC Comma Operator

for(i = 0, j = 0; i > 5; i++, j++) ...

ä You can use commas to join two (or more)statements together to form oneä Very useful in for statements just like this oneä Can be used anywhere

�Don't use commas like this anywhere except infor statementsä Everywhere else you can use { }

835835 IntroductionIntroduction

CC sizeof()

ä sizeof() looks like a function call, but it's actuallybuilt-in to C

ä sizeof() returns the size (in bytes) ofä a data type: sizeof(int) or sizeof(struct date)ä a variable: sizeof(c)

ä Given the name of an array, it can tell you the sizeä Given a pointer, it can only tell you the size of a

pointer

C Programming UCSD Extension

© 1995 Philip J. Mercurio 418

836836 IntroductionIntroduction

CC Handy sizeof() macro

#define ELEMENTS(x) (sizeof(x) /sizeof(x[0])

ä Defines a macro which returns the number ofelements in an array, regardless of what type thearray is

837837 IntroductionIntroduction

CC Program 10-3

/* sizeof Example */#include <stdio.h>

main(){

struct date {int month, day, year;};char *ptr, array[20];

printf("sizeof(int) = %i\n", sizeof(int));printf("sizeof(short) = %i\n", sizeof(short));printf("sizeof(long) = %i\n", sizeof(long));printf("sizeof(float) = %i\n", sizeof(float));printf("sizeof(double) = %i\n", sizeof(double));printf("sizeof(char*) = %i\n", sizeof(char *));printf("sizeof(struct date) = %i\n", sizeof(struct

date));

ptr = array;printf("sizeof(ptr) = %i\n", sizeof(ptr));printf("sizeof(array) = %i\n", sizeof(array));

}

C Programming UCSD Extension

© 1995 Philip J. Mercurio 419

838838 IntroductionIntroduction

CC Program 10-3 Output

sizeof(int) = 2sizeof(short) = 2sizeof(long) = 4sizeof(float) = 4sizeof(double) = 8sizeof(char*) = 2sizeof(struct date) = 6sizeof(ptr) = 2sizeof(array) = 20

839839 IntroductionIntroduction

CC Unions

ä A union is a strange concept used mostly inadvanced programs

ä A union is used when you need to look at thesame location in memory as if it were one of a setof different types

ä A union is declared like a structure

C Programming UCSD Extension

© 1995 Philip J. Mercurio 420

840840 IntroductionIntroduction

CC Unions (continued)

union mixed {char c;

float f;

long int l;

};

ä Defines a single member which can store a char,float, or long

ä The size of the union is the size of its largestmember

841841 IntroductionIntroduction

CC

.c .l

Union vs. Struct

date

.month

.day

.year

struct date { int month, day, year; };

.f

mixed

union mixed { char c; float f; long l; };

C Programming UCSD Extension

© 1995 Philip J. Mercurio 421

842842 IntroductionIntroduction

CC Variable Attributes

ä There are additional keywords that can be addedin front of a variable declaration to modify how thecompiler treats it:register

const

volatile

843843 IntroductionIntroduction

CC register

register int index;

register char *ptr;

ä Asks the compiler to store the variable in a register(on the CPU) rather than in memoryä Used for variables which are used frequently, speeds up

access

ä Each function has its own set of registersä Registers saved/restored when a subroutine is calledä The number of registers available varies, when none left

the compiler ignores the register suggestion

ä You can't take the address of a register variable!

C Programming UCSD Extension

© 1995 Philip J. Mercurio 422

844844 IntroductionIntroduction

CC const

const double pi = 3.141592654;

ä Tells the compiler that you won't be changing avalue

ä Attempts to assign something to pi or change itsvalue will generate a compiler errorä The compiler is not required to generate an error, it may

just generate a warning or do nothing

ä Compiler may optimize by putting this variable inread-only memory

845845 IntroductionIntroduction

CC volatile

ä Sort of the opposite of const, used to tell thecompiler that a variable's value will changeä Prevents the compiler from making optimizations when it

looks like something can be removed

ä Consider an I/O port, every time you place acharacter at that location it is sent to a outputdevice*port = 'O';

*port = 'N';

C Programming UCSD Extension

© 1995 Philip J. Mercurio 423

846846 IntroductionIntroduction

CC volatile (continued)

ä A smart compiler might optimize out the firstassignment, since the value doesn't appear tochange before the next assignment

ä volatile char *port; prevents thisoptimization

847847 IntroductionIntroduction

CC Command-Line Arguments

ä When the operating system executes a C program,it can provide the program with arguments

ä These arguments appear on the command line astyped by the user:ä Unix: cat file1 file2ä MS-DOS: type file1ä Windows: command line is one of the properties of the

program's icon

ä The strings typed on the command line are passedas arguments to main()

C Programming UCSD Extension

© 1995 Philip J. Mercurio 424

848848 IntroductionIntroduction

CC main() Prototype

int main(int argc, char *argv[])ä argv (the argument vector) is an array of strings

(char*)ä argc (the argument count) is the number of elements inargv[]

ä argv[0] is the name of the program itselfä argv[1] is the first argument, argv[2] is the

second, etcä If you typed n arguments, argc will be n + 1

ä Remember argv[0] is the name of the program

849849 IntroductionIntroduction

CC Program 10-4 & Output

/* Arguments example */#include <stdio.h>

int main(int argc, char *argv[]){

register int i;

printf("The program's name is: %s\n", argv[0]);

printf("You typed %i arguments:\n", argc - 1);

for(i=1; i < argc; i++)printf("\t%s\n", argv[i]);

}

The program's name is: C:\0WORK\CCLASS\SRC\PROG10-4.EXEYou typed 0 arguments:

OutputOutput

C Programming UCSD Extension

© 1995 Philip J. Mercurio 425

850850 IntroductionIntroduction

CC More on Arguments

ä Remember that arguments are passed as stringsä If the user is supposed to type a number, you need to

convert the string into a numberä int atoi(char *string) is a good function for this

purpose

ä Options to a program are identified with a specialcharacterä Unix: cc -c -DFOO foo.cä MS-DOS: cc /c /DFOO foo.c

ä The programmer has to write code to look at eachargument and decide whether it's an option, a filename, etc.

851851 IntroductionIntroduction

CC Dynamic Memory Allocation

ä Whenever we create an array, we have to specifythe number of elements as a constant

ä What do we do if we don't know how big the arrayneeds to be until runtime?ä Perhaps we compute the size of the array based on one

of the command-line arguments

ä The standard C library provides functions toallocate memory at runtime, and to de-allocatememory (make it available for re-use)

C Programming UCSD Extension

© 1995 Philip J. Mercurio 426

852852 IntroductionIntroduction

CC malloc()

#include <stdlib.h>

void *malloc(size_t size)ä size_t is the data type used to store sizes on your OS,

usually an unsigned long intä malloc() returns a pointer to size bytes of freshly-

allocated memoryä The return type is void*, it can be type-cast to point to

anythingä The memory is not initializedä Will return NULL if no memory is available--always check

for this!

853853 IntroductionIntroduction

CC malloc() (continued)

struct date *datePtr;

datePtr = (struct date *)malloc(sizeof(struct date));

ä Dynamically allocates a date structureä Note use of sizeof()

ä datePtr->month = 11; just like any otherstructure pointer

C Programming UCSD Extension

© 1995 Philip J. Mercurio 427

854854 IntroductionIntroduction

CC calloc()

ä void *calloc(size_t nElem, size_telemSize)ä nElem is the number of elements, elemSize is the size

of one elementä Same as malloc(nElem * elemSize)ä Except that it initializes the memory to zeros

ä int *intPtr;

ä intPtr = (int *) calloc(1000,sizeof(int));

ä intPtr is a dynamically allocated array of 1000ints

855855 IntroductionIntroduction

CC free()

void free(void *ptr)

ä Frees the memory specified by the pointerä The pointer must have been returned from malloc() orcalloc() or related functions

ä Attempting to free memory that was staticallyallocated by the compiler will cause a run-time error

ä free(intPtr); frees the dynamic arrayä All dynamically allocated memory is freed byexit()

ä Don't use the pointer after you've freed thememory!

C Programming UCSD Extension

© 1995 Philip J. Mercurio 428

856856 IntroductionIntroduction

CC Dynamic Memory Tips

�Linked lists, trees, etc. work very well with dynamicallocation

�Allocate big chunks, not lots of little piecesä Too many malloc()s may slow down your program

�Don't use dynamic allocation when the compiler'sallocation will workä The compiler can't optimize dynamic allocations

857857 IntroductionIntroduction

CC Memory Leaks

ä Remember to free() whatever you malloc()!ä Failing to free all the memory you malloc() is a

common cause for run-time errors that happenafter your program has been running for a while

ä If the pointer is a variable local to your function,before returning you have toä Free the memory orä Pass the pointer to some other piece of code by storing

it in a global variable, returning its value, etc.

ä Otherwise, you lose the pointer and can't free thememory later: this is a memory leak

C Programming UCSD Extension

© 1995 Philip J. Mercurio 429

858858 IntroductionIntroduction

CC Modularity

ä Up to now, we've only dealt with small programsä Less than 100 linesä All in one file

ä Real-world programs are much larger and spreadamong many files

ä Modularity is a means of dealing with complexityä Object-orientation is an approach to modularity

859859 IntroductionIntroduction

CC Code Complexity Scale

Lines of Code Class Team Time

10’s Quick hack 1 Hours

100’s Small utility 1 Days

1000’s Useful tool 1-3 Weeks

10,000’s Smallapplication

1-8 Months

100,000’s Application 3-30 Years

1,000,000’s Major project 20-200 Many years

C Programming UCSD Extension

© 1995 Philip J. Mercurio 430

860860 IntroductionIntroduction

CC Multiple Files

ä In every program we've written so far, we'vecompiled it and linked it immediately afterward

ä If we split our code into multiple .c files, we canä Break up compilation by only recompiling .c files that

changeä Break up work by assigning parts to different

programmersä Break up design by creating modules each responsible

for one thing

861861 IntroductionIntroduction

CC .c Files and .h Files

ä A typical program consists of a directory full of .cand .h filesä .h files contain #defines and #includes, datatype

definitions, data declarations, and function prototypesä .c files contain #includes of .h files, and functionsä .c files are turned into .o files by compiling

�Don't put functions in .h files, might end up inmultiple .o files

�If it can go in a .h file, put it thereä A clean .c file has a few #includes, maybe a small

number of global variables, then functions

C Programming UCSD Extension

© 1995 Philip J. Mercurio 431

862862 IntroductionIntroduction

CC Separate Compilations

ä These examples will be from Unix, but the conceptsare similar in all compilers

cc -o prog1 prog1.cä Compiles prog1.c to produce prog1.oä Links prog1.o with the standard C library to create prog1ä Usually removes prog1.o after link

cc -c prog1.cä Compiles prog1.c to produce prog1.oä Does not link, does not remove .o file

cc -c prog1.c mod1.cä Makes prog1.o and mod1.o, no linking

863863 IntroductionIntroduction

CC Linking

ä Unless there's a -c flag, cc tries to link together anexecutable

ä The file names passed to cc can be a mixture of.c and .o files

ä cc will compile each of the .c files firstcc -o prog1 prog1.c mod1.o

ä Compiles prog1.cä Links prog1.o and mod1.o with the C library to makeprog1

cc -o prog1 prog1.o mod1.o

ä No compilation, just link

C Programming UCSD Extension

© 1995 Philip J. Mercurio 432

864864 IntroductionIntroduction

CC Build Scripts and Makefiles

ä As a project grows to include many .c files, you'llneed a script (or batch file) to run your compilationä But a script would compile every .c file every time,

even if it hasn't changed

ä In Unix and other environments, you can use a toolcalled make

865865 IntroductionIntroduction

CC Make

ä make reads a file describing your project (amakefile)

ä make can compare the dates of a .c file and its.o fileä If the .o file is newer than the last time the .c file was

edited, no need to compile itä You can also tell make which .h files a .c file depends

on

ä Most integrated environments (like Visual C++)have the features of make built-in

C Programming UCSD Extension

© 1995 Philip J. Mercurio 433

866866 IntroductionIntroduction

CC Communication Between Modules

ä Each .c file (plus the .h files it includes) is aseparate module

ä Since each module is compiled separately, itknows nothing about other modules

ä Information (data types, function prototypes,#defines) is shared among modules by#including common .h files

ä Global variables (variables declared outside afunction) in a module can be accessed by othermodules

ä The variable has to be declared as external

867867 IntroductionIntroduction

CC External variables

ä In prog1.c, we have the following global variable:int moveNumber = 0;

ä We can reference this same variable in mod1.c ifwe declareextern int moveNumber;

ä Any module can reference this variable bydeclaring it as an external variable

C Programming UCSD Extension

© 1995 Philip J. Mercurio 434

868868 IntroductionIntroduction

CC The Real Thing

ä Somewhere, the variable must really be createdä That's usually done by making sure, in one module

and one module only, that the variable is declaredwithout the extern:

int moveNumber;

int moveNumber = 0;

869869 IntroductionIntroduction

CC The Real Thing (continued)

ä The variable can only be initialized in one placeä In the special case of an initialization, you can

leave the extern in:ä extern int moveNumber = 0; is the same as intmoveNumber = 0;

ä Don't do this, it's more clear to leave out the extern

C Programming UCSD Extension

© 1995 Philip J. Mercurio 435

870870 IntroductionIntroduction

CC mod10-5a.c & mod10-5b.c

/* Part of Program 10-5 */

extern int i;

foo(){

i = 100;}

mod10-5a.cmod10-5a.c

/* Part of Program 10-5 */

extern int i;

bar(){

i *= 3;}

mod10-5b.cmod10-5b.c

871871 IntroductionIntroduction

CC Program 10-5 & Output

/* Modularity example */#include <stdio.h>

int i = 5;

main(){

printf("%i ", i);

foo();printf("%i ", i);

bar();printf("%i\n", i);

}

5 100 300

OutputOutput

C Programming UCSD Extension

© 1995 Philip J. Mercurio 436

872872 IntroductionIntroduction

CC Extern Arrays

ä Declaring an extern array is like declaring an arrayas an argument to a functionä We don't need to know the size of a one-dimensional

arrayä We don't need the size of the first dimension in a

multidimensional arrayä char text[80]; int matrix[40][50];

global declarationsä extern char text[]; extern intmatrix[][50]; external declarations

873873 IntroductionIntroduction

CC Static Globals

ä By default, all global variables in a module areexternally visibleä Other modules choose to see your global variables by

declaring them as externs

static int moveNumber = 0;ä Declares a global variable that's private to this .c fileä Other modules' attempts to access this variable viaextern won't work

ä Two files can each have a global, static variablewith the same nameä They will be two different variables, not commonä Can't do this without declaring it static

C Programming UCSD Extension

© 1995 Philip J. Mercurio 437

874874 IntroductionIntroduction

CC extern:variable :: prototype:function

ä An extern declaration for a variable is like aprototype for a functionä Functions, like global variables, can be used by any

module that declares a prototype for itstatic int privateFunction() {...code...}

ä Defines a function which cannot be called outside itsmodule

ä Allows you to have more than one function with thesame name, in different .c files

875875 IntroductionIntroduction

CC Why static?

�Modules should know as little about each other aspossibleä By limiting what module A knows about module B,ä it's easier to change B without affecting A

ä By declaring variables and functions as static,we hide them from other modules and are free tochange them

�A perfectly modular program would have no globalvariables and as few global functions as possible

C Programming UCSD Extension

© 1995 Philip J. Mercurio 438

876876 IntroductionIntroduction

CC Object-Orientation

ä How do you decide what functions belong in whichmodules?

ä There are many schools of thought on this, onepopular one is object-orientation (OO)

ä Using OO, we focus on the data structures ratherthan the functions

ä Break down a problem in terms of the objects thathave to be created, destroyed, change and interact

ä For each type of object, define a data structure anda set of functions

877877 IntroductionIntroduction

CC Classes & Objects

ä A class is a description of an object, consisting ofä A C struct containing all the data you need to know

about this type of objectä Including references to other objects

ä The prototypes of all the functions that create, destroy,and operate on this struct (called public methods)

ä Declaring a variable of this struct is creating anobject of this class

ä Objects can also be created dynamically (viamalloc(), etc.)

ä If we break up our project in terms of OO modules,each class Foo will consist of two files:

C Programming UCSD Extension

© 1995 Philip J. Mercurio 439

878878 IntroductionIntroduction

CC Foo.h

ä #includes for other classes referenced by Fooand system libraries

ä #defines for Foo parametersä typedef struct { ...} Foo; the structure

which defines the data stored in a Foo objectä Prototypes for public Foo methods:

Foo* FooCreate(); /* Allocate a new Foo */

void FooDestroy(Foo* f); /* Safelydeallocate a Foo */

int FooUpdate(Foo* f, int t); /* Dosomething to a Foo */

879879 IntroductionIntroduction

CC Foo.c

ä #include "Foo.h"

ä Private (static) global data shared by all Fooobjects

ä Prototypes of private methodsä Definitions of the public methodsä Definitions of the private methods

C Programming UCSD Extension

© 1995 Philip J. Mercurio 440

880880 IntroductionIntroduction

CC The Old #ifndef Trick

ä If we try to include two header files, ClassA.hand ClassB.h, each of which use the Foo classä We might end up including Foo.h twice!ä This will generate all sorts of compilation errors

ä Always wrap the entire contents of your .h file in:#ifndef FOO_HEADER

#define FOO_HEADER

ä ... Everything in the .h file...#endif

ä The #define used (FOO_HEADER) should beunique, so it's usually based on the file name

881881 IntroductionIntroduction

CC How the trick works

ä The first time Foo.h is included, FOO_HEADER isnot definedä The #ifndef succeeds and the contents are includedä FOO_HEADER is #defined

ä The second time Foo.h is included, FOO_HEADERis definedä The #ifndef fails, and the entire contents of the file are

skipped

ä If you always use this trick, you never have toworry about including files more than once

C Programming UCSD Extension

© 1995 Philip J. Mercurio 441

882882 IntroductionIntroduction

CC What C++ Provides

ä C++ adds a lot of syntax for dealing with objectsä In C++, a struct is called a class

ä A class can contain functions as well as dataä Portions of a class can be marked as privateä A class can inherit from another class

ä For example, a Rose class might be defined asbeing just like the Flower class, but with specialproperties (like having thorns)

ä There's a lot more to OO and C++ than presentedhere, but we can still begin to think in OO termswhile programming in C

883883 IntroductionIntroduction

CC One-Dimensional Cellular Automata

ä As our final example, let'screate a program to drawone-dimensional cellularautomata

ä As described in Levy,Steven. Artificial Life, pp. 69-74

C Programming UCSD Extension

© 1995 Philip J. Mercurio 442

884884 IntroductionIntroduction

CC Problem Description

ä We start with a 1-D array of cells which are eitheron or offä Print this out

ä For each cycle, we update the cell array accordingto a set of rules and print it out againä For each cell, we look at its neighbors to the left and

rightä These three cell values are used to look into a tableä The value in the table is the new value for the cell

885885 IntroductionIntroduction

CC Top-Down Breakdown

ä We begin by breaking the design down into threemain objects:

ä Paramsä Stores the parameters for the simulationä Handles parameter input

ä Displayä Handles the display of the 1-D cellular arrayä Might easily be replaced with another module that

displays the array differently, but looks the same to therest of the application

C Programming UCSD Extension

© 1995 Philip J. Mercurio 443

886886 IntroductionIntroduction

CC Top-Down Breakdown (continued)

ä Engineä Given a Params and a Display, computes a cycle of the

simulation

887887 IntroductionIntroduction

CC main() in Pseudocode

ä Create a Paramsä Get the Params inputä Print out the Params

ä Create a Display (using Params)ä Create an Engine (using Params and Display)ä Cycle Engine until completeä Destroy Engine, Display, Params

C Programming UCSD Extension

© 1995 Philip J. Mercurio 444

888888 IntroductionIntroduction

CC Bottom-Up Construction

ä Proceed by designing tools:ä Boolean

ä Contains a true or false value

ä Bitsä An array of Booleans, used to store the values of the

cellsä We'll need more than oneä Can also be used to store transition rule (in a Bits of

size 8)ä We recognize that this is an important class of objects

and put extra effort into it

889889 IntroductionIntroduction

CC Fancy Bits

ä Let's make Bits a workhorse for the entireprogram, and embellish it with methods for:

ä Setting, clearing, and testing individual Booleansin the array

ä Getting and changing the size of the arrayä Converting a Bits into a printable string, and

converting a string into a Bitsä Copying Bits b to Bits a, with features like

ä Centering b within aä Repeating b until until it fills a

ä Filling a Bits with random values

C Programming UCSD Extension

© 1995 Philip J. Mercurio 445

890890 IntroductionIntroduction

CC Input

ä We need to provide the Params object with a wayto get user inputä For now we'll prompt the user to type in each valueä It may be expanded to include many different ways to

get input (command line arguments, graphical userinterface, etc.)

ä Input provides methods whichä Take a string argument containing the promptä Take a pointer to the value you wish to have the user

inputä Are implemented for ints, chars, strings, and

Booleans

891891 IntroductionIntroduction

CC Back to Top-Down

ä Now that we've built some useful tools, Params,Display, and Engine are easy to construct

ä Top-Down view of design:

Input

Boolean

Bits

Params Display

Engine

C Programming UCSD Extension

© 1995 Philip J. Mercurio 446

892892 IntroductionIntroduction

CC Your Final Assignment

ä Study the source to the Cells program in Appendix Aä Look at it from both the top-down and bottom-up

ä Type Cells in (or Email me for it) and get it to run onyour system

ä Modify Cells to add:ä Command-line argumentsä Graphical displayä GUI for Paramsä Cells that can hold more than 1 bit (multi-colored patterns)

ä If you come up with a spiffy new version, pleasesend me a copy!