Presentation is loading. Please wait.

Presentation is loading. Please wait.

Pointers as Structure Members u One reason to use pointers in structure: struct book { float price; char title[50]; char abstract[5000]; }; …… struct book.

Similar presentations


Presentation on theme: "Pointers as Structure Members u One reason to use pointers in structure: struct book { float price; char title[50]; char abstract[5000]; }; …… struct book."— Presentation transcript:

1 Pointers as Structure Members u One reason to use pointers in structure: struct book { float price; char title[50]; char abstract[5000]; }; …… struct book mybook[100]; …… /* set the value for every structure */ sort_by_price( mybook, 100); /*suppose we have the function */ …… u In sort function, you have to move record. That is, you will do a lot of x = mybook[ i ]; mybook[ i ] = mybook[ j ]; mybook[ j ] = x; u This reduces the speed significantly.

2 Pointers as struct members u Instead, we can use struct book { float price; char * title; char * abstract; }; …… struct book mybook[100]; for( I=0; I<100; I++) { mybook[I].title = malloc(50); mybook[I].abstract = malloc(5000); }; …… /*set the value for every structure */ sort_by_price( mybook, 100); /*suppose we have this function*/ …… –That is, we save the real title and abstract in other places, but we point the pointers title and abstract to the real places. u In sorting, the real contents of title and abstract will not move, but only the pointers move. This is efficient.

3 Pointers as struct members u This also has another benefit that you can dynamically allocate memory for titles and abstracts. –For books with short abstracts, you need not allocate the upper bound 5000 bytes. –For books with very long titles, you can still save the full title. u On the other hand, you get the trouble to malloc and free the memory in your program. –But this is worth in most of the cases. u We will talk more about the benefits of “pointers as struct members” soon later.

4 Pointers as struct memebers u This is an example of using the book structure we just defined. …… struct book one_book; one_book.price = 78.50; one_book.title = (char *) malloc(14); strcpy( one_book.title, “Unix System V” ); one_book.abstract = (char *) malloc(16); strcpy( one_book.abstract, “a good textbook” ); ……. free( one_book.title ); free(one_book.abstract); ……

5 More sophisticated uses of pointers

6 Pointers to Structures u First declare the structure struct part { float price ; char name [10] ; } ; u Then define a pointer of that type struct part *p_part ; u Also need to get some space for a thing of type part struct part thing; u Now you can set the pointer to point at the thing p_part = &thing ;

7 Pointers to Structures u p_part is set to point to the first byte of the struct variable u Reference to field price v (* p_part).price = 19.99 ; u The ( ) are required because. has a higher precedence than * u Alternative syntax p_part -> price = 19.99; thing.price thing.name [ ] p_part

8 Pointers to Structures { struct part * p, *q; p = (struct part *) malloc( sizeof(struct part) ); q = (struct part *) malloc( sizeof(struct part) ); p -> price = 199.99 ; strcpy( p -> name, “hard disk” ); (*q) = (*p); …… q = p; …… free(p); free(q);/* this statement causes a problem !!! why? */ }

9 Pointers to Structures u You can allocate a structure array as well: { struct part *ptr; ptr = (struct part *) malloc(10 * sizeof(struct part) ); for( i=0; i< 10; i++) { ptr[ i ].price = 10.0 * i; sprintf( ptr[ i ].name, “part %d”, i ); } …… free(ptr); }

10 Pointers to Structures u You can use pointer arithmetic to access the elements of the array: { struct part *ptr, *p; ptr = (struct part *) malloc(10 * sizeof(struct part) ); for( i=0, p=ptr; i< 10; i++, p++) { p -> price = 10.0 * i; sprintf( p -> name, “part %d”, i ); } …… free(ptr); }

11 Memcpy v.s. assignment operator u This assign a struct to another { struct part a,b; b.price = 39.99; b.name = “floppy”; a = b; } u Equivalently, you can use memcpy #include “string.h …… { struct part a,b; b.price = 39.99; b.name = “floppy”; memcpy(&a,&b,sizeof(part)); }

