Structs, Enums, Unions Rudra Dutta CSC Spring 2007, Section 001
Copyright Rudra Dutta, NCSU, Spring, Derived Data Types Arrays Pointers Structs Enums Unions
Copyright Rudra Dutta, NCSU, Spring, struct : A Single Variable Type with Multiple Components Example: a person has a – Weight – Height – Gender – ID number – Age in years – Etc. To indicate these are all part of the same “entity”, we define a struct data type
Copyright Rudra Dutta, NCSU, Spring, Example Makes more sense than simply defining these fields individually, not indicating how they are related struct person { int weight; int height; char gender; int idnum; short age; … }; struct person person1;
Copyright Rudra Dutta, NCSU, Spring, Compared with Java instance fields of a class in Java are about the same thing as members of a struct in C – Except there is no access specifier ( public, private ) in C for struct members – they are all public Syntax for referring to both is the same person1.height = 72; person1.weight = 180; person1.gender = ‘M’; …
Copyright Rudra Dutta, NCSU, Spring, Initializing Structures Unitialized struct person person1; struct person person1 = {72, 180, ‘M’, , 20}; struct person person1 = {72, 180, ‘M’}; struct person person1 = {.height = 72,.gender = ‘M’,.idnum = }; Fully initialized Partly initialized by member order Partly initialized by member name
Copyright Rudra Dutta, NCSU, Spring, Referring to structs and members Simple assignment to a struct member person3.weight = person2.weight; Assignment to an entire struct person2 = person1; person4 = (struct person) {person2.height, person3.weight, person1.gender, , person1.age+65};
Copyright Rudra Dutta, NCSU, Spring, struct s as Input Parameters Structs are passed by value, as usual – i.e., a copy is made and passed to the function void printperson ( struct person ); int main () { struct person person1 = {…}; … (void) printperson (person1); … } void printperson ( struct person p ) { … }
Copyright Rudra Dutta, NCSU, Spring, struct s as Return Values struct person getperson ( void ) { struct person np = {0, 0, ‘ ‘, 0}; (void) printf (“Enter person characteristics: “); scanf(“%d %d %c %d”, &(np.height), &(np.weight), &(np.gender), &(np.age); return (np); /* function returns multiple values * in a single struct */ } int main () { struct person person1; … person1 = getperson (); … } Parentheses needed?
Copyright Rudra Dutta, NCSU, Spring, Arrays containing struct s Example … int main () { struct person persons[100]; … persons[1] = getperson (); persons[2].age = persons[1].age; … } Parentheses needed, i.e., should it be… … (persons[2]).age = (persons[1]).age; …
Copyright Rudra Dutta, NCSU, Spring, Initializing Arrays of Structs Example struct person persons[100] = { { 72, 180, ‘M’, 20 }, { 66, 100, ‘F’, 19 }, { 76, 240, ‘M’, 25}, [10] = {.height = 70,.gender = ‘M’} };
Copyright Rudra Dutta, NCSU, Spring, struct s Containing struct s Are parentheses needed, e.g., (person1.phone).areacode ? struct phonenumber { short countrycode; short areacode; short exchange; short number; }; struct person { int height; int weight; struct phonenumber phone; … } person1; … if (person1.phone.areacode == 919) … struct phonenumber { short countrycode; short areacode; short exchange; short number; }; struct person { int height; int weight; struct phonenumber phone; … } persons[100]; … if (persons[5].phone.areacode == 919) …
Copyright Rudra Dutta, NCSU, Spring, struct s Containing Arrays struct person { int weight, height; char gender; int idnum; short age; short coursenums[6]; }; struct person persons[100];
Copyright Rudra Dutta, NCSU, Spring, struct s Containing Arrays (cont’d) How query if course number of first class taken by third person is 230? How assign 246 to 4 th class of 10 th person? How initialize 12 th person’s data?
Copyright Rudra Dutta, NCSU, Spring, struct person { int weight, height; char gender; int idnum; short age; short coursenums[6]; }; struct person persons[100]; struct person *p_array; p_array = persons; /* point to first struct */ (*p_array).weight = 175; p_array->height = 170; Pointers to struct s Pointer access to structs is very common – Special notation defined for the purpose
Copyright Rudra Dutta, NCSU, Spring, The const Keyword Indicates to the compiler that a value should not change during program execution – Statements that attempt to change this value will cause a compiler warning – The only way to set variable: initialize during definition const int twopowfive = 32; const float pi; twopowfiv = 64; /* ERROR */ pi = ; /* ERROR */
Copyright Rudra Dutta, NCSU, Spring, The const Keyword (cont’d) Is this better than macros? #define TWOPOWFIV 32 #define PI How about this? struct pet { char *name; unsigned short weight; unsigned char age; unsigned char type; }; const struct pet mypet = { “Fluffy”, 30, 5, DOG };
Copyright Rudra Dutta, NCSU, Spring, const and Pointers Changeable pointer to changeable character Unchanging pointer to changeable character Changeable pointer to unchanging character Unchanging pointer to unchanging character char * cp = &c; *cp++ = ‘A’; /* no problems */ char * const cp = &c; cp = dp ; /* ERROR, changes pointer */ const char * cp = &c; *cp = ‘Z’ ; /*ERROR, changes value pointed to */ const char * const cp = &c; *cp++ = ‘Z’ ; /* ERROR, changes both */
Copyright Rudra Dutta, NCSU, Spring, Enumerated Data Type Use for variables with small set of possible values, where binary encoding of value is unimportant enum colors {red, blue, green, purple}; enum colors mycolors; mycolors = blue; if (mycolors == blue) printf("color == blue\n"); else if (mycolors == green) printf("color == green\n");
Copyright Rudra Dutta, NCSU, Spring, Enumerated Data Type (cont’d) Don’t compare variables of different enumerated types! enum {blue, red, green, purple} newcolors; enum {black, brown, orange, yellow} morecolors; newcolors = red; morecolors = brown; if (morecolors == newcolors) printf("Same color\n"); Although you can interpret enumerated data types as integers, this is not recommended
Copyright Rudra Dutta, NCSU, Spring, Enumerated Data Types (cont’d) Is this better than macros? #define BLUE 0 #define RED 1 #define GREEN 2 #define PURPLE 3 int colors; colors = RED; if (colors == RED) {…};
Copyright Rudra Dutta, NCSU, Spring, The typedef Statement Assigns an alternate name (synonym) to a C data type – More concise, more readable typedef char * cptr; cptr cp, dp; typedef struct mystruct { int val; cptr name; struct mystruct *next; } llnode; llnode entries[100];
Copyright Rudra Dutta, NCSU, Spring, The typedef Statement (cont’d) Sometimes typedefs used to provide machine portability – To retarget a program for a different architecture, just redefine the typedefs and recompile Usually, typedefs are collected in a header file that is #include ’d in all source code modules typedef int values[20]; values tbl1, tbl2;
Copyright Rudra Dutta, NCSU, Spring, _Bool variables Defines an integer variable that is restricted to store only the values 0 (false) and 1 (true) – Attempt to assign any non-zero value will actually store the value 1 #include … _Bool test1; test1 = ((c = getchar()) && (c != ‘n’)); if (test1) …
Copyright Rudra Dutta, NCSU, Spring, Bit Fields in C Way to pack bits into a word – When useful? Bit fields are defined like (integer) members of a structure
Copyright Rudra Dutta, NCSU, Spring, Bit Fields Example ( Frequently devices and OS communicate by means of a single word struct Disk_register { unsigned ready:1; unsigned error_occured:1; unsigned disk_spinning:1; unsigned write_protect:1; unsigned head_loaded:1; unsigned error_code:8; unsigned track:9; unsigned sector:5; unsigned command:5; };
Copyright Rudra Dutta, NCSU, Spring, Example (cont’d) struct Disk_register * dr = (struct Disk_register * ) MEMADDR; /* Define sector and track to start read */ dr->sector = new_sector; dr->track = new_track; dr->command = READ; /* ready will be true when done, else wait */ while ( ! dr->ready ) ; if (dr->error_occured) /* check for errors */ { switch (dr->error_code) }
Copyright Rudra Dutta, NCSU, Spring, Bit Fields (cont’d) Restrictions – My recommendation: always make unsigned – # of bits determines maximum value – Cannot have array of bit fields – Cannot have pointer to a bit field Danger: bit-fields are non-portable! – Order in which bit-fields stored within a word is system dependent
Copyright Rudra Dutta, NCSU, Spring, The union Statement Defined like a structure, but only stores exactly one of the named members – Reason: save storage – Important? Nothing in the union tells you which member is stored there! – Usually: programmer defines another field to indicate
Copyright Rudra Dutta, NCSU, Spring, union Example union info { unsigned short speed_of_flight; // bird _Bool freshwater; // fish enum {VERY, SOME, LITTLE} hairiness; // mammal }; struct { unsigned char type; char * name; union info info; } animals[10]; animals[0].type = MAMMAL; animals[0].name = "Polar Bear"; animals[0].info.hairiness = VERY;