1 / 21

Structures & Unions

Structures & Unions. User-Defined Types. C provides facilities to define one’s own types. These may be a composite of basic types ( int , double , etc) and other user-defined types. The most common user-defined type is a structure, defined by the keyword struct .

thom
Download Presentation

Structures & Unions

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Structures & Unions

  2. User-Defined Types • C provides facilities to define one’s own types. • These may be a composite of basic types (int, double, etc) and other user-defined types. • The most common user-defined type is a structure, defined by the keyword struct. • Another, less common, form of user-defined type is a union, which will be discussed in the next lecture.

  3. Structures • A structure is a collection of one or more variables, possibly of different types, grouped together under a single name for convenient handling (K&R page 127). • Structures are user-defined aggregate types. • They assist program organisation by • Grouping logically related data, and giving this set of variables a higher-level name and more abstract representation. • Enabling related variables to be manipulated as a single unit rather than as separate entities. • Reducing the number of parameters that need to be passed between functions. • Providing another means to return multiple values from a function.

  4. Structure Syntax • A structure is defined by the keyword struct followed by a set of variables enclosed in braces. • Consider the following structure to represent 2-D points. struct Point { int x; int y; }; • The variables x and y are called members of the structure type Point. • Style note: Structures are given names with Capital first letters, by convention. Distinguish them from variables and functions (lowercase first letter), and symbolic constants (all uppercase).

  5. Declaring Structure Variables • There are several equivalent ways to define variables of a particular structure type. • Declare them at the structure definition. struct Point { int x; int y; } p1, p2, p3; /* Define 3 variables */ If these 3 variables were the only definitions of type Point, and the type is not used again, we may well have written struct { int x; int y; } p1, p2, p3; /* Define 3 variables */ • Define the variables at some point after the structure definition. struct Point p1, p2, p3; /* Define 3 variables */

  6. Initialising Structure Variables • A structure may be initialised when it is defined using brace notation. struct Point topleft = {320, 0}; • The order of values in the initialiser list matches the order of declarations in the structure.

  7. Accessing Members • Members of a structure type may be accessed via the “.” member operator. struct Point topleft; topleft.x = 320; topleft.y = 0; struct Point delta = { pt1.x - pt2.x, pt1.y - pt2.y }; double distance = sqrt((double)delta.x * delta.x + (double)delta.y * delta.y);

  8. Nested Structures • Structures may be defined inside other structures. struct Rectangle { struct Point topleft; struct Point bottomright; }; • To access lower-level members, need to use member operator multiple times. struct Rectangle rect; rect.topleft.x = 50;

  9. Operations on Structures • Operations permitted on structure types is a subset of those permitted on basic types. • Structures may be copied and assigned, but not compared. struct Point p1 = { 0, 0 }; struct Point p2; p2 = p1; /* Valid. */ if (p1 == p2) /* Invalid.*/ printf("Points are equal\n"); if (p1.x == p2.x && p1.y == p2.y) /* Valid. */ printf("Points are equal\n");

  10. Operations on Structures • Structures may be passed to functions and returned from functions. (This is a consequence of being copyable.) struct Point point_difference(struct Point p1, struct Point p2) /* Return the delta (dy, dy) of p2 with respect to p1. */ { p2.x -= p1.x; p2.y -= p1y; return p2; } • As for other variables, structures are passed-by-value. So, the second argument in the calling function will not be affected by the changes to p2.

  11. Pass by Reference • Pass by value may be very inefficient if the structure is large (ie, has many members). • Passing a pointer to a structure is generally much more efficient than making a copy of the structure itself. • Defining pointer types is the same as for variables of primitive types. struct Point pt = { 50, 50 }; struct Point *pp; pp = &pt; (*pp).x = 100; /* pt.x is now 100. */

  12. Pointers to Structures • Notice the parentheses around the dereferenced pointer. (*pp).x = 100; • This is necessary to enforce correct precedence. • An alternative notation permits simpler pointer access to structure members. (*pp).x = 100; pp->x = 100; /* equivalent */ • Another example, struct Rectangle rect, *pr = ▭ rect.topleft.x = 50; /* equivalent operations */ (*pr).topleft.x = 50; pr->topleft.x = 50;

  13. Arrays of Structures • The definition of arrays of structure types is virtually identical to arrays of primitive types. struct Point pa[10]; • Structure arrays can be initialised with an initialiser list enclosed in braces (and the size is determined by the compiler if unspecified). struct Point pa[] = { {0, 0}, {0, 240}, {320, 240}, {320, 0} };

  14. Structure Arrays • The size of a structure in bytes may be found via the sizeof operator. • The usual C idiom may be used to compute the number of elements in an array of structures. struct Point pa[] = { {0, 0}, {0, 240}, {320, 240}, {320, 0} }; struct Point *pp = pa; for (; pp != pa + sizeof(pa) / sizeof(pa[0]); ++pp) printf("%d %d\n", pp->x, pp->y);

  15. Structures and Pointer Arithmetic • As with primitive types, the compiler knows the size of a structure and, given a pointer of a structure type will compute the appropriate address offsets automatically. • Important. The size of a structure need not equal the sum of its constituent parts. • Most real machines have alignment restrictions for certain types (e.g., integers must be located at even addresses). • The compiler will pad a structure with unnamed “holes” to ensure each member is properly aligned. Eg, the following structure might not have size 5-bytes, but 6 or 8-bytes. struct MyStruct { char c; int i; }; • The sizeof operator returns the correct size.

  16. Self-Referential Structures • A structure may not contain an object of its own type. struct Node { int item; struct Node n; /* Invalid */ }; • In general, a structure may not contain an object of an incomplete type. • However, a structure may contain a pointer to an incomplete type. struct Node { int item; struct Node *pn; /* Valid */ };

  17. Self-Referential Structures • The ability to refer to (ie, point to) an incomplete type, including itself, is an important property for constructing a variety of data-structures. • For example: linked-lists, binary trees, graphs, hash tables, and more.

  18. Example: A Linked List • Linked lists come in two basic varieties: singly linked and doubly linked. • We describe here a simple version of a singly linked list. • List consists of a set of nodes, where each node contains an item and a pointer to another list node. struct List { int item; struct List *next; }; • (Here we have chosen an int as the contained item. Any other type(s) may be used.)

  19. Unions • Unions look similar to structures. They have identical declaration syntax and member access, but they serve a very different purpose. union Utype { int ival; float fval; char *sval; }; union Utype x, y, z; • Accessing members of a union is via “.” member operator or, for pointers to unions, the -> operator.

  20. Unions • A union holds the value of one-variable at a time. • The compiler allocates storage for the biggest member of the union. • The type retrieved from the union must be the type most recently stored. Otherwise, the result is implementation dependent. union Utype x; x.fval = 56.4; /* x holds type float. */ printf("%f\n", x.fval); /* OK. */ printf("%d\n", x.ival); /* Implementation dependent. */

  21. Unions • Unions are used to store one of a set of different types. • Commonly used to implement a “variant” array. (This is a form of generic programming.) • There are other uses also, but they are quite advanced (e.g., concern the alignment properties of unions).

More Related