1 / 19

# Today’s Material - PowerPoint PPT Presentation

Today’s Material. Aggregate Data Types: Structures and Unions Motivation Definition and Declaration Representation Initialization Access Array of Structures Structures as function parameters Layout in Memory Unions. Motivation. Data frequently occurs in groups

I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.

## PowerPoint Slideshow about ' Today’s Material' - waylon

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.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.

- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript

• Aggregate Data Types: Structures and Unions

• Motivation

• Definition and Declaration

• Representation

• Initialization

• Access

• Array of Structures

• Structures as function parameters

• Layout in Memory

• Unions

• Data frequently occurs in groups

• For example a school has to keep track of some information for each of its students

• This information can be things such as

• Name

• Department

• Gpa

• Accessing these values are simplified if they are stored together

• We cannot use an array to store these values together. Why?

• Because they are of different type

• C provides what is called a “structure” to store values with dissimilar types together

• Also known as a “record”

• A structure is a collection of values called members that can be of different types

• A structure is a collection of values called members that can be of different types

structTAG {member list} variableList;

/* TAG and variableList are optional */

/* No tag. Just declare

* one variable */

struct {

int i;

char c;

float f;

} x;

/* Give a name (tag) */

structSimple {

int i;

char c;

float f;

};

/* declare a variable later */

structSimple y;

• It is usually a good idea to define a new type using typedef instead of using “struct TAG”

typedef structStudent{

char name[40];

int dept;

float gpa;

char email[30];

} Student;

/* Declare a variable */

struct Student s1;

Student s2;

• Just like any other variable, you can initialize structure members during declaration

Student s1={“Ali Veli”, 101, 3.10, “[email protected]”};

Student s2={“Veli Kasap”, 102, 2.10, “[email protected]”};

• As with array initializers, an initializer can be shorter than the structure it is initializing

• Any leftover members are set to 0

typedef structSimple {

int i;

char c;

float f;

} Simple;

Simple z = {2}; /* c and f are set to 0 */

• How to access structure members through a pointer?

typedef structSimple {

int i;

char c;

float f;

} Simple;

Simple x;

Simple *ps = &x;

x.i = 4;

(*ps).i = 4;

(*ps).c = ‘A’;

(*ps).f = 3.33;

/* C provides an alternative

* way to access the members

* of a structure through a

* pointer using -> operator

*/

ps->i = 4;

ps->c = ‘A’;

ps->f = 3.33;

• It is possible to declare an array of structures

Student students[2];

strcpy(students[0].name, “Veli Gocer”);

students[0].dept = 101;

students[0].gpa = 2.85;

strcpy(students[0].email, “[email protected]”);

/* It is possible to assign a structure to another */

students[1] = students[0];

/* Assignment copies the contents of structure

* students[0] to the structure students[1].

* This is a memory-to-memory copy in its entirety

*/

• As with all function arguments, structures are passed by value

• Thus any change made to a function parameter is not reflected to the function argument

void F1(Simple s){

s.i = 2;

s.c = ‘T’;

s.f = 5.32;

} /* end-F1 */

main(){

Simple x = {3, ‘A’, 4.35};

F1(x);

printf(“x.i: %d, x.c: %c, x.f: .2f\n”, x.i, x.c, x.f);

} /* end-main */

x.i: 3, x.c: A, x.f: 4.35

• To change a structure argument inside a function, pass the structure’s address

void F2(Simple *ps){

ps->i = 2;

ps->c = ‘T’;

ps->f = 5.32;

} /* end-F2 */

main(){

Simple x = {3, ‘A’, 4.35};

F2(&x);

printf(“x.i: %d, x.c: %c, x.f: .2f\n”, x.i, x.c, x.f);

} /* end-main */

x.i: 2, x.c: T, x.f: 5.32

• You can return a structure from a function

• This is very inefficient and not recommended

Simple F4(int i, char c, float f){

Simple s;

s.i = i;

s.c = c;

s.f = f;

return s;

} /* end-F4 */

Simple F3(Simple s){

s.i = 22;

s.c = ‘Y’;

s.f = 6.66;

return s;

} /* end-F3 */

