+ All Categories
Home > Documents > Structured Data Typesrlowe/cs1070/notes/structs.pdf · An element of a structure may be an array...

Structured Data Typesrlowe/cs1070/notes/structs.pdf · An element of a structure may be an array...

Date post: 12-Jul-2020
Category:
Upload: others
View: 1 times
Download: 0 times
Share this document with a friend
36
1 Structured Data Types A structure can be used to combine data of different types into a single (compound) data value. Like all data types, structures must be declared and defined. C has three different ways to define a structure variable structures tagged structures type-defined structures
Transcript
Page 1: Structured Data Typesrlowe/cs1070/notes/structs.pdf · An element of a structure may be an array typedef struct {char name[25]; double payRate; int hoursWorked[7];} timeCard_type;

1

Structured Data Types

• A structure can be used to combine data of different types into a single (compound) data value.

• Like all data types, structures must be declared and defined.

• C has three different ways to define a structure

– variable structures

– tagged structures

– type-defined structures

Page 2: Structured Data Typesrlowe/cs1070/notes/structs.pdf · An element of a structure may be an array typedef struct {char name[25]; double payRate; int hoursWorked[7];} timeCard_type;

2

Structured Data Types

A variable structure definition defines a struct variable.

struct{

unsigned char red; unsigned char green;unsigned char blue;

} pixel;

variable name DON’T FORGET THE SEMICOLON

Members

Page 3: Structured Data Typesrlowe/cs1070/notes/structs.pdf · An element of a structure may be an array typedef struct {char name[25]; double payRate; int hoursWorked[7];} timeCard_type;

3

Structured Data Types

A tagged structure definition defines a type. We can use

the tag to define variables, parameters, and return types.

struct point_t structure tag{

double x; Member namesdouble y;

};

DON’T FORGET THE SEMICOLON

To Use: struct point_t point1, point2;

must use the tagnote the use ofstruct

Page 4: Structured Data Typesrlowe/cs1070/notes/structs.pdf · An element of a structure may be an array typedef struct {char name[25]; double payRate; int hoursWorked[7];} timeCard_type;

4

Structured Data Types

• Example 2 (tagged structure definition)

struct pixel_t{

unsigned char red; unsigned char green;unsigned char blue;

};

DON’T FORGET THE SEMICOLON

To Use: struct pixel_t pixel;

Structure tag

Members

Page 5: Structured Data Typesrlowe/cs1070/notes/structs.pdf · An element of a structure may be an array typedef struct {char name[25]; double payRate; int hoursWorked[7];} timeCard_type;

5

Structured Data Types

• A typed-defined structure is the most powerful way to

declare a structure. We can use the tag to define

variables, parameters, and return types.

typedef struct pixel_type{

unsigned char red; unsigned char green;unsigned char blue;

} pixel_t;

• To declare a variable of the new type, use: pixel_t pixel;

New type name

Page 6: Structured Data Typesrlowe/cs1070/notes/structs.pdf · An element of a structure may be an array typedef struct {char name[25]; double payRate; int hoursWorked[7];} timeCard_type;

6

Structured Data Types

Example 2 (typed-defined structure)

typedef struct pointType{

double x; double y;

} point_t;

To declare variables of the type, use:

point_t point1;point_t point2;

These structure variable definitions create member variables x and y associated with the structure.

New type name

Page 7: Structured Data Typesrlowe/cs1070/notes/structs.pdf · An element of a structure may be an array typedef struct {char name[25]; double payRate; int hoursWorked[7];} timeCard_type;

Structured data types

• Member variables of a struct are accessed using the dot operator.

pixel1.red = 200;

pixel1.green = 200;

pixel1.blue = 0;

point1.x = 10.0; // type is double

point1.y = 5.5; // type is double

• These variables may be used exactly like any other variables.

7

Page 8: Structured Data Typesrlowe/cs1070/notes/structs.pdf · An element of a structure may be an array typedef struct {char name[25]; double payRate; int hoursWorked[7];} timeCard_type;

Example

typedef struct student_type

{

int id;

char grade;

} student_t;

int main( )

{

student_t student;

student.id = 2201;

student.grade = ‘A’;

fprintf(stdout, “id: %d, grade: %c\n”,

student.id, student.grade);

return 0;

}8

Page 9: Structured Data Typesrlowe/cs1070/notes/structs.pdf · An element of a structure may be an array typedef struct {char name[25]; double payRate; int hoursWorked[7];} timeCard_type;

9

Initializing Structures

