Title: Structs
1Chapter 9
2Structures
- A structure can be used to combine data of
different types into a single (compound) data
value.
3Structures
- 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
4Structures
- A variable structure definition defines a struct
variable. - struct
- Member names
- double x_coordinate
- double y_coordinate
- point
- variable name DONT FORGET THE SEMICOLON
5Structures
- A tagged structure definition defines a type. We
can use the tag to define variables, parameters,
and return types. - struct point_t
structure tag -
Member names - double x_coordinate
- double y_coordinate
-
-
- DONT FORGET THE SEMICOLON
- To Use struct point_t point1, point2
6Structures
- 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 Member names
- double x_coordinate
- double y_coordinate
- point_t
- new type name DONT FORGET THE
SEMICOLON - To Use point_t point1, point2
7Structures
- Example 2 (tagged-defined structure)
- struct studentRecord_t
structure tag -
Member names - int student_number
- char name31
- char grade
-
-
- DONT FORGET THE SEMICOLON
8Structures
- Given the structure definitions point_t and
studentRecord_t, structure variables can be
defined - point_t point1
- This structure variable definition creates member
variables x_coordinate and y_coordinate
associated with the structure..
8
9Structures
- studentRecord_t student
- This structure variable definition creates member
variables id, name and grade associated with the
structure.
9
10Structures
- Member variables are accessed using the dot
operator. - point1.x_coordinate // type is double
- point1.y_coordinate // type is double
- student.student_number // type is int
- student.grade // type is char
- These variables may be used exactly like any
other variables.
10
11The Dot Operator
- The dot operator is used to specify a member
variable of a structure variable. - dot operator
- Syntax Structure_Variable_Name.Member_variable_n
ame - Example
- struct StudentRecord
- int student_number
- char grade
-
- int main( )
- StudentRecord your_record
- your_record.student_number 2201
- your_record.grade A
-
11
12Programming Tip(1 of 2) Use Hierarchical
Structures
- If a structure has a subset of its members that
may be considered an entity, consider nested
structures. - Example PersonInfo struct might include a
birthday - struct Date
- int month
- int day
- int year
-
- struct PersonInfo
- double height // inches
- int weight // pounds
- Date birthday
-
13Programming Tip(2 of 2) Use Hierarchical
Structures
- Declare a variable of PersonInfo type as usual
- PersonInfo person1
- Person1.birthday
- // This is a Date structure, with members
accessible - // as in any other structure variable.
- If the structure variable person1 has been
set, the year a person was born can be output as
follows - printf("d\n", person1.birthday.year)
-
- structure structure int member
- variable member of contained
structure.
14Initializing Structures
- A structure may be initialized at the time it is
declared. - struct Date
- int month
- int day
- int year
-
- Date due_date 12, 31, 2001
15Initializing Structures
- 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.
16Use 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. - Given
- pixel_t pixel
- The following all have the value 3
- sizeof(pixel)
- sizeof(pixel_t)
17Structures 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
18Structures as parameters to functions
- include ltstdio.hgt
- 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
19Structures as parameters to functions
- Sample Run
- 112647 lowerm_at_spider3 142 ./a.out
- x.a 99
- x.b 11.500000
- y.a 99
- y.b 11.500000
20Structures 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 w1024 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 lt 1000000 i)
- slow_call(fourMB)
-
-
21Passing 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.
22Passing the address of a struct
- include ltstdio.hgt
- typedef struct
- int a
- double b
- sample_t
- / Use the operator. funct modifies the
struct / - void funct (sample_t x)
- fprintf(stdout, "x-gta d\n", x-gta) //
note the use of -gt operator - fprintf(stdout, "x-gtb lf\n", x-gtb)
- x-gta 1000
- x-gtb 55.5
-
- int main()
- sample_t y
- y.a 99
- y.b 11.5
- / use the address operator, , in the call
/
23Passing the address of a struct
- Sample run
- 113929 lowerm_at_spider3 169 ./a.out
- x-gta 99
- x-gtb 11.500000
- y.a 1000
- y.b 55.500000
24Passing 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)
25Using the const modifier
- include ltstdio.hgt
- typedef struct s_type
-
- int a
- double b
- sample_t
- void funct(const sample_t x)
- fprintf(stdout, "x.a d\n", x-gta)
- fprintf(stdout, "x.b d\n", x-gta)
- x-gta 1000
- x-gtb 55.5
-
- int main( )
- sample_t y
- y.a 99
- y.b 11.5
26Using the const modifier
- 113404 lowerm_at_spider3 147 gcc struc5.c
- struc5.c In function 'funct'
- struc5.c12 error assignment of read-only
location - struc5.c13 error assignment of read-only
location
27Arrays within structures
- An element of a structure may be an array
- typedef struct
- char name25
- double payRate
- int hoursWorked7
- timeCard_type
- timeCard_type myTime
- Elements of the array are accessed in the usual
way - myTime.hoursWorked5 6
-
28Arrays of structures
- We can also create an array of structure types
- pixel_t pixelMap400 300
- student_t roster125
- To access an individual element of the array,
- pixelMap20.red 250
- roster50.gpa 3.75
29Arrays of structures containing arrays
- We can also create an array of structures that
contain arrays - timeCard_type employees50
- To access an individual element
- employees10.hoursWorked3 10
30Structures 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 te usual rule of not
referencing a name before it is defined.
31Structures containing structures
- typedef struct
- unsigned char red
- unsigned char green
- unsigned char blue
- pixel_t
- typdef struct
- int numRows
- int numCols
- pixel_t pixelData400 300
- image_t
32Structures 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.
33Structures as return values from functions
- typedef struct
- int a
- double b
- sampleType
- sample_t funct ( )
- sample_t s
- s-gta 1000
- s-gtb 55.5
- return (s)
-
- int main()
- sample_t y
- y funct( )
- fprintf(stdout, "y-gta d\n", y-gta)
- return 0
-
- lowerm_at_shodow7160 ./a.out
34Structures 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.
35Structures 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
36Structures as return values from functions
- include ltstdio.hgt
- 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
37Summary
- 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 you never 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.