C Programming Lecture 23 Enumeration Types Structures Enumeration Types Enumeration types are defined and used by the programmer as the need arises. • They allow the programmer to name a finite set together with its elements. – The elements of the finite set are called enumerators. Naming a Finite Set and Declaring Enumerators enum day {sun, mon, tue, wed, thu, fri, sat}; The keyword enum is used to declare an enumeration type. The enumerators above are the identifiers sun, mon,...,sat. The keyword enum along with the tag name day are used as a type specifier to declare variables of type enum day. enum day d1, d2; /* declares variables d1 & d2 */ Alternative for Declaring Variables On the previous slide, the enumeration type enum day was first declared, then variables of that type were declared. • We can do both at the same time. enum day {sun,mon, tue, wed, thu, fri, sat} d1, d2; What are the Enumerators, Really? enum day {sun, mon, tue, wed, thu, fri, sat} d1; The enumerators sun, mon, ..., sat are identifiers: • They are constants of type int. • By default, the first one is given the value 0, and each succeeding one has the next integer. Initialization of Enumerators enum fruit {apple = 7,pear, orange = 3,lemon} fruit; Since the enumerator apple has been initialized to 7, pear has a value of 8. Since orange has a value of 3, lemon has a value 4. of Using Enumeration Variables The previously declared variables d1 and d2 can only be assigned values from the set we named day. d1 = fri; d2 = sat; Using Enumeration Types Enumerators are treated as programmerspecified constants and used to aid program clarity. • If necessary, the underlying value can be obtained by using a cast. • The variables and enumerators in a function must all have distinct values. The typedef Facility C provides the typedef facility so that a descriptive identifier can be used as the name of a specific type. typedef int color; This makes color a type that is synonymous with int, and color can now be used as a type in declarations. color red, green, blue; Leaving off the Tag Name enum tree_type {fir,pine} tree; We can leave out the tag name, but all variables will have to be declared when the enumeration is declared: enum {fir,pine} tree; Style Since enumerators can be mnemonic (descriptive),their use tends to be self-documenting and is considered good programming style. Examples • • • • enum enum enum enum bool off_on no_yes speed {false, true}; {off, on}; {no, yes}; {slow, fast}; The Structure Type The structure type allows the programmer to aggregate components into a single, named variable. • A structure has components that are individually named. – These components are called members. • The members of a structure can be of various types. – This allows the programmer to create aggregates of data that are suitable for each specific problem. • Like arrays and pointers, structures are considered a derived type. The Member and Structure Pointer Operators “.” and “->” Members of structures are accessed using either: • the member operator . or • the structure pointer operator -> These operators along with () and [] have the highest precedence. Declaring Structures Example Using Playing Cards • Playing cards have what is known as a pip value and a suit value. – The three of spades has a pip value, 3 and a suit value, spades. We can declare the structure type: struct card { int pips; char suit; }; to capture the information needed to represent a playing card. The Derived Type struct card struct card { int pips; char suit; }; struct is a keyword. card is the structure tag name. pips is a member variable that will take values from 1 to 13. suit is a member variable that will take values from ‘c’, ‘d’, ‘h’, and ‘s’,representing clubs, diamonds, hearts, and spades. Declaring Variables of the Derived Type struct card The declaration struct card c1, c2; allocates space for the identifiers c1 and c2, which are of type struct card. To access the members of c1 and c2, we use the structure member operator “.”: c1.pips c1.suit c2.pips c2.suit = = = = 5; ‘d’; 12; ‘s’; /* a construct of the form */ /* structure_variable.member_name */ /* is used as a variable in the */ /* same way a simple variable or */ /* an element of an array is used.*/ Uniqueness of Member Names A member name must be unique within a specified structure. Since the member must always be prefaced or accessed through a unique structure variable identifier, there is no confusion between members of different structures having the same name. Example of Same Member Names in Different Structures struct fruit { char name[15]; int calories; }; struct vegetable { char name[15]; int calories; } struct fruit a; struct vegetable b; We can access a.calories and b.calories without ambiguity. Declaration of Variables During the Creation of a Structure Type It is possible to create a structure type and declare variables of that type at the same time. struct card { int pips; char suit; } c, deck[52]; /* c is a variable that can /* /* /* /* */ store a single card. deck */ is the name of an array */ that can store a deck of */ cards. */ Omission of the Tag Name struct { char *last_name; int student_id; char grade; } s1, s2, s3; /* /* /* /* struct student { char *last_name; int student_id; char grade; }; /* Variables can now be */ /* be declared later in */ /* the program as shown */ /* below. Until the */ /* declaration below, no */ /* storage is allocated. */ struct student Since no tag name is used, no variables can be declared later in the program. temp, class[100]; */ */ */ */ Example: class_info.c See the class_info files in the public subdirectory class23. • Note: The structure member last_name is declared as last_name[20]; instead of *last_name so that the name can be read in from a file rather than being a constant in the program; • The 20 can be any number that is large enough to hold the characters of a name and the null character \0. The Structure Pointer Operator -> C provides the structure pointer operator -> to access members of a structure via a pointer. • -> is typed on the keyboard as a minus sign followed by a greater than sign. If a pointer variable is assigned the address of a structure, then a member of the structure can be accessed by: pointer-to-structure -> member_name An equivalent construct is: (*pointer_to_structure).member_name Examples of the Two Accessing Modes Declarations and Assignments struct student temp, *p = &temp; temp.grade = ‘A’; temp.last_name = “Bushker”; temp.student_id = 590017; Expression temp.grade temp.last_name temp.student_id (*p).student_id Equivalent Expression p p p p -> -> -> -> grade last_name student_id student_id Conceptual Value A Bushker 590017 590017 Precedence and Associativity Operators () [] Associativity . -> ++ (postfix) -- (postfix) ++ (prefix) -- (prefix) ! ~ + (unary) - (unary) & (address) * < / += -= *= % right to left left to right + - left to right << >> left to right <= > == = sizeof(type) * (dereference) left to right /= >= left to right != left to right & left to right ^ left to right | left to right && left to right || left to right ?: right to left %= >>= <<= , (comma operator) &= ^= |= right to left left to right Structures as Arguments to Functions Traditional C allows a pointer to a structure type to be passed as an argument to a function and returned as a value. ANSI C also allows structures themselves to be passed as arguments to functions and returned as values (as a complete structure). • However, a pointer to a structure is still the preferred type of function argument and return value in most cases. Example of Passing a Pointer to a Structure Type struct card { int pips; char suit; }; . . . struct card c; int pip = 12; /* the Queen of Hearts */ char suit = ‘h’; . . . assign_values(&c, pip, suit); /* Function Call */ . . . void assign_values(struct card *c_ptr, int p, char s); { c_ptr->pips = p; c_ptr->suit = s; } Assignment of Structures ANSI C also allows assignment of structures. • If a and b are variables of the same structure type, the assignment expression a = b is allowed. • See the assignment to an array of struct student types in the public subdirectory file class23 for an example of assignment of structures. • Look in class23 and study the programs there. Data Structures In C, structures, pointers, and arrays may be combined to create complicated data structures. • We have entire courses on this. Problem solving is enhanced by matching a data structure to the information that is to be manipulated. • In C, struct is an encapsulation mechanism for a set of characteristics that describe a realworld object such as a student. Initialization of Structures All external and static variables, including structure variables, that are not explicitly initialized are initialized by the system. We can also initialize automatic structures. • Similar to initializing an automatic array. Example of Initializing Automatic Structure Variables struct card { int pips; char suit; }; struct fruit { char name[15]; int calories; }; . . . struct card struct fruit c = {12, ‘s’}; frt = {“plum”, 150}; The Use of typedef The typedef facility is often used to rename a structure type. • We will see examples of this when we look at linked lists.