• At declaration time, members of a struct can be initialized in a manner similar to initializing array elements.

pixel_t pixel = {255, 0, 100};

• The sequence of values is used to initialize the successive variables in the struct. The order is essential.

• It is an error to have more initializers than variables.

• If there are fewer initializers than variables, the initializers provided are used to initialize the data members. The remainder are initialized to 0 for primitive types.

Page 10: Structured Data Typesrlowe/cs1070/notes/structs.pdf · An element of a structure may be an array typedef struct {char name[25]; double payRate; int hoursWorked[7];} timeCard_type;

10

Use of sizeof() with structures

• The sizeof() operator should always be used in dynamic allocation of storage for structured data types and in reading and writing structured data types. However, it is somewhat easy to do this incorrectly.

Page 11: Structured Data Typesrlowe/cs1070/notes/structs.pdf · An element of a structure may be an array typedef struct {char name[25]; double payRate; int hoursWorked[7];} timeCard_type;

We can declare a pointer to a pixel_t in the following manner:

pixel_t *pixptr;

We must allocate memory to the pointer before using it. We can either assign to pixptr the address of a pixel_tstruct or use malloc to allocate memory:

pixptr = malloc(sizeof(pixel_t));

Pointers to structures:

Page 12: Structured Data Typesrlowe/cs1070/notes/structs.pdf · An element of a structure may be an array typedef struct {char name[25]; double payRate; int hoursWorked[7];} timeCard_type;

Declaring a pointer and allocating memory at the same time:

pixel_t *pixptr = malloc(sizeof(pixel_t));

To set or reference components of the pixptr, we can use:

pixptr->red = 250; // make Mr. *pixptr magentapixptr-> = 0;pixptr->b = 250;

Pointers to structures:

Page 13: Structured Data Typesrlowe/cs1070/notes/structs.pdf · An element of a structure may be an array typedef struct {char name[25]; double payRate; int hoursWorked[7];} timeCard_type;

An alteranative “short hand” notation has evolved for accessing elements of structures through a pointer:

pixptr->red = 0;

pixptr->green = 250;

pixptr->blue = 250;

This shorthand form is almost universally used.

Pointers to structures:

Page 14: Structured Data Typesrlowe/cs1070/notes/structs.pdf · An element of a structure may be an array typedef struct {char name[25]; double payRate; int hoursWorked[7];} timeCard_type;

14

Structures containing structures

• It is common for structures to contain elements which are themselves structures or arrays of structures. In these cases, the structure definitions should apear in "inside-out" order.

• This is done to comply with the usual rule of not referencing a name before it is defined.

Page 15: Structured Data Typesrlowe/cs1070/notes/structs.pdf · An element of a structure may be an array typedef struct {char name[25]; double payRate; int hoursWorked[7];} timeCard_type;

15

Structures containing structures

typedef struct dateType{

int month;int day;int year;

} date_t;

typedef struct nameType{

char *firstname;char mi[2];char *lastname;

} name_t;

Page 16: Structured Data Typesrlowe/cs1070/notes/structs.pdf · An element of a structure may be an array typedef struct {char name[25]; double payRate; int hoursWorked[7];} timeCard_type;

16

Structures containing structures

typedef struct addressType

{

char *street;

char *city;

char state[3];

char *zip;

} addr_t;

typedef struct personType

{

name_t name;

addr_t address;

date_t dob;

} person_t;

Page 17: Structured Data Typesrlowe/cs1070/notes/structs.pdf · An element of a structure may be an array typedef struct {char name[25]; double payRate; int hoursWorked[7];} timeCard_type;

17

Arrays of structures

• We can also create an array of structure types:

pixel_t pixelMap[400 * 300];

student_t roster[125];

• To access an individual element of the array,

pixelMap[20].red = 250;

roster[50].gpa = 3.75;

Page 18: Structured Data Typesrlowe/cs1070/notes/structs.pdf · An element of a structure may be an array typedef struct {char name[25]; double payRate; int hoursWorked[7];} timeCard_type;

18

Arrays of structures containing arrays

• We can also create an array of structures that contain arrays

timeCard_type employees[50];

• To access an individual element

employees[10].hoursWorked[3] = 10;

Page 19: Structured Data Typesrlowe/cs1070/notes/structs.pdf · An element of a structure may be an array typedef struct {char name[25]; double payRate; int hoursWorked[7];} timeCard_type;

19

Arrays within structures

An element of a structure may be an array

typedef struct