main(){

Simple x = {3, ‘A’, 4.35};

x = F3(x);

printf(“x.i: %d, x.c: %c, x.f: .2f\n”, x.i, x.c, x.f);

x = F4(8, ‘Z’, 9.99);

printf(“x.i: %d, x.c: %c, x.f: .2f\n”, x.i, x.c, x.f);

} /* end-main */

x.i: 22, x.c: Y, x.f: 6.66

x.i: 8, x.c: Z, x.f: 9.99

• You can declare complex structures by nesting one structure inside another

typedef struct {

int i;

char c;

float f;

} Simple;

typedef struct {

int a;

Simple s;

struct{

int a;

float b;

}x;

float f;

} Complex;

Complex c;

/* Access members of c */

c.a = 5;

c.s.i = 3;

c.s.c = ‘B’;

c.s.f = 4.44;

c.x.a = 2;

c.x.b = 4.52;

c.f = 3.45;

&s

100

&s.i

101

s.i

102

103

104

&s.c

s.c

105

unused

106

unused

107

unused

&s.f

108

109

s.f

110

111

Layout of Structures in Memory(1)

• Structure members are stored consecutively in memory

typedef struct{

int i;

char c;

float f;

} Simple;

Simple s;

• 3 bytes (105, 106, 107) are unused

• s.f starts at a 4-byte boundary due to alignment constraints

• Member alignment plays a crutial role to determine the amount of space a structure will occupy in memory

struct Y {

int i;

char c1;

char c2;

};

struct X {

char c1;

int i;

char c2;

};

• sizeof(struct X) = 12

• sizeof(struct Y) = 8

• Not 6 because if we declare an array of structures, the next structure must start at a 4-byte boundary

• A union is a structure that consists of one or members which may be of different types

• However, the compiler allocates only enough space for the largest of the members in a union

• Thus the members of a union overlay each other within this space

• Assigning a new value to one member alters the values of all the other members as well

100

100

u1.c[0]

101

101

101

u1.c[1]

u2.i

u1.i

s.i

102

102

u1.c[2]

102

u2.f

103

103

u1.c[3]

103

u2.d

104

104

s.c[0]

sizeof(u1) = 4

s.c[1]

105

105

106

106

s.c[2]

107

s.c[3]

107

sizeof(s) = 8

sizeof(u2) = 8

Union: Declaration & Layout

union {

int i;

float f;

double d;

} u2;

union {

int i;

char c[4];

} u1;

struct {

int i;

char c[4];

}s;

union {

int i;

float f;

double d;

} u2;

union {

int i;

char c[4];

} u1;

struct {

int i;

char c[4];

}s;

/* set s.c only. s.i is not changed */

s.c[0]=1; s.c[1]=2; s.c[2]=3; s.c[4]=4; /* set s.c */

s.i = 0x12345678; /* changes s.i only. s.c is not changed */

printf(“%x-%x-%x-%x\n”, s.c[0], s.c[1], s.c[2], s.c[3]);

/* Set u1.c. Changes u1.i as well */

u1.c[0]=1; u1.c[1]=2; u1.c[2]=3; u1.c[4]=4;

u1.i = 0x12345678; /* Changes u1.c as well */

printf(“%x-%x-%x-%x\n”, u1.c[0], u1.c[1], u1.c[2], u1.c[3]);

/* Changes the first 4 bytes of union u2 */

u2.i = 8;

/* Changes all 8 bytes of union u2 */

u2.d = 2.35;

• If you can store a number of values in a union, a typical method is to specify a tag that tell you what is really stored in the union

/* due to alignment */

sizeof(number) = 16;

/* Store an int */

number.type = 0;

number.u.i = 8;

/* Store a float */

number.type = 1;

number.u.f = 8.2;

/* Store a double */

number.type = 2;

number.u.d = 10.5;

struct Number {

/* 0: int

* 1: float

* 2: double

*/

int type;

union {

int i;

float f;

double d;

} u;

} number;

struct Number {

/* 0: int

* 1: float

* 2: double

*/

int type;

union {

int i;

float f;

double d;

} u;

} number;

/* Thus we can store different type

* of numbers in an array

*/

struct Number A[5];

A[0].type = 0;

A[0].u.i = 2;

A[1].type = 1;

A[1].u.f = 2.3;

A[2].type = 2;

A[2].u.d = 3.4;

A[3].type = 2;

A[3].u.d = 5.8;

A[4].type = 0;

A[4].u.i = 4;