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", ¤tTime.hour,
¤tTime.minutes, ¤tTime.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!