{

char name[25];

double payRate;

int hoursWorked[7];

} timeCard_type;

timeCard_type myTime;

Elements of the array are accessed in the usual way:

myTime.hoursWorked[5] = 6;

Page 20: Structured Data Typesrlowe/cs1070/notes/structs.pdf · An element of a structure may be an array typedef struct {char name[25]; double payRate; int hoursWorked[7];} timeCard_type;

20

Structures

• It is also possible for a structure definition to contain functions.

typedef struct dateType

{

int month;

int day;

int year;

// function to display in the form mm/dd/yyyy

void display_short(dateType *);

// function to display in the form string-mo day, yyyy

void display_long(dateType *);

} date_t;

Page 21: Structured Data Typesrlowe/cs1070/notes/structs.pdf · An element of a structure may be an array typedef struct {char name[25]; double payRate; int hoursWorked[7];} timeCard_type;

21

Structures as parameters to functions

• A struct, like an int, may be passed to a function.

• The process works just like passing an int, in that:

– The complete structure is copied to the stack

– The function is unable to modify the caller's copy of the variable

Page 22: Structured Data Typesrlowe/cs1070/notes/structs.pdf · An element of a structure may be an array typedef struct {char name[25]; double payRate; int hoursWorked[7];} timeCard_type;

22

Structures as parameters to functions#include <stdio.h>

typedef struct s_type{

int a;double b;

} sample_t;

void funct(sample_t x){

fprintf(stdout, "x.a = %d\n", x.a);fprintf(stdout, "x.b= %lf\n", x.b);x.a = 1000;x.b = 55.5;

}

int main() {sample_t y;y.a = 99;y.b = 11.5;funct(y);fprintf(stdout, "y.a = %d\n", y.a);fprintf(stdout, "y.b = %lf\n", y.b);return 0;

}

Page 23: Structured Data Typesrlowe/cs1070/notes/structs.pdf · An element of a structure may be an array typedef struct {char name[25]; double payRate; int hoursWorked[7];} timeCard_type;

23

Structures as parameters to functions

Sample Run:

./a.out

x.a = 99x.b= 11.500000y.a = 99y.b = 11.500000

Page 24: Structured Data Typesrlowe/cs1070/notes/structs.pdf · An element of a structure may be an array typedef struct {char name[25]; double payRate; int hoursWorked[7];} timeCard_type;

24

Structures as parameters to functions

• The disadvantages of passing structures by value are that copying large structures onto the stack– is very inefficient and– may even cause program failure due to stack

overflow.

typedef struct{

int w[1024 * 1024];} sample_t;

/* passing a struct of type sampleType above will cause *//* 4 Terabytes to be copied onto the stack. */

sample_t fourMB;for(i = 0; i < 1000000; i++) {

slow_call(fourMB);}

Page 25: Structured Data Typesrlowe/cs1070/notes/structs.pdf · An element of a structure may be an array typedef struct {char name[25]; double payRate; int hoursWorked[7];} timeCard_type;

25

Passing the address of a struct

• A more efficient way is to pass the address of the struct.

• Passing an address requires that only a single word be pushed on the stack, regardless of how large the structure is.

• Furthermore, the called function can then modify the structure.

Page 26: Structured Data Typesrlowe/cs1070/notes/structs.pdf · An element of a structure may be an array typedef struct {char name[25]; double payRate; int hoursWorked[7];} timeCard_type;

26

Passing the address of a struct#include <stdio.h>

typedef struct {int a;double b;

} sample_t;

/* Use the * operator. funct modifies the struct */void funct (sample_t *x) {

fprintf(stdout, "x->a = %d\n", x->a); // note the use of -> operatorfprintf(stdout, "x->b = %lf\n", x->b);x->a = 1000;x->b = 55.5;

}

int main() {

sample_t y;y.a = 99;y.b = 11.5;/* use the address operator, &, in the call */funct(&y);fprintf(stdout, "y.a = %d\n", y.a);fprintf(stdout, "y.b = %lf\n", y.b);return 0;

}

Page 27: Structured Data Typesrlowe/cs1070/notes/structs.pdf · An element of a structure may be an array typedef struct {char name[25]; double payRate; int hoursWorked[7];} timeCard_type;

27

Passing the address of a struct

Sample run:

./a.out

x->a = 99x->b = 11.500000y.a = 1000y.b = 55.500000

Page 28: Structured Data Typesrlowe/cs1070/notes/structs.pdf · An element of a structure may be an array typedef struct {char name[25]; double payRate; int hoursWorked[7];} timeCard_type;

