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.
39
Embed
Pointers as Structure Members u One reason to use pointers in structure: struct book { float price; char title[50]; char abstract[5000]; }; …… struct book.
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
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.
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++) {
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
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 ;
}
}
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.
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;……
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;
}
Files
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;
}
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
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
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.
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)
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
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;
}
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 )
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
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
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));
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;
}
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
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
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