Structures and Unions in C

You might also like

Download as ppt, pdf, or txt
Download as ppt, pdf, or txt
You are on page 1of 18

Structures and Unions in C

Structures
Compound data:
struct ADate { int month; int day; int year; }; struct ADate date; date.month = 9; date.day = 1; date.year = 2005;

A date is
an int month and an int day and an int year

Structure Representation & Size


sizeof(struct ) =
sum of sizeof(field)
struct CharCharInt { char c1; char c2; int i; } foo; foo.c1 = a; foo.c2 = b; foo.i = 0xDEADBEEF;

alignment padding
Processor- and compiler-specific

c1

c2

padding

61

62

EF

BE

AD

DE

x86 uses little-endian representation

Typedef
Mechanism for creating new type names
New names are an alias for some other type

Improves clarity of the program


typedef struct ADate { int month; int day; int year; } Date;

Simplify complex type names

Date d = {9, 1, 2005};

Arrays of Structures
Array declaration Constant #define NFRIENDS 10 #define TRUE 1 #define FALSE 0 typedef int bool; Date birthdays[NFRIENDS]; bool check_birthday(Date today) { int i; for (i = 0; i < NFRIENDS; i++) { if ((today.month == birthdays[i].month) && (today.day == birthdays[i].day)) return (true); }
return FALSE; }

Array index, then structure field

Pointers to Structures
Date create_date1(int month, int day, int year) { Date d; void create_date2(Date *d, int month, Pass-by-reference int day, int year) { d->month = month; d->day = day; d->year = year; }

d.month = month; d.day = day; d.year = year;


return (d);

Date today; today = create_date1(9, 4, 2008); create_date2(&today, 9, 4, 2008);

Copies date

Pointers to Structures (cont.)


void create_date2(Date *d, int month, int day, int year) { d->month = month; d->day = day; d->year = year; } void foo(void) { Date today; create_date2(&today, 9, 4, 2008); } 0x30A8 0x30A4 0x30A0 0x3098

year:

2008

day:
month: d:

4
9

0x1000

0x1008 0x1004 0x1000

today.year:

2008

today.day:
today.month:

4
9

Pointers to Structures (cont.)


Date * create_date3(int month, int day, int year) { Date *d;

What is d pointing to?!?! (more on this later)

d->month = month; d->day = day; d->year = year;


return (d);

Collections of Bools (Bit Vectors)


Byte, word, ... can represent many booleans
One per bit, e.g., 00100101 = false, false, true, ..., true

Bit-wise operations:
Bit-wise Bit-wise Bit-wise Bit-wise AND: OR: NOT: XOR: 00100101 & 10111100 00100101 | 10111100 ~ 00100101 00100101 ^ 10111100 == == == == 00100100 10111101 11011010 10011001

Operations on Bit Vectors


const unsigned int unsigned int low_three_bits_mask = 0x7; bit_vec = 0x15; 000 0111 001 0101

A mask indicates which bit positions we are interested in Always use Cs unsigned types for bit vectors

Selecting bits:
important_bits = bit_vec & low_three_bits_mask;

Result = ?
000 0101 == 001 0101 & 000 0111

Operations on Bit Vectors


const unsigned int unsigned int low_three_bits_mask = 0x7; bit_vec = 0x15; 000 0111 001 0101

Setting bits:
bit_vec |= low_three_bits_mask; 001 0111 == 001 0101 | 000 0111

Result = ?

Operations on Bit Vectors


const unsigned int unsigned int low_three_bits_mask = 0x7; bit_vec = 0x15; 000 0111 001 0101

Clearing bits:
bit_vec &= ~low_three_bits_mask; 001 0000 == 001 0101 & ~000 0111

Result = ?

Bit-field Structures
Special syntax packs structure values more tightly Similar to bit vectors, but arguably easier to read
Nonetheless, bit vectors
struct Flags { int unsigned int unsigned int } foo; foo.f1 = -2; foo.f2 = 1; foo.f3 = 2;

f1:3; f2:1; f3:2;

are more commonly used.

Padded to be an integral number of words


Placement is compiler-

f1

f2

f3

specific.

1 1 0 1 1 0

Unions A union is a special data type available in C that enables you to store different data types in the same memory location. You can define a union with many members, but only one member can contain a value at any given time. Unions provide an efficient way of using the same memory location for multi-purpose.

Unions
Choices:
union AnElt { int i; char c; } elt1, elt2; elt1.i = 4; elt2.c = a; elt2.i = 0xDEADBEEF;

An element is
an int i or a char c

sizeof(union ) =
maximum of sizeof(field)

padding

EF

BE
i

AD

DE

Unions
A union value doesnt know which case it contains
union AnElt { int i; char c; } elt1, elt2; elt1.i = 4; elt2.c = a; elt2.i = 0xDEADBEEF; if (elt1 currently has a char)

?
How should your program keep track whether elt1, elt2 hold an int or a char?

Basic answer: Another variable holds that info

Tagged Unions
Tag every value with its case I.e., pair the type info together with the union
Implicit in Java, Scheme, ML,

enum Union_Tag {IS_INT, IS_CHAR}; struct TaggedUnion { enum Union_Tag tag; union { int i; char c; } data; };

Enum must be external to struct, so constants are globally visible.

Struct field must be named.

Next Time
Memory Allocation

You might also like