+ All Categories
Home > Documents > CHAPTER 5 User-Defined Functions

CHAPTER 5 User-Defined Functions

Date post: 23-Feb-2016
Category:
Upload: misu
View: 79 times
Download: 0 times
Share this document with a friend
Description:
CHAPTER 5 User-Defined Functions. Single-Result Functions Void Functions Nested Functions Overloaded Functions Name Scoping Recursive Functions. CHAPTER 5 – User-Defined Functions. 49. SINGLE-RESULT FUNCTIONS. ////////////////////////////////////////////////////// - PowerPoint PPT Presentation
67
CHAPTER 5 User-Defined Functions Single-Result Functions Void Functions Nested Functions Overloaded Functions Name Scoping Recursive Functions CHAPTER 5 – User-Defined Functions 1
Transcript
Page 1: CHAPTER 5 User-Defined Functions

CHAPTER 5User-Defined Functions

•Single-Result Functions•Void Functions•Nested Functions•Overloaded Functions•Name Scoping•Recursive Functions

CHAPTER 5 – User-Defined Functions 1

Page 2: CHAPTER 5 User-Defined Functions

CHAPTER 5 – User-Defined Functions 2

SINGLE-RESULT FUNCTIONS//////////////////////////////////////////////////////// This program retrieves dimensional box data from //// a user-specified input file and determines the //// maximum volume and the maximum surface area for //// all boxes with dimensions listed in the file. ////////////////////////////////////////////////////////

#include <iostream>#include <fstream>#include <string>using namespace std;

double volume(double length, double width, double height);double surfaceArea(double length, double width, double height);

// The main function queries the user for the input //// file name, opens the file, coordinates the retrieval //// of the dimensional data, and outputs the resulting //// maxima for volumes and surface areas. //void main(){ string boxDataFileName; ifstream boxDataFile; double dim1, dim2, dim3; double largestVolume = -1.0; double largestSurfaceArea = -1.0; double newVolume; double newSurfaceArea;

Note that two functions are defined (via prototypes) prior to the main function.

Each function accepts several values (parameters) for use within the function.Each function has a

declared type (in this case, double), meaning that it will return a value of this type to the location in the code where the function was called.

Page 3: CHAPTER 5 User-Defined Functions

CHAPTER 5 – User-Defined Functions 3

cout << "EXTREME BOX CALCULATOR" << endl << "----------------------" << endl; cout << "Enter the name of the file" << endl << "containing box dimension data: "; cin >> boxDataFileName; boxDataFile.open(boxDataFileName.c_str()); while (boxDataFile.fail()) { cout << endl << "NO FILE WITH THAT NAME LOCATED." << endl << "PLEASE TRY AGAIN WITH AN EXISTING FILE.” << endl << endl; cout << "Enter the name of the file" << endl << "containing box dimension data: "; cin >> boxDataFileName; boxDataFile.open(boxDataFileName.c_str()); }

boxDataFile >> dim1; while (!boxDataFile.eof()) { boxDataFile >> dim2 >> dim3; newVolume = volume(dim1, dim2, dim3); if (newVolume > largestVolume) largestVolume = newVolume; newSurfaceArea = surfaceArea(dim1, dim2, dim3); if (newSurfaceArea > largestSurfaceArea) largestSurfaceArea = newSurfaceArea; boxDataFile >> dim1; }

if ((newVolume < 0.0) || (newSurfaceArea < 0.0)) cout << endl << "NO LEGITIMATE BOX DIMENSIONS FOUND IN FILE"; else cout << endl << "Largest Box Volume: " << int(largestVolume) << " cubic units" << endl << "Largest Box Surface Area: " << int(largestSurfaceArea) << " square units"; cout << endl << endl; return;}

The volume function is called, with the values of the three variables dim1, dim2, and dim3 transmitted as arguments, as well as the assumption that the function will return a value of type double.

Similarly, the surfaceArea function is called.

Page 4: CHAPTER 5 User-Defined Functions

30.7 45.9 20.4 82.6 17.1 10.6 66.2 80.1 17.428.7 67 3 39.6 75.2 18.0 43.3 13.9 18.2 90.246.8 23.4 19.4 91.7 62.8 4.7 28.6 12.7 87.433.2 56.7 33.1 17.8 78.1 81.7 22.6 33.9 77.145.9 25.8 15.7 66.2 62.1 60.0 29.5 50.3 39.1

CHAPTER 5 – User-Defined Functions 4

// The volume function calculates and returns the volume of the //// box with the parameterized dimensions. It returns an invalid //// value if any dimension is determined to be invalid. //double volume(double length, double width, double height){ if ((length >= 0.0) && (width >= 0.0) && (height >= 0.0)) return (length * width * height); else return -1.0;}

// The surfaceArea function calculates and returns the surface //// of the box with the parameterized dimensions. It returns an //// invalid value if any dimension is determined to be invalid. //double surfaceArea(double length, double width, double height){ double frontArea = length * height; double sideArea = width * height; double topArea = length * width; if ((length >= 0.0) && (width >= 0.0) && (height >= 0.0)) return (2 * frontArea + 2 * sideArea + 2 * topArea); else return -1.0;}

The function header is identical to the prototype (except for the semicolon at the end of the prototype).

Since the functions are defined with type double they must return a value of that type (unlike the void main function).

Note that the parameters are treated as variables inside the function, and that the functions may have their own “local” variables as well.

Page 5: CHAPTER 5 User-Defined Functions

CHAPTER 5 – User-Defined Functions 5

VOID FUNCTIONS//////////////////////////////////////////////// This program computes the value to which //// a power series converges, and the number //// of iterations required before the series //// can be said to converge. ////////////////////////////////////////////////

#include <iostream>using namespace std;

double queryUserForValue();void computeSeries(double x, double &sum, int &nbrLoops);void outputResults(double result, int iterations);

// The main function coordinates the retrieval //// of the value to be used in the power series, //// the calculation of the series limit, and the //// output of the results. //void main(){ double number, convergentValue; int nbrIterations; number = queryUserForValue(); computeSeries(number, convergentValue, nbrIterations); outputResults(convergentValue, nbrIterations);}

When a function is not set up to return a single result, it is declared as a void function.Any parameter with an

ampersand (&) preceding its name is being “passed by reference”, meaning that the calling function and the called function are actually sharing that variable’s memory.Parameters

without ampersands preceding their names are “passed by value”, meaning that a copy of the calling function’s value is placed in a new variable in the called function.

Page 6: CHAPTER 5 User-Defined Functions

CHAPTER 5 – User-Defined Functions 6

// This function queries the user for the //// power series generator value, which must //// be strictly between 0 and 1. //double queryUserForValue(){ double nbr; cout << "Enter the number to be tested: "; cin >> nbr; while ((nbr <= 0.0) || (nbr >= 1.0)) { cout << "The number must be greater than 0 and less than 1." << endl << "Enter the number to be tested: "; cin >> nbr; } return nbr;}

// This function repeatedly adds the next power //// of the generator value to the series expansion, //// until two consecutive sums are equal, at which //// time the series is considered to converge. //void computeSeries(double x, double &sum, int &nbrLoops){ double powerOfX, previousSum = 0.0; nbrLoops = 0; sum = x; powerOfX = x; while (previousSum < sum) { nbrLoops++; previousSum = sum; powerOfX *= x; sum += powerOfX; }}

This function has one value that won’t be altered (x) and two that will (sum and nbrLoops). The first is passed by value while the other two are passed by reference.

Page 7: CHAPTER 5 User-Defined Functions

CHAPTER 5 – User-Defined Functions 7

// This function outputs the power series //// final value, as well as the number of //// iterations required to obtain it. //void outputResults(double result, int iterations){ cout.setf(ios::fixed); cout.setf(ios::showpoint); cout.precision(8); cout << "The series converges to " << result << " in " << iterations << " iterations." << endl << endl;}

To format floating-point output, the setf (using fixed for non-scientific notation and showpoint to always show the decimal point) and precision output functions are available.

Page 8: CHAPTER 5 User-Defined Functions

CHAPTER 5 – User-Defined Functions 8

NESTED FUNCTIONS////////////////////////////////////////////////////////////////// This program queries the user for the coefficients of a //// cubic polynomial and then uses ASCII characters to graph //// the polynomial in a user-specified range of the x-y plane. //////////////////////////////////////////////////////////////////

#include <iostream>#include <cmath>using namespace std;

void queryUserForCoefficients(double &coeff3, double &coeff2, double &coeff1, double &coeff0);double queryUserForCoefficient(int exponent);void queryUserForRange(char axisLabel, int &rangeMin, int &rangeMax);void graphCubic(int xMin, int xMax, int yMin, int yMax, double coeff3, double coeff2, double coeff1, double coeff0);void outputLabel(double coeff3, double coeff2, double coeff1, double coeff0);void outputCubicTerm(double coeff3);void outputQuadraticTerm(double coeff3, double coeff2);void outputLinearTerm(double coeff3, double coeff2, double coeff1);void outputConstantTerm(double coeff3, double coeff2, double coeff1, double coeff0);void outputStrip(int yVal, int xMin, int xMax, double coeff3, double coeff2, double coeff1, double coeff0);bool closePoint(int xVal, int yVal, double coeff3, double coeff2, double coeff1, double coeff0);

The main function is not the only function that can call other functions. Any function can be set up to do so!

Page 9: CHAPTER 5 User-Defined Functions

CHAPTER 5 – User-Defined Functions 9

// The main function supervises querying the user for the //// cubic's coefficients and the range to be used within the //// x-y plane, as well as the actual graphing of the cubic. //void main(){ double cubicCoeff, quadraticCoeff, linearCoeff, constantCoeff; int minXValue, maxXValue, minYValue, maxYValue;

