pointers as structure members u one reason to use pointers in structure: struct book { float price;...

39
Pointers as Structure Members 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 */ …… 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; This reduces the speed significantly.

Upload: cameron-stevens

Post on 14-Jan-2016

219 views

Category:

Documents


0 download

TRANSCRIPT

Page 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

Pointers as Structure Members 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 */

…… In sort function, you have to move record. That is, you

will do a lot ofx = mybook[ i ]; mybook[ i ] = mybook[ j ]; mybook[ j ] = x;

This reduces the speed significantly.

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

Pointers as struct members 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.

In sorting, the real contents of title and abstract will not move, but only the pointers move. This is efficient.

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

Pointers as struct members 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.

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.

We will talk more about the benefits of “pointers as struct members” soon later.

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

Pointers as struct memebers 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);

……

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

More sophisticated uses of pointers

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

Pointers to Structures First declare the structure

struct part { float price ; char name [10] ;} ;

Then define a pointer of that typestruct part *p_part ;

Also need to get some space for a thing of type partstruct part thing;

Now you can set the pointer to point at the thingp_part = &thing ;

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

Pointers to Structures

p_part is set to point to the first byte of the struct variable Reference to field price

(* p_part).price = 19.99 ;

The ( ) are required because . has a higher precedence than * Alternative syntax

p_part -> price = 19.99;

thing.price thing.name [ ]

p_part

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

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? */

}

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

Pointers to Structures 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);

}

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

Pointers to Structures 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);

}

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

Memcpy v.s. assignment operator This assign a struct to

another

{

struct part a,b;

b.price = 39.99;

b.name = “floppy”;

a = b;

}

Equivalently, you can use memcpy

#include “string.h

……

{

struct part a,b;

b.price = 39.99;

b.name = “floppy”;

memcpy(&a,&b,sizeof(part));

}

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

Array member v.s. pointer memberstruct 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);

}

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

Passing Structures to Functions (1) 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

This means that the structure is copied if it is passed as a parameter– this can be inefficient if the structure is big

in this case it may be more efficient to pass a pointer to the struct

A struct can also be returned from a function

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

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);

}

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

Linked Lists Pointers to structures can be used to create linked lists We will describe these by example 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

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

Linked Lists (2)#include <stdio.h>

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 ;

}

}

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

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: we passed a pointer to

a pointer to a node (node **) to insert

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.

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

Treesstruct 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;……

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

Release all nodes of a treevoid 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;

}

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

Files

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

FILE * In C, we use a FILE * data type to access files . FILE * is defined in stdio.h . An example:

#include <stdio.h>

int main()

{

FILE *fp;

fp = fopen(“tmp.txt”, “w”);

fprintf(fp,“This is a test”);

fclose(fp);

return 0;

}

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

Opening a File (1) You must include <stdio.h> Prototype Form:

FILE * fopen (const char * filename, const char * mode) FILE is a structure type declared in stdio.h

– you don't need to worry about the details of FILE 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

the argument filename is the name of the file to be opened

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

Opening a File (2)Values of modes Enclose in quotes or pass a pointer to a string Modes:

r : open the file for reading (NULL if it doesn’t exist)

w : open for writing. create if not there. throw away old data

a : open for appending. create if not there. add to bottom

r+ : open for read/write. create if not there. add to top overwriting

existing data

w+ : open for read/write. create if not there. destroy old if there

a+ : open for read/append. create if not there. append at bottom

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

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 !

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

The exit () Function Is used to leave the program at anytime from

anywhere before the “normal” exit location 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

These two constants are defined there too#define EXIT_SUCCESS 0#define EXIT_FAILURE 1

use exit (EXIT_?????) to indicate exit status

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

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

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

Formatted File I/O 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. 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);

}

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

Get and put a character#include <stdio.h>

int fgetc(FILE * fp);

int fputc(int c, FILE * fp); These two functions read or write a single byte from or

to a file. The fgetc returns the character that was read,

converted to an integer. The fputc returns the same value of parameter c if

succeeds, otherwise, return EOF.

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

fwrite and fread (1) fread and fwrite are binary file reading and writing

functions– no interpretation of ASCII characters – prototypes is found in stdio.h

Generic Form:int fwrite (void *buf, int size, int count, FILE *fp) ;int fread (void *buf, int size, int count, FILE *fp) ; buf: is a pointer to the region in memory to be written/read

– it can be a pointer to anything size: the size in bytes of the individual data item count: the number of data items to be written/read

For example a 100 element array of integers– fwrite( buf, sizeof(int), 100, fp);

The fwrite (fread) returns the number of items written (read)

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

fwrite and fread (2) Testing for errors:

if ( (frwrite(buf,size,count,fp)) != count) fprintf (stderr, “Error writing to file.”);

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 i.e., it simply writes the internal machine format of x

Writing an array data[50] of 50 address structures can be done by:– fwrite (data, sizeof(address), 50, fp) ;

or– fwrite (data, sizeof(data), 1, fp);

fread and frwrite is more efficient than fscanf and fprintf

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

fwrite and fread (3)#include <stdio.h>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;

}

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

Closing and Flushing Files We’ve used it but here it is:

int fclose (FILE * fp) ; closes fp -- returns 0 if it works -1 if it fails

You can clear a buffer without closing itint fflush (FILE * fp) ;

essentially this is a force to disk very useful when debugging

Without fclose or fflush, your updating a file may not take effect on the hard disk. (OS usually use memory caches to access files )

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

Sequential and Random Access The standard C libraries are relatively limited in their

file manipulation routines You can "rewind" and start reading from the beginning

of the file againvoid rewind (FILE * fp) ;

this simply move the file’s position indicator from where it is to the first byte in the file

To determine where the position indicator is use:long ftell (FILE * fp) ;

returns a long giving the current position in bytes the first byte of the file is byte 0 if an error occurs ftell () returns a type long -l

– that’s a type long -1

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

Random Access 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

Three options/constants are defined for origin– SEEK_SET

move the indicator offset bytes from the beginning– SEEK_CUR

move the indicator offset bytes from its current– SEEK_END

move the indicator offset bytes from the end

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

Detecting End of File 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

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));

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

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;

}

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

File Management Functions Erasing a File

int remove (const char * filename); this is a character string indicating the file returns 0 if deleted else -1

Renaming a Fileint rename (const char * oldname, const char * newname);

returns 0 if successful or -1 if an error occurs error: file oldname does not exist error: file newname already exists error: try to rename to another disk

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

Using Temporary Files Files with names and only exist during the execution of

the program Generic Form:

char *tmpnam (char *s) ;– included in stdio.h– creates a valid filename that does not conflict with any other

existing files

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

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

An Example#include <stdio.h>

int main () {

char buffer[10];

tmpnam(buffer);

printf ("Temporary name 1: %s", buffer);

return 0;

}

OutputTemporary name 1: /var/tmp/aaaceaywB