Lecture 8 - Pointers

Back to Previous Lecture
Up to Main Page

Call by Value and Address

The program args.c illustrates how scalar arguments are passed to functions by either name or value.

GetInfo - Final Version

This is the final version of getinfo.c. In this version, we have a small database, complete with an editor. The customer file (cust.txt) contains the current records. The index file (cust.ndx) contains information that the getinfo.c program uses to extract records from the file.

Notice that the name fields have been changed. Instead of fixed size fields, we have changed them to character pointers. This means that there is no maximum size for either name field. It also means that there isn't any wasted space either. Database records are written on a single line, with vertical bars separating fields. For example:

The index table is kept sorted. This means that, even though the above records are out of order, when the user lists the records, they will be in the correct order:

Each time the program starts, it opens the database file (cust.txt) for update, and does a binary read of the index file (cust.ndx), into the index table. The index table is used to extract records from the file. There is never more than one customer record in memory at any one time.

The way this program works is that each time a record is written, it is written at the end of the cust.txt file. If this is an update of an existing record, the old record still exists in the file, but the index table doesn't point to it; it points to the new record instead. If a record is deleted, its index record is removed from the index table. That way, when we loop through the file, we only read active, valid records. Old records are never read.

Each time you write an updated record, or delete an existing record, you are creating a "hole" in the file. After a while, this can cause the database file to get much larger than it needs to be. By using the compress option, the program will create a new database file, cust.new copying only the current records from the old file into the new one. Each time a new record is written, the index table is updated to reflect the new location within the new file. When done, it renames cust.txt to cust.old and cust.new to cust.txt. It then re-opens cust.txt as the new database file.

Although you can't get rich selling this program, it does illustrate the operations that are involved in maintaining a real database. You might want to try it for a while, and then see what changes you would like to make to it.

Notice that only a few routines actually know what the records look like. The functions get_cust, display_cust, edit_cust, read_cust, and write_cust know what the record looks like. The functions alloc_cust and free_cust know enough to allocate and free memory. The rest of the program simply calls these routines to process the records.

By changing the definition of a customer record in getinfo.h, you can add additional fields. Then you only have to modify the above functions to support the new record format.

For example, suppose you wanted to add a phone number field. Let's make it a variable length field. The new customer record might look like this:

Since this is a variable length field, using a character pointer, we have to modify alloc_cust to initialize the phone number to NULL, and free_cust to free the phone field. (If the new field was simply a scalar variable, like bal, then free_cust wouldn't have to be changed.)

You would then have to add some lines to get_cust and edit_cust to ask for a phone number. You would have to modify display_cust to display the phone number, read_cust to parse the phone field, and write_cust to write out the phone field. Once that was done, your database would now support phone numbers.

Try it! You might surprise yourself.

Back to Previous Lecture
Up to Main Page