queryUserForCoefficients(cubicCoeff, quadraticCoeff, linearCoeff, constantCoeff); queryUserForRange('x', minXValue, maxXValue); queryUserForRange('y', minYValue, maxYValue); graphCubic(minXValue, maxXValue, minYValue, maxYValue, cubicCoeff, quadraticCoeff, linearCoeff, constantCoeff);

return;}

// This function queries the user for four values that will be used //// as polynomial coefficients for the cubic that is being graphed. //void queryUserForCoefficients(double &coeff3, double &coeff2, double &coeff1, double &coeff0){ coeff3 = queryUserForCoefficient(3); coeff2 = queryUserForCoefficient(2); coeff1 = queryUserForCoefficient(1); coeff0 = queryUserForCoefficient(0); cout << endl; return;}

Page 10: CHAPTER 5 User-Defined Functions

CHAPTER 5 – User-Defined Functions 10

// This function queries the user for the coefficient of the term //// of the cubic polynomial that has the parameterized exponent. //double queryUserForCoefficient(int exponent){ double coeff;

cout << "Enter the coefficient of the "; switch (exponent) { case 3: { cout << "cubic"; break; } case 2: { cout << "quadratic"; break; } case 1: { cout << "linear"; break; } default: { cout << "constant"; break; } } cout << " term of the polynomial: "; switch (exponent) { case 3: { cout << " "; break; } case 1: { cout << " "; break; } case 0: { cout << " "; break; } } cin >> coeff;

return coeff;}

Page 11: CHAPTER 5 User-Defined Functions

CHAPTER 5 – User-Defined Functions 11

// This function queries the user for the minimum and maximum //// values for the specified axis. These values will be used //// to limit the range of the graphing of the cubic polynomial. //void queryUserForRange(char axisLabel, int &rangeMin, int &rangeMax){ cout << "Enter the range of " << axisLabel << "-values to be used in the graph." << endl; cout << "Minimum " << axisLabel << "-value: "; cin >> rangeMin; cout << "Maximum " << axisLabel << "-value: "; cin >> rangeMax; cout << endl; while (rangeMin >= rangeMax) { cout << "INAPPROPRIATE RANGE --- MAXIMUM MUST BE GREATER THAN MINIMUM." << endl; cout << "Enter the range of " << axisLabel << "-values to be used in the graph." << endl; cout << "Minimum " << axisLabel << "-value: "; cin >> rangeMin; cout << "Maximum " << axisLabel << "-value: "; cin >> rangeMax; cout << endl; } return;}

Page 12: CHAPTER 5 User-Defined Functions

CHAPTER 5 – User-Defined Functions 12

// This function uses ASCII characters to graph the cubic polynomial //// with the parameterized coefficients within the parameterized range. //// Where appropriate, characters representing the axes will be output. //void graphCubic(int xMin, int xMax, int yMin, int yMax, double coeff3, double coeff2, double coeff1, double coeff0){ int yVal = yMax; outputLabel(coeff3, coeff2, coeff1, coeff0); while (yVal >= yMin) { outputStrip(yVal, xMin, xMax, coeff3, coeff2, coeff1, coeff0); yVal--; } cout << endl << endl; return;}

// This function outputs the label identifying the //// precise cubic polynomial that is being graphed. //void outputLabel(double coeff3, double coeff2, double coeff1, double coeff0){ cout.setf(ios::fixed); cout.setf(ios::showpoint); cout.precision(3); cout << endl << "GRAPH OF f(x) = "; outputCubicTerm(coeff3); outputQuadraticTerm(coeff3, coeff2); outputLinearTerm(coeff3, coeff2, coeff1); outputConstantTerm(coeff3, coeff2, coeff1, coeff0); cout << endl << endl; return;}

Page 13: CHAPTER 5 User-Defined Functions

CHAPTER 5 – User-Defined Functions 13

// This function outputs the cubic term of the polynomial //// being graphed, with special cases for cubic coefficient //// values of 0 (no output), 1 (no displayed coefficient), //// or -1 (a negative sign, but no displayed coefficient). //void outputCubicTerm(double coeff3){ if (coeff3 != 0.0) { if (coeff3 == -1.0) cout << '-'; else if (coeff3 != 1.0) cout << coeff3; cout << "x^3"; } return;}

// This function outputs the quadratic term of the polynomial //// being graphed, with special cases for quadratic coefficient //// values of 0 (no output), 1 (no displayed coefficient), or //// -1 (a negative sign, but no displayed coefficient). //void outputQuadraticTerm(double coeff3, double coeff2){ if (coeff2 != 0.0) { if (coeff3 != 0.0) { if (coeff2 < 0.0) { cout << " - "; coeff2 *= -1; } else cout << " + "; } if (coeff2 != 1.0) cout << coeff2; cout << "x^2"; } return;}

Page 14: CHAPTER 5 User-Defined Functions

CHAPTER 5 – User-Defined Functions 14

// This function outputs the linear term of the polynomial //// being graphed, with special cases for linear coefficient //// values of 0 (no output), 1 (no displayed coefficient), //// or -1 (a negative sign, but no displayed coefficient). //void outputLinearTerm(double coeff3, double coeff2, double coeff1){ if (coeff1 != 0.0) { if ((coeff3 != 0.0) || (coeff2 != 0.0)) { if (coeff1 < 0.0) { cout << " - "; coeff1 *= -1; } else cout << " + "; } if (coeff1 != 1.0) cout << coeff1; cout << "x"; } return;}

Page 15: CHAPTER 5 User-Defined Functions

CHAPTER 5 – User-Defined Functions 15

// This function outputs the constant term of the polynomial //// being graphed, with special cases for constant coefficient //// values of 0 (no output, unless there are no other terms in //// the polynomial) or nonzero (output the constant, prefaced //// with the appropriate mathematical operator if there are //// other terms in the polynomial). //void outputConstantTerm(double coeff3, double coeff2, double coeff1, double coeff0){ if (coeff0 == 0.0) { if ((coeff3 == 0) && (coeff2 == 0) && (coeff1 == 0)) cout << coeff0; } else { if ((coeff3 != 0.0) || (coeff2 != 0.0) || (coeff1 != 0.0)) { if (coeff0 < 0.0) cout << " - " << (-1 * coeff0); else cout << " + " << coeff0; } else cout << coeff0; } return;}

Page 16: CHAPTER 5 User-Defined Functions

CHAPTER 5 – User-Defined Functions 16

// This function outputs the horizontal strip of characters //// representing the graph at a particular y-value, with a //// asterisks used to represent the graph itself, vertical //// bars, dashes, and plus signs used to represent the axes, //// and blanks used for all empty space. //void outputStrip(int yVal, int xMin, int xMax, double coeff3, double coeff2, double coeff1, double coeff0){ int xVal = xMin; while (xVal <= xMax) { if (closePoint(xVal, yVal, coeff3, coeff2, coeff1, coeff0)) cout << '*'; else if ((xVal == 0) && (yVal == 0)) cout << '+'; else if (xVal == 0) cout << '|'; else if (yVal == 0) cout << '-'; else cout << ' '; xVal++; } cout << endl; return;}

// This function evaluates the cubic polynomial with //// the parameterized coefficients at the parameterized //// x-value, and determines whether the resulting y-value //// (after round-off) equals the parameterized y-value. //bool closePoint(int xVal, int yVal, double coeff3, double coeff2, double coeff1, double coeff0){ double actualY = coeff3 * pow(double(xVal), 3) + coeff2 * pow(double(xVal), 2) + coeff1 * xVal + coeff0; return (int(actualY) == yVal);}

Page 17: CHAPTER 5 User-Defined Functions

CHAPTER 5 – User-Defined Functions 17

Page 18: CHAPTER 5 User-Defined Functions

CHAPTER 5 – User-Defined Functions 18

OVERLOADED FUNCTIONS

///////////////////////////////////////////////////////////////////// This program demonstrates overloaded functions be utilizing //// two versions of the dot product function, one taking vectors //// of double coordinates and the other taking vectors of integer //// coordinates. /////////////////////////////////////////////////////////////////////

#include <iostream>using namespace std;

bool isInt(double value);double dotProduct(double x1, double y1, double x2, double y2);int dotProduct(int x1, int y1, int x2, int y2);char askForMore();bool answerIsYes(char ltr);bool answerIsNo(char ltr);

A program may have multiple functions with the same name, as long as the compiler can distinguish between them and determine which one is actually being called.This is normally accomplished by using different parameter lists (either by using a different number of parameters or different parameter types).

Page 19: CHAPTER 5 User-Defined Functions

CHAPTER 5 – User-Defined Functions 19

// The main function coordinates the user queries //// and the output of dot product results. //void main(){ double firstX, firstY, secondX, secondY; char yOrN = 'y'; while ( answerIsYes(yOrN) ) { cout << "Enter the coordinates for the first vector: "; cin >> firstX >> firstY; cout << "Enter the coordinates for the second vector: "; cin >> secondX >> secondY; if ( isInt(firstX) && isInt(firstY) && isInt(secondX) && isInt(secondY) ) cout << dotProduct( int(firstX), int(firstY), int(secondX), int(secondY) ); else cout << dotProduct( firstX, firstY, secondX, secondY ); cout << endl << endl; yOrN = askForMore(); } return;}

// Returns a boolean flag indicating whether the //// parameterized double value has no fractional component. //bool isInt(double value){ return ( value - int(value) == 0.0 );}

Page 20: CHAPTER 5 User-Defined Functions

CHAPTER 5 – User-Defined Functions 20

// Returns the dot product of two vectors of double values. //double dotProduct(double x1, double y1, double x2, double y2){ return (x1 * x2 + y1 * y2);}

// Returns the dot product of two vectors of integer values. //int dotProduct(int x1, int y1, int x2, int y2){ return (x1 * x2 + y1 * y2);}

