Structure User Defined Data Types typedef The C

  • Slides: 39
Download presentation
Structure

Structure

User Defined Data Types (typedef) The C language provides a facility called typedef for

User Defined Data Types (typedef) The C language provides a facility called typedef for creating synonyms for previously defined data type names. For example, the declaration: typedef int Length; makes the name Length a synonym (or alias) alias for the data type int The data type name Length can now be used in declarations in exactly the same way that the data type int can be used: Length a, b, len ; Length numbers[10] ; typedef char String[50]; typedef int Array[10]; String name; Array ages;

Structures (struct) Structures—sometimes referred to as aggregates—are Structures aggregates collections of related variables under

Structures (struct) Structures—sometimes referred to as aggregates—are Structures aggregates collections of related variables under one name Structures may contain variables of many different data Structures are commonly used to define records Pointers and structures facilitate the formation of more types—in contrast to arrays that contain only elements of types the same data type complex data structures such as linked lists, lists queues, queues stacks and trees Structures are derived data types—they are constructed types using objects of other types

Declaring Structures (struct) The name "employee" is called a structure tag Variables declared within

Declaring Structures (struct) The name "employee" is called a structure tag Variables declared within the braces of the structure definition are the structure’s members struct employee { char first. Name[ 20 ]; char last. Name[ 20 ]; int age; char gender; double hourly. Salary; }; struct employee Ali, emp[10]; struct employee { char first. Name[ 20 ]; char last. Name[ 20 ]; int age; char gender; double hourly. Salary; } Ali, Sara, emp. DTS[20]; struct employee Reza, *emp; struct { char first. Name[ 20 ]; char last. Name[ 20 ]; int age; char gender; double hourly. Salary; } Ali;

Declaring Structures (struct) Often, typedef is used in combination with struct to declare a

Declaring Structures (struct) Often, typedef is used in combination with struct to declare a synonym (or an alias) for a structure: typedef struct { char first. Name[ 20 ]; char last. Name[ 20 ]; int age; char gender; double hourly. Salary; } employee; /* The "alias" employee Ali; /* Create a struct variable */ struct employee { char first. Name[ 20 ]; char last. Name[ 20 ]; int age; char gender; double hourly. Salary; } Ali, Sara, emp. DTS[20]; struct employee Reza, *emp;

Declaring Structures (struct) Members of the same structure type must have unique names, names

