You are on page 1of 14

Goals of this Lecture !

•  Help you learn about:"


•  The fundamentals of C"
•  Program structure, control statements, character I/O"
•  Deterministic finite state automata (DFA)"
C Programming Examples! •  Some expectations for programming assignments"
•  Why?"
•  The fundamentals of C provide a foundation for the
systematic coverage of C that will follow"
•  A power programmer knows the fundamentals of C well"
•  DFA are useful in many contexts "
•  A very important context: Assignment 1"
•  How?"
1
•  Through some examples" 2

Overview of this Lecture! Example #1: Echo!


•  Problem: Echo input directly to output"

•  C programming examples" •  Program design"


•  Echo input to output" •  Include the Standard Input/Output header file (stdio.h)"
•  Convert all lowercase letters to uppercase" #include <stdio.h>"
•  Convert first letter of each word to uppercase" •  Allows your program to use standard I/O calls"
•  Makes declarations of I/O functions available to compiler"
•  Glossing over some details related to pointers " •  Allows compiler to check your calls of I/O functions"
•  … which will be covered subsequently in the course"
•  Define main() function"
int main(void) { … }
int main(int argc, char *argv[]) { … }
•  Starting point of the program, a standard boilerplate"
•  Hand-waving: argc and argv are for input arguments"
3 4

1
Example #1: Echo (cont.)! Putting it All Together!
#include <stdio.h>

•  Within the main program"


int main(void) {
int c; Why int instead
•  Read a single character" of char?"
c = getchar(); "
c = getchar();
•  Read a single character from the standard input
stream (stdin) and return it" putchar(c);
Why return a
value?"
return 0;
•  Write a single character" }
putchar(c); "
•  Write a single character to the standard output
stream (stdout)"

5 6

Read and Write Ten Characters! Read and Write Forever!


•  Loop to repeat a set of lines (e.g., for loop)" •  Infinite for loop"
•  Three expressions: initialization, condition, and increment" •  Simply leave the expressions blank"
•  E.g., start at 0, test for less than 10, and increment per iteration" •  E.g., for ( ; ; ) "
•  No initial value, no per-iteration test, no increment at end of iteration"
#include <stdio.h> #include <stdio.h>
Why not this instead:" int main(void) {
int main(void) { for (i = 1; i <= 10; i++)!
int c, i; int c;

for (i=0; i<10; i++) { for ( ; ; ) { When will this


c = getchar(); be executed?"
c = getchar();
putchar(c); putchar(c);
} }
How would you terminate
return 0; return 0; this program?"
} 7 } 8

2
Read and Write Until End-Of-File! Many Ways to Do the Same Job!
•  Test for end-of-file"
•  EOF is a global constant, defined in stdio.h" for (c=getchar(); c!=EOF; c=getchar())
•  The break statement jumps out of the innermost enclosing loop" " putchar(c); Which approach
#include <stdio.h> before the loop is best?"
int main(void) { Typical idiom in C, but
int c; do some stuff
while ((c=getchar())!=EOF)
messy side-effect in
for ( ; ; ) { putchar(c);" loop test"
c = getchar(); done yet?
if (c == EOF) for (;;) { c = getchar();
break; c = getchar();
do more stuff while (c!= EOF){
putchar(c); if (c == EOF)!
} break; ! putchar(c);
after the loop
return 0; !putchar(c); c = getchar();
} 9 }! } 10

Review of Example #1! Example #2: Convert Uppercase!


•  Character I/O" •  Problem: Write a program to convert a file to all uppercase"
•  Including stdio.h •  Leave non-alphabetic characters alone"
•  Functions getchar() and putchar()
•  Representation of a character as an integer"
•  Predefined constant EOF •  Program design:"
•  Program control flow"
•  The for and while statements" repeat in a loop
•  The break statement" Read a character
•  The return statement" If unsuccessful, break out of loop
If the character is lower-case, convert to upper-
•  Operators" case
•  Assignment operator: = " Write the character
•  Increment operator: ++" "
•  Relational operator to compare for equality: =="
"
•  Relational operator to compare for inequality: !="
11 12