// Queries the user for whether more dot product calculations are needed, //// compelling the user to respond with an appropriate character. //char askForMore(){ char letter; cout << "Would you like to take another dot product? (Y or N) "; cin >> letter; while ( (!answerIsYes(letter)) && (!answerIsNo(letter)) ) { cout << "You must respond with the letter Y or the letter N!" << endl; cout << "Would you like to take another dot product? (Y or N) "; cin >> letter; } return letter;}

Page 21: CHAPTER 5 User-Defined Functions

CHAPTER 5 – User-Defined Functions 21

// Returns a boolean flag indicating whether the parameterized //// character is the first letter of the word "yes". //bool answerIsYes(char ltr){ return ( (ltr == 'y') || (ltr == 'Y') );}

// Returns a boolean flag indicating whether the parameterized //// character is the first letter of the word "no". //bool answerIsNo(char ltr){ return ( (ltr == 'n') || (ltr == 'N') );}

Page 22: CHAPTER 5 User-Defined Functions

CHAPTER 5 – User-Defined Functions 22

NAME SCOPING/////////////////////////////////////////////////////////// This program reads date information from a specific //// text file, determining the percentage of dates in //// that file that utilize each of the twelve months. ///////////////////////////////////////////////////////////#include <iostream>#include <fstream>using namespace std;

int countData();int countData(int month);

// The main function supervises //// the retrieval of the date //// information and formats the //// program's output. //void main(){ int month; int total; int count; double percent;

total = countData(); cout << " DATE FILE DATA ANALYSIS" << endl << " -----------------------" << endl; cout.setf(ios::fixed); cout.setf(ios::showpoint); cout.precision(4); for (month = 1; month <= 12; month++) { count = countData(month); percent = 100.0 * count / total; if (percent < 10.0) cout << " "; else if (percent < 100.0) cout << " "; cout << percent << "% of the dates are " << "from month #" << month << endl; } cout << endl << endl; return;}

Variable names are “local” to the function in which they are declared.

Thus, the same variable names may be used independently in separate functions.

Page 23: CHAPTER 5 User-Defined Functions

CHAPTER 5 – User-Defined Functions 23

// This function opens the date data file and counts //// the total number of dates contained therein. //int countData(){ int count = 0; int month, day, year; ifstream dateFile;

dateFile.open("dates.txt"); dateFile >> month; while ( !dateFile.eof() ) { dateFile >> day >> year; count++; dateFile >> month; } dateFile.close();

return count;}

// This function opens the date data file and counts //// the total number of dates contained therein that //// utilize the parameterized month. //int countData(int month){ int count = 0; int thisMonth, day, year; ifstream dateFile;

dateFile.open("dates.txt"); dateFile >> thisMonth; while ( !dateFile.eof() ) { dateFile >> day >> year; if (thisMonth == month) count++; dateFile >> thisMonth } dateFile.close();

return count;}

Like main, both functions have local variables names count and month.

The values of each function’s versions of count and month are completely independent of each other!

9 17 192911 22 1930 4 4 1934 2 27 1936 7 4 1936 8 3 1938 2 16 194010 16 1941 5 4 1943 7 11 1944 2 20 1945 1 27 1946 6 30 1947 4 11 1948 8 29 194911 19 195012 3 1952 5 13 195310 31 1956 9 12 195712 25 1958 1 12 1961 6 10 1962 6 12 1962 3 20 196511 5 1967 8 2 196912 9 1972 1 30 1974 7 17 197612 12 1978 2 20 1980 3 27 1982 3 12 198411 7 1985 5 14 1986 9 22 198612 3 1986 5 12 1987 2 1 1988 5 16 1988 8 27 1990 7 20 199112 28 1993 8 21 1994 2 10 1996 9 13 1997

Page 24: CHAPTER 5 User-Defined Functions

CHAPTER 5 – User-Defined Functions 24

RECURSIVE FUNCTIONS//////////////////////////////////////////////////////// This program repeatedly asks the user for //// non-negative integer values and then recursively //// converts them into hexadecimal (base 16). ////////////////////////////////////////////////////////#include <iostream>using namespace std;

int retrieveValue();void convertToHexadecimal(int value);char hexDigit(int digit);bool queryForMore();

// The main function supervises the retrieval of data from// the user, the conversion of that data to hexadecimal,// and the determination of when the user is finished.void main(){ int userValue; bool stillActive = true;

while (stillActive) { userValue = retrieveValue(); cout << "HEXADECIMAL FORM OF " << userValue << " IS "; convertToHexadecimal(userValue); cout << endl << endl; stillActive = queryForMore(); } return;}

Not only are functions able to call other functions, they can also call themselves.

Page 25: CHAPTER 5 User-Defined Functions

CHAPTER 5 – User-Defined Functions 25

// This function queries the user until supplied// with a non-negative integer value.int retrieveValue(){ int integerValue; cout << "Please enter a non-negative integer: "; cin >> integerValue; while (integerValue < 0) { cout << endl << "Try again, The value must be non-negative: "; cin >> integerValue; } cout << endl; return integerValue;}

// This function repeatedly divides the parameterized value by 16,// recursively converting the quotient into hexadecimal, followed // by outputting the remainder (an integer between 0 and 15) into // a single hexadecimal digit, which is output to the screen.void convertToHexadecimal(int value){ if (value < 16) cout << hexDigit(value); else { convertToHexadecimal(value / 16); cout << hexDigit(value % 16); }}

Essentially, recursive functions take a divide-and-conquer approach.The large task being attempted is completed by breaking it down into a smaller version of itself.This approach is continued until the task gets small enough to resolve without breaking it down any further.

Page 26: CHAPTER 5 User-Defined Functions

CHAPTER 5 – User-Defined Functions 26

// This function converts the parameterized integer value (assumed// to between 0 and 15) into the corresponding hexadecimal digit.// The hexadecimal digit is returned as a character value.char hexDigit(int digit){ switch (digit) { case 10: { return 'A'; break; } case 11: { return 'B'; break; } case 12: { return 'C'; break; } case 13: { return 'D'; break; } case 14: { return 'E'; break; } case 15: { return 'F'; break; } default: { return char(digit + int('0')); break; } }}

// This function queries the user about additional input// until an appropriate character is entered,bool queryForMore(){ char queryResponse; cout << "Would you like to convert another integer? (Y or N) "; cin >> queryResponse; while ( (queryResponse != 'y') && (queryResponse != 'Y') && (queryResponse != 'n') && (queryResponse != 'N') ) { cout << "You must enter Y for Yes or N for No." << endl << endl << "Would you like to convert another integer? (Y or N) "; cin >> queryResponse; } cout << endl; return ( (queryResponse == 'y') || (queryResponse == 'Y') );}

Page 27: CHAPTER 5 User-Defined Functions

CHAPTER 6 – Data Structures and Objects 27

CHAPTER 6Data Structures and Objects

•Structures•Classes•Constructors•Accessors and Mutators•Overloaded Operators•Class Reuse

Page 28: CHAPTER 5 User-Defined Functions

CHAPTER 6 – Data Structures and Objects 28

STRUCTURES///////////////////////////////////////////////// This program queries the user for a //// chemical element and accesses an external //// file to retrieve data about that element. /////////////////////////////////////////////////

#include <iostream>#include <fstream>#include <string>using namespace std;

struct Element{ int AtomicNumber; string Name; string Symbol; string ChemicalSeries; int Level1Electrons; int Level2Electrons; int Level3Electrons; int Level4Electrons; int Level5Electrons; int Level6Electrons; int Level7Electrons;};

Element queryUserForElement();Element searchByAtomicNumber(ifstream &file);Element searchByAtomicSymbol(ifstream &file);void outputElement(Element elt);

Placing related variables into a single entity, a structure, may simplify the programming process by limiting how many parameters are needed for some functions.Once defined, the

new structure may be used as a

parameter for a function or as a

function’s return type.

Page 29: CHAPTER 5 User-Defined Functions

CHAPTER 6 – Data Structures and Objects 29

// The main function outputs a header and then supervises// the user query and the output of information about the// user-specified chemical element.void main(){ Element elem; cout << "CHEMICAL ELEMENT DATA FINDER" << endl; cout << "----------------------------" << endl; elem = queryUserForElement(); outputElement(elem); cout << endl << endl; return;}

// This function coordinates the user query by first// determining whether the user wants to find the// chemical element by specifying its atomic number// or by specifying its atomic symbol.Element queryUserForElement(){ Element elmnt; char searchChar; ifstream ElementFile; ElementFile.open("Elements.txt"); cout << "Enter # to search by atomic number," << endl << "anything else to search by atomic symbol: "; cin >> searchChar; if (searchChar == '#') elmnt = searchByAtomicNumber(ElementFile); else elmnt = searchByAtomicSymbol(ElementFile); ElementFile.close(); return elmnt;}

Page 30: CHAPTER 5 User-Defined Functions

CHAPTER 6 – Data Structures and Objects 30

// This function searches the parameterized input file for// a user-specified atomic number, returning the Element// that matches (or forcing the user to enter another// atomic number if the previous one was invalid).Element searchByAtomicNumber(ifstream &file){ int aNbr; int index; Element e; cout << "Enter the atomic number of the element being sought: "; cin >> aNbr; while ( (aNbr <= 0) || (aNbr > 118) ) { cout << "Atomic numbers are limited to the 1-118 range." << endl << "Please try again: "; cin >> aNbr; } for (index = 1; index <= aNbr; index++) { file >> e.AtomicNumber; file >> e.Name; file >> e.Symbol; file >> e.ChemicalSeries; file >> e.Level1Electrons; file >> e.Level2Electrons; file >> e.Level3Electrons; file >> e.Level4Electrons; file >> e.Level5Electrons; file >> e.Level6Electrons; file >> e.Level7Electrons; } return e;}

Page 31: CHAPTER 5 User-Defined Functions

CHAPTER 6 – Data Structures and Objects 31