12 Array member v.s. pointer member struct book { float price; char name[50]; }; int main() { struct book a,b; b.price = 19.99; strcpy(b.name, “C handbook”); a = b; strcpy(b.name, “Unix handbook”); puts(a.name); puts(b.name); } struct book { float price; char *name; }; int main() { struct book a,b; b.price = 19.99; b.name = (char *) malloc(50); strcpy(b.name, “C handbook”); a = b; strcpy(b.name, “Unix handbook”); puts(a.name); puts(b.name); free(b.name); }

13 Passing Structures to Functions (1) u Structures are passed by value to functions –The parameter variable is a local variable, which will be assigned by the value of the argument passed. –unlike Java u This means that the structure is copied if it is passed as a parameter –this can be inefficient if the structure is big v in this case it may be more efficient to pass a pointer to the struct u A struct can also be returned from a function

14 Passing Structures to Functions (2) struct book { float price; char abstract[5000]; }; void print_abstract( struct book * p_book) { puts( p_book -> abstract ); }; struct pairInt { int min, max; }; struct pairInt min_max(int x,int y) { struct pairInt pair; pair.min = (x > y) ? y : x; pair.max = (x > y) ? x : y; return pairInt; } int main(){ struct pairInt result; result = min_max( 3, 5 ); printf(“%d<=%d”, result.min, result.max); }

15 Linked Lists u Pointers to structures can be used to create linked lists u We will describe these by example u The basic data type is a node containing data and pointers to the next element struct node_struct { int data; int count; struct node_struct *next; }; typedef struct node_struct node; Note: this is legal! This definition is just for convenience

16 Linked Lists (2) #include struct node_struct { int data; int count; struct node_struct *next; }; typedef struct node_struct node; /* search for a node by its key d */ node * search(node * head, int d) { for(; head != NULL; head = head->next) if ( head -> data == d) return head; return NULL; } /* insert a node into list */ void insert(node ** p_head, int d) { node * loc; loc=search( *p_head, d ); if (loc != NULL) loc->count++; else { node * newhead; newhead = malloc( sizeof(node) ); newhead -> data = d; newhead -> count = 1; newhead -> next= *p_head; * p_head = newhead ; }

17 Linked Lists (3) Void free_list(node *head) { node *p; for(p=head; head!=NULL; p=head, head=head -> next ) free(p); } int main() { int i; node * loc, *list = NULL; for (i=0; i<15; i++) insert(&list,i % 10); for (i=0; i<10; i++) { loc = search(list,i); printf("Item %d: data=%d, count=%d\n", i,loc->data,loc->count); } free_list(list); } Notes: u we passed a pointer to a pointer to a node (node **) to insert u this is because we need to modify the value of list in insert( ), we must pass the address of list to the function, which is a pointer to a pointer.

18 Trees struct s_node { int data; struct s_node * left; struct s_node * right; }; typedef s_node node; /* the following code illustrate how to expand the tree */ …… node * root; root = (node *) malloc(sizeof(node)); root->left = (node *) malloc(sizeof(node)); root->left->left = root->left->right = NULL; root->right = (node *) malloc(sizeof(node)); root->right->left = root->right->right = NULL; ……

19 Release all nodes of a tree void release_tree( node ** p_root) { node * root = (*p_root); if( root == NULL) return; release_tree( &(root->left) ); /* free the left subtree*/ release_tree( &(root->right)); /* free the right subtree */ free( root ); /* free the root node */ *p_root = NULL; /* this subtree has been released, so notify the calling function */ return; }

20 Files

21 FILE * u In C, we use a FILE * data type to access files. u FILE * is defined in stdio.h. u An example: #include int main() { FILE *fp; fp = fopen(“tmp.txt”, “w”); fprintf(fp,“This is a test”); fclose(fp); return 0; }

