27
CSCI 243 The Mechanics of Programming Timothy Fossum ([email protected]) TVF / RIT 20195 C: Structures

CSCI 243 The Mechanics of Programming C: …tvf/CSCI243/Notes/05-c-structs.pdfCSCI 243 The Mechanics of Programming Timothy Fossum ([email protected]) TVF / RIT 20195 C: Structures TVF

  • Upload
    others

  • View
    10

  • Download
    0

Embed Size (px)

Citation preview

Page 1: CSCI 243 The Mechanics of Programming C: …tvf/CSCI243/Notes/05-c-structs.pdfCSCI 243 The Mechanics of Programming Timothy Fossum (tvf@cs.rit.edu) TVF / RIT 20195 C: Structures TVF

CSCI 243The Mechanics of Programming

Timothy Fossum ([email protected])

TVF / RIT 20195

C: Structures

Page 2: CSCI 243 The Mechanics of Programming C: …tvf/CSCI243/Notes/05-c-structs.pdfCSCI 243 The Mechanics of Programming Timothy Fossum (tvf@cs.rit.edu) TVF / RIT 20195 C: Structures TVF

TVF / RIT 20195 CS243: Structures

Aggregate Data Types

• Arrays• Homogeneous collections of elements

• Declare by specifying desired number of elements

• Accessed by position (index)

• Structures• Heterogeneous collections of elements

• Declare by listing the members in desired storage order

• Accessed by member name

Page 3: CSCI 243 The Mechanics of Programming C: …tvf/CSCI243/Notes/05-c-structs.pdfCSCI 243 The Mechanics of Programming Timothy Fossum (tvf@cs.rit.edu) TVF / RIT 20195 C: Structures TVF

TVF / RIT 20195 CS243: Structures

Structures

• Declaration syntax:

• tag – optional “name” for this structure

• Needed if you ever want to refer to this type later

• data_members – fields within structure

• Look like variable declarations

• Need one or more

• vars – optional variable declarations

struct [ tag ] {   data_members} [ vars ];

Page 4: CSCI 243 The Mechanics of Programming C: …tvf/CSCI243/Notes/05-c-structs.pdfCSCI 243 The Mechanics of Programming Timothy Fossum (tvf@cs.rit.edu) TVF / RIT 20195 C: Structures TVF

TVF / RIT 20195 CS243: Structures

Structures

• Data members: essentially, variable prototypes• Any type that is fully known to the compiler

• Any legal variable name

• → no self-containing structures

• → no mutually-containing structures

• Member selection: . operator

• Initializable, assignable

Page 5: CSCI 243 The Mechanics of Programming C: …tvf/CSCI243/Notes/05-c-structs.pdfCSCI 243 The Mechanics of Programming Timothy Fossum (tvf@cs.rit.edu) TVF / RIT 20195 C: Structures TVF

TVF / RIT 20195 CS243: Structures

Struct Example – daytime.c (1/4)////// a simple program to illustrate basic structure declaration,/// initialization, and use////// it also illustrates (in passing) the dangers of using/// uninitialized local variables in functions///#include <stdio.h>

////// basic day + time structure///struct daytime {

int day;int month;int year;int hour;int minute;int second;

};

Page 6: CSCI 243 The Mechanics of Programming C: …tvf/CSCI243/Notes/05-c-structs.pdfCSCI 243 The Mechanics of Programming Timothy Fossum (tvf@cs.rit.edu) TVF / RIT 20195 C: Structures TVF

TVF / RIT 20195 CS243: Structures

Struct Example – daytime.c (2/4)////// print_date(date) ­ print the supplied date/time information/// in yyyy/mm/dd hh:mm:ss format///void print_date( struct daytime date ) {

printf( "Day/time:  %4d/%02d/%02d %02d:%02d:%02d\n",date.year, date.month, date.day,date.hour, date.minute, date.second );

}

Page 7: CSCI 243 The Mechanics of Programming C: …tvf/CSCI243/Notes/05-c-structs.pdfCSCI 243 The Mechanics of Programming Timothy Fossum (tvf@cs.rit.edu) TVF / RIT 20195 C: Structures TVF

TVF / RIT 20195 CS243: Structures