// This function searches the parameterized input file for// a user-specified atomic symbol, returning the Element// that matches (or forcing the user to enter another// atomic symbol if the previous one was invalid).Element searchByAtomicSymbol(ifstream &file){ bool foundElement = false; int aNbr; string aSym; Element e; cout << "Enter the atomic symbol of the element being sought: "; cin >> aSym; do { aNbr = 0; while ( (aNbr < 118) && (!foundElement) ) { aNbr++; file >> e.AtomicNumber; file >> e.Name; file >> e.Symbol; file >> e.ChemicalSeries; file >> e.Level1Electrons; file >> e.Level2Electrons; file >> e.Level3Electrons; file >> e.Level4Electrons; file >> e.Level5Electrons; file >> e.Level6Electrons; file >> e.Level7Electrons; foundElement = (e.Symbol == aSym); }

if (!foundElement) { cout << "The symbol you entered (" << aSym << ") is invalid." << endl << "Please try again: "; cin >> aSym; file.close(); file.open("Elements.txt"); } } while (!foundElement); return e;}

Page 32: CHAPTER 5 User-Defined Functions

CHAPTER 6 – Data Structures and Objects 32

// This function outputs the data associated with the parameterized chemical element.void outputElement(Element elt){ cout << endl << "Information about the element " << elt.Name << ":" << endl; cout << " Atomic Number: " << elt.AtomicNumber << endl; cout << " Atomic Symbol: " << elt.Symbol << endl; cout << " Chemical Series: " << elt.ChemicalSeries << endl; cout << "# Level 1 Electrons: " << elt.Level1Electrons << endl; if (elt.Level2Electrons > 0) { cout << "# Level 2 Electrons: " << elt.Level2Electrons << endl; if (elt.Level3Electrons > 0) { cout << "# Level 3 Electrons: " << elt.Level3Electrons << endl; if (elt.Level4Electrons > 0) { cout << "# Level 4 Electrons: " << elt.Level4Electrons << endl; if (elt.Level5Electrons > 0) { cout << "# Level 5 Electrons: " << elt.Level5Electrons << endl; if (elt.Level6Electrons > 0) { cout << "# Level 6 Electrons: " << elt.Level6Electrons << endl; if (elt.Level7Electrons > 0) cout << "# Level 7 Electrons: " << elt.Level7Electrons << endl; } } } } } return;}

Page 33: CHAPTER 5 User-Defined Functions

CHAPTER 6 – Data Structures and Objects 33

1HydrogenHNonmetal1 0 0 0 0 0 02HeliumHeNobleGas2 0 0 0 0 0 03LithiumLiAlkaliMetal2 1 0 0 0 0 04BerylliumBeAlkalineEarthMetal2 2 0 0 0 0 05BoronBMetalloid2 3 0 0 0 0 06CarbonCNonmetal2 4 0 0 0 0 07NitrogenNNonmetal2 5 0 0 0 0 08OxygenONonmetal2 6 0 0 0 0 09FluorineFHalogen2 7 0 0 0 0 010NeonNeNobleGas2 8 0 0 0 0 011SodiumNaAlkaliMetal2 8 1 0 0 0 012MagnesiumMgAlkalineEarthMetal2 8 2 0 0 0 013AluminiumAlPoorMetal2 8 3 0 0 0 014SiliconSiMetalloid2 8 4 0 0 0 015PhosphorusPNonmetal2 8 5 0 0 0 016SulfurSNonmetal2 8 6 0 0 0 017ChlorineClHalogen2 8 7 0 0 0 018ArgonArNobleGas2 8 8 0 0 0 019PotassiumKAlkaliMetal2 8 8 1 0 0 020CalciumCaAlkalineEarthMetal2 8 8 2 0 0 021ScandiumScTransitionMetal2 8 9 2 0 0 022TitaniumTiTransitionMetal2 8 10 2 0 0 023VanadiumVTransitionMetal2 8 11 2 0 0 024ChromiumCrTransitionMetal2 8 13 1 0 0 025ManganeseMnTransitionMetal2 8 13 2 0 0 026IronFeTransitionMetal2 8 14 2 0 0 027CobaltCoTransitionMetal2 8 15 2 0 0 028NickelNiTransitionMetal2 8 16 2 0 0 029CopperCuTransitionMetal2 8 18 1 0 0 030ZincZnTransitionMetal2 8 18 2 0 0 031GalliumGaPoorMetal2 8 18 3 0 0 032GermaniumGeMetalloid2 8 18 4 0 0 033ArsenicAsMetalloid2 8 18 5 0 0 034SeleniumSeNonmetal2 8 18 6 0 0 035BromineBrHalogen2 8 18 7 0 0 036KryptonKrNobleGas2 8 18 8 0 0 037RubidiumRbAlkaliMetal2 8 18 8 1 0 038StrontiumSrAlkalineEarthMetal2 8 18 8 2 0 039YttriumYTransitionMetal2 8 18 9 2 0 040ZirconiumZrTransitionMetal2 8 18 10 2 0 041NiobiumNbTransitionMetal2 8 18 12 1 0 042MolybdenumMoTransitionMetal2 8 18 13 1 0 043TechnetiumTcTransitionMetal2 8 18 14 1 0 044RutheniumRuTransitionMetal2 8 18 15 1 0 045RhodiumRhTransitionMetal2 8 18 16 1 0 046PalladiumPdTransitionMetal2 8 18 18 0 0 047SilverAgTransitionMetal2 8 18 18 1 0 048CadmiumCdTransitionMetal2 8 18 18 2 0 049IndiumInPoorMetal2 8 18 18 3 0 050TinSnPoorMetal2 8 18 18 4 0 051AntimonySbMetalloid2 8 18 18 5 0 052TelluriumTeMetalloid2 8 18 18 6 0 053IodineIHalogen2 8 18 18 7 0 054XenonXeNobleGas2 8 18 18 8 0 055CaesiumCsAlkaliMetal2 8 18 18 8 1 056BariumBaAlkalineEarthMetal2 8 18 18 8 2 057LanthanumLaLanthanide2 8 18 18 9 2 058CeriumCeLanthanide2 8 18 19 9 2 059PraseodymiumPrLanthanide2 8 18 21 8 2 060NeodymiumNdLanthanide2 8 18 22 8 2 061PromethiumPmLanthanide2 8 18 23 8 2 062SamariumSmLanthanide2 8 18 24 8 2 063EuropiumEuLanthanide2 8 18 25 8 2 064GadoliniumGdLanthanide2 8 18 25 9 2 065TerbiumTbLanthanide2 8 18 27 8 2 066DysprosiumDyLanthanide2 8 18 28 8 2 067HolmiumHoLanthanide2 8 18 29 8 2 068ErbiumErLanthanide2 8 18 30 8 2 069ThuliumTmLanthanide2 8 18 31 8 2 070YtterbiumYbLanthanide2 8 18 32 8 2 071LutetiumLuLanthanide2 8 18 32 9 2 072HafniumHfTransitionMetal2 8 18 32 10 2 073TantalumTaTransitionMetal2 8 18 32 11 2 074TungstenWTransitionMetal2 8 18 32 12 2 075RheniumReTransitionMetal2 8 18 32 13 2 076OsmiumOsTransitionMetal2 8 18 32 14 2 077IridiumIrTransitionMetal2 8 18 32 15 2 078PlatinumPtTransitionMetal2 8 18 32 17 1 079GoldAuTransitionMetal2 8 18 32 18 1 080MercuryHgTransitionMetal2 8 18 32 18 2 081ThalliumTlPoorMetal2 8 18 32 18 3 082LeadPbPoorMetal2 8 18 32 18 4 083BismuthBiPoorMetal2 8 18 32 18 5 084PoloniumPoMetalloid2 8 18 32 18 6 085AstatineAtHalogen2 8 18 32 18 7 086RadonRnNobleGas2 8 18 32 18 8 087FranciumFrAlkaliMetal2 8 18 32 18 8 188RadiumRaAlkalineEarthMetal2 8 18 32 18 8 289ActiniumAcActinide2 8 18 32 18 9 290ThoriumThActinide2 8 18 32 18 10 291ProtactiniumPaActinide2 8 18 32 20 9 292UraniumUActinide2 8 18 32 21 9 293NeptuniumNpActinide2 8 18 32 22 9 294PlutoniumPuActinide2 8 18 32 24 8 295AmericiumAmActinide2 8 18 32 25 8 296CuriumCmActinide2 8 18 32 25 9 297BerkeliumBkActinide2 8 18 32 27 8 298CaliforniumCfActinide2 8 18 32 28 8 299EinsteiniumEsActinide2 8 18 32 29 8 2100FermiumFmActinide2 8 18 32 30 8 2101MendeleviumMdActinide2 8 18 32 31 8 2102NobeliumNoActinide2 8 18 32 32 8 2103LawrenciumLrActinide2 8 18 32 32 9 2104RutherfordiumRfTransitionMetal2 8 18 32 32 10 2105DubniumDbTransitionMetal2 8 18 32 32 11 2106SeaborgiumSgTransitionMetal2 8 18 32 32 12 2107BohriumBhTransitionMetal2 8 18 32 32 13 2108HassiumHsTransitionMetal2 8 18 32 32 14 2109MeitneriumMtTransitionMetal2 8 18 32 32 15 2110DarmstadtiumDsTransitionMetal2 8 18 32 32 16 2111RoentgeniumRgTransitionMetal2 8 18 32 32 17 2112UnunbiumUubTransitionMetal2 8 18 32 32 18 2113UnuntriumUutPoorMetal2 8 18 32 32 18 3114UnunquadiumUuqPoorMetal2 8 18 32 32 18 4115UnunpentiumUupPoorMetal2 8 18 32 32 18 5116UnunhexiumUuhPoorMetal2 8 18 32 32 18 6117UnunseptiumUusHalogen2 8 18 32 32 18 7118UnunoctiumUuoNobleGas2 8 18 32 32 18 8

