310 likes | 331 Views
The C Language – Brief Tutorial. Prof. Steven A. Demurjian Computer Science & Engineering Department The University of Connecticut 371 Fairfield Road, Box U-2155 Storrs, CT 06269-2155. Steven.demurjian@uconn.edu http://sdcse.engr.uconn.edu (860) 486 – 4818 (860) 486 – 3719 (office).
E N D
The C Language – Brief Tutorial Prof. Steven A. Demurjian Computer Science & Engineering Department The University of Connecticut 371 Fairfield Road, Box U-2155 Storrs, CT 06269-2155 Steven.demurjian@uconn.edu http://sdcse.engr.uconn.edu (860) 486 – 4818 (860) 486 – 3719 (office)
Word Count Program Using argc/argv #include <stdio.h> main(argc,argv) int argc; char *argv[]; { int lines[10], words[10], chars[10]; int i, tot_lines=0, tot_words=0, tot_chars=0; /* Need error checks here */ for (i=0; i<(argc-1); i++) { lines[i] = count_lines(argv[i+1]); words[i] = count_words(argv[i+1]); chars[i] = count_chars(argv[i+1]); } for (i=0; i<(argc-1); i++) { tot_lines += lines[i]; tot_words += words[i]; tot_chars += chars[i]; } printf(" **********The Results ****************\n"); /* Both Individual and Total results */ for (i=0; i<(argc-1); i++) { printf("%10d%10d%10d%20s\n", lines[i], words[i], chars[i], argv[i+1]); } printf("Totals for the Input are:\n"); printf("Lines: %10d\nWords: %10d\nChars: %10d\n", tot_lines, tot_words, tot_chars); }
Word Count Program Associated Functions intcount_lines(f_name) char f_name[]; { FILE *fp; char c; intnum_lines=0; fp = fopen(f_name, "r"); while ((c=getc(fp)) != EOF) { while (c != '\n') c = getc(fp); num_lines++; } fclose(fp); return(num_lines); } intcount_chars(f_name) char f_name[]; { /* Characters include any character except for the newline at the end of a line and EOF*/ } intcount_words(f_name) char f_name[]; { /* Words are separated by blanks and newline at the end */ }
Word Count Program Alternate Function Definition /* Note the use of char *f_name */ int count_lines(char *f_name) { FILE *fp; char c; int num_lines=0; fp = fopen(f_name, "r"); while ((c=getc(fp)) != EOF) { while (c != '\n') c = getc(fp); num_lines++; } fclose(fp); return(num_lines); } int count_chars(char *f_name) { /* Characters include any character except for the newline at the end of a line and EOF*/ } int count_words(char *f_name) { /* Words are separated by blanks and newline at the end */ }
Example Using Pointers and Dereferences int i=3, j=4; int *k; /* pointer to integer - holds address */ k= &(j); /* holds the address of j */ printf("%d", *k); /* print j's address */ k= &(i); /* holds the address of i */ *k+=j; /* increment k's address by value of j */ printf("%d %d %d\n", i, j, k); /* what prints? */
Call by Reference using Pointers • C Only Allows Pass-by-Value • Using Pointers Facilitates Pass-by-Ref • Can’t change the Pointer Value • Change What Pointer References • Consider Swap Below main() { int x=5, y=10; swap(x,y); } /*Does this Work?*/ swap(x,y) int x; int y; { int temp; temp = x; x = y; y = temp; } /* A Better Swap! */ main() { int x=5, y=10; swap(&x, &y); } swap(x,y) int *x; int *y; { int temp; temp = *x; *x = *y; *y = temp; }
Call by Reference using Pointers • If you want to Swap the Value of the Pointer (addresses) • Use Pointers to Pointers • Change What Pointer Points To • In this Case, an Address main() { int i=1 j=2; int *r, *s; r = &i; s=&j; printf(“BEFORE: %d %d\n”,r,s); swap_addr(&x, &y); printf(“AFTER: %d %d\n”,r,s); } swap_addr(x,y) int **x; int **y; { int *temp; temp = *x; *x = *y; *y = temp; } 1 4000 i 2 4004 j 4000 4008 r 4004 4012 s
Pointers and Count Lines • Revisit Count_Lines • Change to Return Value in Parameter • Function now Returns Void void count_lines(f_name, num_lines) char f_name[]; int *num_lines; { FILE *fp; char c; *num_lines = 0; fp = fopen(f_name, "r"); while ((c=getc(fp)) != EOF) { while (c != '\n') c = getc(fp); *num_lines = *num_lines+1; } fclose(fp); } Function invocation: count_lines(argv[i+1], &lines[i]);
Correlating Pointers and Arrays • An Array Name is a Fixed Address int a[100]; int *p; a[0], a[1], a[2], . . . a[99] have Addresses 4000, 4004, 4008, . . . Valid Assignments Include: p = &(a[1]); p = &(a[i]); p = &a; Equivalent to: p = &(a[0]); If p = &(a[1]); What Does p++; Do? p = &a; What Does p = p+4 Do?
Basic Concepts for Strings • String Processing in C is Achieved via Character Arrays • Strings Terminate with ‘\0’ #include <stdio.h> main() { char b[]=“hello”; char *c =“goodbye”; printf(“BEFORE: %s %s\n”, b, c); /* Using b – putchar works from stdin */ for (i=0; putchar(b[i]) !=‘\0’; i++) ; /* Using c – putchar works from stdin */ for (i=0; putchar(*(c+i)) !=‘\0’; i++) ; printf(“AFTER: %s %s\n”, b, c); }
Passing Strings as Parameters #include <stdio.h> main() { char str1[]=“steve”; char str2[]=“”; printf(“BEFORE: %s %s\n”, str1, str2); copy(str1, str2); printf(“AFTER: %s %s\n”, str1, str2); } copy(src, dst) char src[], dst[]; { int i=0; while( (dst[i] = src[i]) != ‘\0’) i++; }
Three Other Versions of Copy copy(src, dst) char src[], dst[]; { int i; for( i=0; (dst[i] = src[i]) != ‘\0’; i++) ; } copy(src, dst) char *src, *dst; { for( ; (*dst = *src) != ‘\0’; dst++, src++) ; } copy(src, dst) char *src, *dst; { for( ; (*dst++ = *src++) != ‘\0’; ) ; }
String Functions in C • Defined in #include <strings.h> • Integer Returning Functions: • Pointer Returning Functions strcmp(s1,s2); 0:equal, s1<s2:neg, s1>s2:pos strncmp(s1,s2,n); compare first n chars strlen(s1); returns length without \0 strcat(s1,s2); adds s2 to s1 strncat(s1,s2,n); add first n chars:s2 to s1 strcpy(s1, s2); copy s1 to s2 strncpy(s1,s2,n); copy first n chars char *strcat(s1,s2) register char *s1, *s2; { register char *p; p = s1; while (*p++ != ‘\0’) ; --p; while( (*p++ = *s2++) != ‘\0’) ; return(s1); }
Structures • Structures in C are the Predecessors of Classes • Allow Named Groupings • Passed as Parameters • What are some Examples? struct card { int pips; /* value of 1 to 13 */ char suit; /* s, h, d, c */ }; struct card c1, c2; struct card deck[52]; c1.pips = 12; c1.suit = ‘s’; deck[i].pips = j; typedef struct card card; card c1, c2, c3;
Structures – More Examples /* The following is in a file “class.h” */ #define CLASS_SIZE 100 typedef struct { char *last_name; int student_id; char grade; } student; /* The following is in a file “main.c” */ #include “class.h” main() { student temp, class[CLASS_SIZE]; . . . temp.grade = ‘A’; temp.last_name = “smith”; temp.student_id = 999999; . . . /* How Many Failed the class? */ printf( “Failed: %d\n”, fail(class)); . . . } /* What is fail? */
Structures – More Examples /* The following is in a file “class.c” */ /* This file contains functions defined *//* on the class structure. We can mimic */ /* an ADT/class, even if we can’t have */ /* the C language enforce the concepts. */ #include “class.h” /* This function counts failing grades */ int fail( student class[ ]) { int i, cnt = 0; for (i=0; i < CLASS_SIZE; i++); cnt += class[i].grade == ‘F’; return cnt; }
Structures – A Poker Example #include <stdio.h> #include <stdlib.h> #include <time.h> #define NDEALS 3000 /* No. of Deals */ #define NPLAYERS 6 /* No. of Players */ typedef enum {clubs, diamonds, hearts, spades} cdhs; typedef struct { int pips; /* value of 1 to 13 */ cdhs suit; /* s, h, d, c */ } card; /* Now Define the function prototypes */ /* These define names used in code for */ /* compile to be successful */ card assign_values(int pips, cdhs suit); void prn_card(card *c_ptr); void play_poker(card deck[52]); void shuffle(card deck[52]); void swap(card *p, card *q); void deal_the__cards(card deck[52], card hand[NPLAYERS][5]); int is_flush(card h[5]);
Structures – A Poker Example main() { cdhs suit; int i, pips; card deck[52]; for (i=0; i<52; ++i){ pips = i % 13 + 1; if (i < 13) suit = clubs; else if (i < 26) suit = diamonds; else if (i < 39) suit = hearts; else suit = spades; deck[i]=assign_values(pips, suit); } /* Now Print out the hearts */ for (i=26; i<39; ++i) prn_card_values(&deck[i]); /* Now start the game */ play_poker(deck); } card assign_values(int pips, cdhs suit) { card c; c.pips = pips; c.suit = suit; return c; }
Poker – Other Functions void play_poker(card deck[52]) { int flush_cnt=0, hand_cnt=0; int i, j; card hand[NPLAYERS][5]; /*Two-D Array */ srand(time(NULL)); /*seed random gen */ for(i=0; i < NDEALS; ++i) { shuffle(deck); deal_the_cards(deck, hand) for(j=0; j < NPLAYERS; ++j) { ++hnd_cnt; if (is_flush(hand[j])) { ++flush_cnt; printf(“ LOTS OF STUFF ON THE HAND AND PROBABILITY OF FLUSH”); } } } }
Poker – Other Functions void shuffle(card deck[52]) { int j,k; for(j=0, j < 52; ++j) { k = rand() % 52; swap(&deck[j], &deck[k]); } } void swap(card *p, card *q) { card temp; temp = *P; *p = *q; *q = temp; } int is_flush (card h[5]) { int i; for(i = 1; i < 5; ++i) if (h[i].suit != h[0].suit) return 0; return 1; }
Lists and Memory Allocation • Structures can be Leveraged to Create Lists of Self-Referential Data • Students in a Class • Cards in a Poker Hand • Consider a Hand as Follows • As Defined, Hand can have Multiple Cards (in fact, one or More) • Structure General • Poker, Blackjack, Bridge, etc. typedef struct { int pips; cdhs suit; cards *next_card; } cards;
Lists and Memory Allocation typedef struct { int pips; cdhs suit; cards *next_card; } cards; /* Using Structures and Pointers */ cards hand; cards c1, c2, c3, c4; /* Four aces */ c1.pips = c2.pips = c3.pips = c4.pips = 1; c1.cdhs = clubs; c2.cdhs = diamonds; c3.cdhs = hearts; c4.cdhs = spades; c1.next_card = c2.next_card = NULL; c3.next_card = c4.next_card = NULL; /* Now, build a hand */ hand.pips = 10; hand.suit = hearts; hand.next_card = &c1; c1.next_card = &c2; c2.next_card = &c3; c3.next_card = &c4; c4.next_card = &c5;
Lists and Memory Allocation • Example as Given is Very Limited • Requires Know Ahead of Time • Number of Elements in List • How you Want to Connect Them • We’ll use a Word Count Version as Example for These Concepts #include <stdio.h> #include <string.h> /* String Functions */ #include <stdlib.h> /* Malloc Routines */ #define MAX_CHARS 256 typedef struct { char line[MAX_CHARS+1]; int line_no; struct line_list *next_line; struct line_list *prev_line; } line_list; typedef struct { char f_name[MAX_CHARS+1]; struct line_list *f_lines; struct input_file *next_file; } input_file;
Word Count - Continued main(argc,argv) int argc; char *argv[]; { input_file *head, *next, *hold; line_list *aline, *bline; /* Create head to point to input_file */ head = (struct input_file *) malloc(sizeof(struct input_file)); /* Copy in argv[0] - this is program name */ strcpy(head->f_name, argv[0]); head->next_file = NULL; /* Create next to point to input_file */ next = (struct input_file *) malloc(sizeof(struct input_file)); /* Copy in argv[1] - this is input file*/ strcpy(next->f_name, argv[1]); next->next_file = NULL; /* Print out both file names */ printf("Files: %s %s \n",head->f_name, next->f_name); /* Link head to next and increment*/ hold = head; /* keep head of list */ head->next_file = next; head=head->next_file; /* Now, what prints? */ printf("%s \n",head->f_name); head = hold; /* restore head of list */
Word Count - Continued /* Now alloc and initialize two lines */ aline = (struct line_list *) malloc(sizeof(struct line_list)); strcpy(aline->line, "Hello World"); printf("Line A is: %s \n",aline->line); aline->next_line = aline->prev_line = NULL; aline->line_no=1; bline = (struct line_list *) malloc(sizeof(struct line_list)); strcpy(bline->line, "Goodbye World"); bline->next_line = bline->prev_line = NULL; bline->line_no=1; printf("Line B is: %s \n", bline->line); /* Now, link lines to files */ head->f_lines = aline; next->f_lines = bline; /* Work with references and permuted_index structures in a similar manner! */ }
All Structures for Project - .h File /* The File p1pbhdr.h */ #define MAX_CHARS 256 /* The line_list structure contains, for each line, the line itself (256 characters - max in Unix), a integer line_no, and pointers to the next line (next_line) and previous line (prev_line). */ typedef struct { char line[MAX_CHARS+1]; /* Allow for end of string */ int line_no; struct line_list *next_line; struct line_list *prev_line; } line_list; /* The input_file structure contains, for each file, the name of the file as read from argv (f_name), a pointer to the list of lines (f_lines), and a pointer to the next file (next_file). */ typedef struct { char f_name[MAX_CHARS+1]; struct line_list *f_lines; struct input_file *next_file; } input_file;
All Structures for Project - .h File /* The File p1pbhdr.h */ /* The references structure tracks, for each word in the permuted index, the list of (file,line) pairs. It does so by having a link to the input_file entry (file_ptr) and the corresponding line of that file (line_ptr). The structure is self-referential with a next_ref pointer to allow all of the references to the word in all (file, line) pairs to be tracked. */ typedef struct { struct input_file *file_ptr; struct line_list *line_ptr; struct references *next_ref; } references; /* The permuted_index structure tracks the list of all words that occur in all files. Each permuted index entry contain the word found (in some line), a list of indexes to that word (the index_list pointer to the references structure), and a pointer to the next word in the permuted index (next_word pointer). The words in this list must be kept in alphabetical order. This list is created by scanning every line of every file, as tracked in the input_file structure. */ typedef struct { char word[MAX_CHARS+1]; struct references *index_list; struct permuted_index *next_word; } permuted_index;
Code for Project - .c File /* The File p1pbcode.c */ #include <stdio.h> #include <string.h> #include <stdlib.h> #include “p1pbhdr.h” main(argc,argv) int argc; char *argv[]; { input_file *head, *next, *hold; line_list *aline, *bline; /* Create head to point to input_file */ head = (struct input_file *) malloc(sizeof(struct input_file)); /* Remainder as before . . . (see prior slide) */ /* Work with references and permuted_index structures in a similar manner! */ }