Struct Example – daytime.c (3/4)int main( void ) {

// declare a few initialized dates – the initializations// are done in the order the struct variables appearstruct daytime day1 = { 4, 7, 1779, 12, 00, 00 };struct daytime day2 = { 10, 9, 2013, 11, 54, 21 };

// another one, using “designated initializers”   struct daytime day3 = { .hour = 15, .month = 8, .day = 26,

.year = 2013, .second = 0, .minute = 0 };

// declare a few uninitialized datesstruct daytime day4, day5, day6;

// print the first set of dates

puts( "Initialized dates:" );print_date( day1 );print_date( day2 );print_date( day3 );

Page 8: CSCI 243 The Mechanics of Programming C: …tvf/CSCI243/Notes/05-c-structs.pdfCSCI 243 The Mechanics of Programming Timothy Fossum (tvf@cs.rit.edu) TVF / RIT 20195 C: Structures TVF

TVF / RIT 20195 CS243: Structures

// just for fun, print the uninitialized datesputs( "\nUninitialized dates, before assignments:" );print_date( day4 );print_date( day5 );print_date( day6 );

// initialize (or assign) contents of the latter three dates   // using “compound literals”

day4 = (struct daytime) { 13, 4, 2001, 3, 12, 17 };

   // using compound literals and designated initializersday5 = (struct daytime) { .month = 11, .day = 8, .hour = 14,

.year = 2002, .second = 0, .minute = 0 };

   // using structure assignment – this happens field­by­fieldday6 = day1;

// print the new contents of these datesputs( "\n'Uninitialized' dates, after assignments:" );print_date( day4 );  print_date( day5 );  print_date( day6 );

return( 0 );}

Struct Example – daytime.c (4/4)

Page 9: CSCI 243 The Mechanics of Programming C: …tvf/CSCI243/Notes/05-c-structs.pdfCSCI 243 The Mechanics of Programming Timothy Fossum (tvf@cs.rit.edu) TVF / RIT 20195 C: Structures TVF

TVF / RIT 20195 CS243: Structures

Struct Example – Using daytime.c (1/2)

% gcc ­Wall ­std=c99 ­c daytime.c% gcc ­Wall ­std=c99 ­o daytime daytime.o

% ./daytimeInitialized dates:Day/time:  1779/07/04 12:00:00Day/time:  2013/09/10 11:54:21Day/time:  2013/08/26 15:00:00

Uninitialized dates, before assignments:Day/time:  134514688/­1217433612/­1075290180 134520820:01:134513405Day/time:  134520820/1048576/­1217432604 134514721:­1:­1218948714Day/time:  ­1217224064/­1218948571/­1217433612 00:134514697:­1217433612

'Uninitialized' dates, after assignments:Day/time:  2001/04/13 03:12:17Day/time:  2002/11/08 14:00:00Day/time:  1779/07/04 12:00:00

Page 10: CSCI 243 The Mechanics of Programming C: …tvf/CSCI243/Notes/05-c-structs.pdfCSCI 243 The Mechanics of Programming Timothy Fossum (tvf@cs.rit.edu) TVF / RIT 20195 C: Structures TVF

TVF / RIT 20195 CS243: Structures

Struct Example – Using daytime.c (2/2)

% ./daytimeInitialized dates:Day/time:  1779/07/04 12:00:00Day/time:  2013/09/10 11:54:21Day/time:  2013/08/26 15:00:00

Uninitialized dates, before assignments:Day/time:  134514688/­1216970764/­1075409076 134520820:01:134513405Day/time:  134520820/1048576/­1216969756 134514721:­1:­1218485866Day/time:  ­1216761216/­1218485723/­1216970764 00:134514697:­1216970764

'Uninitialized' dates, after assignments:Day/time:  2001/04/13 03:12:17Day/time:  2002/11/08 14:00:00Day/time:  1779/07/04 12:00:00

Page 11: CSCI 243 The Mechanics of Programming C: …tvf/CSCI243/Notes/05-c-structs.pdfCSCI 243 The Mechanics of Programming Timothy Fossum (tvf@cs.rit.edu) TVF / RIT 20195 C: Structures TVF

TVF / RIT 20195 CS243: Structures

Digression: C Standard Versions

• Case in point: gcc “-std=” options:• No standard specified: whatever the compiler does by default

• ansi: "ANSI C" -- typically, C89, the first ANSI C standard

• c89: same as "ANSI C"; a.k.a. "c90"

• gnu89: C89 with GNU extensions; a.k.a. "gnu90"

• c99: 1999 C standard

• gnu99: C99 with GNU extensions

• c11: 2011 C standard