Page 34: CHAPTER 5 User-Defined Functions

CHAPTER 6 – Data Structures and Objects 34

CLASSESClasses are used to implement the object-oriented programming feature of encapsulation, by which the details of how the data of the class is structured and how it operates are hidden from code outside of the class.

Data Members

Constructors Accessors Member

Functions

Each class is a collection of members:• Data members are the data

components of the class, usually marked as private to prevent direct access from outside of the class.• Constructors are the mechanism by which new variables of the type defined by the class can be declared, marked as public to allow access from outside of the class.• Accessors are the public mechanism by which code outside of the class is allowed to have indirect access to the data members.• Member functions are operations that are defined within the class, some of which may be public and some of which may be private.

Page 35: CHAPTER 5 User-Defined Functions

CHAPTER 6 – Data Structures and Objects 35

/////////////////////////////////////////////////// This program generates the data for circles //// and then draws them using ASCII characters. ///////////////////////////////////////////////////#include <iostream>#include <cmath>using namespace std;

const double PI = 3.1416;const int PADDING = 3;const int ASCII_ZERO_VALUE = 48;

class Circle{ public: // Constructor Circle();

// Member functions void setCoordinates(int x, int y); void setRadius(int r); void setASCIICharacter(char ch); double computeArea(); double computePerimeter(); void displayCircleAttributes(); void drawCircle();

// Accessor functions int getXCoord() const; int getYCoord() const; int getRadius() const; char getASCIICharacter() const;

private: // Data members int xCoord; int yCoord; int radius; char asciiCharacter;};

// This default constructor sets up the //// data members with default values. //Circle::Circle(){ xCoord = yCoord = radius = 0; asciiCharacter = ' ';}

// Assign the x- and y- coordinates of the //// circle's center with parameterized values. //void Circle::setCoordinates(int x, int y){ xCoord = x; yCoord = y; return;}

// Assign the radius of the circle //// the parameterized value. //void Circle::setRadius(int r){ radius = r; return;}

Page 36: CHAPTER 5 User-Defined Functions

CHAPTER 6 – Data Structures and Objects 36

// Assign the fill character of the //// circle the parameterized value. //void Circle::setASCIICharacter(char ch){ asciiCharacter = ch; return;}

// Compute and return the area of the circle. //double Circle::computeArea(){ return PI * radius * radius;}

// Compute and return the perimeter of the circle. //double Circle::computePerimeter(){ return 2 * PI * radius;}

// Output the circle's data member values, as //// well as the area and perimeter of the Circle. //void Circle::displayCircleAttributes(){ cout.setf(ios::fixed); cout.precision(4); cout << "Center's x-coordinate: " << xCoord << endl; cout << "Center's y-coordinate: " << yCoord << endl; cout << "Circle's radius: " << radius << endl; cout << "Circle's area: " << computeArea() << endl; cout << "Circle's perimeter: " << computePerimeter() << endl; cout << "Circle's fill character: " << asciiCharacter << endl;}

Notice the use of the class name followed by the scope resolution operator (::) just before the name of the member function.This is needed whenever the definition of the member function is outside of the declaration of the class.

Page 37: CHAPTER 5 User-Defined Functions

CHAPTER 6 – Data Structures and Objects 37

// Output the Circle, using its ASCII character to draw it, //// as well as vertical and horizontal symbols to draw the //// coordinate axes, and an 'X' at the center of the circle. //void Circle::drawCircle(){ const int PADDING = 4; const double HEIGHT_WIDTH_RATIO = 1.5; int x, y; int lowerX = (xCoord - radius < -PADDING) ? (xCoord - radius-PADDING) : -PADDING; int upperX = (xCoord + radius > PADDING) ? (xCoord + radius+PADDING) : PADDING; int lowerY = (yCoord - radius < -PADDING) ? (yCoord - radius-PADDING) : -PADDING; int upperY = (yCoord + radius > PADDING) ? (yCoord + radius+PADDING) : PADDING; for (y = upperY; y >= lowerY; y--) { for (x = int(HEIGHT_WIDTH_RATIO*lowerX); x <= int(HEIGHT_WIDTH_RATIO*upperX); x++) { if ((x == xCoord) && (y == yCoord)) cout << 'X'; else if (pow((x - xCoord) / HEIGHT_WIDTH_RATIO, 2) + pow(double(y - yCoord), 2) <= pow(double(radius), 2)) cout << asciiCharacter; else if ((x == 0) && (y == 0)) cout << '+'; else if (x == 0) cout << '|'; else if (y == 0) cout << '-'; else cout << ' '; } cout << endl; }}

Notice the use of the conditional operators (? :) when setting the upper and lower values.

Page 38: CHAPTER 5 User-Defined Functions

CHAPTER 6 – Data Structures and Objects 38

// Access and return the Circle's x-coordinate value. //int Circle::getXCoord() const{ return xCoord;}

// Access and return the Circle's y-coordinate value. //int Circle::getYCoord() const{ return yCoord;}

// Access and return the value of the Circle's radius. //int Circle::getRadius() const{ return radius;}

// Access and return the value of the Circle's ASCII fill character. //char Circle::getASCIICharacter() const{ return asciiCharacter;}

The const modifier may be used to guarantee that the accessor is not allowed to alter the values of any of the data members in the class.

Page 39: CHAPTER 5 User-Defined Functions

CHAPTER 6 – Data Structures and Objects 39

//////////////////////////////////////////////////////////////////// The main function serves as a driver to display a variety of //// circles with a variety of sizes, positions, and characters. ////////////////////////////////////////////////////////////////////void main(){ Circle circ; char YorN; int count = 1; int positionX = 4; int positionY = 2; cout << "Ready for the first circle? (Enter Y or N) "; cin >> YorN; while ((YorN == 'y') || (YorN == 'Y')) { circ.setASCIICharacter(char(ASCII_ZERO_VALUE + count)); circ.setRadius(count + 3); circ.setCoordinates(positionX,positionY); circ.displayCircleAttributes(); circ.drawCircle(); cout << "Ready for another circle? (Enter Y or N) "; cin >> YorN; count++; positionX = (positionX + 11) % 13; positionY = (positionY + 13) % 11; }

return;}

Page 40: CHAPTER 5 User-Defined Functions

CHAPTER 6 – Data Structures and Objects 40

Page 41: CHAPTER 5 User-Defined Functions

CHAPTER 6 – Data Structures and Objects 41

ENCAPSULATION///////////////////////////////////////////////////////////////////////////////////////////////// This header file contains the full definition of the Quadratic class, including //// constructors (default, initializing, and copy), accessors ("get" member functions for all //// data members), mutators ("set" member functions for all data members), and other member //// functions (evaluation, root determination, derivative, and input and output operators). /////////////////////////////////////////////////////////////////////////////////////////////////

#ifndef QUADRATIC_H

#include <iostream>#include <fstream>#include <cmath>

using namespace std;

// The class definition //class Quadratic{ public:

// Constructors Quadratic(); Quadratic(double quadratic, double linear, double constant); Quadratic(const Quadratic &quad);

To better hide the details of a class from the rest of the program, and to facilitate the reuse of the class in other programs, the entire class can be encapsulated into a separate header file.

Page 42: CHAPTER 5 User-Defined Functions

CHAPTER 6 – Data Structures and Objects 42

// Accessors double getQuadratic() const; double getLinear() const; double getConstant() const; void getCoefficients(double &quadratic, double &linear, double &constant) const;

// Mutators void setQuadratic(double quadratic); void setLinear(double linear); void setConstant(double constant); void setCoefficients(double quadratic, double linear, double constant);

// Member Functions double evaluateAt(double x); bool getRoots(double &x1, double &x2); Quadratic derivative(); friend ostream& operator << (ostream &outputFile, const Quadratic &quad); friend istream& operator >> (istream &inputFile, Quadratic &quad);

private:

// Data Members double quadraticCoefficient; double linearCoefficient; double constantCoefficient;};

Page 43: CHAPTER 5 User-Defined Functions

CHAPTER 6 – Data Structures and Objects 43

CONSTRUCTORS// Default Constructor //// Sets all coefficients to zero initially. //Quadratic::Quadratic(){ quadraticCoefficient = 0.0; linearCoefficient = 0.0; constantCoefficient = 0.0; return;}

// Initializing Constructor //// Sets all coefficients to parameterized values. //Quadratic::Quadratic(double quadratic, double linear, double constant){ quadraticCoefficient = quadratic; linearCoefficient = linear; constantCoefficient = constant; return;}

// Copy Constructor //// Sets all coefficients to the same values // // as the parameterized Quadratic. //Quadratic::Quadratic(const Quadratic &quad){ quadraticCoefficient = quad.quadraticCoefficient; linearCoefficient = quad.linearCoefficient; constantCoefficient = quad.constantCoefficient; return;}

Classes use constructors to enable programs to create variables of the type defined by the class.

The default constructor is called whenever a variable is declared of the type defined by the class.

An initializing constructor allows variables to be declared with some of the data member values set.Copy

constructors are used when passing variables by value to functions.

Page 44: CHAPTER 5 User-Defined Functions

CHAPTER 6 – Data Structures and Objects 44

ACCESSORS// Quadratic Coefficient Accessor //double Quadratic::getQuadratic() const{ return quadraticCoefficient;}

// Linear Corfficient Accessor //double Quadratic::getLinear() const{ return linearCoefficient;}

// Constant Coefficient Accessor //double Quadratic::getConstant() const{ return constantCoefficient;}

// All-Coefficient Accessor //void Quadratic::getCoefficients(double &quadratic, double &linear, double &constant) const{ quadratic = quadraticCoefficient; linear = linearCoefficient; constant = constantCoefficient;}

Accessor member functions provide programs with the ability to look up the current values of the data members.To ensure that these functions do not actually change the values of any of the data members, they are often defined to be constant functions.

