coit29222-structured programming lecture week 11 reading: textbook (4 th ed.), chapter 3 textbook...
TRANSCRIPT
COIT29222-Structured Programming
Lecture Week 11 Reading: Textbook (4th Ed.), Chapter 3
Textbook (6th Ed.), Chapter 6Study Guide Book 3, Module 2
Study Guide Book 3, Module 3This week, we will cover the following
topics:Common Mathematical FunctionsData TypesData Structures
Some Common C++ Mathematical Functions
To use numeric functions:#include <cmath>
The sqrt() function, with prototype:double sqrt(double x);
– Effective use of this function relies on the knowledge that the square root of a negative number is undefined.
– Thus, your program should ensure that a negative number is not passed to this library function.
Use of the sqrt() function#include <iostream> // for cin, cout, endl#include <cmath> // for sqrt() // names used from std namespaceusing std::cout;using std::cin;using std::endl; void main(void){double Number;
// get a number from the usercout << "Enter a number ==> ";cin >> Number;
cout << endl; // generate blank line …/cont’d
Use of the sqrt() function// determine if the square root of the number // can be taken if (Number >= 0.0)
cout << "The square root of " << Number << " is " << sqrt(Number) << endl;
elsecout << Number
<< " does not have a square root" << endl;}
Trigonometric functions Trigonometric functions: sin() , cos() , tan()
– Prototype form: double trigFn(double x); To use these functions effectively, note:
– the argument must be in radians (not degrees)where radians 180 degrees to convert
from degrees to radians, multiply by /180 – the tangents of angles in the sequence: 90,
270, 450... degrees (i.e. /2, 3 /2, 5 /2... radians) are undefined the tan() function should not be invoked with
an argument in this sequence
Example: Use of tan() function
Write a program to generate a table of angles (0–360 degrees, in 45 degree steps) & their corresponding tangents i.e.
Example: Use of tan() function#include <cmath> const double PI = 3.142;…// table headingscout << setw(8) << "Angle" << setw(12) << "Tangent" << endl;
// gen. table – angles (deg) & tangentsfor (int Alpha = 0; Alpha <= 360; Alpha += 45){// output the angle in degreescout << setw(8) << Alpha;
// determine if Alpha in seq. 90, 270…if ((Alpha - 90) % 180 == 0)cout << setw(12) << "undefined" << endl;else …/cont’d
Example: Use of tan() function
else // Alpha not in seq. 90, 270,…{
// convert angle Alpha to radiansAlphaInRadians =
static_cast<double>(Alpha) * PI / 180.0;cout << setprecision(2) << setiosflags(ios::fixed |
ios::showpoint)<< setw(12) << tan(AlphaInRadians)
<< endl;}
}
Example: Use of pow() function Distance Between Two Points
#include <cmath> double calculate();void main(){
double value;value = calculate();cout << value;
}double calculate(){
double xDist, yDist, xCord1=1, yCord1=1, xCord2=4, yCord2=4;double distance;xDist=xCord2-xCord1;yDist=yCord2-yCord1;distance = sqrt(pow(xDist,2)+pow(yDist,2));return distance;
}
Write a program that calculates the VALUE using the following
formula:
VALUE = n + Where sum =x+y+z x=1.0, y=2.0 and z=3.0n must be a random number between 1
and 5 inclusive
The result of VALUE must be displayed on the screen.
)( 85 zyxex sum
Operations and data A computer program manipulates
values. – We say that operations are
performed on data in computer programs data are just the values a program
might manipulate – Example operation: 6 / 3
the operation is divisionthe values or data are the integer
values 6 and 3
Operations and data
Example operation: 7 / 2– The result of this operation depends
on the meaning attributed to the division operator in the context of two integer operands.
– Typically, the programming language definition meaning of this operation to be integer division: result is 3
Operations and dataIn programming languages the same operator
can have different meanings in different contexts:– called operator overloading– Example: 7.0 / 2.0
•i.e. the division operator used in the context of 2 real operands
•typically, real division is performed result of 3.5
Thus, the meaning of an operation determined by the operator & type of data to which it is applied.
Operations and dataYou are familiar with the following types of
data manipulated by computer programs:– integer data– real data– character data
•for example in some languages the + operator, in the context of 2 character string operands means concatenation:
– i.e. the result of:
“My ” + “dog” is “My dog”
Classification of data into typesA data type can be viewed as a data
classification. – Classifying data into types facilitates the
specification of a program’s meaning.Data types:
– provide a context for operations so that their meaning is well-defined
– limit the set of operations that can be performed in a context •E.g. 7.0 / “Jo Bloggs” (typically) semantic error
Meaning - SemanticsThe definition of a programming language
involves:– a set of syntax rules which govern the form
or structure of correct programs Example: Omission of a semicolon where one is
required syntax error
– a set of semantic rules which determine the meaning of syntactically correct programsif the compiler can determine that an invalid
operation has been performed in a context (semantic rules broken) it generates a semantic error
Semantic Errors in C++Static semantic error:
– invalid operation determined at compile-time
– Examples:IntVar = “Jo Bloggs”RealVar >= “My dog”
Dynamic semantic error: – invalid operation determined at run-time– Example:
14 / IntVar–where IntVar takes the value zero at
runtime
Associating variables with data types
For variable operands to provide a context for an operation, the data types of the variables must be well-defined
Example: for the operationVar1 / Var2
to be well-defined, the data types of Var1 and Var2 must be well-defined
Thus, variables are defined to be of a particular data type – E.g:
int Var1, Var2;
The data types of expressions Operators occur in constructs called
expressions– Expressions are combinations of
operators, literals and variables which perform computations and return values.Operator precedence rules
determine the order of evaluation of the operations in an expression
The value returned by an expression has a data type – Example:
IntVar / 3 + 4.2 – data type of the whole expression is type double
The classification of data into types
We can define a data type by: – defining the set of values in the data
type– defining the set of operations that
can be performed on values of the typeData types can be divided into 2
broad categories:– Scalar data types– Composite data types
Data-type categoriesScalar data types – those whose data values are:
– ordered - 2 scalar values are either equal or one value is greater than the other value
– numeric data is ordered– character data is ordered (characters mapped to
the underlying (numeric) ASCII character set
– atomic – values of the type are single-valuedComposite data types – data values are composed of the values of the simpler scalar data types (and possibly other composite data types)– Example: array types
C++ Scalar data types
The scalar data types can be subdivided into 2 categories:– standard (built-in or pre-defined)
data typesvalid operations on values of the types pre-
defined by the C++ language definitionset of values in such a data type pre-defined
by the C++ language definition in conjunction with a particular implementation of the language
– enumerated data types
C++ Standard data types There are 4 categories of pre-
defined data types in C++: – integer, floating-point (real),
character, booleanC++ integer data types:
•short (int) •int •long (int)
– each of these types has an unsigned version
Integer overflow and underflow When performing integer calculations in C++ it is
the programmer’s responsibility to ensure that overflow or underflow do not occur.– integer overflow occurs when the result of an
operation is larger than the maximum allowable value for the data type of the operation
– integer underflow occurs when an operation results in a negative value whose magnitude is too large for the data type of the operation
A computation involving overflow or underflow will generate an incorrect result.
Operations on floating-point values
When performing operations on floating-point values:– ensure that floating-point
overflow/underflow does not occur– ensure that the data type of an operation
has sufficient precision to express the result
– do not compare floating-point values for equality (or inequality)since the internal representation of a
floating-point value may not be an exact representation of the value
C++ character data types
Type char provides a mapping between the character symbols in the ASCII character set and numeric values in the range 0 to 127. – This numeric representation determines the ordering of characters – Example:‘A’ (ASCII value 65) < ‘a’ (ASCII value 97)
Type unsigned char allows for an extended character set.
C++ character data typesIn C++, characters are stored as integer
values: character values may be used in any
context in which an integer is expected– Advantage: This increases the flexibility of
the language – Example:the expression ‘a’ + 1 evaluates to ‘b’
– Disadvantage: This weak typing there is less protection for the programmer
C++ boolean data type The C++ type bool, consists solely of
the two values true and false It is a scalar type since false is
defined to be less than true
The C++ enumeration type
An enumerated type is a user-defined type– i.e. the data type, itself, is defined by the
programmerall possible values of the type are enumerated (or itemised)
– Having defined an enumerated type, variables can be defined to be of this new type
Enumerated types are used to model real-world concepts such as days of the week, the seasons of the year or card suits – i.e. any relatively small collection of related entities
C++ enumeration type
The general syntax for defining an enumeration type is:
enum EnumTypeId { <enumerated list> }; – No storage is allocated for the definition of a type.
A type definition merely associates an identifier with the description of a type
The syntax for defining variables of enumeration types is exactly the same as for defining variables of pre-defined types:
EnumTypeId EnumVar;– Storage is allocated for the definition of a variable.
C++ enumeration type - Example
Using the C++ keyword enum, a new data type can be defined whose values are explicitly listed – Example:
enum TriColour {RED, WHITE, BLUE};
– defines a new type, TriColour, whose values are RED, WHITE and BLUE.
Given the definition of the type, variables of this new type may be defined – Example:
TriColour AColour = RED;
– defines a variable AColour, of type TriColour, initialised to the value RED
Data abstractionThe programmer communicates solutions to
real-world problems to a computer using a programming language.
programmer’s view of the world: couched in real-world terms – colours, books, vehicles etc.
computer’s view of the world: couched in terms of bits, bytes and words
– Data abstraction: the process of identifying & extracting the essential characteristics of a real-world situation so that it can be represented as data in a computer program.
Data abstractionThe pre-defined data types of a
programming language provide a degree of data abstraction– when manipulating integers/reals in a program
the programmer isn’t concerned with how they are actually implemented on a particular machine
User-defined data types allow for the representation of data at a higher level of abstraction – programmers can define their own classifications
of data representing colours, books, vehicles etc.
Type coercionWe’ve defined types in terms of:
– the valid values of the type– the valid operations of the type
allows the compiler to generate a semantic error when an invalid operation is performed in a context
however, most compilers allow some mixing of types in expressions – Example:
RealVar = 3;– where the compiler automatically converts
the int value 3, to the double value 3.0, prior to performing the assignment operation
– this process of automatic type conversion in certain contexts is called type coercion
Type coercion in C++
C++ compilers perform a great deal of type coercion. – thus, C++ is said to be a weakly
typed language a greater degree of responsibility is
placed on the C++ programmer to ensure that expressions do indeed produce the desired results
Type coercion in C++
In C++, type coercion is performed:– in arithmetic expressions– in relational expressions (which may
involve both relational and logical operators)
– in assignment operations– when passing arguments to functions– when returning values from functions
Type promotion—coercions involving no loss
of data The coercion to type double of the int
variable, IntVar in the expression:IntVar / 3.0
– is called type promotion in C++, where: built-in data types of C++ are organised into a
promotion hierarchyprior to performing a mixed-type arithmetic
operation:– an operand which is ‘lower’ in the promotion
hierarchy is automatically converted to the type of the operand which is ‘higher’ in the promotion hierarchy
Coercion - The assignment operation
In a mixed-type assignment operation involving the built-in data types:– the right-hand operand is coerced to the
type of the left-hand operand, even if it is lower in the promotion hierarchy – Example:
IntVar = 3.1413; Since only int values can be stored in int
variables, 3.1413 will be converted to the int value, 3, prior to being stored in IntVar.
This automatic type conversion does result in a loss of data.
Coercion - The assignment operation
• Automatic coercion does not occur if an attempt is made to assign a built-in data-type value into an enumeration-type variable – Example:
enum Fruit {APPLE, ORANGE, GRAPE};Fruit Snack = 2; // Semantic ERROR!
• Automatic coercion does occur when assigning an enumeration-type value into a built-in type variable – Example:
int IntVar;Fruit Snack = ORANGE;IntVar = Snack; // valid operation
Type casting – Explicit type conversion
Type casting is type conversion that is performed explicitly by the programmer.– by contrast, type coercion is known as implicit
type conversion
When an automatic type conversion a loss of data, it is good programming practice to perform an explicit type cast use of static_cast operator in C++ – Example:int IntVar;...IntVar = static_cast<int>(3.1413);
Coercion of function arguments
Assignment-style type coercions occur when a function argument value does not match the parameter type specified in the function definition – Example:
void SomeFn(int Param);...void main(void){
...
SomeFn(static_cast<int>(19.6));...
}
Coercion to type bool in relational expressions
In C++ the scalar data types are coerced to type bool in contexts where a bool value is expected – non-zero values are coerced to true – zero values are coerced to false – Example:
while (IntVar){ ...
}loop iterates while IntVar non-zero
Coercion to type boolConsider the following common
programming error:while (AInt = BInt)... // (1)
where the programmer’s intention was:while (AInt == BInt)...
– The programmer intended to write a loop which iterates while the value in AInt is equal to the value in BInt.
– the loop at (1) will iterate while BInt is non-zeroThe value of the assignment expression, AInt = BInt, is the value of BInt, which is automatically coerced to type bool.
Operations on C++ scalar data types
To specify the operations that can be performed on the values of C++ scalar data types, it is useful to group types: – Integral types are those data types
whose values are represented as integers by the C++ compiler. boolean, enumeration, integer and
character types, are all integral typesthe floating-point types are not integral
types
C++ Expressions
The table care must be exercised when writing C++ expressions: – use parentheses to document and
explicitly force intended operator evaluation order
– use explicit type casts to document type coercions which would cause a loss of data
Values of enumeration types as loop counter
variablesThe auto-increment/-decrement operators are
not defined for values of enumeration types an explicit type cast must be used on the
counter variable of a loop which iterates over the values of an enumeration type – Example:
enum TriColour {RED, WHITE, BLUE};TriColour ColCtr;
...for (ColCtr = RED; ColCtr <= BLUE;
ColCtr = static_cast<TriColour>(ColCtr + 1))...
Type void
Type void is a (previously unmentioned) pre-defined data type in C++– You will be familiar with the use of type void
as the return type of a function which does not return a value
Type void describes an empty set of values i.e. the absence of any data
No variable of type void can be defined in a C++ program
Composite data types
The composite (or structured) data types can be divided into 3 categories:– the array– the record (or structure)– the class
C++ provides facilities which allow the programmer to create more sophisticated types from the fundamental or built-in data types of the language.
typedef statement - Type aliasing in C++
The term typedef is misleading:– it seems to suggest a “type definition”
but the typedef statement does not define a new type
– it merely introduces an alias (another name) for an existing type
The general syntax for the typedef statement is:typedef ExistingTypeDescription AliasTypeName;
typedef statement - ExamplePrograms designed for portability might use
an alias, INT4, to define all integer objects which occupy 4 bytes of storage. – On systems which implement 4-byte integers,
the alias would be defined with: typedef int INT4;
– On systems which implement 2-byte integers, the alias would be defined with:
typedef long int INT4; – On both systems INT4 would be used to define
4-byte integer objects – Example:INT4 IntVar;
The C++ structure data type
The data values of record (structure) types, like those of the array, are composed of the values of other types. – unlike the array, the individual
components of a record type may be of different data types the record type is a more general
structure than the array typethis generality provides a powerful tool
for data abstraction
Defining a structure type - Example
Example – define a new data type to represent a person:
struct PersonType{
string name; int age;
}; – uses the keyword struct to define the new
structure (record) type, PersonType– the new data type has 2 components called fields: name of type string & age of type int
– the field definitions are enclosed in braces and the entire structure definition terminates with a semicolon
C++ structure typeHaving defined the new structure type,
objects of the type may be defined – Example:
PersonType APerson;
– defines and allocates storage for a variable, APerson, of type, PersonType
The fields of a structure type can be of:– built-in type– enumerated type or – composite type (i.e. array or structure
type).
C++ structure type - ExampleWe can, for example, augment our PersonType structure type with a field designating a person’s sex. – Since a person’s sex is either male or
female we could define an enumeration type:
enum SexType {MALE, FEMALE}; new PersonType definition:struct PersonType{
string name;int age;SexType sex;
};
Values of objects of type PersonType
The values of variables of type PersonType are composed of a string value, an int value and a SexType value– we could not list all values of the type but the
following schematic shows some possible instantiations:
Accessing the fields of structure-type objects
A field of a structure type object is accessed using the member access operator – the period symbol. The general format is:
StructureTypeObject.FieldName Examples:
PersonType TopOfClass; // initialise TopOfClass objectTopOfClass.name = "Jo Bloggs";// (1)TopOfClass.sex = FEMALE; // (2)TopOfClass.age = 44; // (3)...if (TopOfClass.sex == MALE)...
Fields of structure objects as function arguments
The data type of a field being passed as an argument to a function must be compatible with the data type of the corresponding function parameter. – Example: to pass the sex field of an object of type PersonType to a function, the corresponding function parameter must be compatible with type SexType:
PersonType Person; …// insert Male or Female in the default// output streamDisplaySex(Person.sex); …/cont’d
Fields of structure objects as function arguments -
Example// insert Male or Female in the default
// output stream
void DisplaySex(SexType s) // IN: MALE or
FEMALE
{if (s == MALE)
cout << "Male";else
cout << "Female";
}
Structure objects as function parameters
When passing entire structure objects as arguments to functions - the default parameter-passing mechanism in C++ is pass-by-value. – Example, for the function declaration:
SomeFunction(PersonType P); PersonType objects will be passed by value into the
parameter, P changes made to the fields of P in the function
body will be made on a local copy of P and the corresponding argument in the calling routine will remain unchanged by the function call
Passing structure objects by reference
To pass a structure object by reference, the parameter name must be preceded with the ampersand symbol. Example:
SomeFunction(PersonType &P);
More concrete example - definition of a function to get a person’s details from the user:
void GetPerson( PersonType &Person)
// OUT: PersonType: name, age, sex
{char Sex; // for m/f input
…/cont’d
Passing structure objects by reference - Example
cout << "Name ==> "; // prompt for nameReadString(Person.name);cout << endl;cout << "Age ==> "; // prompt for ageReadInteger(Person.age);cout << endl;cout << "Sex (m/f) ==> "; // prompt for sexReadChar(Sex); // (1)// if ‘m’ input set to MALE// any other input set to FEMALEif (Sex == ‘m’)
Person.sex = MALE;else
Person.sex = FEMALE;}
Building C++ data structures
The real power of the structure type is realised when used in conjunction with the array type.
For example, the base (element) type of an array can be a structure type. – To define an array of 100 PersonType
records:const int MAX_PEOPLE = 100; PersonType People[MAX_PEOPLE];
Accessing the fields of an array of records object
Individual fields of individual elements of this array can be accessed as, for example:// set the age field of the first element
// of the People array to 19People[0].age = 19;
// set the name field of the 20th element // of the People array to "Mo Jo" People[19].name = "Mo Jo"
Building C++ data structures
Not only can we have arrays of structure types, but fields of structure type objects can themselves be arrays. we can construct arbitrarily complex
data types– Example: to extend the PersonType record with
a field representing a person’s qualifications:assume that we need to store up to 5
qualifications for each personfor each qualification, assume we need to
store the qualification name and the year it was awarded
Building C++ data structures - Example
The qualification type could be defined with:
struct QualType{
string qualName;int yearAwarded;
}; The PersonType structure type can now
be extended to include an array of 5 QualType objects: …/cont’d
Building C++ data structures - Example
// max. no. of quals in a PersonType recordconst int MAX_QUALS = 5;
// alias for an array of MAX_QUALS QualType// recordstypedef QualType QUALS_ARRAY[MAX_QUALS]; //(1)
struct PersonType{string name;int age;SexType sex;QUALS_ARRAY quals; // array of MAX_QUALS
// qualifications};
Building C++ data structures - Example
Let us assume that we need to store the details for up to 100 people define an array of 100 PersonType records:const int MAX_PEOPLE = 100;PersonType People[MAX_PEOPLE]; storage allocated for 100 PersonType
records:
Building C++ data structures - Example
– code to get details for up to 100 people:for (int i = 0;
i < MAX_PEOPLE && !Finished; i++)
// get one person’s details;
// returns true if no more people // to be entered or array fullFinished = GetPerson(People[i]);
Building C++ data structures - Example
bool GetPerson( PersonType &Person){// Finished set true if user enters// END_OF_INPUT in response to name prompt bool Finished = false;char Sex; // store user entry ‘m’ or ‘f’
// prompt for namecout << "Name (0 when no more entries) ==> ";ReadString(Person.name);
if (Person.name == END_OF_INPUT)Finished = true; // end getting
detailselse // user did not enter END_OF_INPUT
…/Cont’d
Building C++ data structures - Example
{cout << "Age ==> ";// prompt for ageReadInteger(Person.age);cout << "Sex (m/f) ==> ";// prompt for sexReadChar(Sex);// if ‘m’ input set sex to MALE// any other input set sex to FEMALEif (Sex == ‘m’)
Person.sex = MALE;else
Person.sex = FEMALE;// get up to MAX_QUALS qualifications
GetQuals(Person.quals);}return Finished;// true if no more entries
}
Building C++ data structures - Example
// get qualifications from the uservoid GetQuals(QualType Quals[]){//set true when all qualifications enteredbool Finished = false;// loop until no more storage in the array// or all qualifications enteredfor (int i = 0; i < MAX_QUALS && !Finished; i++)
// get a qual., return true if no moreFinished = GetQual(Quals[i]);
if (Finished) // insert line before next person entry
cout << endl;}
Building C++ data structures - Example
// get a single qualification from userbool GetQual(QualType &Qual) {// true when END_OF_INPUT entered for name bool Finished = false;cout << "Qualification name (0 -> end) ==> ";ReadString(Qual.qualName);if (Qual.qualName == END_OF_INPUT)
Finished = true; // no more qualificationselse{
cout << "Year qualification awarded ==> ";ReadInteger(Qual.yearAwarded);
}// return true if no more qualificationsreturn Finished;
}