struct

advertisement
C Programming
Structured Data
Combining Data into Structures
• Structure: C construct that allows multiple
variables to be grouped together
• Structure Declaration Format:
struct structure name
{
type1 field1;
type2 field2;
…
typen fieldn;
};
Example struct Declaration
struct Student
{
int studentID;
string name;
short year;
double gpa;
};
structure tag
structure members
Notice the
required
;
struct examples
• Example:
struct StudentInfo{
int Id;
int age;
char Gender;
double CGA;
};
The “StudentInfo”
structure has 4 members
of different types.
• Example:
struct StudentGrade{
char Name[15];
char Course[9];
int Lab[5];
int Homework[3];
int Exam[2];
};
The “StudentGrade”
structure has 5
members of
different array types.
4
struct examples
• Example:
struct BankAccount{
char Name[15];
int AcountNo[10];
double balance;
Date Birthday;
};
The “BankAcount”
structure has simple,
array and structure
types as members.
• Example:
struct StudentRecord{
char Name[15];
int Id;
char Dept[5];
char Gender;
};
The “StudentRecord”
structure has 4
members.
5
struct Declaration Notes
• struct names commonly begin with
an uppercase letter
• Multiple fields of same type can be in a
comma-separated list
string name,
address;
Defining Structure Variables
• struct declaration does not allocate
memory or create variables
• To define variables, use structure tag as
type name
s1
Student s1;
studentID
name
year
gpa
Example: structures
struct date
Defines type struct date, with 3 fields of type int
{
The names of the fields are local in the context
int month;
of the structure.
int day;
A struct declaration defines a type: if not followed by a
int year;
list of variables it reserves no storage; it merely
};
describes a template or shape of a structure.
struct date today, purchaseDate;
today.year = 2004;
Defines 3 variables of
type struct date
today.month = 10;
Accesses fields of a variable of
type struct date
today.day = 5;
A member of a particular structure is referred to
in an expression by a construction of the
form structurename.member
9
Structure definition
• To define a structure for student’s
information
typedef struct {
char [30] name;
int age;
} student;
Student s1, s2;
Structure using
• When we use the structure data as
S1.age = 21;
S2.age = 20;
Strcpy(s1.name, “mohamed”);
Strcpy(s2.name, “ahmed”);
Accessing Structure Members
• Use the dot (.) operator to refer to
members of struct variables
Printf(“%d”, s1.studentID);
s1.gpa = 3.75;
• Member variables can be used in any
manner appropriate for their data type
Displaying struct Members
• To display the contents of a struct
variable, you must display each field
separately, using the dot operator
Wrong:
cout << s1; // won’t work!
Correct:
cout
cout
cout
cout
<<
<<
<<
<<
s1.studentID << endl;
s1.name << endl;
s1.year << endl;
s1.gpa;
Initializing a Structure
• Cannot initialize members in the structure
declaration, because no memory has been
allocated yet
struct Student
// Illegal
{
// initialization
int studentID = 1145;
string name = "Alex";
short year = 1;
float gpa = 2.95;
};
15
Example
• Write a program which accepts from the user via
the keyboards, and the following data items:
•
it_number – integer value,
•
name – string, up to 20 characters,
•
amount – integer value.
• Your program will store this data for 3 persons
and display each record is proceeded by the
record number.
Comparing struct Variables
• Cannot compare struct variables
directly:
if (stu1 == stu2) // won’t work
• Instead, must compare on a member
basis:
if (stu1.studentID == stu2.studentID)
Initializing a Structure (continued)
• Structure members are initialized at the time
a structure variable is created
• Can initialize a structure variable’s members
with either
– an initialization list
– a constructor
Using an Initialization List
• An initialization list is an ordered set of
values, separated by commas and
contained in { }, that provides initial values
for a set of data members
{12, 6, 3}
// initialization list
// with 3 values
More on Initialization Lists
• Order of list elements matters: First value
initializes first data member, second value
initializes second data member, etc.
• Elements of an initialization list can be constants,
variables, or expressions
{12, W, L/W + 1} // initialization list
// with 3 items
Initialization List Example
Structure Declaration
struct Dimensions
{ int length,
width,
height;
};
Structure Variable
box
length
12
width
6
height
3
Dimensions box = {12,6,3};
Partial Initialization
• Can initialize just some members, but
cannot skip over members
Dimensions box1 = {12,6}; //OK
Dimensions box2 = {12,,3}; //illegal
Problems with Initialization List
• Can’t omit a value for a member without
omitting values for all following members
• Does not work on most modern compilers
if the structure contains any string objects
– Will, however, work with C-string members
Examples
//Create a box with all dimensions given
Dimensions box4(12, 6, 3);
//Create a box using default value 1 for
//height
Dimensions box5(12, 6);
//Create a box using all default values
Dimensions box6;
Omit () when
no arguments
are used
Example
• Write a car struct that has the following
fields: YearModel (int), Make (string),
and Speed (int).
• The program has function assign_data (
) accelerate ( ) which add 5 to the
speed each time it is called, break ()
which subtract 5 from speed each time
it is called, and display () to print out the
car’s information.
Nested Structures
A structure can have another structure as a
member.
struct PersonInfo
{ string name,
address,
city;
};
struct Student
{ int
studentID;
PersonInfo pData;
short
year;
double
gpa;
};
Members of Nested Structures
• Use the dot operator multiple times to
dereference fields of nested structures
Student s5;
s5.pData.name = "Joanne";
s5.pData.city = "Tulsa";
Example
• Create a structTime that contains data
members, hour, minute, second to
store the time value, provide a function
that sets hour, minute, second to
zero, provide three function for
converting time to ( 24 hour ) and
another one for converting time to ( 12
hour ) and a function that sets the time
to a certain value specified by three
parameters
Arrays of Structures
• Structures can be defined in arrays
• Structures can be used in place of parallel arrays
Student stuList[20];
• Individual structures accessible using subscript
notation
• Fields within structures accessible using dot notation:
cout << stuList[5].studentID;
Structures as Function
Arguments
• May pass members of struct variables
to functions
computeGPA(s1.gpa);
• May pass entire struct variables to
functions
showData(s5);
• Can use reference parameter if function
needs to modify contents of structure
variable
Example
Coffee shop needs a program to
computerize its inventory. The data will
be Coffee name, price, and amount in
stock, sell by year. The function on
coffee are: prepare to enter stock,
Display coffee data, change price, add
stock (add new batch), sell coffee,
remove old stock (check sell by year).
Notes on Passing Structures
• Using a value parameter for structure can
slow down a program and waste space
• Using a reference parameter speeds up
program, but allows the function to modify
data in the structure
• To save space and time, while protecting
structure data that should not be changed,
use a const reference parameter
void showData(const Student &s)
// header
Returning a Structure from a
Function
• Function can return a struct
Student getStuData();
s1 = getStuData();
// prototype
// call
• Function must define a local structure
– for internal use
– to use with return statement
Returning a Structure Example
Student getStuData()
{ Student s;
// local variable
cin >> s.studentID;
cin.ignore();
getline(cin, s.pData.name);
getline(cin, s.pData.address);
getline(cin, s.pData.city);
cin >> s.year;
cin >> s.gpa;
return s;
}
Example
• Design a struct named BankAccount with data:
balance, number of deposits this month, number of
withdrawals, annual interest rate, and monthly
service charges. The program has functions: Deposit
(amount) {add amount to balance and increment
number of deposit by one}, Withdraw (amount)
{subtract amount from balance and increment
number of withdrawals by one}, CalcInterest() {
update balance by amount = balance * (annual
interest rate /12)}, and MonthlyPocess() {subtract
the monthly service charge from balance, set number
of deposit, number of withdrawals and monthly
service charges to zero}.
Pointers to Structures
• A structure variable has an address
• Pointers to structures are variables that can hold the
address of a structure:
Student * stuPtr, stu1;
• Use the & operator to assign an address:
stuPtr = & stu1;
• A structure pointer can be a function parameter
Accessing Structure Members via Pointer Variables
• Use () to dereference the pointer variable, not
the field within the structure:
cout << (*stuPtr).studentID;
• You can use the structure pointer operator
( -> ), a.k.a arrow operator to eliminate use
of(*).
cout << stuPtr -> studentID;
Pointers to Structures
• You may take the address of a structure variable and create
variables that are pointers to structures.
Circle *cirPtr;
CirPtr = &piePlate;
// cirPtr is a pointer to a Circle
*cirPtr.radius = 10;
// incorrect way to access Radius because the dot operator
// has higher precedence than the indirection operator
(*cirPtr).radius = 10; //correct access to Radius
cirPtr -> radius = 10;
// structure pointer operator ( -> ), easier notation for
// dereferencing structure pointers
Example
• Write a complete program to
– Define a person struct with members: ID,
name, address, and telephone number.
The functions are change_data( ),
get_data( ), and display_data( ).
– Declare record table with size N and
provide the user to fill the table with data.
– Allow the user to enter certain ID for the
Main function to display the corresponding
person's name, address, and telephone
Linked List
Unions
• Similar to a struct, but
– all members share a single memory location
(which saves space)
– only 1 member of the union can be used at a
time
• Declared using key word union
• Otherwise the same as struct
• Variables defined and accessed like
struct variables
Example union Declaration
union WageInfo
{
double hourlyRate;
float annualSalary;
};
union tag
union members
Notice the
required
;
Anonymous Union
• A union without a tag:
union { ... };
• With no tag you cannot create additional
union variables of this type later
• Allocates memory at declaration time
• Refer to members directly without dot
operator
Enumerated Data Types
• An enumerated data type is a programmerdefined data type.
It consists of values known as enumerators,
which represent integer constants.
Enumerated Data Types
• Example:
enum Day { MONDAY, TUESDAY,
WEDNESDAY, THURSDAY,
FRIDAY };
• The identifiers MONDAY, TUESDAY, WEDNESDAY,
THURSDAY, and FRIDAY, which are listed inside
the braces, are enumerators. They represent the
values that belong to the Day data type. The
enumerators are named constants.
Enumerated Data Types
• Once you have created an enumerated
data type in your program, you can
define variables of that type. Example:
Day workDay;
• This statement defines workDay as a
variable of the Day type.
Enumerated Data Types
• We may assign any of the enumerators
MONDAY, TUESDAY, WEDNESDAY,
THURSDAY, or FRIDAY to a variable of
the Day type.
• Example:
workDay = WEDNESDAY;
Enumerated Data Types
enum Day { MONDAY, TUESDAY,
WEDNESDAY, THURSDAY,
FRIDAY };
In memory...
MONDAY = 0
TUESDAY = 1
WEDNESDAY = 2
THURSDAY = 3
FRIDAY = 4
Enumerated Data Types
• Using the Day declaration, the following
code...
cout << MONDAY
<< " "
<< WEDNESDAY << " “
<< FRIDAY
<< endl;
...will produce this output:
0 2 4
Assigning an Enumerator to an int Variable
• You CAN assign an enumerator to an
int variable. For example:
int x;
x = THURSDAY;
• This code assigns 3 to x.
Enumerated Data Types
• Program shows enumerators used to control a
loop:
// Get the sales for each day.
for (index
{
cout <<
<<
cin >>
}
= MONDAY; index <= FRIDAY; index++)
"Enter the sales for day "
index << ": ";
sales[index];
// Would not work if index was an enumerated type
Using an enum Variable to Step through an Array's Elements
• Because enumerators are stored in memory as
integers, you can use them as array subscripts.
For example:
enum Day { MONDAY, TUESDAY, WEDNESDAY,
THURSDAY, FRIDAY };
const int NUM_DAYS = 5;
double sales[NUM_DAYS];
sales[MONDAY]
sales[TUESDAY]
sales[WEDNESDAY]
sales[THURSDAY]
sales[FRIDAY]
=
=
=
=
=
1525.00;
1896.50;
1975.63;
1678.33;
1498.52;
STRUCT, TYPEDEF, ENUM & UNION



