540 likes | 658 Views
CPS 393 Introduction to Unix and C. START OF WEEK 8 (C-2). << If Statement >> if (a < 7) printf("yes"); if (a < 7) { printf("yes "); printf("it is<br>"); }. if (a < 7 && b != 5) a=a+1; else { a=a+b; printf("%d<br>",a); } See sample1.
E N D
CPS 393Introduction to Unix and C START OF WEEK 8 (C-2) Course material created by D. Woit
<<If Statement>> if (a < 7) printf("yes"); if (a < 7) { printf("yes "); printf("it is\n"); } if (a < 7 && b != 5) a=a+1; else { a=a+b; printf("%d\n",a); } See sample1 Program Control Statements-similar to Java Course material created by D. Woit
Operators Relational Operators: > >= < <= == != Each operator requires 2 operands . Result evaluates to integer 0 when false; int 1 when true. Note1: in C, any non-0 (int) value is "true“ 0 is "false" Logical Operators: && and || or ! not. Note: !5 is 0 (false) !!5 is 1 (true) 9/15/2014 Course material created by D. Woit 3
Can nest ifs if (i != 0) if (i != 1) if (i != 2) if (i != 3) if (i != 4) if (i != 5) if (i != 6) if (i != 7) if (i != 8) if (i != 9) printf("%d is not a digit\n",i); else binds with nearest "else-less" if above if (i != 0) if (i > 0) printf("\a"); else printf("\a\a\a"); The else binds to which if? Operators 9/15/2014 Course material created by D. Woit 4
If then else No "elseif" but can do "else if" if (c >= '0' && c <= '9') printf("digit"); else if (c >= 'a' && c <= 'z') printf("lower case letter"); else if (c >= 'A' && c <= 'Z') printf("upper case letter"); else printf("not alphanumeric"); 9/15/2014 Course material created by D. Woit 5
/*Source: fact.c Purpose: function fact(long n) computes n! Input argument: n an integer Output: n! an integer Note: a program using fact.c must include fact.h */ long fact(long n) { if (n == 0) return(1); else return (n*fact(n-1)); } /*Source: fact.h Purpose: header file for fact.c */ long fact(long n); Ifs good for checking for *valid input* e.g., what should fact check about n? See example usefact.c Fact.c 9/15/2014 Course material created by D. Woit 6
/*Source: dimcheck.c Input: int length, width (length & width of room) Output: the square footage (integer) of room Exit: 0 if good dimensions; 1 otherwise */ int GetDim(void); int main(void) { int dim1, dim2 /*dimension of room */ Int ExitFlag; /*code to exit with 0=good*/ /*initialize ExitFlag to good value*/ ExitFlag=0; /*read in dimensions*/ dim1 = GetDim(); dim2 = GetDim(); /*check for valid input*/ if ((dim1 <= 0) || (dim2 <= 0) ) { /*invalid dims*/ fprintf(stderr,"Input error. Please re-run program\n"); ExitFlag=1; } else printf("Floor Space is %d\n",dim1*dim2); exit(ExitFlag); } Example program to compute dimensions of the room 9/15/2014 Course material created by D. Woit 7
Example program to compute dimensions of the room • int GetDim(void) { • int dim; /*dimension */ • int sret; //scanf return value • printf("Enter a dimension (pos. int.): "); • sret=scanf ("%d",&dim); • if (sret != 1) return(-1); • else return (dim); • } • Note: echo $? in shell displays a pgms's exit status 9/15/2014 Course material created by D. Woit 8
HMWK here is a file called math2.c which contains functions for factorial and fibonacci /*Source: math2.c Purpose: source code for factorial and fibonacci functions */ long fact(long n) { if (n == 0) return(1); else return (n*fact(n-1)); } long fibonacci(long n) { if (n == 0) return (0); else if (n == 1) return (1); else return (fibonacci(n-1) + fibonacci(n-2)); } 9/15/2014 Course material created by D. Woit 9
HMWK continued Write file math2.h, a header file for math2.c Write a program evaluate.c which prompts the user to enter a 0 or a 1. If 0 entered, calculate fact(n) where n is prompted for and read in. If 1 entered, calculate fibonacci(n), where n is prompted for and read in. Make sure your program does error checking on all input. Your program should exit with 0 if successful; with 1 if user didn't enter a "0 or 1"; and with 2 if the user entered an invalid (including negative) value for "n". 9/15/2014 Course material created by D. Woit 10
General form of for statement is: for (expr1; expr2; expr3); statement Is equivalent to: expr1; while (expr2) { statement expr3; } Example: for (i=0; i<=9; i++) { printf("%d",i); printf("\n"); } Infinite loop: For (;;) { … } /* exit by break or return */ For loop 9/15/2014 Course material created by D. Woit 11
Example for for statement /* Source: rand.c Purpose: generate MaxNum random integers Input: integer MaxNum (max number of rand numberrs to generate) Output: MaxNum random integers Exit: 0 if successful; 1 if improper user input (not +ve int) */ #include <stdio.h> #include <stdlib.h> /* rand() is defined here */ #include <time.h> int main(void) { int MaxNum, /*number of random nos to generate */ i, /*index */ RandNo, /*a random number */ ExitCode=0; /*value to exit program with */ 9/15/2014 Course material created by D. Woit 12
srand(time(NULL)); //seed with fairly unique number printf("How many rand nos to generate? "); if (((scanf("%d",&MaxNum)) != 1) || (MaxNum <=0)) ExitCode=1; else for (i=1; i <= MaxNum; i++) { RandNo=rand(); printf("Random No %d is %d\n",i,RandNo); //RandNo=(rand()%6); //gives numbers 0 to 5 //c = (char) (rand() % 128); } exit(ExitCode); } 9/15/2014 Course material created by D. Woit 13
More for examples Lines below are in forexample1.c for (i=5; i<20; i=i+5) printf("%d",i); for (i=10; i>0; i--) printf("%d",i); for (i=1,j=5; i<10&&j>0; i++,j--) printf("%d",i); #three loops below are in forexample2.c char c; for (c='a'; c<='z'; c++) putchar(c); for (c=getchar(); c!='X'; c=getchar()); printf("Thanks for finally inputting an X!!"); for ( ; ;) ; /*infinite loop*/ for (c='A'; c<='Z'; ) { putchar(c); c=c+2; } 9/15/2014 Course material created by D. Woit 14
HMWK write a program that prints out the extended ASCII character set. Use a for loop from 0 to 255, printing the index as a char in each loop. . 9/15/2014 Course material created by D. Woit 15
While loop while (expression) /* if expr is non-zero, statement is executed */ statement Example1 first loop in program thanksX.c: char c; c=getchar(); while (c != 'X') c=getchar(); printf("Thanks for finally inputting an X!!"); Example2 second loop in program thanksX //source thanksX.c char c; while ( (c=getchar()) != 'X'); /* more elegant than the first one */ printf("Thanks for finally inputting an X!!"); 9/15/2014 Course material created by D. Woit 16
Use to choose between several alternatives can only switch on int or char switch(c) { case 'a': printf("a vowel"); break; case 'e': printf("a vowel"); break; case 'i': printf("a vowel"); break; case 'o': printf("a vowel"); break; case 'u': printf("a vowel"); break; default: printf("non-vowel"); break; //can be omitted } Default is executed if none of other cases is satisfied See example switch1.c Switch Statement 9/15/2014 Course material created by D. Woit 17
Example 2 (previous one improved), see switch2.c switch(c) { /*falls thru with no break*/ case 'a': case 'e': case 'i': case 'o': case 'u': printf("vowel"); break; default: printf("non-vowel"); } Example3, see switch3.c switch(i) { case 1: putchar('H'); case 2: putchar('E); case 3: putchar('L'); case 4: putchar('L'); case 5: putchar('O'); default: putchar('\a'); } This switch does not have breaks so it falls through If i is 1? If i is 3? Switch Statement 9/15/2014 Course material created by D. Woit 18
HMWK (1) Write a program which reads in a character, and prints whether the character is a vowel or non-vowel. It must work for any case, e.g., 'a' and 'A' are both vowels. You should not have separate cases for upper and lower case vowels. Do this by converting the character to lower case before the switch. Use function "tolower" which is in ctype.h (for usage see tolower man page.) For non-letter (a-z,A-Z) characters, print an appropriate error message. Remember exit codes. (2) Modify your program to read in any number of characters and report, after each read, whether it is a vowel. You should stop processing characters when a '%' is input. You should always remind the user that a '%' will stop the program. 9/15/2014 Course material created by D. Woit 19
Example We use functions in ctype.h toupper, isdigit etc. Note: there is built-in function atoi(s) which converts string to an integer See example makeint.c /*Function: MakeInt() Source: MakeInt.c Purpose: to convert a sequence of digits to its integer value Input: a sequence of digit characters, e.g., 125 Output: the integer 125 (one hundred and twenty five) */ #include <stdio.h> #include <ctype.h> 9/15/2014 Course material created by D. Woit 20
Example MakeInt() int MakeInt() { int num=0, /*final integer value */ digit; /*digit that is read in*/ digit=getchar(); for( ; isdigit(digit); digit=getchar()) { num=num*10; num=num+ (digit - '0'); } return (num); } digit - '0' converts char 0,1, ... 9 to int 0,1, ... 9 remember printf("%d %c", digit,digit); => 66 B ASCII decimal code for '0' is 48, '1' is 49, … '9' is 57 so if digit is 5 digit-'0' evals to 53-48 = 5 9/15/2014 Course material created by D. Woit 21
/* source tryatoi.c purpose: to convert a sequence of digits placed in a string into integer value input: a sequence of digits output: the integer */ #include <stdio.h> #include <ctype.h> int myatoi(char *s); int main(void) { int number; char s[10]; printf("Insert a number : \n"); scanf("%s" , s ); number=myatoi(s); printf("Number is %d\n", number ); } int myatoi(char *s) { int i, num=0; /*final integer value */ for (i=0; s[i]>='0' && s[i]<='9'; ++i) num=num*10 + s[i] - '0'; return(num); } Converting a string fo digits to an integer
HMWK: (2) create a a program to display, at top of screen: ------------------------------------------------------ Welcome to the calculator program! Please choose the operation you desire by entering the appropriate number: 1. addition 2. subtraction 3. multiplication 4. division 5. absolute value 6. exit Your choice: ------------------------------------------------------ 9/15/2014 Course material created by D. Woit 23
. . Note that you can clear screen using the C system command from stdlib.h, as in: system("clear"); //(system does any linux command). The program will re-display this until user enters correct input. Then the program will prompt for necessary operands, calculate and display the result. The program will repeat the above until the user enters choice 6 (exit program). Use a separate function for each operation. Exit main with appropriate code (3) Design and implement a program to print a table of squares, cubes and quatrics for numbers 1 to N, where N is input by user. Use functions for each of square, cube and quatric, and reuse square where possible. The table would look like: Number Square Cube Quatric ------ ------ ----- ------- 1 1 1 1 2 4 8 16 3 9 27 81 9/15/2014 Course material created by D. Woit 24
TryScan.c This program will read in ints and print them out until 0 entered. Try entering 99a and see what happens? /*TryScan.c*/ #include <stdio.h> int main(void) { int j,i=1; char c; while (i!=0) { scanf("%d",&i); # scanf obtains negative number if alfa char is entered which is not stored in var. i printf("i is %d\n",i); } exit(1); } 9/15/2014 Course material created by D. Woit 25
TryScan We should try to fix TryScan.c. Could try: adding line while ((c=getchar())!='\n'); after the scanf line, or fflush(stdin); which doesn't work on all systems, or j=scanf... and then after if (j!=1) {fprintf(stderr,"BAD"); exit(0);} See TryScanfix.c and TryScanfix2.c 9/15/2014 Course material created by D. Woit 26
Fix fact(long n) so that it is robust (does something reasonable, like returns -1 when called with negative input). See fixfact.c #include <stdio.h> #include <stdlib.h> #include "math2.h" void test(int TestNumber, long result, long answer ); int main(void) { test(1,fact(0),1); /*boundary*/ test(2,fact(1),1); /*boundary*/ test(3,fact(2),2); /*boundary*/ test(4,fact(7),5040); /*interior*/ test(5,fact(-1),-1); /*error and boundary*/ test(6,fact(-3),-1); /*error*/ exit(0); } void test(int TestNo, long result, long answer) { if (result != answer) printf("Test %d failed\n",TestNo); } 9/15/2014 Course material created by D. Woit 27
HMWK (1)write test drivers for the square function and for the fibonacci function. What input would you use to test the program for computing floor space we did previously? 9/15/2014 Course material created by D. Woit 28
Static Functions and Variables Remember: a static variable is known only to the function in which it is declared, and retains its value from one call of the function to another. A static function is known only in the file in which it is defined/declared (like being private to that file.) e.g., Function q is only available to code in file f.c. It is not available to main or any other code. If you try to use q() from main, it gives "undefined" error 9/15/2014 Course material created by D. Woit 29
//Source f.h int f (int x); //Source f.c static int q(int x) { return(x*x); } int f (int x) { return (q(x)); } //Source: m.c #include <stdio.h> #include "f.h" int main(void) { int y=f(7); printf("%d\n",y); return(0); } Function q is only available to code in file f.c. It is not available to main or any other code. If you try to use q() from main, it gives "undefined" error Static Functions and Variables 9/15/2014 30 Course material created by D. Woit
On a moon, the following program prints something like: 1 2 3 4 5 1 1 1 1 1 //Source: accum.c int fs(int x) { static int count=0; count=count+x; return (count); } int fn(int x) { int count=0; count=count+x; return (count); } int main(void) { int i; for (i=0;i<5;i++) printf("%d ",fs(1)); putchar('\n'); for (i=0;i<5;i++) printf("%d ",fn(1)); putchar('\n'); } Static variables within functions: 9/15/2014 Course material created by D. Woit 31
Static functions A function,f, that is not declared "static" will be exportable. i.e., you can put f's definition in f.c and declaration in f.h Then if you include f.h in another file, M.c, and compile both M.c and f.c, f will be available to the code in M.c If f was static, then it would not be available to code in M.c 9/15/2014 Course material created by D. Woit 32
Arrays and Strings Some differences from java. <<1-Dimensional arrays>> int A[20]; gives A[0] A[1] ... A[19] Assign: A[14]=1005; Reference: printf("%d", A[14]); Initialize at declaration: int A[5] = {1,2,7,15,3}; or later: int A[5]; for (i=0; i<5; i++) scanf("%d",&A[i]); 9/15/2014 Course material created by D. Woit 33
Arrays and Strings Compiler does not check array bounds : printf("%d",A[92]); compiles OK char a[10], b[10]; for (i=0; i<10; i++) b[i]=i; If we want to copy array b into array a Incorrect: a = b; /*compiler error:incompatible types*/ Correct: for (i=0; i<10; i++) a[i]=b[i]; 9/15/2014 Course material created by D. Woit 34
example • /*Source: FindLtr.c • Purpose: output occurrences of A,B,...Z found in input • Input: chars from stdin • Output: each upper case letter and its occurrences • */ • #include <stdio.h> • #include <ctype.h> 9/15/2014 Course material created by D. Woit 35
int main(void) { int i, /*index */ c, /*char from stdin*/ letter[26]; /*array for upper case letters*/ for (i=0; i<26; i++) letter[i]=0; /*initialize array*/ while((c=getc(stdin)) != EOF) /*^d on UNIX */ if (isupper(c)) ++letter[c - 'A']; /*increment right slot*/ for (i=0; i<26; ++i) { /*print results*/ if (i%6 == 0) printf("\n"); /*new line every 6 chrs*/ printf("%5c: %4d", 'A'+i, letter[i]); } printf("\n\n"); exit(0); } EOF is ^d UNIX, or ^z DOS/Windows 'A' is 65, 'B' is 66, etc. Therefore, 'A' - 'A' = 0, 'B' - 'A' = 1, etc. This prog can be tried with the input redirected from a input file FindLtr < direwolves.txt 9/15/2014 Course material created by D. Woit 36
Strings C has no string type like java. In C, string: null-terminated char array null is '\0' (= byte 00000000) Always declare array 1 larger than string length (for \0) compiler automatically null-terminates string constants "Hello There" gets() in stdio.h reads chars up to and including carriage return or EOF discards the '\n' (or EOF) and null-terminates string 9/15/2014 Course material created by D. Woit 37
/*Source: str1.c */ #include <stdio.h> int main(void) { int i; /*index*/ char str[40]; /*string max 39 chars*/ printf("Enter a string (max 39 chars):"); /* gets(str); compiler hates this func */ fgets(str, 40, stdin) ; /* nicer and preferred by compiler*/ for (i=0; str[i]; i++) /*loops until str[i] is \0 */ printf("%c",str[i]); /*==printf(str); ==printf("%s",str); */ putchar('\n'); exit(0); } 9/15/2014 Course material created by D. Woit 38
Fgets and fputs fgets(str, length, fp); gets chars from "file" pointed to by fp (fp could be stdin) and stores them in array str, until either event occurs: 1. '\n' read (and transfered to str) 2. (length-1) chars have been read, or 3. EOF terminates str with a '\0' returns ptr to str if successful Otherways it returns NULL ptr e.g., fgets(str,40,stdin); would stop memory overwrite However, it also puts \n in str (if str not full) If you don't want the \n, you have to remove it yourself (copy a '\0' over the '\n'). 9/15/2014 Course material created by D. Woit 39
/*Source:tryfgets.c*/ #include <stdio.h> int main(void) { int i; /*index*/ char str[40]; /*string max 39 chars*/ printf("Enter a string (max 38 chars):"); //leave slots for newline and null fgets(str,40,stdin); fputs(str,stdout); exit(0); } Note: String only 38 chars now (\n and \0) enter <=38 chars, it includes the newline in str enter >38 chars, there is no \n, but 40th slot (str[39]) gets \0 9/15/2014 Course material created by D. Woit 40
char a[40], b[40]; strcpy(b,"Hello"); strcpy(a,b); printf("%s %s",a,b); strcpy(a,"Hi"); strcat(a," There"); printf(a); strcmp(a,b) returns: 0 if same <0 if a < b in dictionary order (str length irrel) >0 if a > b strcpy(b, "Hello"); strcpy(a, "Hellp"); printf("b has length %d",strlen(b)); printf("%d", strcmp(a,b)); //prints 1 printf("%d", strcmp("Hello",b)); //prints 0 null string contains only \0 strcpy(a,""); /*or*/ a[0]='\0'; int i; i=atoi("127"); /*converts digit string to integer*/ printf("%d",i); /* prints integer 127 */ Functions on strings see strops.c 9/15/2014 Course material created by D. Woit 41
useful string functions are: sprintf, sscanf int sprintf (char *out_string, const char *format_string, ... ); -const is a qualifier indicating the data cannot be modified -works like printf but prints into string out_string instead of stdout char S[20]; double x=94.12345; sprintf(S, "%.2lf", x); --> S is "94.12" the '\0' added automatically int sscanf(char *str, const char *format_string, ...); does a scanf from a string instead of stdin Nice, because we can use gets to read whole line including \n (no worry about scanf "stuck" on the \n) remember: gets discards the read-in '\n' and null-terminates the string char S[40]; int x,y; gets(S); sscanf(S, "%d %d", &x,&y); 9/15/2014 Course material created by D. Woit 42
Multi-dimensional Arrays int A[3][4]; /*3 rows (0-2), 4 columns (0-3)*/ int A[3][4][2]; /*array of 2-dim arrays - a prism */ Initialization: int A[3] = {1,4,7}; char B[3] = {'A','B','C'}; /*no null term*/ char C[4] = "ABC"; /*null term added automatically so need [4] */ int D[2][3] = { 2,4,7, 6,9,5 }; /*D[0][0] is 2; D[0][1] is 4, etc */ 9/15/2014 Course material created by D. Woit 43
/*Source: 3dimary.c*/ #include <stdio.h> int main(void){ int A[2][3][2]= {1,2,3,4,5,6,7,8,9,10,11,12}; int i,j,k; for (i=0; i<2; i++) for (j=0; j<3; j++) for (k=0; k<2; k++) printf("A[%d][%d][%d]=%d\n",i,j,k,A[i][j][k]); exit(0); } Automatic (local) arrays not initialized by compiler Global & Static are initialized to 0 by compiler (like all global & static variables) 9/15/2014 Course material created by D. Woit 44
Unsized Arrays: (compiler counts # of constants to find size needed) int A[] = {1,4,2,6}; /*size 4*/ char UserMsg[] = "Enter a number: "; int b[][2] = { 1,4, 7,9, 3,5 }; Need to include one dimension-count to help compiler Why unsized? easy modification, especially if use sentinel when looping (no change of declaration size and no change of loop index max) 9/15/2014 Course material created by D. Woit 45
Arrays of Strings: char colors[5][9]; /*5 strings, each string max 9 chars incl null*/ char colors[][7] = { "blue", "red", "pink", "purple" }; printf("%s",colors[2]); //prints pink printf("%c",colors[2][3]); //prints k see example strary.c 9/15/2014 Course material created by D. Woit 46
Arrays of Strings: char names[3][40]; gets(names[0]); gets(names[1]); gets(names[2]); /*fills array*/ for (i=0;<3; i++) printf(names[i]); 9/15/2014 Course material created by D. Woit 47
/*Source: printword.c */ /* Purpose: print the english word equivalent of a digit Input: a digit, e.g., 9 Output: the word equivalent, e.g., nine Note: should exit with bad code if invalid input */ #include <stdio.h> int main(void) { /*set up array of english words for digits*/ char digits [10][6]= { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" }; char num; /*digit to read in*/ 9/15/2014 Course material created by D. Woit 48
printf("Enter a digit: "); num = getchar(); num = num - '0'; if (num >= 0 && num < 10) printf("\n%s\n", digits[num]); else printf("\nThat wasn't a digit\n"); return 0; } ASCII for '0' is 48, for '1' is 49 etc so if enter 2: num = '2' - '0' = 50 - 48 = 2 so digit[2] is printed 9/15/2014 Course material created by D. Woit 49
/*Source: trypas.c*/ #include <stdio.h> #include <stdlib.h> void f1(int num[5],int loc), f2(int num[],int loc); int main(void) { int i,loc=0; int count[5] = {0,0,0,0,0}; f1(count,loc); f2(count,loc); printf("count="); for (i=0; i<5; i++) printf("%d ", count[i]); printf("\nloc=%d\n",loc); exit(0); } void f1(int num[5], int loc) { num[0] = 99; loc=99; } void f2(int num[], int loc) { num[1] = 22; loc=22; } Passing arrays to Functions: 9/15/2014 Course material created by D. Woit 50