• gnu11: C11 with GNU extensions

• Each has slightly different features

The nice thing about standards is that you have so many to choose from. – Andrew S. Tanenbaum

Page 12: CSCI 243 The Mechanics of Programming C: …tvf/CSCI243/Notes/05-c-structs.pdfCSCI 243 The Mechanics of Programming Timothy Fossum (tvf@cs.rit.edu) TVF / RIT 20195 C: Structures TVF

TVF / RIT 20195 CS243: Structures

Struct Example – months.c (1/3)//// a simple program that illustrates the declaration,// initialization, and use of a structure containing// data of more than one type//#include <stdio.h>

//// an example of a mixed­content struct//// the 'name' field is 10 characters long because the longest// month name (September) is 9 characters, and we need to leave// room for the trailing NUL character//struct monthinfo {

int ndays;      // number of days in the monthchar name[10];  // month name

};

Page 13: CSCI 243 The Mechanics of Programming C: …tvf/CSCI243/Notes/05-c-structs.pdfCSCI 243 The Mechanics of Programming Timothy Fossum (tvf@cs.rit.edu) TVF / RIT 20195 C: Structures TVF

TVF / RIT 20195 CS243: Structures

// an example of initializing an array of structures//struct monthinfo year1[12] = {

{ 31, "January" }, { 28, "February" }, { 31, "March" },{ 30, "April" },   { 31, "May" },      { 30, "June" },{ 31, "July" },    { 31, "August" },   { 30, "September" },{ 31, "October" }, { 30, "November" }, { 31, "December" }

};

//// another example, this time using [] designators// to initialize the array elements//struct monthinfo year2[12] = {

[1]  = { 28, "February" },  [3]  = { 30, "April" },[5]  = { 30, "June" },      [10] = { 30, "November" },[8]  = { 30, "September" }, [7]  = { 31, "August" },[11] = { 31, "December" },  [0]  = { 31, "January" },[6]  = { 31, "July" },      [2]  = { 31, "March" },[4]  = { 31, "May" },       [9]  = { 31, "October" }

};

Struct Example – months.c (2/3)

Page 14: CSCI 243 The Mechanics of Programming C: …tvf/CSCI243/Notes/05-c-structs.pdfCSCI 243 The Mechanics of Programming Timothy Fossum (tvf@cs.rit.edu) TVF / RIT 20195 C: Structures TVF

TVF / RIT 20195 CS243: Structures

//// print_year(year) ­ print the contents of a year array//void print_year( struct monthinfo year[] ) {

for( int i = 0; i < 12; ++i ) {printf( "Month %2d:  %2d days, name '%s'\n",

i, year[i].ndays, year[i].name );}

}

int main( void ) {

puts( "First year contains:" );print_year( year1 );

puts( "\nSecond year contains:" );print_year( year2 );

return( 0 );}

Struct Example – months.c (3/3)

Page 15: CSCI 243 The Mechanics of Programming C: …tvf/CSCI243/Notes/05-c-structs.pdfCSCI 243 The Mechanics of Programming Timothy Fossum (tvf@cs.rit.edu) TVF / RIT 20195 C: Structures TVF

TVF / RIT 20195 CS243: Structures

Struct Example – Using months.c

% gcc ­Wall ­std=c99 ­c months.c% gcc ­Wall ­std=c99 ­o months months.o

% ./monthsFirst year contains:Month  0:  31 days, name 'January'Month  1:  28 days, name 'February'Month  2:  31 days, name 'March'Month  3:  30 days, name 'April'Month  4:  31 days, name 'May'Month  5:  30 days, name 'June'Month  6:  31 days, name 'July'Month  7:  31 days, name 'August'Month  8:  30 days, name 'September'Month  9:  31 days, name 'October'Month 10:  30 days, name 'November'Month 11:  31 days, name 'December'

Second year contains:Month  0:  31 days, name 'January'Month  1:  28 days, name 'February'Month  2:  31 days, name 'March'Month  3:  30 days, name 'April'Month  4:  31 days, name 'May'Month  5:  30 days, name 'June'Month  6:  31 days, name 'July'Month  7:  31 days, name 'August'Month  8:  30 days, name 'September'Month  9:  31 days, name 'October'Month 10:  30 days, name 'November'Month 11:  31 days, name 'December'