You cannot use the typedef specifier inside a
function definition.
When declaring a local-scope identifier by the same
name as a typedef, or when declaring a member of a
structure or union in the same scope or in an inner
scope, the type specifier must be specified.
For example,
typedef float TestType;
int main(void)
{ ... }
// function scope (local)
int MyFunct(int)
{
// same name with typedef, it is OK
int TestType;
}
www.tenouk.com, ©
57/93
STRUCT, TYPEDEF, ENUM & UNION


Names for structure types are often defined
with typedef to create shorter and simpler
type name.
For example, the following statements,
typedef struct Card MyCard;
typedef unsigned short USHORT;



Defines the new type name MyCard as a synonym
for type struct Card and USHORT as a synonym
for type unsigned short.
Programmers usually use typedef to define a
structure (also union, enum and class) type so
a structure tag is not required.
For example, the following definition.
typedef struct{
char *face;
char *suit;
} MyCard;
62/93
Creating Header File and File Re-inclusion Issue






It is a normal practice to separate structure, function,
constants, macros, types and similar definitions and
declarations in a separate header file(s).
Then, those definitions can be included in main() using the
include directive (#include).
It is for reusability and packaging and to be shared between
several source files.
Include files are also useful for incorporating declarations of
external variables and complex data types.
You need to define and name the types only once in an
include file created for that purpose.
The #include directive tells the preprocessor to treat the
contents of a specified file as if those contents had appeared
in the source program at the point where the directive
appears.
www.tenouk.com, ©
54/93
 The syntax is one of the following,
1. #include
2. #include
"path-spec"
<path-spec>
 Both syntax forms cause replacement of that
directive by the entire contents of the specified
include file.
 The difference between the two forms is the
order in which the preprocessor searches for
header files when the path is incompletely
specified.
 Preprocessor searches for header files when
the path is incompletely specified.
www.tenouk.com, ©
42/93
56
Bitwise Operators
• All data is represented internally as
sequences of bits
– Each bit can be either 0 or 1
– Sequence of 8 bits forms a byte
Exercise: even or odd
• testing if an integer is even or odd, using bitwise operations:
• the rightmost bit of any odd integer is 1 and of any even integer is 0.
int n;
if ( n & 1 )
printf(“odd”);
else
printf(“even”);
58
Operator
&
Description
bitwise AND
The bits in the result are set to 1 if the corresponding bits
in the two operands are both 1 .
|
bitwise inclusive
OR
The bits in the result are set to 1 if at least one of the corresponding bits
in the two operands is 1.
^
bitwise exclusive
OR
The bits in the result are set to 1 if exactly one of the corresponding bits
in the two operands is 1.
<<
left shift
Shifts the bits of the first operand left by the number of bits specified by
the second operand; fill from the right with 0 bits.
>>
right shift
Shifts the bits of the first operand right by the number of bits specified by
the second operand; the method of filling from the left is machine
dependent.
~
one’s complement
All 0 bits are set to 1 and all 1 bits are set to 0.
Fig. 10.6 | Bitwise operators.
59
Bit 1
Bit 2
Bit 1 & Bit 2
0
0
0
1
0
0
0
1
0
1
1
1
Fig. 10.8 | Results of combining two bits with the bitwise AND operator &.
60
Bit 1
Bit 2
Bit 1 | Bit 2
0
0
0
1
0
1
0
1
1
1
1
1
Fig. 10.11 | Results of combining two bits with the bitwise inclusive OR operator |.
61
Bit 1
Bit 2
Bit 1 ^ Bit 2
0
0
0
1
0
1
0
1
1
1
1
0
Fig. 10.12 | Results of combining two bits with the bitwise exclusive OR operator ^.
The result of combining the following
65535 = 00000000 00000000 11111111 11111111
1 = 00000000 00000000 00000000 00000001
using the bitwise AND operator & is
1 = 00000000 00000000 00000000 00000001
62
Outline
fig10_10.c
The result of combining the following
15 = 00000000 00000000 00000000
241 = 00000000 00000000 00000000
using the bitwise inclusive OR operator
255 = 00000000 00000000 00000000
00001111
11110001
| is
11111111
The result of combining the following
139 = 00000000 00000000 00000000
199 = 00000000 00000000 00000000
using the bitwise exclusive OR operator
76 = 00000000 00000000 00000000
10001011
11000111
^ is
01001100
The one's complement of
21845 = 00000000 00000000 01010101 01010101
is
4294945450 = 11111111 11111111 10101010 10101010
1
2
/* Fig. 10.13: fig10_13.c
Using the bitwise shift operators */
3
4
#include <stdio.h>
5
void displayBits( unsigned value ); /* prototype */
6
7
8
9
int main( void )
{
unsigned number1 = 960; /* initialize number1 */
10
11
12
/* demonstrate bitwise left shift */
printf( "\nThe result of left shifting\n" );
13
displayBits( number1 );
14
15
16
printf( "8 bit positions using the " );
printf( "left shift operator << is\n" );
displayBits( number1 << 8 );
17
Left shift operator shifts all bits left a specified
number of spaces, filling in zeros for the empty bits
63
Outline
fig10_13.c
(1 of 3 )
18
19
/* demonstrate bitwise right shift */
printf( "\nThe result of right shifting\n" );
20
displayBits( number1 );
21
22
printf( "8 bit positions using the " );
printf( "right shift operator >> is\n" );
23
displayBits( number1 >> 8 );
24
25
return 0; /* indicates successful termination */
26 } /* end main */
27
28
29
30
30
/* display bits of an unsigned integer value */
void displayBits( unsigned value )
{
{
31
32
unsigned c; /* counter */
33
34
/* declare displayMask and left shift 31 bits */
unsigned displayMask = 1 << 31;
35
36
printf( "%7u = ", value );
37
64
Outline
fig10_13.c
(2 of 3 )
Right shift operator shifts all bits right a specified
number of spaces, filling in the empty bits in
an implementation-defined manner
38
39
/* loop through bits */
for ( c = 1; c <= 32; c++ ) {
40
41
putchar( value & displayMask ? '1' : '0' );
value <<= 1; /* shift value left by 1 */
42
43
if ( c % 8 == 0 ) { /* output a space after 8 bits */
44
45
46
47
48
49
putchar( ' ' );
} /* end if */
} /* end for */
putchar( '\n' );
50 } /* end function displayBits */
The result of left shifting
960 = 00000000 00000000 00000011 11000000
8 bit positions using the left shift operator << is
245760 = 00000000 00000011 11000000 00000000
The result of right shifting
960 = 00000000 00000000 00000011 11000000
8 bit positions using the right shift operator >> is
3 = 00000000 00000000 00000000 00000011
65
Outline
fig10_13.c
(3 of 3 )
66
Bitwise assignment operators
&=
Bitwise AND assignment operator.
|=
Bitwise inclusive OR assignment operator.
^=
Bitwise exclusive OR assignment operator.
<<=
Left-shift assignment operator.
>>=
Right-shift assignment operator.
Fig. 10.14 | The bitwise assignment operators.
Download