Assume that Laurent, for some elusive reason, needs to keep a record of all CEO members using a C program. He needs to keep diverse information on each member like their name, their snail-mail and e-mail addresses, the date when they first subscribed and the type of machine they have (Oric-1, Atmos or Telestrat). People with previous Pascal experience will be smiling, BASIC users will be curious, and I hope there aren't any COBOL users around.

Composite Data Structures

Assume that Laurent, for some elusive reason, needs to keep a record of all CEO members using a C program. He needs to keep diverse information on each member like their name, their s-mail 1 and e-mail addresses, the date when they first subscribed and the type of machine they have (Oric-1, Atmos or Telestrat). People with previous Pascal experience will be smiling, BASIC users will be curious, and I hope there aren't any COBOL users around.

The way to do this is by defining our very own composite data structure. Such data structures are called structs in C. Let's define the struct for Laurent's database 2:

struct ceo_member {
	char                name[40];
	char                smail[80];
	char                email[40];
	short unsigned int  year_subscribed;
	short unsigned int  month_subscribed;
	short unsigned int  day_subscribed;
	char                machine[10];
};

Place all data structure definitions outside functions. The new data structure is called struct ceo_member. It's not called simply ceo_member! C also wants the struct keyword. We define 7 fields within this new struct. The name field is a 40-character string (Laurent will be forced to change it if he gets many Greek subscribers). s-mail might be long, so we allocate 80 bytes for it. e-mail also gets 40 characters. The subscription date is stored as three short unsigned ints. They have a range of 0..65535 (0..255 on the 16-bit compiler). Finally, we allocate a 10-byte string for the machine type owned by that person. The string is just long enough to hold "Telestrat" (remember, C strings are null-terminated: we need an additional 10th character to store the final '\0').

How do we use this new struct? Well, we've just defined a new data structure. We can now declare variables of type struct ceo_member.

struct ceo_member one_member;
struct ceo_member members[1000];

one_member is a record of a single member. Simple isn't it? Of course, we can have arrays of structs. members is a big enough array of CEO members.

The usual operation on a struct is to access one of its fields. To access the name of the CEO member stored in one_member, we write one_member.name (remember the dot (.) operator?) It's simple, really. The following example prints the names and addresses of the first 10 CEO members stored in members. It also shows you how to use arrays of structs.

void main()
{
	int i;
 
	for(i = 0; i < 10; i++) {
	        printf ("%d. NAME=%s, ADDRESS=%s\n",
		i,
		members[i].name,
		members[i].smail);
	}
}

Of course, you can use the fields as normal variables. You can involve one_member.year_subscribed in any expression you want!

structs may contain any data structure, even other structs. This piece of information will allow us to make struct ceo_member look better by making a new data structure:

struct date {
	short unsigned int year, month, day;
};

Now we can change struct ceo_member as follows:

struct ceo_member {
	char         name[40];
	char         smail[80];
	char         email[40];
	struct date  subscription_date;
	char         machine[10];
};

Now we can access the subscription year of the member stored in one_member by writing one_member.subscription_date.year (as you can see this can get quite long).

What's the sizeof() of a struct? Well, it's equal to the sum of the sizeof()s of its fields3. A struct is only a way of grouping data. It does not take any space by itself.

  • 1. ‘Snail-Mail’. Some people insist on calling it conventional mail or just mail.
  • 2. Laurent, after this you're entitled to ask for a dedicated CEO database in Oric C!
  • 3. This holds on the Oric, but not on other computers. Most modern computers prefer their values to be ‘word-aligned’, i.e. to start on an address divisible by four (on a 32-bit computer). This can introduce gaps between fields of a struct (and its sizeof can be larger than the sum of the sizes of its fields). 32-bit computers don't care because they usually have enough memory to spare (or because they simply can't access anything unless it's properly aligned). On the Oric, space is of the essence, so we leave no gaps.

Tags: 


Add new comment

Leave a comment