Declaring Structures (struct) Members of the same structure type must have unique names, names but two different structure types may contain members of the same name without conflict struct employee { char Name[ 20 ]; // Error!!! int age; char gender; double hourly. Salary; } Ali, Sara, emp. DTS[20]; struct employee Reza, *emp; struct Student { char Name[ 20 ]; // OK int age; char gender; }; struct Student Ce 40153[80]; Each structure definition must end with a semicolon

Declaring Structures (struct) A structure cannot contain an instance of itself For example, a

Declaring Structures (struct) A structure cannot contain an instance of itself For example, a variable of type struct employee cannot be declared in the definition for struct employee A pointer to struct employee, however, may be included struct employee 2 { // … double hourly. Salary; struct employee 2 person; /* ERROR */ struct employee 2 *e. Ptr; /* pointer */ }; A structure containing a member that is a pointer to the same structure type is referred to as a self-referential structure

Declaring Structures (struct) The structure tag name is optional struct { char first. Name[

Declaring Structures (struct) The structure tag name is optional struct { char first. Name[ 20 ]; char last. Name[ 20 ]; int age; char gender; double hourly. Salary; } Ali; If a structure definition does not contain a structure tag name, variables of the structure type may be declared only in the structure definition—not in a separate declaration

Structure’s sizeof Structure definitions do not reserve any space in memory; memory rather, each

Structure’s sizeof Structure definitions do not reserve any space in memory; memory rather, each definition creates a new data type that is used to define variables sizeof(struct …) = sum of sizeof(members) + alignment padding (Processor- and compiler-specific) struct employee { char first. Name[ 20 ]; char last. Name[ 20 ]; int age; char gender; double hourly. Salary; }; struct employee Ali, emp[10]; printf("%d", sizeof(Ali)); sizeof(Ali) printf("%d", sizeof(emp)); sizeof(emp) printf("%d", sizeof(struct employee)); employee)

alignment padding struct { char a[3]; short int b; long int c; char d[3];

alignment padding struct { char a[3]; short int b; long int c; char d[3]; }; it's much, much easier on the processor if the compiler arranges it like this: most compilers will “pad” the structure (as if with extra, invisible fields) like this:

Accessing Struct Members Individual members of a struct variable may be accessed using the

Accessing Struct Members Individual members of a struct variable may be accessed using the structure member operator (the dot, dot ". "): my. Emp. first. Name ; employee. first. Name; first. Name // Error Or , if a pointer to the struct has been declared and initialized struct employee *emp = &my. Emp ; { char first. Name[ ◦ by using the structure pointer operator : emp -> first. Name; // arrow operator 20 ]; // … ◦ which could also be written as: (* emp). first. Name; ). } my. Emp;

An Example - Initialization //Create a struct but don’t reserve space struct personal {

An Example - Initialization //Create a struct but don’t reserve space struct personal { long id; // student ID float gpa; // grade point average }; struct identity js = {"Joe", js. person. id = 123456789 ; js. person. gpa = 3. 4 ; struct identity { char First. Name[30]; char Last. Name[30]; unsigned age; struct personal person; }; "Smith", 25}, *ptr = &js ; strcpy(js. First. Name, js = {"Joe", "Smith", 25, "Joe"); 9, 10} js. personal. id Error strcpy( printf ("%s %s %d %ld %fn", js. First. Name, js. Last. Name, js. age, js. person. id, js. person. gpa) ; printf ("%s %s %d %ld %fn", ptr->First. Name, ptr->Last. Name, ptr->age, ptr>person. id, ptr->person. gpa) ; struct identity js = {"Joe", "Smith", 25, {123, 3. 4}}

An Example - Assignment //Create a struct but don’t reserve space struct personal {

An Example - Assignment //Create a struct but don’t reserve space struct personal { long id; // student ID float gpa; // grade point average }; struct identity { char First. Name[30]; char Last. Name[30]; unsigned age; struct personal person; }; struct identity js = {"Joe", "Smith", 25}, oj , *ptr; js. person. id = 123456789 ; js. person. gpa = 3. 4 ; oj = js; ptr=&oj; printf ("%s %s %d %ld %fn", oj. First. Name, oj. Last. Name, oj. age, js. person. id, oj. person. gpa) ; printf ("%s %s %d %ld %fn", ptr->First. Name, ptr->Last. Name, ptr->age, ptr->person. id, ptr->person. gpa) ;

Linked Lists (example 1) typedef struct Linked. List{ int X; struct Linked. List *

Linked Lists (example 1) typedef struct Linked. List{ int X; struct Linked. List * nextnode; }linkedlist; linkedlist node 1={10, 0}; printf("Linked list with 1 node contain: %dn", node 1. X); linkedlist node 2={20, 0}; node 1. nextnode=&node 2; linkedlist node 3={30, 0}; node 2. nextnode=&node 3; printf("Show the linked list values: n"); linkedlist* ptr=&node 1; printf("%dn", ptr->X); while(ptr->nextnode) { ptr=ptr->nextnode; printf("%dn", ptr->X); }

Linked Lists (example 2) typedef struct Linked. List{ int X; struct Linked. List *

Linked Lists (example 2) typedef struct Linked. List{ int X; struct Linked. List * nextnode; }linkedlist; linkedlist* node 1; node 1=(linkedlist*) malloc(sizeof(linkedlist)); node 1 ->X=10; //create linke list! node 1 ->nextnode=0; for(i=20; i<100; i+=10) { linkedlist* ptr=node 1, *lastnode; lastnode=(linkedlist*) int i; malloc(sizeof(linkedlist)); lastnode->X=i; lastnode>nextnode=0; ptr>nextnode=lastnode; ptr=ptr->nextnode; }

//show linked list value ptr=node 1; printf("fill node %dn", ptr->X); while(ptr->nextnode) { } ptr=ptr->nextnode;

//show linked list value ptr=node 1; printf("fill node %dn", ptr->X); while(ptr->nextnode) { } ptr=ptr->nextnode; printf("fill node %dn", ptr->X); //free linked list ptr=node 1; linkedlist *ptr 2=node 1 ->nextnode; ptr->nextnode=0; printf("free %dn", ptr->X); free(ptr); while(ptr 2) { } ptr=ptr 2; ptr 2=ptr 2 ->nextnode; ptr->nextnode=0; printf("free %dn", ptr->X); free(ptr);

struct identity sharif. C 40153[80] = {“Omid", "Jafarinezhad", 14, 9140153, 20, "Samad", "Shekarestani", 90,

struct identity sharif. C 40153[80] = {“Omid", "Jafarinezhad", 14, 9140153, 20, "Samad", "Shekarestani", 90, 2222222, 20} ; strcpy(sharif. C 40153[2]. First. Name, "Khaje Nezam"); strcpy(sharif. C 40153[2]. Nezam" strcpy(sharif. C 40153[2]. Last. Name, "Shekarestani"); strcpy(sharif. C 40153[2]. "Shekarestani" sharif. C 40153[2]. age = 100; sharif. C 40153[2]. person. id = 1111; sharif. C 40153[2]. person. gpa = 20; Arrays of Structures //Create a struct but don’t reserve space struct personal { long id; // student ID float gpa; // grade point average }; struct identity { char First. Name[30]; char Last. Name[30]; unsigned age; struct personal person; } students[4]; First. Name Last. Name age students[0] omid Jafarinezhad Students[1] Samad students[2] Khaje Nezam students[3] person id gpa 14 9140153 20 Shekarestani 90 2222222 20 Shekarestani 100 1111 20

An Example #define NFRIENDS 10 struct Date { unsigned year; unsigned month; unsigned day;

An Example #define NFRIENDS 10 struct Date { unsigned year; unsigned month; unsigned day; }; struct Friend { char First. Name[30]; char Last. Name[30]; struct Date Birthday; }; bool check_birthday(struct Date today, struct Date my. Friend) { if ((today. month == my. Friend. month) && (today. day == my. Friend. day)) return (true); return (false); } typedef struct int main() { unsigned year; struct Friend friends[NFRIENDS]; unsigned struct Datemonth; today = {2012, 3, 11}; unsigned day; //. . . } Date; for (i = 0; i < NFRIENDS; i++) bool { check_birthday(Date today, Date my. Friend) { if(check_birthday(today, today friends[i]. Birthday)) friends[i]. Birthday //… printf ("%s %sn", friends[i]. First. Name, }oj. Last. Name) ; } // …

Pointers to Structures void create_date 2(Date *d, Date create_date 1(int month, int day, int

Pointers to Structures void create_date 2(Date *d, Date create_date 1(int month, int day, int year) Pass-by-reference int year) { { Date d; d->month = month; d->day = day; d. month = month; d->year = year; d. day = day; } d. year = year; return (d); } Date today; Copies date today = create_date 1(9, 4, 2008); create_date 2(&today, 9, 4, 2008);

Pointers to Structures void create_date 2(Date *d, int month, int day, int year) {

Pointers to Structures void create_date 2(Date *d, int month, int day, int year) { d->month = month; d->day = day; d->year = year; } void foo(void) { Date today; create_date 2(&today, 9, 4, 2008); } 0 x 30 A 8 year: 2008 0 x 30 A 4 day: 4 0 x 30 A 0 month: 9 0 x 3098 d: 0 x 1008 today. year: 2008 0 x 1004 today. day: 4 0 x 1000 today. month: 9 0 x 1000

Pointers to Structures Date * create_date 3(int month, int day, int year) { Date

Pointers to Structures Date * create_date 3(int month, int day, int year) { Date *d; d->month = month; d->day = day; d->year = year; return (d); } What is d pointing to? !? !

Pointers to Structures void change. By. Value(Date date) { date. day ++; } void

Pointers to Structures void change. By. Value(Date date) { date. day ++; } void change. By. Ref(Date *date) { date->day++; } void print. Date(const Date date) { printf("today(d/m/y) is : n"); printf("%d/%d/%dn", date. day, date. month, date. year); } Date today = {2012, 3, 11}; print. Date(today); change. By. Value(today); print. Date(today); change. By. Ref(&today); print. Date(today); today(d/m/y) is : 11/3/2012 today(d/m/y) is : 12/3/2012

Compression of Structures may not be compared using operators == and != struct a

Compression of Structures may not be compared using operators == and != struct a { int a; // OK int b; }; struct a b, c; b. a = 10; b. b = 30; c = b; if(c == b) // Error

Enumeration is a user-defined data type. It is defined using the keyword enum and

Enumeration is a user-defined data type. It is defined using the keyword enum and the syntax is: enum tag_name {name_0, …, name_n} ; The tag_name is not used directly The names in the braces are symbolic constants that take on integer values from zero through n. As an example, the statement: enum colors { red, yellow, green } ; ◦ creates three constants. red is assigned the value 0, yellow is assigned 1 and green is assigned 2

Enumeration Values in an enum start with 0, unless specified otherwise, otherwise and are

Enumeration Values in an enum start with 0, unless specified otherwise, otherwise and are incremented by 1 The identifiers in an enumeration must be unique The value of each enumeration constant of an enumeration can be set explicitly in the definition by assigning a value to the identifier Multiple members of an enumeration can have the same constant value Assigning a value to an enumeration constant after it has been defined is a syntax error Use only uppercase letters enumeration constant names. This makes these constants stand out in a program and reminds you that enumeration constants are not variables

An Example /* This program uses enumerated data types to access the elements of

An Example /* This program uses enumerated data types to access the elements of an array */ #include <stdio. h> int main( ) { int March[5][7]={{0, 0, 1, 2, 3, 4, 5}, {6, 7, 8, 9, 10, 11, 12}, {13, 14, 15, 16, 17, 18, 19}, {20, 21, 22, 23, 24, 25, 26}, {27, 28, 29, 30, 31, 0, 0}}; enum days {Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday}; enum week {week_one, week_two, week_three, week_four, week_five}; } printf ("Monday the third week of March is March %dn", March [week_three] [Monday] );

An Example /* enumeration constants represent months of the year */ enum months {JAN

An Example /* enumeration constants represent months of the year */ enum months {JAN = 1, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC }; enum months month; /* initialize array of pointers */ const char *month. Name[] = { "", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", “November", "December"}; /* loop through months */ for (month = JAN; month <= DEC; month++ ) { printf( "%2 d%11 sn", month. Name[month] ); }

Unions A union is a derived data type—like a structure—with type members that share

Unions A union is a derived data type—like a structure—with type members that share the same storage space For not the not different situations in a program, some variables may be relevant, but other variables are—so a union shares space instead of wasting storage on variables that are being used The members of a union can be of any data type The number of bytes used to store a union must be at least enough to hold the largest member Only one member, member and thus one data type, can be referenced at a time

Unions representation union my. Data. Union { int i; char c; float f; }

Unions representation union my. Data. Union { int i; char c; float f; } u 1, u 2; union my. Data. Union u 3; u 1. i = 4; u 1. c = ’a’; u 2. i = 0 x. DEADBEEF; c i f

Unions The operations that can be performed on a union are the following: ◦

Unions The operations that can be performed on a union are the following: ◦ ◦ ◦ assigning a union to another union of the same type taking the address (&) of a union variable accessing union members using the structure member operator and the structure pointer operator Unions may not be compared using operators == and != for the same reasons that structures cannot be compared

Unions In a declaration, a union may be initialized with a value of the

Unions In a declaration, a union may be initialized with a value of the same type as the first union member union a { int a; // OK char b[4]; }; union a b = {10}; printf("%d", b. a);

Unions A union value doesn’t "know" which case it contains union An. Elt {

Unions A union value doesn’t "know" which case it contains union An. Elt { int i; char c; } elt 1, elt 2; elt 1. i = 4; elt 2. c = ’a’; elt 2. i = 0 x. DEADBEEF; if (elt 1 currently has a char) … How should your program keep track whether elt 1, elt 2 hold an int or a char? ? Basic answer: Another variable holds that info

Tagged Unions Tag every value with its case enum Union_Tag {IS_INT, IS_CHAR}; struct Tagged.

Tagged Unions Tag every value with its case enum Union_Tag {IS_INT, IS_CHAR}; struct Tagged. Union { enum Union_Tag tag; union { int i; char c; } data; };

Bit-field Structures C enables you to specify the number of bits in which an

Bit-field Structures C enables you to specify the number of bits in which an unsigned or int member of a structure or union is stored This is referred to as a bit field Bit fields enable better memory utilization by storing data in the minimum number of bits required Bit field members must be declared as int or unsigned A bit field is declared by following an unsigned or int member name with a colon (: ) and an integer constant representing the width of the field (i. e. , the number of bits in which the member is stored)

Bit-field Structures Notice that bit field members of structures are accessed exactly as any

Bit-field Structures Notice that bit field members of structures are accessed exactly as any other structure struct Flags member { int unsigned int } foo; foo. f 1 = -2; foo. f 2 = 1; foo. f 3 = 2; f 1: 3; f 2: 1; f 3: 2; f 1 f 2 f 3 1 1 0 … … … 8 bit … Padded to be an integral number of words ◦ Placement is compiler-specific … 8 bit …

Unnamed Bit-field struct example { unsigned a : 13; unsigned : 19; unsigned b

Unnamed Bit-field struct example { unsigned a : 13; unsigned : 19; unsigned b : 4; }; � uses an unnamed 19 -bit field as padding—nothing can be stored in those 19 bits An unnamed bit field with a zero width is used to align the next bit field on a new storage-unit boundary storage For example, the structure definition struct example { unsigned a : 13; unsigned : 0; }; unsigned b : 4; uses an unnamed 0 -bit field to skip the remaining bits (as many as there are) of the storage unit in which a is stored and to align b on the next storage-unit boundary

An Example - disk drive controller Frequently device controllers (e. g. disk drives) and

An Example - disk drive controller Frequently device controllers (e. g. disk drives) and the operating system need to communicate at a low level. Device controllers contain several registers which may be packed together in one integer

An Example - disk drive controller struct DISK_REGISTER { unsigned ready: 1; unsigned error_occured:

An Example - disk drive controller 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; }; struct DISK_REGISTER *disk_reg = (struct DISK_REGISTER *) DISK_REGISTER_MEMORY; /* Define sector and track to start read */ disk_reg->sector = new_sector; disk_reg->track = new_track; disk_reg->command = READ; /* wait until operation done, ready will be true */ while ( ! disk_reg->ready ) ; /* check for errors */ if (disk_reg->error_occured) { /* interrogate disk_reg->error_code for error type */ switch (disk_reg->error_code). . . }

Notes of caution Bit-field manipulations are machine dependent Attempting to access individual bits of

Notes of caution Bit-field manipulations are machine dependent Attempting to access individual bits of a bit field as if they were elements of an array is a syntax error. Bit fields are not "arrays of bits" Attempting to take the address of a bit field (the & operator may not be used with bit fields because they do not have addresses) Although bit fields save space, using them can cause the compiler to generate slower-executing machine-language code This occurs because it takes extra machine language operations to access only portions of an addressable storage unit. This is one of many examples of the kinds of space–time trade-offs that occur in computer science