Page 16: CSCI 243 The Mechanics of Programming C: …tvf/CSCI243/Notes/05-c-structs.pdfCSCI 243 The Mechanics of Programming Timothy Fossum (tvf@cs.rit.edu) TVF / RIT 20195 C: Structures TVF

TVF / RIT 20195 CS243: Structures

Digression: sizeof Operator

• Compile-time constant• Not evaluated at runtime!

• Like a #defined constant

• sizeof(x) – number of bytes occupied by “x”

• Can apply to types• # of bytes an instance of this type will occupy

• Can apply to variables• # of bytes this variable occupies

Page 17: CSCI 243 The Mechanics of Programming C: …tvf/CSCI243/Notes/05-c-structs.pdfCSCI 243 The Mechanics of Programming Timothy Fossum (tvf@cs.rit.edu) TVF / RIT 20195 C: Structures TVF

TVF / RIT 20195 CS243: Structures

Sizeof Example – chararrsize.c

/// file: chararraysize.c/// description: illustrate C 'string', a char array, and its size/// author: [email protected]/// gcc -std=c99 -Wall -Wextra -pedantic chararrsize.c -o chararrsize

#include <stdio.h>

int main(void) { char message[] = "ab";

printf("sizeof(char) = %ld\n", sizeof(char)); printf("sizeof(message) = %ld\n", sizeof(message)); return 0;}

% gcc -std=c99 -Wall -Wextra -pedantic chararrsize.c -o chararrsize% ./chararrsizesizeof(char) = 1sizeof(message) = 3

Page 18: CSCI 243 The Mechanics of Programming C: …tvf/CSCI243/Notes/05-c-structs.pdfCSCI 243 The Mechanics of Programming Timothy Fossum (tvf@cs.rit.edu) TVF / RIT 20195 C: Structures TVF

TVF / RIT 20195 CS243: Structures

Sizeof Example – sizes.c (1/2)

////// a simple program to illustrate the use of sizeof()///

#include <stdio.h>#include <string.h>

int main( void ) {int x;int y[10];char a[15];

printf( "sizeof(int) is %ld\n", sizeof(int) );printf( "sizeof(long) is %ld\n", sizeof(long) );

printf( "sizeof(x) is %ld\n", sizeof(x) );printf( "sizeof(y) is %ld\n", sizeof(y) );printf( "sizeof(y[0]) is %ld\n", sizeof(y[0]) );

Page 19: CSCI 243 The Mechanics of Programming C: …tvf/CSCI243/Notes/05-c-structs.pdfCSCI 243 The Mechanics of Programming Timothy Fossum (tvf@cs.rit.edu) TVF / RIT 20195 C: Structures TVF

TVF / RIT 20195 CS243: Structures

Sizeof Example – sizes.c (2/2)

strcpy( a, "Hello" );

// applied to a string - note the difference// between sizeof(string) and strlen(string)

printf( "sizeof(a) is %ld\n", sizeof(a) );printf( "length of a is %ld\n", strlen(a) );

return( 0 );}

% gcc -Wall -std=c99 -c -o sizes.o sizes.c% gcc -Wall -std=c99 -o sizes sizes.o% ./sizessizeof(int) is 4sizeof(long) is 8sizeof(x) is 4sizeof(y) is 40sizeof(y[0]) is 4sizeof(a) is 15length of a is 5

Page 20: CSCI 243 The Mechanics of Programming C: …tvf/CSCI243/Notes/05-c-structs.pdfCSCI 243 The Mechanics of Programming Timothy Fossum (tvf@cs.rit.edu) TVF / RIT 20195 C: Structures TVF

TVF / RIT 20195 CS243: Structures

Structure Layout in Memory

• Consider this structure:

• How much memory does it use?

struct stuff { char c1; int i1; char c2; int i2; char c3; double d1;};

Page 21: CSCI 243 The Mechanics of Programming C: …tvf/CSCI243/Notes/05-c-structs.pdfCSCI 243 The Mechanics of Programming Timothy Fossum (tvf@cs.rit.edu) TVF / RIT 20195 C: Structures TVF

TVF / RIT 20195 CS243: Structures

Struct Example – layout.c (1/3)////// a simple program that illustrates the layout of /// a structure with data members of varying types////// to compile: gcc -Wall -std=c99 -o layout layout.c//#include <stdio.h>

////// an example of a mixed-content struct///struct stuff { char c1; int i1; char c2; int i2; char c3; double d1;};