22 Opening a File (1) u You must include u Prototype Form: FILE * fopen (const char * filename, const char * mode) u FILE is a structure type declared in stdio.h –you don't need to worry about the details of FILE v in fact it may vary from system to system –fopen returns a pointer to the FILE structure type –you must declare a pointer of type FILE to receive that value when it is returned –use the returned pointer in all subsequent references to that stream –if fopen fails NULL is returned u the argument filename is the name of the file to be opened

23 Opening a File (2) Values of modes u Enclose in quotes or pass a pointer to a string u Modes: r : v open the file for reading (NULL if it doesn’t exist) w : v open for writing. create if not there. throw away old data a : v open for appending. create if not there. add to bottom r+ : v open for read/write. create if not there. add to top overwriting existing data w+ : v open for read/write. create if not there. destroy old if there a+ : v open for read/append. create if not there. append at bottom

24 Opening a File (3) int main() { FILE *fp; char ch, filename[40], mode[4]; while (1) { printf ("\nEnter a filename"); gets (filename); printf ("\nEnter a mode (3 chars)"); gets (mode); if ( (fp = fopen (filename, mode) ) != NULL) { printf ("\nSuccessful opening %s in mode %s.\n", filename, mode); fclose (fp); } else { fprintf (stderr, "\nError opening file %s in mode %s.\n", filename, mode); } puts ("Enter x to exit, any other to continue."); if ( (ch = getch()) == 'x') break; } Watch out for directories !

25 The exit () Function u Is used to leave the program at anytime from anywhere before the “normal” exit location u Syntax: exit (status); –Normal termination is with a 0 exit status –Anything larger than 0 indicates an error condition and can be caught by the system –stdlib.h must be included to use exit u These two constants are defined there too #define EXIT_SUCCESS 0 #define EXIT_FAILURE 1 v use exit (EXIT_?????) to indicate exit status

26 Three ways to read and write files u Formatted file I/O u Get and put a character u Block read and write

27 Formatted File I/O u Formatted File input is done through fscanf: –Prototype Form: int fscanf (FILE * fp, const char * fmt,...) ; –Exactly the same as scanf except it include a file descriptor. u Formatted File output is done through fprintf: –int fprintf(FILE *fp, const char *fmt, …); { FILE *fp1, *fp2; int n; fp1 = fopen(“file1”, “r”); fp2 = fopen(“file2”, “w”); fscanf(fp1, “%d”, &n); fprintf(fp2, “%d”, n); fclose(fp1); fclose(fp2); }

28 Get and put a character #include int fgetc(FILE * fp); int fputc(int c, FILE * fp); u These two functions read or write a single byte from or to a file. u The fgetc returns the character that was read, converted to an integer. u The fputc returns the same value of parameter c if succeeds, otherwise, return EOF.

29 fwrite and fread (1) u fread and fwrite are binary file reading and writing functions –no interpretation of ASCII characters –prototypes is found in stdio.h u Generic Form: int fwrite (void *buf, int size, int count, FILE *fp) ; int fread (void *buf, int size, int count, FILE *fp) ; v buf: is a pointer to the region in memory to be written/read –it can be a pointer to anything v size: the size in bytes of the individual data item v count: the number of data items to be written/read u For example a 100 element array of integers –fwrite( buf, sizeof(int), 100, fp); u The fwrite (fread) returns the number of items written (read)

30 fwrite and fread (2) u Testing for errors: if ( (frwrite(buf,size,count,fp)) != count) fprintf (stderr, “Error writing to file.”); u Writing a single double variable x to a file: fwrite (&x, sizeof(double), 1, fp) ; –this writes the double x to the file in raw binary format v i.e., it simply writes the internal machine format of x u Writing an array data[50] of 50 address structures can be done by: –fwrite (data, sizeof(address), 50, fp) ; v or –fwrite (data, sizeof(data), 1, fp); u fread and frwrite is more efficient than fscanf and fprintf

31 fwrite and fread (3) #include const int size=20; int main() { int count,array1[size],array2[size]; FILE *fp; for (count=0;count<size;count++) array1[count] = 2*count; if ((fp=fopen("direct.txt","w")) ==NULL) { fprintf(stderr, "Error opening file"); exit (1); } if (fwrite(array1,sizeof(int),size,fp) != size) { fprintf(stderr, "Error writing to file"); exit (1); } fclose (fp); if ((fp=fopen("direct.txt","r"))==NULL) { fprintf(stderr, "Error opening file"); exit (1); } if (fread(array2, sizeof(int),SIZE,fp) != SIZE) { fprintf(stderr, "Error reading file"); exit(1); } fclose (fp); for (count=0;count<SIZE;count++) printf("%d\t%d\n", array1[count], array2[count]); return 0; }

32 Closing and Flushing Files u We’ve used it but here it is: int fclose (FILE * fp) ; v closes fp -- returns 0 if it works -1 if it fails u You can clear a buffer without closing it int fflush (FILE * fp) ; v essentially this is a force to disk v very useful when debugging u Without fclose or fflush, your updating a file may not take effect on the hard disk. (OS usually use memory caches to access files )

33 Sequential and Random Access u The standard C libraries are relatively limited in their file manipulation routines u You can "rewind" and start reading from the beginning of the file again void rewind (FILE * fp) ; v this simply move the file’s position indicator from where it is to the first byte in the file u To determine where the position indicator is use: long ftell (FILE * fp) ; v returns a long giving the current position in bytes v the first byte of the file is byte 0 v if an error occurs ftell () returns a type long -l –that’s a type long -1

34 Random Access u One additional operation gives slightly better control int fseek (FILE * fp, long offset, int origin) ; –fp is the appropriate file pointer –offset is the number of bytes to move the position indicator –origin is the moves relative starting position u Three options/constants are defined for origin –SEEK_SET v move the indicator offset bytes from the beginning –SEEK_CUR v move the indicator offset bytes from its current –SEEK_END v move the indicator offset bytes from the end

35 Detecting End of File u Text mode files: while ( (c = fgetc (fp) ) != EOF ) –reads characters until it encounters the EOF –the problem is that the byte of data read may actually be indistinguishable from EOF u Binary mode files: –The standard library provides a function int feof (FILE * fp) ; –Note: the feof realizes the end of file only after a reading was not successful (fread, fscanf, fgetc … ) …… fseek(fp,0,SEEK_END); printf(“%d\n”, feof(fp)); fgetc(fp); printf(“%d\n”,feof(fp));

36 An Example #define BUFSIZE 100 int main () { char buf[BUFSIZE]; if ( (fp=fopen(“file1”, "r"))==NULL) { fprintf (stderr,"Error opening file."); exit (1); } while (!feof(fp)) { fgets (buf,BUFSIZE,fp); printf ("%s",buf); } fclose (fp); return 0; }

37 File Management Functions u Erasing a File int remove (const char * filename); v this is a character string indicating the file v returns 0 if deleted else -1 u Renaming a File int rename (const char * oldname, const char * newname); v returns 0 if successful or -1 if an error occurs v error: file oldname does not exist v error: file newname already exists v error: try to rename to another disk

38 Using Temporary Files u Files with names and only exist during the execution of the program u Generic Form: char *tmpnam (char *s) ; –included in stdio.h –creates a valid filename that does not conflict with any other existing files u Note this does not create the file –just the NAME –you then go and open it and presumably write to it –The file created will continue to exist after the program executes unless you delete it

39 An Example #include int main () { char buffer[10]; tmpnam(buffer); printf ("Temporary name 1: %s", buffer); return 0; } u Output Temporary name 1: /var/tmp/aaaceaywB


Download ppt "Pointers as Structure Members u One reason to use pointers in structure: struct book { float price; char title[50]; char abstract[5000]; }; …… struct book."

Similar presentations


Ads by Google