280 likes | 419 Views
CS 108 Computing Fundamentals April 10, 2014. Factorial Via Recursion. First: answer = 1 if n = = 0 … factorial(0) = 1 Second: otherwise: factorial(n) = n * factorial ( n - 1 ) Notice that the identifier "factorial" appears on both sides of the assignment operator
E N D
CS 108 Computing Fundamentals April 10, 2014
Factorial Via Recursion • First: answer = 1 if n = = 0 … factorial(0) = 1 • Second: otherwise: factorial(n) = n * factorial( n - 1 ) • Notice that the identifier "factorial" appears on both sides of the assignment operator • How would we write a factorial function to implement these two rules into a C algorithm ?
Factorial Via Recursion • First: 1 if n = 0 • Second: factorial( n ) = n* factorial( n-1 ) if n > 0 int factorial ( int n ) { if n = = 0 return 1 ; else return ( n * factorial ( n – 1 ) ); }
Understanding Recursion • You can think of a recursive function call as if it were calling a completely separate function. • Understand this about recursively called functions: the operations that can be performed by recursively called functions are the same, but the data that is input to each recursively called function is different • The next slide might help to visualize the sameness of operations and the differences in data through the use of different (but very, very similar) functions... we’ll pass factorial_a the value 3.
int factorial_b ( int n ) { if ( n = = 0 ) return 1; else return n * factorial_c ( n - 1) ; } Understanding Recursion int factorial_a ( int m ) { if ( m = = 0 ) return 1; else return m * factorial_b ( m - 1 ) ; } int factorial_c ( int q ) { if( q = = 0 ) return 1; else return q * factorial_d ( q - 1) ; } int factorial_d ( int r ) { if( r = = 0 ) return 1; else return r * factorial_e ( r - 1) ; }
Let's develop a symbol table for the previous slide which is incorporated in this program (this program can handle 0 – 3 as inputs, which is enough to demonstrate the concepts) : • http://web.cs.sunyit.edu/~urbanc/cs_108_apr_08a.txt • Let's look at the addresses and values of the variables/parameters • http://web.cs.sunyit.edu/~urbanc/cs_108_apr_08b.txt • Notice that each version of the factorial functions does the same thing • Therefore, we can condense this into something more general
Recursion Example: Factorial #include <stdio.h> // 2.c int factorial ( int ) ; int main (void) { int input = 0 , answer = 0; printf("\n\n The program computes the factorial of an entered integer. ") ; printf("\n Enter an postive integer: ") ; scanf("%d", &input ) ; answer = factorial ( input ) ; printf("\n\n %d factorial equals: %d \n\n" , input , answer ) ; return 0 ; } int factorial ( int passed_input ) { if ( passed_input = = 0)// if cutting, remove the extra space between = and = return 1 ; else return ( passed_input * factorial ( passed_input - 1 ) ) ; }
Let's develop a symbol table for the previous slide which is incorporated in this program: • http://web.cs.sunyit.edu/~urbanc/cs_108_apr_08c.txt
Questions to Guide The Use of Recursion • Can you define the problem in terms of smaller problem(s) of the same type? • Think about the factorial problem: factorial(n) = n * factorial ( n-1 ) if n > 0 • Does each recursive call reduce the size of the problem? • As the problem "shrinks", will you eventually reach a point where an obvious solution presents itself? • Again, think about the factorial problem: factorial (0) = 1
Files and File Access • Thus far we have used volatile memory (primary storage) in our programs • Volatile memory has certain advantages and disadvantages • Long-term storage requires the use of secondary storage • Data files are used by programmers to store and retrieve data in secondary storage
Files and File Access • Data file hierarchy: • bits (binary digits… 0’s and 1’s) • bytes (bits grouped together (in 8’s) to form a single character) • words or fields(logical groupings of bytes (characters) that, taken together, can represent data or information (data in context)) • records(logical groupings of fields that describe an object or entity) • files (a collection of records)
Files and File Access • In C a file can refer to a data file, but in C a file can also refer to any concrete device with which we want to exchange data (monitor, printer, tape drive, hard disk, etc…) • In C a file stream is the flow of data between a program and a file • File streams are a series of bytes • File streams are not device dependent… all streams have the same behavior
Files and File Access • File streams have two formats: • text stream(think readable data or text) • binary stream(non-readable… think .exe files) • We use pointers to manage file streams that read and write data… pointers that are used to manage file streams are called file pointers • C provides an internal structure named FILE that is used to declare file pointers • We use FILE as a data type when we declare a file pointer FILE *file_pointer_name ;
#include <stdio.h> // Example of declaring a file pointer using FILE. int main (void) { FILE *read_ptr; // The names and the number of file pointers FILE *write_ptr; // used in program: determined by FILE *append_ptr; // the programmer. // We will need to assign a file to a file pointer. return (0) ; }
Files and File Access • To work with files in C we must do four things: • create a file pointer (using FILE) • assign a file to the file pointer (using fopen) • opens the file (should test the file when opening) • process the file (read and/or write, transform) • close the file (using fclose) • Opening usually involves using the stdio.h function fopen • fopen is used in an assignment statement to pass a file pointer to a previously declared (by the programmer… us) file pointer
Opening a File • fopen syntax: FILE *file_pointer_name ; file_pointer_name = fopen ("file_name", "file_mode"); • fopen example: FILE *read_ptr ; read_ptr = fopen ("student_1.dat", "r");
Opening a File • File mode: specifies the way to open the file:"r" opens and existing file for reading"w" creates a text file for writing "a" opens an existing file for appending
Opening a File • File mode: specifies the way to open the file:"r+" opens an existing file for reading and/or writing "w+" creates a text file for reading and/or writing "a+" opens or creates a file for appending "rb" creates a binary file for writing "wb" creates a binary file for writing "ab" opens an existing binary file for appending "r+b" opens an existing binary file for reading and/or writing "w+b" creates a binary file for reading and/or writing "a+b" opens or creates a binary file for appending
Opening a File #include <stdio.h> //example of declaring and assigning a file pointer int main (void) { FILE *read_ptr ; read_ptr = fopen("student_1.dat", "r"); return (0) ; } • It’s considered "good practice" to check each file pointer assignment so that you know each file is successfully opened
Opening a File and Checking It #include <stdio.h> //example of declaring and assigning a file pointer //then checking it int main (void) { FILE *read_ptr ; read_ptr = fopen("student_1.dat", "r"); if (read_ptr == NULL) printf("\n\nstudent_1.dat was not properly opened.\n"); else printf("\n\nstudent_1.dat is opened in the read mode.\n"); return (0) ; }
Reading a File: Single Field/Single Record • fscanf is used like scanf for files… in stdio.h… then fclose #include <stdio.h> //3.c int main (void) { FILE *read_ptr ; char last_name [15]; read_ptr = fopen("student_1.dat", "r"); if (read_ptr == NULL) printf("\n\n student_1.dat was not properly opened.\n\n"); else { printf("\n\n student_1.dat is opened in the read mode.\n"); fscanf(read_ptr, "%s", last_name); printf("%s \n\n", last_name); fclose(read_ptr); } return (0) ; }
Reading a File: Single Field/Multiple Records • feof is used to check for a file’s EOF marker #include <stdio.h> //4.c int main (void) { FILE *read_ptr ; char last_name [15]; read_ptr = fopen("student_2.dat", "r"); if (read_ptr == NULL) printf("\n\nstudent_2.dat was not properly opened.\n"); else { printf("\n\nstudent_2.dat is opened in the read mode.\n"); fscanf (read_ptr, "%s", last_name ); while ( !feof (read_ptr) ) { printf ("%s \n", last_name); fscanf (read_ptr , "%s", last_name ); } fclose(read_ptr); } return (0) ; }
Reading a File: Multiple Fields and Records #include <stdio.h> //5.c int main (void) { FILE *read_ptr ; char last_name [15]; char major [15]; read_ptr = fopen("student_3.dat", "r"); if (read_ptr == NULL) printf("\n\nstudent_3.dat was not properly opened.\n"); else { printf("\n\nstudent_3.dat is opened in the read mode.\n"); fscanf (read_ptr, "%s %s", last_name , major); while ( !feof (read_ptr) ) { printf ("%s %s \n", last_name, major); fscanf (read_ptr , "%s %s", last_name , major); } fclose(read_ptr); } return (0) ; }
Writing a File: Use fprintf and fclose #include <stdio.h> //6.c int main (void) { FILE *write_ptr ; char last_name [15]; char major [15]; write_ptr = fopen("student_3.dat", "w"); // need "w" for mode if (write_ptr == NULL) printf("\n\nstudent_3.dat was not properly opened.\n"); else { printf("\n\nEnter the last name and major: "); scanf ("%s %s", last_name , major); fprintf (write_ptr, "%s %s \n", last_name, major); } fclose (write_ptr); return (0); }
Appending a File: Use fprintf and fclose #include <stdio.h> //7.c int main (void) { FILE *append_ptr ; char last_name [15]; char major [15]; append_ptr = fopen("student_3.dat", "a"); //need "a" for mode if (append_ptr == NULL) printf("\n\nstudent_3.dat was not properly opened.\n"); else { printf("\n\nEnter the last name and major: "); scanf ("%s %s", last_name , major); fprintf (append_ptr, "%s %s \n", last_name, major); } fclose (append_ptr); return (0) ; }
Writing an Array to a File #include <stdio.h> //8.c int main(void) { FILE *scores; int score_array[10] = { 97, 65, 72, 84, 79, 81, 91, 93, 67, 73 }; int x; scores=fopen("test_scores.dat","w"); if(scores==NULL) printf("\n\ntest_scores.dat was not properly opened.\n"); else { for(x = 0 ; x < 10 ; x++ ) { fprintf(scores,"%d\n", score_array[x]); } fclose(scores); printf("All ten exam scores saved to disk.\n\n\n"); } return(0); }
Reading an Array From a File #include <stdio.h> //9.c int main(void) { FILE *scores; int score_array[10] ; int x; scores=fopen("test_scores.dat","r"); if(scores==NULL) printf("\n\ntest_scores.dat was not properly opened.\n"); else { for(x = 0 ; x < 10 ; x++ ) { fscanf(scores,"%d", &score_array[x]); } fclose(scores); for(x = 0 ; x < 10 ; x++ ) printf("Exam #%d score is %d \n", x + 1, score_array[x]); } return(0); }
#include <stdio.h> //10.c int main(void) { FILE *scores; int score_array[10] [3]; int x; scores=fopen("test_scores_2.dat","r"); if(scores==NULL) printf("\n\ntest_scores_2.dat was not properly opened.\n"); else { for(x = 0 ; x < 10 ; x++ ) { fscanf(scores,"%d %d", &score_array[x] [0], &score_array[x] [1]) ; score_array[x] [2] = score_array[x] [0] + score_array[x] [1] ; } fclose(scores); for(x = 0 ; x < 10 ; x++ ) printf("Student #%d scores and total: \t %d \t %d \t %d\n\n\n", x + 1, score_array[x] [0] , score_array[x] [1] , score_array[x] [2] ); } return(0); }