3
ASCII! Implementation in C!
American Standard Code for Information Interchange" #include <stdio.h>
int main(void) {
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
int c;
0 NUL SOH STX ETX EOT ENQ ACK BEL BS HT LF VT FF CR SO SI
16 DLE DC1 DC2 DC3 DC4 NAK SYN ETB CAN EM SUB ESC FS GS RS US for ( ; ; ) {
32 SP ! " # $ % & ' ( ) * + , - . / c = getchar();
48 0 1 2 3 4 5 6 7 8 9 : ; < = > ? if (c == EOF) break;
64 @ A B C D E F G H I J K L M N O
if ((c >= 97) && (c < 123))
80 P Q R S T U V W X Y Z [ \ ] ^ _
96 ` a b c d e f g h i j k l m n o
c -= 32;
112 p q r s t u v w x y z { | } ~ DEL putchar(c);
}
Lower case: 97-122 and upper case: 65-90" return 0;
E.g., a is 97 and A is 65 (i.e., 32 apart)" }
13 14

It works!! Itʼs a …!
"

•  Submit"

•  Receive your grade with quiet confidence "

B-"
15 16

4
What? But it works …! Avoid Hard-coded Numbers!
#include <stdio.h>
int main(void) {
•  A good program is:" Ugly. "
int c;
•  Clean" And works for
•  Readable" for ( ; ; ) {
ASCII only"
•  Maintainable" c = getchar();
if (c == EOF) break;
•  It s not enough that your program works!"
if ((c >= 97) && (c < 123))
c -= 32;
•  We take this seriously in COS 217" putchar(c);
•  Seriously == It affects your grade substantially" }
return 0;
17
} 18

Improvement: Character Constants! Improvement: Existing Functions!


Standard C Library Functions ctype(3C)
#include <stdio.h> Section 3C is for C
library functions"
Better. " NAME
int main(void) {
But still ctype, isdigit, isxdigit, islower, isupper, isalpha, isalnum, isspace, iscntrl, ispunct, isprint,
int c; assumes that
isgraph, isascii - character handling

for ( ; ; ) { alphabetic SYNOPSIS


character codes #include <ctype.h> DESCRIPTION
c = getchar(); int isalpha(int c);
are contiguous" These macros classify character-
int isupper(int c);
if (c == EOF) break; coded integer values. Each is a
int islower(int c); predicate returning non-zero for true, 0
if ((c >= a ) && (c <= z )) int isdigit(int c); for false...
int isalnum(int c); The toupper() function has as a
c += A - a ; int isspace(int c); domain a type int, the value of which is
int ispunct(int c); representable as an unsigned char or
putchar(c); int isprint(int c);
the value of EOF.... If the argument of
toupper() represents a lower-case
int isgraph(int c);
} int iscntrl(int c);
letter ... the result is the corresponding
upper-case letter. All other arguments
int toupper(int c); in the domain are returned unchanged.
return 0;
int tolower(int c);
} 19 20

5
Using the ctype Functions! Building and Running!
#include <stdio.h> % ls
#include <ctype.h> upper.c
int main(void) {
% gcc217 upper.c –o upper
int c;
for ( ; ; ) { % ls
c = getchar(); upper upper.c
if (c == EOF) break;
if (islower(c)) Returns non-zero" % upper
c = toupper(c); (true) iff c is a lowercase" We ll be on time today!
putchar(c); character"
WE LL BE ON TIME TODAY!
}
return 0; ^D
} 21 % 22

Run the Code on Itself! Output Redirection!


% upper < upper.c % upper < upper.c > junk.c
#INCLUDE <STDIO.H> % gcc217 junk.c –o junk
#INCLUDE <CTYPE.H>
INT MAIN(VOID) { test.c:1:2: invalid preprocessing directive #INCLUDE
INT C; test.c:2:2: invalid preprocessing directive #INCLUDE
FOR ( ; ; ) { test.c:3: syntax error before "MAIN"
C = GETCHAR();
IF (C == EOF) BREAK; etc...
IF (ISLOWER(C))
C = TOUPPER(C);
PUTCHAR(C);
}
RETURN 0;
}

23 24

6
Review of Example #2! Example #3: Capitalize First Letter!
•  Representing characters" •  Capitalize the first letter of each word"
•  ASCII character set" •  cos 217 rocks à Cos 217 Rocks "
•  Character constants (e.g., A or a )"
•  Sequence through the string, one letter at a time"
•  Manipulating characters" •  Print either the character, or the uppercase version"
•  Arithmetic on characters"
•  Challenge: need to remember where you are"
•  Functions like islower() and toupper()
•  Capitalize c in cos , but not o in cos or c in
•  Compiling and running C code" rocks "
•  Compile to generate executable file "
•  The program should do different things for the
•  Invoke executable to run program"
same input letter, "
•  Can redirect stdin and/or stdout"
•  “c” in “cos” (capitalize) versus “c” in rocks (donʼt)"
•  Depends on “where it is” right now"
25 26
"

States! Deterministic Finite Automaton!


•  Where am I?" Deterministic Finite Automaton (DFA)"
•  Iʼm inside a word" •  States"
•  Iʼve seen the first letter of it but not yet the space after it" •  State 1: Iʼm not already inside a word"
•  State 2: Iʼm already inside a word"
•  If I see a letter now, I should not capitalize it"
•  Inputs: cause state transitions"
•  Iʼm not inside a word " Actions are not"
•  (Actions: determined by state+input)"
•  If I see a letter now, I should capitalize it" part of DFA formalism;"
•  Iʼm in my car" but they re helpful"
•  If I get a phone call I shouldnʼt take it" letter"
•  Iʼm in my room" (print uppercase equivalent)"
•  If I get a phone call I can take it"

•  What am I doing?" 1" 2"


not-letter"
•  Iʼm awake, Iʼm asleep, …"
(print)" letter"
Program needs a way to keep track of states, and take not-letter" (print)"
actions not only based on inputs but also on states" 27 (print)" 28

7
Implementation Skeleton! Implementation Skeleton!
#include <stdio.h> •  Process one character:"
#include <ctype.h> •  Check current state"
int main (void) { •  Check input character"
•  Based on state and character, check DFA and execute: "
int c;
•  a transition to new state, or stay in same state"
for ( ; ; ) { •  the indicated action"
c = getchar(); •  Note: same input can lead to different actions"
letter"
if (c == EOF) break; (print uppercase equivalent)"

<process one character>


} 1" not-letter" 2"
(print)"
return 0; letter"
(print)"
not-letter"
} 29 (print)" 30

not-letter letter
letter
Implementation! 1 2
not-letter
Complete Implementation!
Process one character: if input char is a letter { #include <stdio.h>
print uppercase (since #include <ctype.h>
first letter of new word); int main(void) {
if input char is a letter {
switch (state) { move to state 2 (in word); int c; int state=1;
print uppercase (since
for ( ; ; ) {
} first letter of new word);
case 1: otherwise print char as is;
c = getchar();
if (c == EOF) break; move to state 2 (in word);
<state 1 input check and action> switch (state) { }
case 1: otherwise print char as is;
break; if (isalpha(c)) {
putchar(toupper(c));
case 2: state = 2;
} else putchar(c);
<state 2 input check and action> break;
case 2:
break; if input not a letter
if (!isalpha(c)) state = 1;
change state to 1 (not in
putchar(c);
word); if input is not a letter
default: in any case, print char as is;
break;
} change state to 1 (not
<this should never happen> } in word);
return 0;
} } in any case, print char;
31 32

8
Running Code on Itself " It works!!
% gcc217 upper1.c -o upper1
% upper1 < upper1.c
#Include <Stdio.H> •  Submit"
#Include <Ctype.H>
Int Main(Void) {
Int C; Int State=1;
For ( ; ; ) {
C = Getchar(); •  What did I get? What did I get?"
If (C == EOF) Break;
Switch (State) {
Case 1:
If (Isalpha(C)) {
Putchar(Toupper(C));
State = 2;
} Else Putchar(C);
Break;
Case 2:
If (!Isalpha(C)) State = 1;
Putchar(C);
Break;
}
}
Return 0;
}
33 34

Your grade! OK, That s a B!


"

•  Works correctly, but"


•  Mysterious integer constants ( magic numbers )"

B"
•  What now?"
•  States should have names, not just 1, 2

35 36

9
Improvement: Names for States! Improvement: Names for States!
#include <stdio.h>
#include <ctype.h>
enum Statetype {NOT_IN_WORD,IN_WORD};
•  Define your own named constants"
int main(void) {
int c; enum Statetype state = NOT_IN_WORD;
enum Statetype {NOT_IN_WORD,IN_WORD}; for ( ; ; ) {
•  Define an enumeration type" c = getchar();
if (c == EOF) break;
switch (state) {
enum Statetype state;" case NOT_IN_WORD:
•  Define a variable of that type" if (isalpha(c)) {
putchar(toupper(c));
state = IN_WORD;
} else putchar(c);
break;
case IN_WORD:
if (!isalpha(c)) state = NOT_IN_WORD;
putchar(c);
break;
}
}
37 return 0; 38
}

It still works, no magic constants! Ask and you shall not receive …!
"

•  Submit"

•  Can I have my A+ please? I have a party to go to."

B+"
39 40

10
Huh?! Improvement: Modularity!
#include <stdio.h>
#include <ctype.h>
enum Statetype {NOT_IN_WORD,IN_WORD};
•  Works correctly, but" enum Statetype handleNotInwordState(int c) {...}
enum Statetype handleInwordState(int c) {...}
•  No modularity"
int main(void) {
int c;
enum Statetype state = NORMAL;
for ( ; ; ) {
•  What now?" c = getchar();
•  Should handle each state in a separate function if (c == EOF) break;
switch (state) {
•  Each state handling function does the work for a given case NOT_IN_WORD:
state, including reading the input and taking the action state = handleNotInwordState(c);
break;
•  It returns the new state, which we will store in the “state” case IN_WORD:
state = handleInwordState(c);
variable for the next iteration of our infinite loop break;
}
}
return 0;
}
41 42

Improvement: Modularity! Improvement: Modularity!


enum Statetype handleNotInwordState(int c) { enum Statetype handleInwordState(int c) {
enum Statetype state; enum Statetype state;
if (isalpha(c)) { putchar(c);
putchar(toupper(c)); if (!isalpha(c))
state = IN_WORD; state = NOT_IN_WORD;
} else
else { state = IN_WORD;
putchar(c); return state;
state = NOT_IN_WORD; }
}
return state;
}

43 44

11
Itʼs a thing of beauty …! Seriously??!
"

•  No comments"

•  Should add (at least) function-level comments

A-"
45 46

Function Comments Function Comment Examples


•  Bad main() function comment
Read a character from stdin. Depending upon the
•  A function s comment should: current DFA state, pass the character to an
appropriate state-handling function. The value
•  Describe what the function does
returned by the state-handling function is the
•  Describe input to the function next DFA state. Repeat until end-of-file.
•  Parameters, input streams •  Describes how the function works!
•  Describe output from the function •  Good main() function comment
•  Return value, output streams, (call-by-reference Read text from stdin. Convert the first
parameters) character of each "word" to uppercase, where a
word is a sequence of letters. Write the result
•  Not describe how the function works to stdout. Return 0.
•  Describes what the function does from caller s point of view"

47 48

12
An A Effort! An A Effort!
#include <stdio.h>
#include <ctype.h>
/*------------------------------------------------------------*/
enum Statetype {NOT_IN_WORD, IN_WORD};
/* handleInwordState: Implement the IN_WORD state of the DFA. */
/*------------------------------------------------------------*/ /* c is the current DFA character. Return the next state. */
/* handleNormalState: Implement the NOT_IN_WORD state of the DFA. */ /*------------------------------------------------------------*/
/* c is the current DFA character. Return the next state. */
enum Statetype handleInwordState(int c) {
/*------------------------------------------------------------*/
enum Statetype handleNotInwordState(int c) { enum Statetype state;
enum Statetype state; putchar(c);
if (isalpha(c)) {
putchar(toupper(c));
if (!isalpha(c))
state = IN_WORD; state = NOT_IN_WORD;
}
else
else {
putchar(c);
state = IN_WORD;
state = NOT_IN_WORD; return state;
}
}
return state;
}

49 50

An A Effort! Review of Example #3!


/*------------------------------------------------------------*/
/* main: Read text from stdin. Convert the first character */ •  Deterministic finite state automaton"
/* of each "word" to uppercase, where a word is a sequence of */ •  Two or more states"
/* letters. Write the result to stdout. Return 0. */
/*------------------------------------------------------------*/
•  Transitions between states"
int main(void) { •  Next state is a function of current state and current input"
int c;
•  Actions can occur during transitions"
enum Statetype state = NOT_IN_WORD;
/* Use a DFA approach. state indicates the state of the DFA. */
for ( ; ; ) { •  Expectations for COS 217 assignments"
c = getchar(); •  Readable"
if (c == EOF) break;
switch (state) {
•  Meaningful names for variables and values"
case NOT_IN_WORD: •  qqq is not meaningful. Nor are foo and bar"
state = handleNotInwordState(c);
•  Modular"
break;
case IN_WORD: •  Multiple functions, each of which does one well-defined job"
state = handleInwordState(c); •  Function-level comments"
break;
}
•  Should describe what function does"
} •  See K&P book for style guidelines specification"
return 0;
51 " 52
}

13
Another DFA Example! Yet Another DFA Example!
•  Does the string have nano in it?" Question #4 from fall 2005 midterm
•  banano " Identify whether or not a string is a floating-point number
•  nnnnnnnanofff "
•  banananonano " •  Valid numbers" •  Invalid numbers"
•  bananananashanana " •  -34 " •  abc "
n •  78.1 " •  -e9 "
n •  +298.3 " •  1e "
•  -34.7e-1 " •  + "
n a n o •  34.7E-1 " •  17.9A "
S 1 2 3 F
•  7. " •  0.38+ "
a •  .7 " •  . "
•  999.99e99 " •  38.38f9 "
No input shown on an
arc => any other input
53 54

Summary !
•  Examples illustrating C"
•  Overall program structure"
•  Control statements (if, while, for, and switch)"
•  Character input/output (getchar() and putchar())"

•  Deterministic finite state automata (i.e., state


machines)"
•  Expectations for programming assignments"

55

14

You might also like