Page 45: CHAPTER 5 User-Defined Functions

CHAPTER 6 – Data Structures and Objects 45

MUTATORS// Quadratic Coefficient Mutator //void Quadratic::setQuadratic(double quadratic){ quadraticCoefficient = quadratic;}

// Linear Coefficient Mutator //void Quadratic::setLinear(double linear){ linearCoefficient = linear;}

// Constant Coefficient Mutator //void Quadratic::setConstant(double constant){ constantCoefficient = constant;}

// All-Coefficient Mutator //void Quadratic::setCoefficients(double quadratic, double linear, double constant){ quadraticCoefficient = quadratic; linearCoefficient = linear; constantCoefficient = constant;}

Mutator member functions provide programs with the ability to alter the current values of the data members.

Page 46: CHAPTER 5 User-Defined Functions

CHAPTER 6 – Data Structures and Objects 46

MEMBER FUNCTIONS// Evaluation Member Function //// Returns the evaluation of the quadratic //// equation at the parameterized x-value. //double Quadratic::evaluateAt(double x){ return quadraticCoefficient * x * x + linearCoefficient * x + constantCoefficient;}

// Root Determination Member Function //// Obtains the roots of the quadratic equation, //// returning a boolean flag that indicates //// whether the root or roots are real. //bool Quadratic::getRoots(double &x1, double &x2){ double discriminant;

// If the quadratic is actually a constant, set the return flag to false // if ( (quadraticCoefficient == 0) && (linearCoefficient == 0) ) return false;

// If the quadratic is actually linear, the root is the solution to the linear equation. // else if (quadraticCoefficient == 0) { x1 = x2 = -constantCoefficient / linearCoefficient; return true; }

Page 47: CHAPTER 5 User-Defined Functions

CHAPTER 6 – Data Structures and Objects 47

// If the quadratic is really a quadratic, use the quadratic // // formula to determine its roots, if they happen to be real values. // else { discriminant = linearCoefficient * linearCoefficient - 4 * quadraticCoefficient * constantCoefficient; if (discriminant < 0) return false; else { x1 = (-linearCoefficient – sqrt(discriminant)) / (2 * quadraticCoefficient); x2 = (-linearCoefficient + sqrt(discriminant)) / (2 * quadraticCoefficient); return true; } }}

// Derivative Member Function //// Returns the first derivative of the Quadratic. //Quadratic Quadratic::derivative(){ Quadratic derivQuad(0.0, 2 * quadraticCoefficient, linearCoefficient); return derivQuad;}

Page 48: CHAPTER 5 User-Defined Functions

CHAPTER 6 – Data Structures and Objects 48

OVERLOADED OPERATORS// Overloaded Output Operator //// Outputs the Quadratic in "ax^2 + bx + c" form, unless //// the quadratic coefficient is zero ("bx + c") or both //// the quadratic and linear coefficients are zero ("c"). //ostream& operator << (ostream &outputFile, const Quadratic &quad){ if (quad.quadraticCoefficient != 0.0) outputFile << quad.quadraticCoefficient << "x^2"; if (quad.linearCoefficient != 0.0) { if (quad.quadraticCoefficient == 0.0) outputFile << quad.linearCoefficient << "x"; else if (quad.linearCoefficient < 0.0) outputFile << " - " << -quad.linearCoefficient << "x"; else outputFile << " + " << quad.linearCoefficient << "x"; } if ( (quad.quadraticCoefficient == 0.0) && (quad.linearCoefficient == 0.0) ) outputFile << quad.constantCoefficient; else if (quad.constantCoefficient < 0.0) outputFile << " - " << -quad.constantCoefficient; else if (quad.constantCoefficient > 0.0) outputFile << " + " << quad.constantCoefficient; return outputFile;}

Operators can be extended to apply to the new class by declaring them as “friends” and giving them access to the private members of the class.

Page 49: CHAPTER 5 User-Defined Functions

CHAPTER 6 – Data Structures and Objects 49

// Overloaded Input Operator //// Inputs the three coefficients //// from the designated input file. //istream& operator >> (istream &inputFile, Quadratic &quad){ inputFile >> quad.quadraticCoefficient >> quad.linearCoefficient >> quad.constantCoefficient; return inputFile;}

#define QUADRATIC_H#endif

With the class fully defined, it may now be used inside an actual program, as long as the program file includes its header file in its preprocessing statements.

Page 50: CHAPTER 5 User-Defined Functions

CHAPTER 6 – Data Structures and Objects 50

DRIVER PROGRAM//////////////////////////////////////////////////////////// This driver program requests a Quadratic from the //// user and outputs its roots (if any), its derivative, //// and its minimum or maximum point (if any). ////////////////////////////////////////////////////////////

#include <iostream>#include "Quadratic.h"

using namespace std;

Quadratic requestQuadratic();

// The main function handles all program activity in the driver, //// except for the user query for the Quadratic's coefficients. //void main(){ Quadratic quadro; Quadratic firstDerivative; double root1, root2; double maxmin1, maxmin2;

cout << "Initial Quadratic: f(x) = " << quadro << endl << endl; quadro = requestQuadratic(); cout << endl << "Current Quadratic: f(x) = " << quadro << endl << endl;

if ( quadro.getRoots(root1, root2) ) cout << " Roots: " << root1 << " and " << root2 << endl << endl; else cout << " No real roots to this quadratic." << endl << endl;

Page 51: CHAPTER 5 User-Defined Functions

CHAPTER 6 – Data Structures and Objects 51

firstDerivative = quadro.derivative(); cout << " Derivative: f'(x) = " << firstDerivative << endl << endl; if ( firstDerivative.getRoots(maxmin1, maxmin2) ) { if (quadro.evaluateAt(maxmin1) < quadro.evaluateAt(maxmin1 + 1.0)) cout << " Parabolic Minimum At x = " << maxmin1 << " (y = " << quadro.evaluateAt(maxmin1) << ")" << endl << endl; else cout << " Parabolic Maximum At x = " << maxmin1 << " (y = " << quadro.evaluateAt(maxmin1) << ")" << endl << endl; }

return;}

// The requestQuadratic function queries the user for the //// Quadratic coefficients and returns the resulting Quadratic. //Quadratic requestQuadratic(){ Quadratic quad; cout << "Enter the coefficients of a quadratic equation," << endl << "in order, beginning with the quadratic term: "; cin >> quad; return quad;}

Page 52: CHAPTER 5 User-Defined Functions

CHAPTER 6 – Data Structures and Objects 52

CLASS REUSE/////////////////////////////////////////////////////////////////////////// This driver program requests a projectile's angle and initial speed //// and calculates the peak and the landing distance of its trajectory. ///////////////////////////////////////////////////////////////////////////

#include <iostream>#include <cmath>#include "Quadratic.h"

using namespace std;

const double PI = 3.1416;const double GRAVITATIONAL_ACCELERATION = 32.174;

Quadratic getTrajectoryQuadratic();

// The main function handles all program activity in the driver, //// except for the user query for the Quadratic's coefficients. //void main(){ Quadratic quad; Quadratic firstDerivative; double root1, root2; double maxmin1, maxmin2;

cout << "PROJECTILE TRAJECTORY CALCULATION" << endl; cout << "---------------------------------" << endl; quad = getTrajectoryQuadratic();

Once a class is written, it may be reused with other driver programs.

Page 53: CHAPTER 5 User-Defined Functions

CHAPTER 6 – Data Structures and Objects 53

cout << "Landing distance: "; quad.getRoots(root1, root2); (root1 != 0.0) ? (cout << root1) : (cout << root2); cout << " feet" << endl;

firstDerivative = quad.derivative(); firstDerivative.getRoots(maxmin1, maxmin2); cout << "Peak height: " << maxmin1 << " feet" << endl << endl;

return;}

// This function queries the user regarding the projectile's initial velocity// and angle, and returns the quadratic corresponding to its trajectory.Quadratic getTrajectoryQuadratic(){ Quadratic q; double theta; double initialVelocity; cout << "Enter the initial velocity of the projectile (in feet/second): "; cin >> initialVelocity; cout << "Enter the projectile's initial angle (in degrees): "; cin >> theta; theta *= (PI / 180); q.setCoefficients( -GRAVITATIONAL_ACCELERATION / (2 * pow(initialVelocity * cos(theta), 2)), tan(theta), 0.0); return q;}

Page 54: CHAPTER 5 User-Defined Functions

CHAPTER 4 - RepetitionStructures 54

CHAPTER 7Arrays and Strings

•Arrays•Strings•Dynamic Arrays

Page 55: CHAPTER 5 User-Defined Functions

CHAPTER 7 – Arrays and Strings 55

ARRAYS////////////////////////////////////////////////////////// This program examines an external file composed of //// temperature readings, placing the highest values //// in an array that is then output to the user. //////////////////////////////////////////////////////////

#include <iostream>#include <iomanip>#include <fstream>using namespace std;

const int MAX_LIST_SIZE = 10;

void loadList(double list[], int &listSize);void insertNewHighValue(double list[], int listSize, double highVal);void outputList(double list[], int listSize);

// The main function merely coordinates the list creation and output.void main(){ double highVal[MAX_LIST_SIZE]; int nbrOfVals;

loadList(highVal, nbrOfVals); outputList(highVal, nbrOfVals);

return;}

Data of the same type may be placed into a single structure, an array, which facilitates locating particular items via indexing.

When the array variable is declared, its number of slots is specified (i.e., in this case the array is allocated enough memory to hold ten double values).

Page 56: CHAPTER 5 User-Defined Functions

CHAPTER 7 – Arrays and Strings 56

// The loadList function opens the input file, reads all of its// data, retaining the highest values in the parameterized array.void loadList(double list[], int &listSize){ double newVal; ifstream valFile;