28

Passing the address of a struct

• What if you do not want the recipient to be able to modify the structure?

• In the prototype and function header, use the * operator.

– Use the const modifier

void funct(const sample_t *x) ;

Page 29: Structured Data Typesrlowe/cs1070/notes/structs.pdf · An element of a structure may be an array typedef struct {char name[25]; double payRate; int hoursWorked[7];} timeCard_type;

29

Using the const modifier#include <stdio.h>

typedef struct s_type{

int a;double b;

} sample_t;

void funct(const sample_t *x) {fprintf(stdout, "x.a = %d\n", x->a);fprintf(stdout, "x.b = %d\n", x->a);x->a = 1000;x->b = 55.5;

}

int main( ) {sample_t y;y.a = 99;y.b = 11.5;/* to pass the address use the & operator */funct(&y);fprintf(stdout, "y.a = %d\n", y.a);fprintf(stdout, "y.b = %d\n", y.b);return 0;

}

– The above code will generate a compile-time error.

Page 30: Structured Data Typesrlowe/cs1070/notes/structs.pdf · An element of a structure may be an array typedef struct {char name[25]; double payRate; int hoursWorked[7];} timeCard_type;

30

Using the const modifier

• gcc struc5.c• struc5.c: In function 'funct':• struc5.c:12: error: assignment of read-only location• struc5.c:13: error: assignment of read-only location

Page 31: Structured Data Typesrlowe/cs1070/notes/structs.pdf · An element of a structure may be an array typedef struct {char name[25]; double payRate; int hoursWorked[7];} timeCard_type;

31

Structures as return values from functions

• Scalar values (int, float, etc) are efficiently returned in CPU registers.

• Historically, the structure assignments and the return of structures was not supported in C.

• But, the return of pointers (addresses), including pointers to structures, has always been supported.

Page 32: Structured Data Typesrlowe/cs1070/notes/structs.pdf · An element of a structure may be an array typedef struct {char name[25]; double payRate; int hoursWorked[7];} timeCard_type;

32

Structures as return values from functions

typedef struct {int a;double b;

} sampleType;

sample_t *funct ( ) {sample_t s;s->a = 1000;s->b = 55.5;return (&s);

}

int main() {sample_t *y;y = funct( );fprintf(stdout, "y->a = %d\n", y->a);return 0;

}

./a.outreturnParam.c: In function 'funct':returnParam.c:8: warning: function returns address of local variable

Page 33: Structured Data Typesrlowe/cs1070/notes/structs.pdf · An element of a structure may be an array typedef struct {char name[25]; double payRate; int hoursWorked[7];} timeCard_type;

33

Structures as return values from functions

• The reason for the warning is that the function is returning a pointer to a variable that was allocated on the stack during execution of the function.

• Such variables are subject to being wiped out by subsequent function calls.

Page 34: Structured Data Typesrlowe/cs1070/notes/structs.pdf · An element of a structure may be an array typedef struct {char name[25]; double payRate; int hoursWorked[7];} timeCard_type;

34

Structures as return values from functions

• It is possible for a function to return a structure.

• This facility depends upon the structure assignment mechanisms which copies one complete structure to another.

– This avoids the unsafe condition associated with returning a pointer, but

– incurs the possibly extreme penalty of copying a very large structure

Page 35: Structured Data Typesrlowe/cs1070/notes/structs.pdf · An element of a structure may be an array typedef struct {char name[25]; double payRate; int hoursWorked[7];} timeCard_type;

35

Structures as return values from functions

#include <stdio.h>

typedef struct s_type {int a;double b;

} sample_t;

sample_t funct ( ) {sample_t s;s.a = 1000;s.b = 55.5;return s;

}

int main() {sample_t y;sample_t z;y = funct();z = y;printf("%d %d\n", y.a, z.a);return 0;

}./a.out1000 1000

Page 36: Structured Data Typesrlowe/cs1070/notes/structs.pdf · An element of a structure may be an array typedef struct {char name[25]; double payRate; int hoursWorked[7];} timeCard_type;

36

Summary

• Passing/returning instances of structures potentially incurs big overhead.

• Passing/returning addresses incurs almost no overhead

• Accidental modifications can be prevented with const

– Therefore, it is recommended that, in general, you do not pass nor return an instance of a structure unless you have a very good reason for doing so.

• This problem does not arise with arrays.

– The only way to pass an array by value in the C language is to embed it in a structure

– The only way to return an array is to embed it in a structure.


Recommended