Page 22: CSCI 243 The Mechanics of Programming C: …tvf/CSCI243/Notes/05-c-structs.pdfCSCI 243 The Mechanics of Programming Timothy Fossum (tvf@cs.rit.edu) TVF / RIT 20195 C: Structures TVF

TVF / RIT 20195 CS243: Structures

Struct Example – layout.c (2/3)////// create a global instance///struct stuff data = { 'a', 42, 'b', 1776, 'c', 4.125};

int main( void ) {

// print the sizes of the individual fields

printf( "sizeof(c1)\t%ld\n", sizeof(data.c1) ); printf( "sizeof(i1)\t%ld\n", sizeof(data.i1) ); printf( "sizeof(c2)\t%ld\n", sizeof(data.c2) ); printf( "sizeof(i2)\t%ld\n", sizeof(data.i2) ); printf( "sizeof(c3)\t%ld\n", sizeof(data.c3) ); printf( "sizeof(d1)\t%ld\n", sizeof(data.d1) );

Page 23: CSCI 243 The Mechanics of Programming C: …tvf/CSCI243/Notes/05-c-structs.pdfCSCI 243 The Mechanics of Programming Timothy Fossum (tvf@cs.rit.edu) TVF / RIT 20195 C: Structures TVF

TVF / RIT 20195 CS243: Structures

Struct Example – layout.c (3/3)

// sum up the sizes

printf( "\nsum:\t%ld\n", sizeof(data.c1) + sizeof(data.i1) + sizeof(data.c2) + sizeof(data.i2) + sizeof(data.c3) + sizeof(data.d1) );

// now, print the size of the entire structure

printf( "\nsizeof(data)\t%ld\n", sizeof(data) );

return( 0 );}

Page 24: CSCI 243 The Mechanics of Programming C: …tvf/CSCI243/Notes/05-c-structs.pdfCSCI 243 The Mechanics of Programming Timothy Fossum (tvf@cs.rit.edu) TVF / RIT 20195 C: Structures TVF

TVF / RIT 20195 CS243: Structures

Struct Example – Using layout.c

• Results:

• But 19 is not equal to 32. Why?

% gcc -Wall -std=c99 -c layout.c% gcc -Wall -std=c99 -o layout layout.o

% ./layoutsizeof(c1) 1sizeof(i1) 4sizeof(c2) 1sizeof(i2) 4sizeof(c3) 1sizeof(d1) 8

sum: 19

sizeof(data) 32

Page 25: CSCI 243 The Mechanics of Programming C: …tvf/CSCI243/Notes/05-c-structs.pdfCSCI 243 The Mechanics of Programming Timothy Fossum (tvf@cs.rit.edu) TVF / RIT 20195 C: Structures TVF

TVF / RIT 20195 CS243: Structures

Structure Layout in Memory

• Some architectures require alignment of data items• MIPS, SPARC, M680x0 require it

• x86, x86_64, others don’t require alignment (but the compiler might still align items)

• Alignment is done to speed up data transfers

• Common rules:• char aligned on byte boundary

• int aligned on four-byte boundary

• double aligned on eight-byte boundary

• Compilers know this and insert “padding” bytes…

• …even if the hardware doesn’t require it

Page 26: CSCI 243 The Mechanics of Programming C: …tvf/CSCI243/Notes/05-c-structs.pdfCSCI 243 The Mechanics of Programming Timothy Fossum (tvf@cs.rit.edu) TVF / RIT 20195 C: Structures TVF

TVF / RIT 20195 CS243: Structures

Padding

• Our structure and its layout

struct stuff { char c1; // offset 0, size 1 int i1; // offset 4, size 4 char c2; // offset 8, size 1 int i2; // offset 12, size 4 char c3; // offset 16, size 1 double d1; // offset 24, size 8};

Page 27: CSCI 243 The Mechanics of Programming C: …tvf/CSCI243/Notes/05-c-structs.pdfCSCI 243 The Mechanics of Programming Timothy Fossum (tvf@cs.rit.edu) TVF / RIT 20195 C: Structures TVF

TVF / RIT 20195 CS243: Structures

Padding

• More memory-friendly layout:

• No padding → 19 bytes• 40.6% reduction in space usage

• Some compilers may add padding at end• Add one byte → 20 bytes total → 32.5% reduction

• Add 5 bytes → 24 bytes total → 25% reduction

struct stuff { double d1; int i1; int i2; char c1; char c2; char c3;};