listSize = 0; valFile.open("TempReadings.txt"); valFile >> newVal; while (!valFile.eof()) { if (listSize < MAX_LIST_SIZE) { list[listSize] = newVal; listSize++; } else insertNewHighValue(list, listSize, newVal); valFile >> newVal; } valFile.close();

return;}

The size of the list is not specified in the array parameter’s brackets; arrays are actually always passed by reference (even though no ampersand is used).When accessing a particular

value in the array, an index is used (starting with the first element in slot #0).

Page 57: CHAPTER 5 User-Defined Functions

CHAPTER 7 – Arrays and Strings 57

// The insertNewHighValue function determines whether the // parameterized newVal is larger in value than any of the // values in the parameterized array. If so, the smallest // such value is replaced in the array with newVal.void insertNewHighValue(double list[], int listSize, double newVal){ int i; int lowValIndex = 0;

for (i = 0; i < listSize; i++) if (list[i] < list[lowValIndex]) lowValIndex = i; if (newVal > list[lowValIndex]) list[lowValIndex] = newVal;

return;}

// The outputList function outputs the contents of the// parameterized array to the user, using a stylized format.void outputList(double list[], int listSize){ int i;

cout << setw(20) << "Highest Values" << endl; cout.setf(ios::fixed); cout.setf(ios::showpoint); cout.precision(5);

for (i = 0; i < listSize; i++) cout << setw(17) << list[i] << endl; cout << endl;

return;}

98.6453799.0012896.7834997.0022698.5520198.6629798.0662998.6323098.6000198.7110298.8155398.2517298.6723598.8237696.8232697.8025198.9920998.3427899.0018997.12194

Page 58: CHAPTER 5 User-Defined Functions

CHAPTER 7 – Arrays and Strings 58

STRINGSThe string header file includes various functions and operators for processing string data.

//////////////////////////////////////////////////////////// The Element class represents a chemical element //// with data members for the atomic number, the name, //// the symbol, the chemicalseries, and the number of //// electrons in each of the seven electron levels. It //// also provides overloaded input and output operators. ////////////////////////////////////////////////////////////

#ifndef ELEMENT_H

#include <iostream>#include <fstream>#include <string>

using namespace std;

class Element{ public:

// Constructors Element(); Element(const Element &elt);

// Accessors int getAtomicNumber() const; string getName() const; string getSymbol() const; string getChemicalSeries() const; void getElectrons(int elec[]) const;

Page 59: CHAPTER 5 User-Defined Functions

CHAPTER 7 – Arrays and Strings 59

// Mutators void setAtomicNumber(int aNbr); void setName(string nm); void setSymbol(string sym); void setChemicalSeries(string ser); void setElectrons(int elec[]);

// Overloaded Operators friend ostream& operator << (ostream &outputFile, const Element &elt); friend istream& operator >> (istream &inputFile, Element &elt);

private:

// Data Members int AtomicNumber; string Name; string Symbol; string ChemicalSeries; int Electrons[7];};

// Default Constructor: Sets new// Element to hydrogen by default.Element::Element(){ int i; AtomicNumber = 1; Name = "Hydrogen"; Symbol = "H"; ChemicalSeries = "Nonmetal"; Electrons[0] = 1; for (i = 1; i < 7; i++) Electrons[i] = 0;}

// Copy Constructor: Duplicates parameterized Element.Element::Element(const Element &elt){ int i; AtomicNumber = elt.AtomicNumber; Name = elt.Name; Symbol = elt.Symbol; ChemicalSeries = elt.ChemicalSeries; for (i = 0; i < 7; i++) Electrons[i] = elt.Electrons[i];}

// Atomic Number Accessor: Retrieves value.int Element::getAtomicNumber() const{ return AtomicNumber;}

// Name Accessor: Retrieves value.string Element::getName() const{ return Name;}

Page 60: CHAPTER 5 User-Defined Functions

CHAPTER 7 – Arrays and Strings 60

// Symbol Accessor: Retrieves value.string Element::getSymbol() const{ return Symbol;}

// Chemical Series Accessor: Retrieves value, padding with blanks to separate words.string Element::getChemicalSeries() const{ int index = 1; string revisedSeries = ChemicalSeries; while (index < int(revisedSeries.length())) { if ( (revisedSeries[index] >= 'A') && (revisedSeries[index] <= 'Z') && (revisedSeries[index - 1] >= 'a') && (revisedSeries[index - 1] <= 'z') ) revisedSeries = revisedSeries.substr(0, index) + " " + revisedSeries.substr(index, revisedSeries.length() - index); index++; } return revisedSeries;}

// Electrons Accessor: Retrieves values.void Element::getElectrons(int elec[]) const{ int i; for (i = 0; i < 7; i++) elec[i] = Electrons[i];}

Page 61: CHAPTER 5 User-Defined Functions

CHAPTER 7 – Arrays and Strings 61

// Atomic Number Mutator// Sets value, using 1 if parameter's value is invalid.void Element::setAtomicNumber(int aNbr){ if ( (aNbr <= 0) || (aNbr > 118) ) AtomicNumber = 1; else AtomicNumber = aNbr;}

// Name Mutator// Sets value to parameterized value.void Element::setName(string nm){ Name = nm;}

// Symbol Mutator// Sets value to parameterized value.void Element::setSymbol(string sym){ Symbol = sym;}

// Chemical Series Mutator// Sets value to parameterized value.void Element::setChemicalSeries(string ser){ ChemicalSeries = ser;}

// Electrons Mutator: Sets values to// parameterized values, correcting// for non-zeros after first zero.void Element::setElectrons(int elec[]){ int i; bool previousWasZero = false; for (i = 0; i < 7; i++) { if (previousWasZero) Electrons[i] = 0; else { Electrons[i] = elec[i]; if (Electrons[i] == 0) previousWasZero = true; } }}

Page 62: CHAPTER 5 User-Defined Functions

CHAPTER 7 – Arrays and Strings 62

// Output Operator: Outputs Element data members in formatted fashion.ostream& operator << (ostream &outputFile, const Element &elt){ int i; outputFile << elt.Name + " (" + elt.Symbol + ")" << endl; outputFile << " Atomic Number: " << elt.AtomicNumber << endl; outputFile << " Chemical Series: " << elt.getChemicalSeries() << endl; outputFile << " Electron Levels: {"; for (i = 0; i < 7; i++) { outputFile << elt.Electrons[i]; if (i < 6) outputFile << ", "; else outputFile << "}"; } return outputFile;}

// Input Operator: Inputs Element data members, assuming a specific format.istream& operator >> (istream &inputFile, Element &elt){ int i; inputFile >> elt.AtomicNumber >> elt.Name >> elt.Symbol >> elt.ChemicalSeries; for (i = 0; i < 7; i++) inputFile >> elt.Electrons[i]; return inputFile;}

#define ELEMENT_H#endif

Page 63: CHAPTER 5 User-Defined Functions

CHAPTER 7 – Arrays and Strings 63

DYNAMIC ARRAYSIf the size of the array is unknown at the beginning approach, the static approach is to allocate enough memory to accommodate anticipated needs.

///////////////////////////////////////////////////////////////// This program employs the previously defined Element class //// to load a dynamic array with all elements whose names and //// symbols don't appear to correspond (i.e., characters in //// the symbol that do not appear in the name). The results //// are then output to the user. /////////////////////////////////////////////////////////////////

#include <iostream>#include <fstream>#include <string>#include "Element.h"

using namespace std;

void retrieveOddSymbols(Element* &list, int &listSize);bool nameSymbolMismatch(Element elt);void alphabetizeOddSymbols(Element list[], int listSize);void reportOddSymbols(Element list[], int listSize);

// The main function coordinates the program's activity by out-// putting a header and then calling functions to make the list// of elements with name-symbol mismatches, to alphabetize those// elements (by name), and to output the final alphabetized list.void main(){ Element* oddElement; int nbrOddElements; cout << "CHEMICAL ELEMENTS WITH NAME-SYMBOL MISMATCHES" << endl << endl; retrieveOddSymbols(oddElement, nbrOddElements); alphabetizeOddSymbols(oddElement, nbrOddElements); reportOddSymbols(oddElement, nbrOddElements); delete[] oddElement;}

Alternatively, memory allocation can be delayed until after the program determines the actual array size.

Page 64: CHAPTER 5 User-Defined Functions

CHAPTER 7 – Arrays and Strings 64

// This function creates the dynamic array of elements by first counting how// many elements have mismatched names and symbols, allocating memory for an// array of that size, and then loading the mismatched elements into that array.void retrieveOddSymbols(Element* &list, int &listSize){ int eltNbr; int oddEltNbr; ifstream eltFile; Element nextElt;

eltFile.open("Elements.txt"); listSize = 0; for (eltNbr = 1; eltNbr <= 118; eltNbr++) { eltFile >> nextElt; if (nameSymbolMismatch(nextElt)) listSize++; } eltFile.close();

list = new Element[listSize]; eltFile.open("Elements.txt"); oddEltNbr = 0; for (eltNbr = 1; eltNbr <= 118; eltNbr++) { eltFile >> nextElt; if (nameSymbolMismatch(nextElt)) { list[oddEltNbr] = nextElt; oddEltNbr++; } } eltFile.close(); return;}

Page 65: CHAPTER 5 User-Defined Functions

CHAPTER 7 – Arrays and Strings 65

// This function determines whether the parameterized Element// has a name-symbol mismatch by searching the name for each// character in the symbol. If any symbol character is not// found in the name, the function returns a boolean flag// indicating that the Element has a mismatch.bool nameSymbolMismatch(Element elt){ int symbolIndex = 0; int nameIndex; bool symbolCharFound = true; char symbolChar; while ( symbolIndex < int(elt.getSymbol().length()) ) { symbolChar = elt.getSymbol().at(symbolIndex); symbolCharFound = false; nameIndex = 0; while ( (!symbolCharFound) && (nameIndex < int(elt.getName().length())) ) { if (elt.getName().at(nameIndex) == symbolChar) symbolCharFound = true; else nameIndex++; } if (symbolCharFound) symbolIndex++; else return true; } return false;}

