Structures: Used to combine related items (called members) into a single unit. Useful in passing data to functions: - could use global variables, but this is bad because of potential unseen side effects and because only one copy is possible. - could use long parameter lists, but this is inconvenient and requires much copying during function calls. - could pass structures. Convenient but still lots of copying required. - could pass pointers to structures. This is preferred as it is fast and there is little copying. Further, the data structure can be partially "hidden" from clients by returning/passing pointers to void. A client cannot take * of a pointer to void and cannot cast unless you make the type available. The part analogous to the int, char or double of ordinary types is: struct tag /* tag is some name (optional if not needed elsewhere) */ { type1 member1; type2 member2; ... } /* you may omit the body if tag has been used previously */ /* follow by an ; ultimately - one of few places where }; occurs. */ For example: struct time { char dst; int hour; int min; } meeting, *psupper; declares a variable "meeting" and a pointer "psupper" to object of type "struct time" whose members include a char called dst. You can now declare struct time nap; without having to describe "struct time" again. Initializers are allowed: struct time nap = {'y',3,10}; is the same as "struct time nap;" followed by: nap.dst = 'y'; nap.hour = 3; nap.min = 10; Refer to members using the member operator "." The compiler treats members as offsets -- like indices in an array. Typical way: Member: dst - hour min Contents: 'y' garbage 3 10 Sizeof: 1 1 4 4 Offset: 0 - 2 6 Note sizeof(time) is NOT necessarily the sum of the member sizes (10 versus 9) It is most efficient to put the most frequently used member first, for example, in linked lists put the pointer to the next struct first. Make life easier by using typedefs with structures: typedef struct time { ... } TIME, *PTIME; TIME meeting, *psupper; /* or */ TIME meeting; PTIME psupper; The advantage in typedefs is that "TIME" can be used alone, while "time" can NEVER be used alone - you always need to use "struct time". e.g. in old C: (struct time *) malloc(sizeof(struct time)) versus (PTIME) malloc(sizeof(TIME)) To alloc struct use: TIME *pmeeting; pmeeting = malloc(sizeof(TIME)); pmeeting = realloc(pmeeting,sizeof(TIME)); pmeeting = calloc(count,sizeof(TIME)); free(pmeeting); Function calls generally involve passing a pointer to a structure, not the structure itself. For example, suppose you want to change the hour. Then "changehour(meeting, 5);" will fail since the function only gets a COPY of the structure, just like "changehour(meeting.hour, 5);" fails. Instead call function with a pointer to the struct: changehour(&meeting, 5); /* call function with pointer */ ... void changehour(TIME *pmeeting, int newhr) { (*pmeeting).hour = newhr; } The construction *(pointer_to_struct).member occurs so often it is abbreviated as pointer_to_struct->member { pmeeting->hour = newhr; /* the member value pointed to */ } You can have arrays of struct: TIME meetings[10]; struct time meetings[10]; To change the hour on the third meeting: meetings[2].hour = 17; Initialize via: TIME meetings[10]={{'y',3,5},{'n',7,8}, ... }; You can have struct with arrays in them: typedef struct sstr /* Short STRings */ { char val[5]; /* Size 5 not optional. Different than char *val */ } SSTR; SSTR midget; Then midget.val is array of 5 characters. midget.val[2] is third of the characters, as is (midget.val)[2] Note the precedence of . [] -> is the same and associates left to right: x.y.z is (x.y).z x->y->z is (x->y)->z x->y[i] is (x->y)[i] as is usually intended. You can have a struct within a different(!) struct. You can have a struct with a pointer to itself. A typical use is for linked lists and for hash tables. For linked lists of arbitrary data use generic pointers: (void *) You can have struct with bit fields: The members are declared in order as unsigned int bit_field_name : size; where size is usually 1. Bit fields are machine dependent. Related to "struct" is "union" which is used as struct, except that all members have zero offset, so a union can hold only one value at a time. In C++: struct may contain function members, access to members is controlled, and a class is a struct whose members are "private" by default. Structure assignment is allowed and copies over the values of all members. In contrast, array assignment, does not copy values or is illegal: char *str1, char str2[20]; str1 = str2; /* OK but just copies pointer, not the characters */ str2 = str1; /* illegal; str2 is a constant */