Page 66: CHAPTER 5 User-Defined Functions

CHAPTER 7 – Arrays and Strings 66

// This function places the parameterized Element array in alphabetical// order, according to the names of the Elements. It accomplishes this// by swapping the Element with the name that comes first alphabetically// with the first array Element, the second with the second, and so forth.void alphabetizeOddSymbols(Element list[], int listSize){ Element tempElement; int currentIndex, smallestElementIndex, possibleSwapIndex; for (currentIndex = 0; currentIndex < listSize - 1; currentIndex++) { smallestElementIndex = currentIndex; for (possibleSwapIndex = currentIndex + 1; possibleSwapIndex < listSize; possibleSwapIndex++) if (list[possibleSwapIndex].getName() < list[smallestElementIndex].getName()) smallestElementIndex = possibleSwapIndex; if (smallestElementIndex != currentIndex) { tempElement = list[currentIndex]; list[currentIndex] = list[smallestElementIndex]; list[smallestElementIndex] = tempElement; } } return;}

// This function uses the Element output operator to output the// list of Elements with mismatched names and symbols to the user.void reportOddSymbols(Element list[], int listSize){ int eltIndex; for (eltIndex = 0; eltIndex < listSize; eltIndex++) cout << list[eltIndex] << endl << endl; return;}

Page 67: CHAPTER 5 User-Defined Functions

CHAPTER 7 – Arrays and Strings 67

1 Hydrogen H Nonmetal 1 0 0 0 0 0 02 Helium He NobleGas 2 0 0 0 0 0 03 Lithium Li AlkaliMetal 2 1 0 0 0 0 04 Beryllium Be AlkalineEarthMetal 2 2 0 0 0 0 05 Boron B Metalloid 2 3 0 0 0 0 06 Carbon C Nonmetal 2 4 0 0 0 0 07 Nitrogen N Nonmetal 2 5 0 0 0 0 08 Oxygen O Nonmetal 2 6 0 0 0 0 09 Fluorine F Halogen 2 7 0 0 0 0 010 Neon Ne NobleGas 2 8 0 0 0 0 011 Sodium Na AlkaliMetal 2 8 1 0 0 0 012 Magnesium Mg AlkalineEarthMetal 2 8 2 0 0 0 013 Aluminium Al PoorMetal 2 8 3 0 0 0 014 Silicon Si Metalloid 2 8 4 0 0 0 015 Phosphorus P Nonmetal 2 8 5 0 0 0 016 Sulfur S Nonmetal 2 8 6 0 0 0 017 Chlorine Cl Halogen 2 8 7 0 0 0 018 Argon Ar NobleGas 2 8 8 0 0 0 019 Potassium K AlkaliMetal 2 8 8 1 0 0 020 Calcium Ca AlkalineEarthMetal 2 8 8 2 0 0 021 Scandium Sc TransitionMetal 2 8 9 2 0 0 022 Titanium Ti TransitionMetal 2 8 10 2 0 0 023 Vanadium V TransitionMetal 2 8 11 2 0 0 024 Chromium Cr TransitionMetal 2 8 13 1 0 0 025 Manganese Mn TransitionMetal 2 8 13 2 0 0 026 Iron Fe TransitionMetal 2 8 14 2 0 0 027 Cobalt Co TransitionMetal 2 8 15 2 0 0 028 Nickel Ni TransitionMetal 2 8 16 2 0 0 029 Copper Cu TransitionMetal 2 8 18 1 0 0 030 Zinc Zn TransitionMetal 2 8 18 2 0 0 031 Gallium Ga PoorMetal 2 8 18 3 0 0 032 Germanium Ge Metalloid 2 8 18 4 0 0 033 Arsenic As Metalloid 2 8 18 5 0 0 034 Selenium Se Nonmetal 2 8 18 6 0 0 035 Bromine Br Halogen 2 8 18 7 0 0 036 Krypton Kr NobleGas 2 8 18 8 0 0 037 Rubidium Rb AlkaliMetal 2 8 18 8 1 0 038 Strontium Sr AlkalineEarthMetal 2 8 18 8 2 0 039 Yttrium Y TransitionMetal 2 8 18 9 2 0 040 Zirconium Zr TransitionMetal 2 8 18 10 2 0 041 Niobium Nb TransitionMetal 2 8 18 12 1 0 042 Molybdenum Mo TransitionMetal 2 8 18 13 1 0 043 Technetium Tc TransitionMetal 2 8 18 14 1 0 044 Ruthenium Ru TransitionMetal 2 8 18 15 1 0 045 Rhodium Rh TransitionMetal 2 8 18 16 1 0 046 Palladium Pd TransitionMetal 2 8 18 18 0 0 047 Silver Ag TransitionMetal 2 8 18 18 1 0 048 Cadmium Cd TransitionMetal 2 8 18 18 2 0 049 Indium In PoorMetal 2 8 18 18 3 0 050 Tin Sn PoorMetal 2 8 18 18 4 0 051 Antimony Sb Metalloid 2 8 18 18 5 0 052 Tellurium Te Metalloid 2 8 18 18 6 0 053 Iodine I Halogen 2 8 18 18 7 0 054 Xenon Xe NobleGas 2 8 18 18 8 0 055 Caesium Cs AlkaliMetal 2 8 18 18 8 1 056 Barium Ba AlkalineEarthMetal 2 8 18 18 8 2 057 Lanthanum La Lanthanide 2 8 18 18 9 2 058 Cerium Ce Lanthanide 2 8 18 19 9 2 059 Praseodymium Pr Lanthanide 2 8 18 21 8 2 060 Neodymium Nd Lanthanide 2 8 18 22 8 2 061 Promethium Pm Lanthanide 2 8 18 23 8 2 062 Samarium Sm Lanthanide 2 8 18 24 8 2 063 Europium Eu Lanthanide 2 8 18 25 8 2 064 Gadolinium Gd Lanthanide 2 8 18 25 9 2 065 Terbium Tb Lanthanide 2 8 18 27 8 2 066 Dysprosium Dy Lanthanide 2 8 18 28 8 2 067 Holmium Ho Lanthanide 2 8 18 29 8 2 068 Erbium Er Lanthanide 2 8 18 30 8 2 069 Thulium Tm Lanthanide 2 8 18 31 8 2 070 Ytterbium Yb Lanthanide 2 8 18 32 8 2 071 Lutetium Lu Lanthanide 2 8 18 32 9 2 072 Hafnium Hf TransitionMetal 2 8 18 32 10 2 073 Tantalum Ta TransitionMetal 2 8 18 32 11 2 074 Tungsten W TransitionMetal 2 8 18 32 12 2 075 Rhenium Re TransitionMetal 2 8 18 32 13 2 076 Osmium Os TransitionMetal 2 8 18 32 14 2 077 Iridium Ir TransitionMetal 2 8 18 32 15 2 078 Platinum Pt TransitionMetal 2 8 18 32 17 1 079 Gold Au TransitionMetal 2 8 18 32 18 1 080 Mercury Hg TransitionMetal 2 8 18 32 18 2 081 Thallium Tl PoorMetal 2 8 18 32 18 3 082 Lead Pb PoorMetal 2 8 18 32 18 4 083 Bismuth Bi PoorMetal 2 8 18 32 18 5 084 Polonium Po Metalloid 2 8 18 32 18 6 085 Astatine At Halogen 2 8 18 32 18 7 086 Radon Rn NobleGas 2 8 18 32 18 8 087 Francium Fr AlkaliMetal 2 8 18 32 18 8 188 Radium Ra AlkalineEarthMetal 2 8 18 32 18 8 289 Actinium Ac Actinide 2 8 18 32 18 9 290 Thorium Th Actinide 2 8 18 32 18 10 291 Protactinium Pa Actinide 2 8 18 32 20 9 292 Uranium U Actinide 2 8 18 32 21 9 293 Neptunium Np Actinide 2 8 18 32 22 9 294 Plutonium Pu Actinide 2 8 18 32 24 8 295 Americium Am Actinide 2 8 18 32 25 8 296 Curium Cm Actinide 2 8 18 32 25 9 297 Berkelium Bk Actinide 2 8 18 32 27 8 298 Californium Cf Actinide 2 8 18 32 28 8 299 Einsteinium Es Actinide 2 8 18 32 29 8 2100 Fermium Fm Actinide 2 8 18 32 30 8 2101 Mendelevium Md Actinide 2 8 18 32 31 8 2102 Nobelium No Actinide 2 8 18 32 32 8 2103 Lawrencium Lr Actinide 2 8 18 32 32 9 2104 Rutherfordium Rf TransitionMetal 2 8 18 32 32 10 2105 Dubnium Db TransitionMetal 2 8 18 32 32 11 2106 Seaborgium Sg TransitionMetal 2 8 18 32 32 12 2107 Bohrium Bh TransitionMetal 2 8 18 32 32 13 2108 Hassium Hs TransitionMetal 2 8 18 32 32 14 2109 Meitnerium Mt TransitionMetal 2 8 18 32 32 15 2110 Darmstadtium Ds TransitionMetal 2 8 18 32 32 16 2111 Roentgenium Rg TransitionMetal 2 8 18 32 32 17 2112 Ununbium Uub TransitionMetal 2 8 18 32 32 18 2113 Ununtrium Uut PoorMetal 2 8 18 32 32 18 3114 Ununquadium Uuq PoorMetal 2 8 18 32 32 18 4115 Ununpentium Uup PoorMetal 2 8 18 32 32 18 5116 Ununhexium Uuh PoorMetal 2 8 18 32 32 18 6117 Ununseptium Uus Halogen 2 8 18 32 32 18 7118 Ununoctium Uuo NobleGas 2 8 18 32 32 18 8


Recommended