122
C++ lab session tasks: 2011/2012 Table of Contents for Part A Part A of the C++ lab tasks for ma1690 in 2011/2012 1 Your first C++ lab session 3 1.1 Preliminary task: customizing your set-up ................... 3 1.2 Comments on differences between the labs ................... 5 1.3 Initial tests of your set-up ............................ 8 1.3.1 cl and g++ from the command line ................... 8 1.3.2 The u: drive and the Linux computer fenrir ............. 8 1.3.3 Testing that the IDEs for C++ start .................. 10 2 Creating some short C++ programs in various ways 11 2.1 Using the program cr proj to create project files ............... 11 2.1.1 Using Code::Blocks ............................ 12 2.1.2 Using Visual Studio 2008 ......................... 16 2.2 Compiling using the command line ....................... 16 2.3 Summary of the options and some comments .................. 18 3 Trying a few C++ programs 20 3.1 Preliminary remarks and customising the output window ........... 20 3.2 Possibly adjusting the font size in the IDEs and showing the line numbers . . 21 3.3 A program illustrating integer arithmetic and rounding error with floating point arithmetic .................................. 21 3.4 Testing if a 32-bit or a 64-bit environment ................... 23 3.4.1 Running show some defines.cpp with the default set-up ....... 23 3.4.2 Getting the 64-bit output with the Windows compilers ........ 25 3.5 Another program illustrating formatting commands .............. 29 3.6 Short examples with for–loops ......................... 30 3.7 Printing the times table, loops within loops and the C++ beautifier programs 32 3.8 Printing the ASCII character set ........................ 37 3.9 Accessing some system parameters and using macros ............. 38 4 Using the IDEs to create everything (may be skipped) 40 4.1 Using the codeblocks IDE to create everything ................. 40 4.2 Using the Visual Studio 2008 IDE to create everything ............ 41 5 A linear equation program – interactive input of the parameters 43 6 Assignment statements and standard mathematical functions 44 i

Table of Contents for Part A Part A of the C++ lab tasks for ...people.brunel.ac.uk/~icstmkw/ma1690/all_labs_2011.pdfTable of Contents for Part A Part A of the C++ lab tasks for ma1690in

  • Upload
    lytu

  • View
    216

  • Download
    0

Embed Size (px)

Citation preview

C++ lab session tasks: 2011/2012

Table of Contents for Part A

Part A of the C++ lab tasks for ma1690 in 2011/2012

1 Your first C++ lab session 3

1.1 Preliminary task: customizing your set-up . . . . . . . . . . . . . . . . . . . 3

1.2 Comments on differences between the labs . . . . . . . . . . . . . . . . . . . 5

1.3 Initial tests of your set-up . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

1.3.1 cl and g++ from the command line . . . . . . . . . . . . . . . . . . . 8

1.3.2 The u: drive and the Linux computer fenrir . . . . . . . . . . . . . 8

1.3.3 Testing that the IDEs for C++ start . . . . . . . . . . . . . . . . . . 10

2 Creating some short C++ programs in various ways 11

2.1 Using the program cr proj to create project files . . . . . . . . . . . . . . . 11

2.1.1 Using Code::Blocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12

2.1.2 Using Visual Studio 2008 . . . . . . . . . . . . . . . . . . . . . . . . . 16

2.2 Compiling using the command line . . . . . . . . . . . . . . . . . . . . . . . 16

2.3 Summary of the options and some comments . . . . . . . . . . . . . . . . . . 18

3 Trying a few C++ programs 20

3.1 Preliminary remarks and customising the output window . . . . . . . . . . . 20

3.2 Possibly adjusting the font size in the IDEs and showing the line numbers . . 21

3.3 A program illustrating integer arithmetic and rounding error with floatingpoint arithmetic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21

3.4 Testing if a 32-bit or a 64-bit environment . . . . . . . . . . . . . . . . . . . 23

3.4.1 Running show some defines.cpp with the default set-up . . . . . . . 23

3.4.2 Getting the 64-bit output with the Windows compilers . . . . . . . . 25

3.5 Another program illustrating formatting commands . . . . . . . . . . . . . . 29

3.6 Short examples with for–loops . . . . . . . . . . . . . . . . . . . . . . . . . 30

3.7 Printing the times table, loops within loops and the C++ beautifier programs 32

3.8 Printing the ASCII character set . . . . . . . . . . . . . . . . . . . . . . . . 37

3.9 Accessing some system parameters and using macros . . . . . . . . . . . . . 38

4 Using the IDEs to create everything (may be skipped) 40

4.1 Using the codeblocks IDE to create everything . . . . . . . . . . . . . . . . . 40

4.2 Using the Visual Studio 2008 IDE to create everything . . . . . . . . . . . . 41

5 A linear equation program – interactive input of the parameters 43

6 Assignment statements and standard mathematical functions 44

i

6.1 A quadratic equation program . . . . . . . . . . . . . . . . . . . . . . . . . . 44

6.2 Computing the angles of a triangle . . . . . . . . . . . . . . . . . . . . . . . 46

6.3 Approximations to sinx and cos x . . . . . . . . . . . . . . . . . . . . . . . . 48

6.4 Converting mathematical expressions into C++ statements . . . . . . . . . . 49

6.5 A C++ expression for Gauss’ formula for cos(2π/17) . . . . . . . . . . . . . 50

6.6 Cardano’s method for a root of a cubic equation . . . . . . . . . . . . . . . . 51

7 C++ programming tasks with for loops and if-else statements 54

7.1 A compound interest rate program . . . . . . . . . . . . . . . . . . . . . . . 54

7.2 Comparing doubles and the dangers of using == or != with this type . . . . . 54

7.3 Approximately locating roots . . . . . . . . . . . . . . . . . . . . . . . . . . 55

7.4 Generating the factorials . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58

7.5 Computing sums . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59

7.6 Determining prime numbers . . . . . . . . . . . . . . . . . . . . . . . . . . . 60

8 Lab tests in Term 1 in previous years 62

8.1 One of the versions in Nov 2009 – version A . . . . . . . . . . . . . . . . . . 62

8.2 One of the versions in Nov 2010 – version A . . . . . . . . . . . . . . . . . . 66

9 C++ programming tasks with if, if–else and for statements 69

9.1 Generating Fibonacci numbers . . . . . . . . . . . . . . . . . . . . . . . . . . 69

9.2 Approximately determining the area under a curve . . . . . . . . . . . . . . 70

10 C++ programming tasks involving arrays and for loops 72

10.1 Displaying in reverse order . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72

10.2 Generating Fibonacci numbers (again) . . . . . . . . . . . . . . . . . . . . . 72

10.3 The number of days since 31 December 2010 . . . . . . . . . . . . . . . . . . 73

10.4 The exact amount with the minimum number of coins . . . . . . . . . . . . . 74

10.5 Reading a data set and analysing the data . . . . . . . . . . . . . . . . . . . 75

10.6 Testing a random number generator . . . . . . . . . . . . . . . . . . . . . . . 79

Part B, Jan 2012–Apr 2012 (weeks 16–27)Reminders of the arrangements for the remainder of 2011/2012

11 Creating functions: Binomial coefficients and Pascal’s triangle 85

11.1 A function to compute binomial coefficients and generating Pascal’s triangle 85

11.2 Using arrays to generate Pascal’s triangle . . . . . . . . . . . . . . . . . . . . 86

12 Locating roots and turning points of functions 88

13 Computing exp(x) using the Maclaurin expansion 91

14 Functions as arguments to other functions 93

ii

14.1 A bisection method function . . . . . . . . . . . . . . . . . . . . . . . . . . . 93

14.2 Using the composite mid-point rule . . . . . . . . . . . . . . . . . . . . . . . 95

15 Using arrays and some functions from <cstring> 97

16 Using arrays: A route planning journey 99

17 Reading data from files 103

17.1 Some preliminary tasks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103

17.2 Reading a file byte by byte . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104

17.3 Getting all the lines in a file as C-style strings . . . . . . . . . . . . . . . . . 107

18 Programs to sort data 109

18.1 Some explanation about using qsort() . . . . . . . . . . . . . . . . . . . . . 109

18.2 Testing qsort() to sort various types . . . . . . . . . . . . . . . . . . . . . . 111

18.3 Using qsort() to sort C-style strings by the number of vowels . . . . . . . . 112

18.4 Using qsort() to show the most frequent letters . . . . . . . . . . . . . . . . 114

19 Experiments and tasks related to functions in <ctime> 116

This information can also be found in the directory (folder)

http://people.brunel.ac.uk/~icstmkw/ma1690/

If mistakes are spotted then the electronic version kept in this location will be corrected.Please let me know in any of the timetabled events or by email if you detect any mistakesin this document.

iii

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 1

Location of the labs

All the computer labs around the campus, that I am aware of, can run at least some of theC++ software used in this module and thus you should be able to do your work in any ofthese. However, there are some differences between the labs relating mainly to the softwarewhich is installed and comments about these are made on page 5. All the timetabled labsessions take place in rooms maintained by our school (SISCM) and these are rooms 213

and 223 of the Halsbury building (HB213, HB233) and in room 123 of the St. Johns building(SJ123). The extract from the campus map shows where the buildings are. In the case ofthe Halsbury building if you enter the building using the steps opposite the Lecture Centrethen the labs are in the middle and the back of the building on the second floor. If youcannot use the steps and need to use a lift then access is on the left hand side of the buildingif you approach from the Lecture Centre (the entrance is thus on the west facing side closeto Student Union rooms in the neighbouring Hamilton Centre); see figures 1 and 2 for moredetails.

�������������

GaskellEnglishHERGCSHISocial SciencesArts

Marie JahodaCRICTLawPsychologySocial AnthropologySociology and

CommunicationEconomics and FinanceBusiness and ManagementPolitics and History

ChadwickArts Centre

(until Summer 2006)

Heinz WolffBiosciencesSport SciencesBIBBECDisability and

Dyslexia Service

Wilfred Brown RegistryEstates and OperationsBeldam GalleryMarketing

(Student Recruitment)

Bannerman CentreLibraryCash OfficeStudent FinanceStudent Centre

Tower ABCASTDesign

Tower BBCMMMechanical Engineering

Tower CMechanical EngineeringElectronic and Computer

Engineering

Tower DCLEAPSSMechanical EngineeringElectronic and

Computer Engineering

Hamilton CentreRefectoryStudent’s UnionCampus Shops

Halsbury Institute for

the EnvironmentGeography and Earth

SciencesGraduate SchoolWolfson CentreSchool of Sport and

Education

Howell Electronic and

Computer EngineeringMechanical Engineering

John CrankComputer CentreMathematical Sciences

Lecture CentreRecital RoomLTDUMedia Services

St Johns Information Systems

and Computing

Mary SeacoleHealth Studies Centre –

opening autumn 2006

Brunel Science Park(A) RussellBrunel InternationalLanguage CentreLIBT

(B) Elliott Jaques Business and

Management MBA

(C) Gardiner

Residential Buildings1. Isambard Flats2. Galbraith Hall3. Fleming Hall4. Mill Hall5. Saltash Hall6. Chepstow Hall7. Clifton Hall8. Bishop Hall9. Kilmorey Hall10. Lacy Hall11. St Margarets Hall12. Faraday Hall13. Borough Road Hall14. Maria Grey Hall15. Lancaster Hall16. Southwark Hall17. Stockwell Hall18. Gordon Hall

Brunel UniversityUxbridge, Middlesex UB8 3PHTel 01895 274000Fax 01895 232806Web www.brunel.ac.uk

100516 040706

Uxbridge Campus Plan

W E

S

N

Figure 1: Extract from the Uxbridge campus

The assessment for this module will involve a lab test in the second half of term 1, therewill be questions as part of the written combined core test that you have in term 2, therewill be an assignment in term 2 and there is a written exam in the April/May exam period.To pass the module you need at least 40% overall on the non-exam parts and at least 40%on the exam. As with all modules, if you are required to do re-assessment and you pass there-assessment then your mark for the module is 40%.

Please note that in the labs you work at your own pace and, based on previous years,the number of tasks here is usually more than all (or most) students are able to complete. Ifyou cannot do one of the tasks then it may be best to try some of the other tasks and seekhelp in one of the timetabled events and you should note that some tasks are harder thanothers.

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 1–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 2

HB223PCs

HB213

W E

S

N

W E

S

N

Figure 2: Halsbury building details

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 2–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 3

1 Your first C++ lab session

The following are a number of tasks we would like you to try as your first steps in creatingC++ programs on our system at Brunel. The intention is that the tasks will attempt toget you used to using one of the Integrated Development Environments (IDEs) and withsome elements of the language which will be covered more fully later. After attempting afew different ways of doing things it will be up to you to select which way you find mostconvenient for creating and running the programs that you create.

As many of you probably have access to PCs or laptops you are likely to be fast atjust typing things in and following the instructions. However, we recommend that you tryto understand at least some of what is happening although do not expect to understandeverything at first. If you have never done programming before then you are likely to findthings difficult for a while and you need to appreciate that learning programming is aboutgradually becoming more familiar with what you can and cannot do and with graduallyimproving your understanding of the language and with using the language to solve tasksand the most important thing with learning programming is to practice. Although itis frustrating when programs do not work at first, you learn things from the struggle toovercome the mistakes to get things working.

Notation comment

In the following a typewriter font is used for commands to be typed and for programlistings. With this font, and with many other fonts, some letters are quite close in appearanceand in particular take care to distinguish between the lower case letter l and the digit 1. An

enlarged version appears like this l and 1. At certain times you also need to distinguishbetween the double quote character " and the single quote character ’. On a UK qwertykeyboard (see figure 3) " is above 2 character and ’ is below the @ character. The characterwhich appears as ` (in the top left hand corner) is unlikely to be used in this module.

Figure 3: The UK qwerty keyboard.

1.1 Preliminary task: customizing your set-up

The following should not need to be done again or will be easier the next time if we ask youto repeat these instructions or similar instructions.

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 3–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 4

1. Note that “Start” is in the bottom left hand corner of the screen. Place the mousepointer over this region and click the mouse. If you are using Vista or Windows 7 thentype cmd in the start box and you should get a command window.

Alternatively, if you are using Windows XP, get the start menu by clicking on “Start”as above and then use the menus as follows.

Start --> All Programs --> Accessories --> Command Prompt.

Whichever route you use you should get a window as shown in figure 4.

Figure 4: cmd.exe command prompt window. The default window has a black backgroundand white text with a size which is such that it can show 25 rows with each row having upto 80 characters. You can scroll back to see previous information for 300 rows. The fontused and all such properties can be changed.

2. In the command window created the lines listed below have to be entered. You cantype them exactly as shown or you can load this file

http://people.brunel.ac.uk/~icstmkw/ma1690/Brunel_c++_setup.html

into a web browser (e.g. internet explorer), highlight the lines using the mouse bymoving the mouse cursor to the first character of the first line, press the mouse andkeep it pressed as you move to the last character of the last of the lines. With the lineshighlighted then press the Ctrl key and the letter C at the same time. This copies thehighlighted lines to a buffer. You then make the command prompt window the activewindow again and click the mouse on the top left hand corner to get a menu. Fromthe menu select “Edit” and from the sub-menu select “Paste”. This should executethe batch of lines that you highlighted.

There are at least two sets of lines you could type or cut and paste in the above waywhich will have about the same effect.

You could use the 3 lines.

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 4–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 5

net use r: /d

net use r: \\uxisapp1.brunel.ac.uk\apps

r:\c++\mybin11\mkw_s11.bat

The first time you do this the first line can be skipped as you will not have an existingr: drive to disconnect. The other net use command needs to be successful for thethe last command to work.

An alternate set of lines to highlight and paste or to type are the following.

H:

cd\

cd L:\ma\mingw\usr\local\wbin

if exist h:\mybin11.zip del h:\mybin11.zip

L:wget.exe http://people.brunel.ac.uk/~icstmkw/mybin11.zip

L:unzip -o mybin11.zip mkw_s11.bat

mkw_s11.bat

If you type the lines then please note that the line containing wget.exe must besuccessful before you type the subsequent lines.

If the above is done successfully then your desktop should contain, among other things,the icons indicated in figure 5 with some of them are explained in figure 6. For infor-mation, H: and L: are both network drives which you should have everytime you loginto the system in one of our labs.

These instruction copy a file called mybin11.zip from my web area and when the batchfile mkw s11.bat is run a directory h:\mybin11 is created and the files in the zip fileare put into this directory. The environment is then set so that you can more easilyuse software such as C++ compilers (provided they are installed on the PC) with anumber of icons put on the desktop.

1.2 Comments on differences between the labs

Due to changes in the last few weeks I now believe that most PCs in labs aroundthe campus run 64 bit Windows 7 as their operating system. Windows 7 has beenthe operating system in the labs run by our school for about 1 year (the SISCMlabs include HB213, HB223, SJ123 and JC123) but this is new for the labs run bythe Computer Centre such as JC124 and JC125. Until recently the Computer Centrelabs ran Windows XP. Although the SISCM labs and the Computer Centre labs nowboth have the same versions of Windows the software available differs which partlyaffects the C++ modules. The IDE codeblocks and the compiler g++ are availableon network drives and thus you should be able to use these anywhere. If you usecodeblocks in the Computer Centre labs then you will need to select the version ofthe projects which uses g++ as the compiler as the Microsoft compiler cl.exe is notavailable. In the SISCM labs you can use codeblocks with either compiler and youcan also use the IDE Visual Studio 2008. Visual Studio is only available in the SISCMlabs.

If you have your own computer then please note that there are a few differences betweenwhere things are located on your own computer compared with where they are locatedwhen you login at Brunel. In the case of the location of the desktop it is now at

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 5–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 6

Figure 5: The desktop after the initial set-up instructions. By default your backgroundscreen (i.e. the ‘wallpaper’) will probably not be the the plain white screen shown here andyou will probably have a smaller size for the desktop icons. (The plain desktop and largeicons were chosen here for legibility when this is printed and also to save print toner.) You caneasily set the wallpaper to any image (in .bmp, .jpg or .png format) that you have available.The Windows system has some possible wallpaper in the folder c:\windows\web\wallpaperand also the sub-folders. An explanation of some the icons is given on page 7.

H:\Desktop

which is on a network drive. On your own computer it is probably located on the localC: drive in a folder with a name of the form

c:\users\your_name\desktop

if you have Vista or Windows 7 or at

c:\documents and settings\your_name\desktop

where your_name is specific to you.

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 6–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 7

codeblocks

msdev latest

cmd 441

cmd 345

h dr

Start taskbar

codeblocks The latest version of the IDE known asCode::Blocks is version 10.05 from May 2010. Thisis located on network drives.

msdev latest This starts the IDE of the latest version of Mi-crosoft Visual Studio detected which is likely tothe version from 2008. If you have the versionfrom 2010 then this is started instead. (Visual Stu-dio 2008 has been available in most labs since thesummer of 2008, i.e. in the school rooms (JC123in the John Crank building and HB213 and HB223

in the Halsbury building and also in most of theComputer Centre rooms.)

cmd 441 This gives you a command window in which youcan run the latest version of the compiler cl.exe

(if available) and version 4.4.1 of g++.exe. (Whenyou install version 10.05 of Codeblocks you get ver-sion 4.4.1 of g++.)

cmd 345 This gives you a command window in which youcan run a version of the compiler cl.exe (if avail-able) and version 3.4.5 of g++.exe (which first ap-peared in 2006).

h dr This first creates a recursive listing of all your fileson the h: drive and it then sorts them by date, sizeand alphabetically and presents a menu so thatyou can select which one to see. This is useful tolocate your recent work and to locate large filescausing you to exceed your file quota.

Figure 6: Some of the icons created. In the directory h:\mybin11 there is a file namedas readme.html which describes all or most of the other icons and/or commands. All theicons containing cmd create command windows which are such that various compilers canbe used. Please let me know if anything is missing, or needs updating or does not workproperly.

If you remove or alter the entries in h:\mybin11, or the entries in your desktop areathat you get by following the previous instructions, then you may be able to quicklyrecover them by typing

h:\mkw_s11.bat

provided this file still exists. Alternatively, you can click on the icon which containsmkw s11 (provided this still exists). This may also be necessary, from time to time, ifcorrections to what is in mybin11.zip are necessary or if additional things are added.

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 7–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 8

1.3 Initial tests of your set-up

1.3.1 cl and g++ from the command line

1. To test that everything has worked, place the mouse pointer on the icon cmd 441.bat

and click the mouse. It is set-up so that it shows if cl.exe or g++.exe are availableand which versions.

2. Similarly place the mouse pointer on the icon cmd 345.bat and click the mouse andnote the versions that you get in this case.

3. To see all the versions of cl.exe and g++.exe that appear to be available on thecomputer type

adjust_cb.exe

and enter Z each time you are offered a choice. adjust cb is a program that I havewritten to easily adjust the settings in Codeblocks so that it uses a specific compilerwhen several versions exist. To reconfigure the command window to use another 32-bitversion of g++ you simply type, for example, a command of the form

cmd_bat -q -g 4.5.2

g++ -v

To reconfigure the command window to use a 64-bit version of g++ you simply type acommand of the form

cmd_bat -q -g 4.5.2 -64bit

g++ -v

Most programs that you write should work in exactly the same way with all of theseversions of g++ or will require only minor changes to make them work the same withall the compilers. If you spot differences between the versions then please let me know.

4. In the command window create a directory appropriate to this module by typing thefollowing.

h:

mkdir \cplusplus

You can organise your files differently if you prefer.

1.3.2 The u: drive and the Linux computer fenrir

5. From the previous items a number of drive letters have been mentioned which are H:,L: and R: and your files for this module and other modules should be saved on the H:

drive on which (I am informed) you have a quota of 500 MBytes in 2011/2012. The H:

drive is on one of the Windows Servers. There is actually also another drive which isallocated to you which a command window such as cmd_441 attempts to mount withthe letter U:. To check that this has been done type the following at the commandprompt.

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 8–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 9

net use

mkdir u:\cplusplus

cl >u:\cl_output 2>&1

dir u:

The U: drive is on a different server and corresponds to your home directory if youlogin to the computer named as fenrir.brunel.ac.uk. Your quota on the U: driveis only 10 MBytes.

In this module the U: drive may be used to copy files from your file space to elsewherewhich is possible provided you connect to fenrir and set the permissions to allow thiswhich can be done as follows. In the command prompt window created with cmd_441

type the following

putty %username%@fenrir.brunel.ac.uk

(Note that you do type exactly %username% in the above.) A new window will appearwith a login screen and you need to enter the same password that you used to startthe session. When you have successfully done this you will have a prompt of the form

v-fenrir%

At this prompt type

ls

which lists your files in a similar manner to the command dir u: done in the commandwindow on Windows and it should show a directory cplusplus, which was just createdabove, and the file cl_output which was also created above. For someone else to beable to copy any files put on u: you need to type the following.

cd

chmod ugo+x ../$user

To allow someone else to copy cl output created above type

chmod ugo+rx cl_output

After the first lab session I will check which files with the name cl_output I can copyas a check as to who attended the session and correctly did this step.

For information, the above instructions do not allow other people to list your files inyour u: drive area to see what is available then it only allows other people to list andcopy files when they know the exact name.

As a final task on fenrir you can do the following to create your own personal webpage. At the command prompt type

mkdir ~/webhome

chmod ugo+rx webhome

If you create a file with the name home.html in ~/webhome (as identified in linux) oru:\webhome (as identified in Windows) then this is what is seen if you use a URL ofthe form

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 9–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 10

http://people.brunel.ac.uk/~fo11XYZ/home.html

where fo11XYZ should be replaced by your actual login id.. To ensure that otherpeople have access to view the URL you will need to ensure that the permissions areset properly which can be done on fenrir by typing the command

chmod ugo+rx ~/webhome/home.html

When you have finished what you need to do on fenrir then type

exit

to logout.

Creating web pages is not part of this module and remember that U: only has a quotaof 10 MBytes and thus use the space carefully.

1.3.3 Testing that the IDEs for C++ start

6. To test the integrated development environment (IDE) known as codeblocks (oras code::blocks) starts you should place the mouse pointer on one of the iconscodeblocks and click the mouse. If this is the first time that you have used thesoftware then certain global initialisation files that the software uses will not yet existand the IDE will create these for you after first searching the computer for possiblecompilers. At Brunel it should locate one of the g++ compilers and Visual Studio 2008compiler cl and the IDE can be used with either of these. Close down the IDE byplacing the mouse on the cross on the top right hand corner and click.

For information, the initialization file that it has been created for you, and which willbe used on subsequent occasions by both versions, is located at

%appdata%\codeblocks\default.conf

Here %appdata% denotes a windows environmental variable. If you want to see thevalue of the variable then in a cmd window you should type

echo %appdata%

If you corrupt the initialization file for Codeblocks then I suggest that you delete theinitialization file and let Codeblocks create a new version.

7. To test that the IDE of the latest version of Visual Studio detected (which is likely tobe the version from 2008 at Brunel) place the mouse pointer on the icon msdev latest

and click the mouse. Close it down by placing the mouse on the cross on the top righthand corner and click. If the version that you are using is the 2008 version and if youare using this software for the first time then this may take a while as it creates folderswith names starting with

h:\Visual Studio 2008

8. A task for later and in a different lab: If you later use one of the computer centrelabs then I recommend that you try some of the above tests in such rooms to determinewhat can be done in such rooms.

Please let me know if you find that the situation with the IDEs and compilers isdifferent from what I indicate above.

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 10–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 11

2 Creating some short C++ programs in various ways

The following instructions are concerned with showing you various ways in which you cancreate and run a short “hello world” type program which is traditionally the first programthat people create when they start learning a programming language. When you have doneeverything you can decide which of the approaches you wish to continue to use for creatingsubsequent programs or you can use a way not described here if you have an alternativewhich you prefer. You are never tested on your ability to use one of these environments, youare only tested on aspects of the C++ language and the programs that you create to solvegiven problems.

As you will see, if you use one of the IDEs then for each C++ program that you create youalso have to create a project. The project contains information about all the files involved(which will be just one C++ file in this first module) and with how they will be compiledand various other details. Unfortunately, the IDEs do not usually provide a default projectbut there are not too many steps involved at this stage. I have created a program (actuallywritten in C++) which allows you to by-pass this step by creating project files for all, orsome, of the IDEs available in the lab (e.g. Code::Blocks, various versions of MicroSoftVisual Studio, and also other IDEs MinGWStudio, Dev-Cpp which some students have usedin previous years). You have to run this program in a suitable command window createdwith one of the icons starting with cmd and this is described below. The project files createdby this program can then be used within the IDE that you wish to use.

The following instructions are concerned with trying these possibilities. You can alsoalways compile and run a program from the command line and this is described in subsec-tion 2.2 on page 16.

2.1 Using the program cr proj to create project files

Click on one of the icons starting with cmd to create a suitable command prompt window.In the command prompt change directory (folder) to where you want to keep your C++ filesand my suggestion is the directory h:\cplusplus created in item 4 on page 8. You type

h:

cd \cplusplus

Provided you have not changed your set-up the prompt in the command window should thenlook like

H:\cplusplus\>

and this is your guide that you have done things correctly.

Next, to create a skeleton C++ file and projects for 2 of the IDEs type

cr_proj hellow.cpp

This creates hellow.cpp (providing that it does not already exist) and project files forcodeblocks and the latest version of Visual Studio detected. Currently at Brunel it createshellow.cbp, hellow cl.cbp (both for use with codeblocks) and hello vc9.vcproj for usewith Visual Studio 2008. If any of these files already exist then it is not overwritten. In thecase of codeblocks the project file hellow.cbp is set to use g++.exe when the source file is

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 11–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 12

compiled whilst hellow cl.cbp is set to use cl.exe (which is the same compiler as VisualStudio uses) when the source file is compiled.

To find out all the project files that can be created type the following at the prompt ina command window.

cr_proj

2.1.1 Using Code::Blocks

To use the IDE with project hellow.cbp or hellow cl.cbp place the mouse on an iconcontaining codeblocks and click the mouse. You should get a screen similar to that shownin figure 7.

As you already have codeblocks project files hellow.cbp and hellow cl.cbp you canuse either of these. One way to do this is to select File (top left hand corner) and thenselect Open.

In the File name box you need to arrange (by selecting or just typing or a combinationof these actions) that the information shown is the name of the project, e.g.

h:\cplusplus\hellow.cbp or h:\cplusplus\hellow_cl.cbp

Your setup should look similar to that shown in figure 8. Once this is done click on Open.Then on the side panel on the left hand side of the screen click on sources and whenhellow.cpp is shown click on this so that it is shown in the main window. The displayshould look like that shown in figure 9.

Modify the program so that it becomes

#include <iostream>

#include <iomanip>

#include <cstdlib>

#include <cstdio>

#include <cmath>

using namespace std;

int main()

{

cout << "Hello World, my first C++ program" << endl;

cout << "\n..type a key to finish " << flush; getc(stdin);

return 0;

}

Then attempt to compile and run by pressing the F9 key which is on the top line of yourkeyboard. If there are no mistakes then a default cmd type window is created and the outputgenerated from the program (the cout statements) is displayed in that window.

For this short program you actually only need one of the include lines which is

#include <iostream>

and hence you can remove lines so that the program is just the following.

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 12–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 13

Figure 7: The initial codeblocks screen.

Figure 8: The codeblocks screen when an existing project is being selected.

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 13–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 14

Figure 9: The codeblocks screen with a template of C++ lines shown.

Figure 10: The codeblocks screen for a C++ program with compilation errors indicated.

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 14–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 15

#include <iostream>

using namespace std;

int main()

{

cout << "Hello World, my first C++ program" << endl;

return 0;

}

Press the F9 key again to check that the program still works correctly.

For information, the other line containing cout is only needed if you use an IDE whichimmediately removes the output window when the program has finished. As far as I amaware, the IDEs which need this are Dev-Cpp and Visual Studio 2010 (VS 2010 is notcurrently installed in our labs). If you have the extra statement as given then the includeline containing <cstdio> is needed to use getc(stdin).

If you have mistakes then you need to go to the edit window and make the correctionswith the lines that the compiler does not understand being displayed in the dialogue part ofthe IDE which is below the edit window. For example, if your program has one of the linestruncated as in

cout << "Hello World, my first C++ program

then the IDE will look like that shown in figure 10.

If you did not make any mistakes then you might wish to experiment by introducingerrors to see what happens and to start getting experience with correcting compilationerrors. Please note that one syntax error may lead to many error messages and the usualrecommendation is to tackle the errors in the order that they are reported and to try tore-compile after each attempt at a correction.

I would recommend that you leave the session with codeblocks with a program thatcompiles. As in item 6 on page 10 close down the IDE by placing the mouse on the cross onthe top right hand corner and click.

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 15–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 16

2.1.2 Using Visual Studio 2008

To start the IDE at Brunel click on the icons containing msdev latest which should giveyou a screen which is of the form shown in figure 11. As you already have a project you can

Figure 11: The Visual Studio 2008 screen when you start.

use this. Select File on the top bar, then select Open and then select Project/Solution.Then in the file name box you need to arrange (by selecting or just typing or a combinationof these actions) that the information shown is h:\cplusplus\hellow_vc9.vcproj. TheIDE should be as shown in figure 12. You should click on Open and then click on the Source

Files part in the panel on the left hand side so that the screen is as shown in figure 13.

If line numbers are not shown in your version yet then there are instructions on page 21to activate these.

You will have exactly the same program that you used with the previous IDEs. Tocompile and run press the two keys Ctrl and F5 together and just press return to anyquestion that you are asked.

As in item 7 on page 10 close down the IDE by placing the mouse on the cross on thetop right hand corner and click.

2.2 Compiling using the command line

You can ignore the IDEs completely if you wish for the compilation and running of programs.In a command window created with any of the icons containing cmd type the following.

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 16–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 17

Figure 12: The Visual Studio screen when you have selected a project.

Figure 13: The Visual Studio screen with a project loaded and a C++ file displayed in theedit window.

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 17–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 18

H:

cd \cplusplus

To check what .cpp files exist in this location type

dir *.cpp

If hellow.cpp exists then you can compile with the Visual Studio compiler by typing

cl hellow.cpp

or

cl /EHsc hellow.cpp

(The second version does not show some of the warnings that might be generated.) Ifsuccessful hellow.exe is created then you can run by typing

hellow.exe

To do this instead with the compiler g++.exe type

g++ -s -o hellow.exe hellow.cpp

to create hellow.exe. To compile using g++.exe with all warnings shown type

g++ -s -Wall -o hellow.exe hellow.cpp

It is good practice to attempt to create programs with no warnings.

Please note that the compilation with cl.exe will be faster under Windows than usingg++.exe using the command line.

2.3 Summary of the options and some comments

This module is about learning C++ and creating working programs and it is your choice asto which of the ways offered you decide to mainly use. Whichever option you choose youneed to practice. I recommend that you always be aware of the command line way ofdoing things even though you may mainly use an IDE. Remember, when you use an IDE itis the project file that you open, which is only created once, and it is the .cpp file that youspend most of time creating in this module and which you need to take care to save.

The basic recommendation is that you use the way of working which you find easiestand most convenient. If you get errors that you cannot understand in one environment thenyou can sometimes get useful additional information by seeing what happens in anotherenvironment which is partly why it is good to have more than one way of doing things. Ifyou get errors that you cannot understand and overcome yourself then please ask us duringa supervised lab session and possibly also at the start of a lecture. I am likely to put theanswers to frequently asked questions in a web area that I use for the module.

All the IDEs are similar with some of the differences summarised below.IDE Extension in project file name Keys to press to compile and runCode::Blocks .cbp F9

Visual Studio 2008 .vcproj Ctrl F5

Visual Studio 2010 .vcxproj Ctrl F5

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 18–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 19

Other IDEs which some students have used in previous years include MinGWStudio andDev-Cpp and some details about using them are available in the document with the URLhttp://people.brunel.ac.uk/~icstmkw/ma1690/other_ides.pdf .

The end part of the project names and the keys to use are as follows.

IDE Extension in project file name Keys to press to compile and runMinGWStudio .mdsp F8

Dev-Cpp .dev F9

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 19–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 20

3 Trying a few C++ programs

3.1 Preliminary remarks and customising the output window

In the following, if you are using an IDE then you need to first create a project and thencreate and run each of the programs given. For example, in the case of the program insection 3.3 you can type the following in a suitable command prompt window

cr_proj prog33.cpp

to get you started.

From the tasks that you did in the previous section the output of the programs is alwaysshown in a command prompt window that is created. There are some adjustments that youcan make to this window to make it larger (or smaller), to change the colours or to increasethe number of lines that you can scroll backwards. By default the window has white text ona black background with the window size being such that there are 25 rows and 80 columnswith the capability to be able to scroll back 300 rows. As part of your set-up you can use aprogram that I have written to change these attributes when the window is created. In thecase of a “hello world” type program you may wish to try to create and run the following.

#include <iostream>

#include <cstdlib>

using namespace std;

int main()

{

system("y:\\cust_cmd.exe -s1");

cout << "Hello World, my first C++ program" << endl;

return 0;

}

For information, the include line containing <cstdlib> is needed to use the functionsystem().

You may also wish to see what happens if you replace the first line in the main() functionby

system("y:\\cust_cmd.exe -s2");

and then by

system("y:\\cust_cmd.exe -s3");

and finally by

system("y:\\cust_cmd.exe -fgcolor 4 -bgcolor A -rows 40 -cols 100 -fn 8");

To see all the options of cust_cmd.exe you can type the following in a command promptwindow.

y:\cust_cmd.exe -h -rows 40

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 20–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 21

3.2 Possibly adjusting the font size in the IDEs and showing theline numbers

From the initial tests that you have done you might prefer to increase or decrease the fontsize used and if you select to use Visual Studio then you may want line numbers shown inthe edit window. This can be done as follows.

If you have decided now which IDE you prefer then you only need to try the followingwith that IDE.

Adjusting the font size with codeblocks

This is achieved by selecting Settings (on the top bar) and then selecting Editor. In thewindow that is presented the top line gives a sample of text in the font currently being usedand there is a box next to it labelled as Choose which you need to click to alter the font.You can then either just select Cancel or you can select the font you want to use and clickon OK.

For information, the setting that you choose for codeblocks are saved in the followingfile which was mentioned earlier.

%appdata%\codeblocks\default.conf

If this file gets corrupted then you can delete it and a new version will be created for youthe next time you start codeblocks.

Adjusting the font size with Visual Studio and showing line numbers

You can change the font size by selecting Tools (on the top bar) and then selecting options

and then selecting Environment. In the left hand part of the window there is an item Fonts

and Colors which you need to use.

By default codeblocks shows line numbers but Visual Studio does not. To force this IDEto show line numbers in the editor window you need to use the menus provided as follows.

Select Tools on the top bar.

Select Options from the menu.

Select Text Editor from the menu.

Select C/C++

Select General

Select Display and click so that there is a tick symbol in the Line numbers box.

3.3 A program illustrating integer arithmetic and rounding errorwith floating point arithmetic

Create and run the following.

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 21–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 22

#include <iostream>

#include <iomanip>

using namespace std;

int main()

{

// .. arithmetic with type int

cout << "1/2=" << 1/2 << endl;

cout << "1.0/2=" << 1.0/2 << "\n" << endl;

// .. rounding error experiment

double v=1.0/3.0;

cout << setprecision(20);

cout << "v=" << v << endl;

cout << "3*v-1=" << 3*v-1 << "\n" << endl;

v=1.0/49.0;

cout << setprecision(20);

cout << "v=" << v << endl;

cout << "49*v-1=" << 49*v-1 << endl;

return 0;

}

As you should see, 1/2 gives 0 as integer arithmetic is used (which gives an integeranswer) but 1.0/2 is done using floating arithmetic to the precision of type double (whichhas an accuracy of about 15 decimal digits).

The <iomanip> include instruction is required to be able to use the setprecision()

command. The results of the 3*v-1 and/or 49*v-1 computations may vary with the compilerthat you use and may not be exactly 0 on the computer in both cases.

With Visual Studio 2008 from the command line I obtained

1/2=0

1.0/2=0.5

v=0.33333333333333331

3*v-1=0

v=0.020408163265306121

49*v-1=-1.1102230246251565e-016

With g++ version 3.4.5 from the command line I obtained

1/2=0

1.0/2=0.5

v=0.33333333333333331483

3*v-1=-5.5511151231257827021e-17

v=0.02040816326530612082

49*v-1=-7.9797279894933126343e-17

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 22–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 23

3.4 Testing if a 32-bit or a 64-bit environment

If you have purchased a computer recently or just browsed what is available you shouldhave noted that you do not have to go too far down the price list to get computers whichare installed with a 64-bit operating system. Thus we are now in a transisition periodwhen some computers are running a 32-bit operating system whilst others are operatinga 64-bit operating system. It must however be noted that if your computer is running a64-bit operating system then it may be that many of the applications that you use arestill the 32-bit versions that you have previously run and indeed you possibly would notnotice any difference if the response is fast. Everything in this module can be done in eitherenvironment although there will be differences in the results in certain situations which wenow investigate.

3.4.1 Running show some defines.cpp with the default set-up

In a command window when you are in folder h:\cplusplus type

copy h:\mybin11\show_some_defines.cpp prog34.cpp

cr_proj prog34.cpp

to copy a file and to create projects. Try running the program in the IDEs described earlier.

If you have not re-configured things then codeblocks using g++ should produce thefollowing output

a g++ compiler, possibly version 4.4.1

a windows compiler

_WIN32=1

processor __i386=1

1 byte=8bits, number of bytes in a pointer=4

..largest values of int and unsigned int follow:

INT_MAX= 2147483647

UINT_MAX=4294967295

..number of bytes in some standard types:

sizeof(char)= 1

sizeof(int)= 4

sizeof(long)= 4

sizeof(float)= 4

sizeof(double)= 8

sizeof(long double)=12

If you are using codeblocks with cl.exe or you are using Visual Studio 2008 then youshould get the following output

a windows compiler

_WIN32=1

_MSC_VER=1500

1 byte=8bits, number of bytes in a pointer=4

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 23–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 24

..largest values of int and unsigned int follow:

INT_MAX= 2147483647

UINT_MAX=4294967295

..number of bytes in some standard types:

sizeof(char)= 1

sizeof(int)= 4

sizeof(long)= 4

sizeof(float)= 4

sizeof(double)= 8

sizeof(long double)= 8

In both cases 32-bit versions are being used which is perhaps best indicated by the size of apointer only being 4-bytes which is 32-bits. (Pointers will be described later in the module.)There is a small difference between the two cases here in that the g++ compiler uses 12-bytesfor the type long double whereas for the compiler cl.exe this type is the same as double.(The standard for C++ only requires that long double is at least as accurate as double.)The INT MAX and UINT MAX values are 231 − 1 and 232 − 1 respectively.

You can also run the same program on fenrir as indicated previously by first typing

copy prog34.cpp u:\cplusplus\

and then connect to fenrir by typing

putty fenrir.brunel.ac.uk

and once logged in by typing

cd ~/cplusplus

g++ prog34.cpp

a.out

In this case you should get the following output

a g++ compiler, possibly version 4.1.2

not a windows compiler

processor __x86_64=1

1 byte=8bits, number of bytes in a pointer=8

..largest values of int and unsigned int follow:

INT_MAX= 2147483647

UINT_MAX=4294967295

..number of bytes in some standard types:

sizeof(char)= 1

sizeof(int)= 4

sizeof(long)= 8

sizeof(float)= 4

sizeof(double)= 8

sizeof(long double)=16

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 24–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 25

In this case the size of a pointer is 8-bytes (64 bits) as fenrir is running a 64-bit versionof linux and this version of g++ is 64-bit. Another difference, as compared with the teston Windows, is that each quantity of the type long uses 8-bytes and each quantity ofthe type long double uses 16-bytes. This means that the largest value of type long is263−1 = 9223372036854775808 (approx 9.22×1018). whereas it is only the INT MAX value inthe earlier cases. The difference between these values is gradually becoming a more significantissue as it is becoming more and more common to encounter single files which have a size inbytes which exceeds the values of both INT MAX and UINT MAX on 32-bit systems.

In this module I will mostly only use the types char, int and double. The type float

is a type which is like double in that it is for numbers with decimal points but it is lessaccurate with about 7 decimal digits of accuracy compared with about 15 decimal digits ofaccuracy of the type double.

3.4.2 Getting the 64-bit output with the Windows compilers

This section should be skipped if you do not have a 64-bit operating system or your compileris only 32-bit.

Using the command window

Compiling a program to create a 64-bit executable can be done quite easily using the com-mand window, it is straightforward with Visual Studio (provided Visual Studio has therelevant components installed) but a small number of steps are needed to force the IDEcodeblocks to use the 64-bit versions of the compilers instead of the 32-bit versions whichit automatically detects.

In case of the command window, click on the icon cmd 64bit. If 64-bit versions of thesoftware are detected then these are put in the path otherwise 32-bit versions are put in thepath.

If the first thing shown is close to the following, i.e. containing x64, then you have a64-bit version of cl.exe available. (If it shows x86 instead then you just have a 32-bitversion.)

Microsoft (R) C/C++ Optimizing Compiler Version 16.00.30319.01 for x64

Copyright (C) Microsoft Corporation. All rights reserved.

usage: cl [ option... ] filename... [ /link linkoption... ]

Unfortunately, at the time of writing these notes only the 32-bit version is available in theset-up that is being used in the labs.

The second thing shown relates to the version of g++ and if part of the output containsthe following then a 64-bit version of g++ is available.

Using built-in specs.

COLLECT_GCC=g++

....

Target: x86_64-w64-mingw32

....

Thread model: win32

gcc version 4.5.2 (tdm64-1)

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 25–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 26

I have installed a 64-bit version on a network drive and hence this is available everywherebut will only work if the computer is running a 64-bit version of Windows. You will usuallybe warned when you start if you use this command window but the computer is only runninga 32-bit version of Windows.

To compile and run you just type at the command prompt the following in the case ofcl.exe.

cl /EHsc show_some_defines.cpp

show_some_defines.exe

If you have a 64-bit version of cl.exe and you have Visual Studio 2010 then you will getthe following. (Visual Studio 2008 gives the same output except that 1500 is shown for theMSC VER value.)

a windows compiler

_WIN32=1

_WIN64=1

_MSC_VER=1600

1 byte=8bits, number of bytes in a pointer=8

..largest values of int and unsigned int follow:

INT_MAX= 2147483647

UINT_MAX=4294967295

..number of bytes in some standard types:

sizeof(char)= 1

sizeof(int)= 4

sizeof(long)= 4

sizeof(float)= 4

sizeof(double)= 8

sizeof(long double)= 8

Pointers are 8-bytes but long is still only 4-bytes.

On the computer fenrir the compiler being used is g++ and if you compile using g++

on windows then you would expect similar results. To compile and run you just type at thecommand prompt the following in the case of g++.exe.

g++ -s show_some_defines.cpp

a.exe

The output should now be as follows.

a g++ compiler, possibly version 4.5.2

a windows compiler

_WIN32=1

_WIN64=1

processor __x86_64=1

1 byte=8bits, number of bytes in a pointer=8

..largest values of int and unsigned int follow:

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 26–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 27

INT_MAX= 2147483647

UINT_MAX=4294967295

..number of bytes in some standard types:

sizeof(char)= 1

sizeof(int)= 4

sizeof(long)= 4

sizeof(float)= 4

sizeof(double)= 8

sizeof(long double)=16

This is similar to the fenrir output except that the type long is only the same as the typeint. Unfortunately there is no standard yet for an 8-byte int type although many compilershave the type long long to store whole numbers which exceed UINT MAX.

Using the IDE Visual Studio

Skip this if you do not have a 64-bit version of Visual Studio which is likely to be the casein the labs at Brunel.

If you have used cr proj to create the project then selecting the “build” to create the64-bit executable is straightforward and just involves the following. Near the top of the IDEwindow locate the box which is showing WIN32 or WIN64. If the box is showing WIN32 thenchange it to show WIN64 and I suggest that you adjust the neighbouring box showing Debug

or Release to show Release. Then compile and run as usual.

Using the IDE Codeblocks with g++

Adjusting Codeblocks to use the 64-bit versions of the compilers is a bit more complicatedthan it needs to be at the moment but I have set things up so that there are not too manysteps. In a command window type

adjust_cb

This program attempts to locate what versions of g++ and cl.exe are available, the ver-sions detected are shown and you just have to enter a letter to indicate which ones youwant codeblocks to use. Once you have done this start codeblocks and load the projectprog34.cbp. Compile and run by pressing F9. If you have selected the 64-bit version of g++then you should get the same output as was obtained using the command line.

When you have finished I would recommend that you type adjust cb again and makethe selections to return the settings of Codeblocks to use version 4.4.1 which it has beenset-up to use. There has been less testing of Codeblocks with the other versions of g++.

Using the IDE Codeblocks with cl.exe

Skip this if you do not have a 64-bit version of Visual Studio which is likely to be thecase in the labs at Brunel.

If you selected a 64-bit version of cl.exe when you used adjust cb then you are toldthat you need to type a command such as

set2008_64

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 27–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 28

This puts the 64-bit components of cl.exe in a location where codeblocks is set-up tofind them. Once you have done this start codeblocks and load the project prog34 cl.cbp.Compile and run by pressing F9. If you have previously run this program then codeblocks

is likely to think that no compilation is necessary as the .cpp file has not changed and youwill need to force it to compile by pressing the two keys Ctrl and F11 together followed byF9 to run again. You should now get the output that you obtained using the command linewith the 64-bit version of cl.exe.

As indicated previously, when you have finished I would recommend that you typeadjust cb again and make the selections to return the settings of codeblocks to use version4.4.1 of g++ and a 32-bit version of cl.exe. There has been less testing of codeblockswith the other versions.

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 28–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 29

3.5 Another program illustrating formatting commands

Create and run the following.

#include <iostream>

#include <iomanip>

using namespace std;

int main()

{

int i;

double v;

float f;

i=-89;

v=1.0/3.0;

f=v;

// .. output with default format

cout << "default int, double and float output" << endl;

cout << "i=" << i << endl;

cout << "v, f=" << v << " " << f << endl;

// .. change the width

cout << "a setw() example" << endl;

cout << "i=" << setw(12) << i << " i=" << setw(5) << i << endl;

// .. change the precision of all floats and doubles that follow

cout << "show results to 20 digit accuracy" << endl;

cout << setprecision(20);

cout << "v, f=" << v << " " << f << endl;

// .. other changes to the format

cout << "show other formatting possibilities" << endl;

cout << "v=";

cout << setw(30) << setfill(’_’) << v;

cout << scientific;

cout << setprecision(4);

cout << " v=" << setw(16) << v << endl;

return 0;

}

This illustrates what happens with the commands setw(), setprecision(), setfill()and scientific as part of the statements involving cout. The setw() instruction gives thewidth of the next item and if the item does not fit in this width then it is ignored. Thesetprecision() instruction determines how many decimal digits will be shown, it does notdetermine the accuracy of the floating point computation which will be about 15 decimaldigit accuracy on our PCs.

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 29–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 30

3.6 Short examples with for–loops

Create and run the following.

#include <iostream>

#include <iomanip>

using namespace std;

int main()

{

int i;

for(i=1; i<=12; i++)

cout << setw(2) << i << setw(2*i) << " " << "hello world" << endl;

cout << "after the loop i=" << i << endl;

return 0;

}

Here i is declared and starts with the value 1. The i++ part means that i increases by1 at each stage and the loop ends when the test i<=12 is no longer true.

Having the correct syntax is important. Note what happens if you change the programto the following which just involves adding a semi-colon at the end of the line starting withfor.

#include <iostream>

#include <iomanip>

using namespace std;

int main()

{

for(int i=1; i<=12; i++);

cout << setw(2) << i << setw(2*i) << " " << "hello world" << endl;

cout << "after the loop i=" << i << endl;

return 0;

}

The program will not compile and with g++ the error message when the program is calledforloop notcompile.cpp is as follows.

forloop_notcompile.cpp: In function ’int main()’:

forloop_notcompile.cpp:8: error: name lookup of ’i’ changed for

new ISO ’for’ scoping

forloop_notcompile.cpp:7: error: using obsolete binding at ’i’

The Microsoft compiler cl.exe reports the errors as

forloop_notcompile.cpp(8) : error C2065: ’i’ : undeclared identifier

forloop_notcompile.cpp(9) : error C2065: ’i’ : undeclared identifier

In C++ you must declare things before you use them but you must also be aware thatthings which you declare have a scope which is the part of the program in which they can

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 30–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 31

be used. When i is declared as above the scope is the for–block. Now when the semi-colonis put at the end of the for statement this means that the for–block finishes at that pointand i is no longer declared in the two lines that follow.

One way to overcome the scope problem above is to further change the program bydeclaring i earlier in the file so that we now have the following.

#include <iostream>

#include <iomanip>

using namespace std;

int main()

{

int i;

for(i=1; i<=12; i++);

cout << setw(2) << i << setw(2*i) << " " << "hello world" << endl;

return 0;

}

The program should now run but only give one line of output which should be as follows.

13 hello world

As was previously stated the for–block has scope which is just the one line

for(i=1; i<=12; i++);

which means that i increases by 1 until the test fails (i.e. when it has the value 13) and thecout statement is after the block and thus only one line of output is produced.

Finally remove the semi-colon at the end of the for statement to create

#include <iostream>

#include <iomanip>

using namespace std;

int main()

{

int i;

for(i=1; i<=12; i++)

cout << setw(2) << i << setw(2*i) << " " << "hello world" << endl;

return 0;

}

Check that it runs again and produces 12 lines of output. Further change the program to

#include <iostream>

#include <iomanip>

using namespace std;

int main()

{

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 31–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 32

int i;

for(i=1; i<=12; i++)

{

cout << setw(2) << i << setw(2*i) << " " << "hello world" << endl;

}

return 0;

}

In this example the for–block only has one statement and the brackets { and } are notneeded although it is harmless to include them. You will need to use these brackets whenthe block contains more than one statement.

As a final point with this example, note that there is no semi-colon needed after a closingbrackets }.

3.7 Printing the times table, loops within loops and the C++beautifier programs

To create a table you need a loop to generate the table row-by-row and on each row youneed an inner loop to generate each item on each row. To illustrate this create and run thefollowing.

#include <iostream>

#include <iomanip>

using namespace std;

int main()

{

// .. show the times tables

for(int i=1; i<=14; i++)

{

cout << setw(2) << i << ": ";

for(int j=1; j<=14; j++)

{

cout << setw(4);

cout << i*j << " ";

}

cout << endl;

}

return 0;

}

This illustrates the use of nested for–loops. Your output should be as follows.

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 32–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 33

1: 1 2 3 4 5 6 7 8 9 10 11 12 13 14

2: 2 4 6 8 10 12 14 16 18 20 22 24 26 28

3: 3 6 9 12 15 18 21 24 27 30 33 36 39 42

4: 4 8 12 16 20 24 28 32 36 40 44 48 52 56

5: 5 10 15 20 25 30 35 40 45 50 55 60 65 70

6: 6 12 18 24 30 36 42 48 54 60 66 72 78 84

7: 7 14 21 28 35 42 49 56 63 70 77 84 91 98

8: 8 16 24 32 40 48 56 64 72 80 88 96 104 112

9: 9 18 27 36 45 54 63 72 81 90 99 108 117 126

10: 10 20 30 40 50 60 70 80 90 100 110 120 130 140

11: 11 22 33 44 55 66 77 88 99 110 121 132 143 154

12: 12 24 36 48 60 72 84 96 108 120 132 144 156 168

13: 13 26 39 52 65 78 91 104 117 130 143 156 169 182

14: 14 28 42 56 70 84 98 112 126 140 154 168 182 196

Note that a number of lines in the above do not end in a semi-colon and you need totake care with the use of the semi-colon inorder that your program performs as you wouldlike. To see how you can damage the previous program observe what happens if you addsemi-colons at the end of the lines containing for, i.e. modify your program to the following.

#include <iostream>

#include <iomanip>

using namespace std;

int main()

{

// .. show the times tables

for(int i=1; i<=14; i++);

{

cout << setw(2) << i << ": ";

for(int j=1; j<=14; j++);

{

cout << setw(4);

cout << i*j << " ";

}

cout << endl;

}

return 0;

}

This will not compile because i and j are now being used outside of their scope. Tocorrect such errors you can move the int declaration parts to create the following.

#include <iostream>

#include <iomanip>

using namespace std;

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 33–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 34

int main()

{

// .. show the times tables

int i, j;

for(i=1; i<=14; i++);

{

cout << setw(2) << i << ": ";

for(j=1; j<=14; j++);

{

cout << setw(4);

cout << i*j << " ";

}

cout << endl;

}

return 0;

}

There is no compilation error now but the output will only be the following.

15: 225

The reason for this output is that the loops end at the semi-colon that follows them and thusthe only action in the loops is to increase i until 14 is exceeded and to increase j until 14is exceeded. After the loops both have the value 15 and thus the output is just 15 and152 = 225.

To help understand your programs you should aim to present them reasonably well withusually having uniform indentation of blocks of statements in loops. This will not howeverchange how a program compiles or runs. To see this you may wish to remove a few spacesand end of line characters in the previous program to create something close to the following.

#include <iostream>

#include <iomanip>

using namespace std;

int main()

{

// .. show the times tables

int i, j; for(i=1; i<=14; i++); {

cout << setw(2) << i << ": "; for(j=1; j<=14; j++);

{ cout << setw(4); cout << i*j << " "; } cout << endl; } return 0; }

To recover a better formatted version you can use some freely available programs that Ihave downloaded and put on our network r: drive. The programs are astyle (which standsfor artistic style) and bcpp (which stands for C++ beautifier).

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 34–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 35

The astyle program can be used within codeblocks by just clicking on Plugins (topbar) and then selecting Source Code formatter (AStyle). This is very convenient al-though you do not have much control over how astyle re-formats the C++ file with 4 spacesused for each indentation.

If you want a little more control over the re-formatting or if you are using a differentIDE than you need to use a suitable command prompt window. If your program is calleduntidy1.cpp then at the command prompt you can type

astyle_bat untidy1.cpp -s2

or alternatively you can type

astyle_bat untidy1.cpp -A7

Both these options lead to 2 spaces being used for each level or indentation. astyle bat.bat

is a batch file which first creates a back-up of the file in your temporary area before the re-formatting is done in case you need to return to the original file. The back-up version in thetemporary area will be lost when you logout and hence if you need to keep it you will needto move it before you logout.

To use the other program bcpp you also need to use a suitable command prompt window.I have added a front end part to this (which is mainly to check that the re-formatting doesnot change how the program will run). If the above C++ program is the file

h:\cplusplus\timestable.cpp

then in a command window created by one of the icons containing cmd you should type

h:

cd \cplusplus

bcpp_check timestable.cpp

This will create

out_bcpp_timestable.cpp (re-formatting from bcpp alone)

out3_bcpp_timestable.cpp (possible further re-formatting)

The out3.. version is the part I have added and there is also some checking and anindication as to how to replace the untidy version by the tidy version as in the following.

From testing the file out3_bcpp_timestable.cpp

..possible mistake, semi-colon found as in in for(..); or if(..);

10: for(i=1; i<=14; i++);

From testing the file out3_bcpp_timestable.cpp

..possible mistake, semi-colon found as in in for(..); or if(..);

13: for(j=1; j<=14; j++);

Type

use3 timestable.cpp

to replace timestable.cpp by out3_bcpp_timestable.cpp

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 35–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 36

If you type this command then the program becomes

#include <iostream>

#include <iomanip>

using namespace std;

int main()

{

// .. show the times tables

int i, j;

for(i=1; i<=14; i++);

{

cout << setw(2) << i << ": ";

for(j=1; j<=14; j++);

{

cout << setw(4);

cout << i*j << " ";

}

cout << endl;

}

return 0;

}

and you can edit the file by changing lines 10 and 13 to remove the extra semi-colon so thatyou have the following.

#include <iostream>

#include <iomanip>

using namespace std;

int main()

{

// .. show the times tables

int i, j;

for(i=1; i<=14; i++)

{

cout << setw(2) << i << ": ";

for(j=1; j<=14; j++)

{

cout << setw(4);

cout << i*j << " ";

}

cout << endl;

}

return 0;

}

The re-formatting uses two spaces for each level of indentation. To have instead 4 spacesyou should type instead

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 36–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 37

bcpp_check timestable.cpp -i 4

This will create the file

#include <iostream>

#include <iomanip>

using namespace std;

int main()

{

// .. show the times tables

int i, j;

for(i=1; i<=14; i++)

{

cout << setw(2) << i << ": ";

for(j=1; j<=14; j++)

{

cout << setw(4);

cout << i*j << " ";

}

cout << endl;

}

return 0;

}

Again, to replace the ‘old’ version of timestable.cpp with the version above you needto type

use3 timestable.cpp

in the command window.

Comment about astyle and bcpp

You can use astyle and bcpp check as frequently or as infrequently as you choose and youuse it at your own risk (i.e. the possibility of converting a working program into one that doesnot work (although I have not encountered this yet)). The program is useful in maintaining auniform formatting of your source code (which can be difficult to do when you are constantlyextending it). In the case of bcpp checks are made to determine if the re-formatted sourcecode will work in exactly the same way as the original source code although the dis-advantageof this is that it takes longer to run. There are valid programming situations where the re-formatted code will not run in exactly the same way, for example, if you use the macro__LINE__ (see subsection 3.9), which can be useful in identifying the line number in thesource file associated with an output statement, then the re-formatted file will usually havedifferent line numbers to the original file and both programs will probably not behave in anidentical way.

3.8 Printing the ASCII character set

Create and run the following.

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 37–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 38

#include <iostream>

#include <iomanip>

using namespace std;

int main()

{

// .. show the characters corresponding to integers in the range

// .. 32--126

cout << setw(7) << " ";

for(int i=32; i<=126; i++)

{

cout << setw(4) << i << " " << setw(1) << char(i) << " ";

if(i%10==0) cout << endl;

}

cout << endl;

return 0;

}

In this example i%10 gives the remainder when i is divided by 10 and should not beconfused with i/10 which gives the int type result of dividing i by 10. The answer obtainedis compared with 0 (the == part of the instruction). When the outcome of i%10 is the sameas 0 the instruction following the if is executed. With this set-up a new line is printed afteri=40, then i=50 etc. and you should get the following output.

32 33 ! 34 " 35 # 36 $ 37 % 38 & 39 ’ 40 (

41 ) 42 * 43 + 44 , 45 - 46 . 47 / 48 0 49 1 50 2

51 3 52 4 53 5 54 6 55 7 56 8 57 9 58 : 59 ; 60 <

61 = 62 > 63 ? 64 @ 65 A 66 B 67 C 68 D 69 E 70 F

71 G 72 H 73 I 74 J 75 K 76 L 77 M 78 N 79 O 80 P

81 Q 82 R 83 S 84 T 85 U 86 V 87 W 88 X 89 Y 90 Z

91 [ 92 \ 93 ] 94 ^ 95 _ 96 ‘ 97 a 98 b 99 c 100 d

101 e 102 f 103 g 104 h 105 i 106 j 107 k 108 l 109 m 110 n

111 o 112 p 113 q 114 r 115 s 116 t 117 u 118 v 119 w 120 x

121 y 122 z 123 { 124 | 125 } 126 ~

There is a article about the character set available at the URL

http://en.wikipedia.org/wiki/ASCII

3.9 Accessing some system parameters and using macros

Create and run the following which uses some macros (the lines starting with #define).Take care with the syntax of the first few lines.

#include <iostream>

#include <iomanip>

#include <ctime>

#include <cmath>

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 38–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 39

using namespace std;

#define LINE_NUM_DET(v) {cout << __FILE__ << ", line " << __LINE__ << ": ";}

#define VAR_PR(v) {cout << #v << "=" << (v) << endl;}

#define PR(v) {LINE_NUM_DET(v) VAR_PR(v)}

int main()

{

// .. show pi using the macro

double pi=4*atan(1.0);

PR(pi);

cout << setprecision(16);

PR(pi);

// .. get the current time and display the current time

time_t p;

time(&p);

cout << "The number of seconds since 01 Jan 1970 is ";

cout << p << endl;

cout << setprecision(10);

cout << "This is approximately "

<< p/(365.25*24*60*60) << " years" << endl;

cout << "In words the current time is " << ctime(&p);

return 0;

}

The header <ctime> is needed for the time() and ctime() functions. If you use thetime() function at two different points in a program and you take the difference betweenthe two values generated then you obtain the number of seconds taken between the twostages of the program. Please note that if a task takes less than a second then this does notgive any useful information.

The ctime() function produces the time in a more readable form. The function time()

requires a pointer of the appropriate type as its argument which is the &p part of theexpression (&p means the pointer to p). Pointers will be considered later in the module.

At the start of the function main() the statement involving 4*atan(1.0) is a way ofobtaining the constant π to the accuracy of type double. Here atan(1.0) is the C++way of writing what mathematically is often written as arctan 1 or tan−1 1, i.e. the inversetangent of 1. From your knowledge of trigonometry you should know than tan 45◦ = 1.Now in C++ the standard mathematical functions available with the header <cmath> useradians and as 360◦ corresponds to 2π radians it follows that 45◦ corresponds to π/4, i.e.tanπ/4 = 1. Hence π/4 = tan−1 1 and we get π = 4 tan−1 1.

You are not expected to remember these macros although if you can remember whereto find them then you may find instructions such as PR(pi) useful later to easily print outvariables when you are attempting to work out why a longer program is not working as youwould like. Statements containing PR(.) can then be easily identified and removed whenyou no longer need to output such information.

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 39–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 40

4 Using the IDEs to create everything (may be skipped)

If you are happy with creating projects using cr proj then this section can be skippedthroughout this year. If you are not happy with cr proj or if you are curious to learn moreand know now which IDE you wish to use then you should only consider the subsection hererelevant to that IDE. If you do create project files yourself then you need to take care withwhere files are stored, so that you can easily find them again, and with where the IDE storesthe intermediate files that it creates. The program cr proj puts most of the intermediatefile in the temporary area which assigned to you (this is identfied by %TEMP% and is on thelocal hard disk) so as not to use up your disk quota (i.e. on h:) as well as being faster assaving files to the local disk is usually faster than saving to the network drive when manyother people are also using the network drive.

It seems to be an unfortunate fact that the larger, the more sophisticated and the morefeatures a piece of software has the more complicated it can be to use as a beginner untilyou become familiar with the correct choices to make from the numerous options that areavailable.

4.1 Using the codeblocks IDE to create everything

The following assumes that you are creating a new project and not opening an existingproject as described earlier.

1. To start the IDE you can click the mouse on an icon containing the word codeblocks.

2. Click the mouse on File (top left hand corner), select New and select Project.

3. You are offered several templates and you need to choose Console application.

4. You next choose C++.

5. You next get a window in which you need to indicate the name of your project andalso where it will be stored. I would avoid using names which contain spaces. If theproject is to be called hellow2 then enter this in the Project title box. At BrunelI would recommend that in the Folder to create project in: box that you puth:\cplusplus. You could then just accept the resulting file name which is created foryou (the bottom box) although you may which to adjust it so that it just shows

h:\cplusplus\hellow2.cbp

In this way all your short programs are in the same folder instead of having manysub-folders each containing files which are quite small. Click on Next when you havecompleted the decisions.

6. The next screen concerns where the intermediate files and the executable file will becreated with suggestions for each offered. If you are using your own computer then youmay wish to just accept all the suggestions and click the mouse on Finish. However,if you are at Brunel then this is likely to mean (depending on exactly what you aredoing now and have previously done) that all the intermediate files are stored on yourh:\ drive which will clutter up this drive, which may be slow if many people are usingthe network, and which will may lead to file quota problems later. You only need toensure that the C++ files (those ending in .cpp) are safely stored as all the other

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 40–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 41

files can be generated again quickly. Assuming that you did the initial set-up and y:\

is associated with the temporary space allocated to you then you should adjust the4 boxes so that they respectively show

y:\bin\Debug

y:\obj\Debug

y:\bin\Release

y:\obj\Release

The Debug and Release versions just relate to how the program is compiled.

7. In the next window you are shown the C++ file which is attached to your project whichis the template main.cpp file which comes with the software. You should rename thisand arrange that the new file name is part of the project. This can be achieved byselecting File (top left hand corner), select Save as and entering the C++ name youwant to use (e.g. hellow2.cpp). This saves the contents of the editor window using thename given. To adjust the project you then need to click on main.cpp in the left handpanel and select Remove from Project. Then click on Sources in the left hand paneland select Add files and then enter or select the file to use (e.g. hellow2.cpp). Youwill then also get a window in which you should click on the boxes bin and Releases

so that the file is properly part of the project.

8. You should check that the project works by pressing the F9 key as was done in sub-section 2.1.1.

9. You should add and/or remove lines from the file hellow2.cpp until your programsolves your given task.

In summary you create a Console application and it is likely to help if you arrangethat the project file .cbp and C++ file .cpp are stored in a directory such as h:\cplusplusbut with the Debug and Release files stored on y:\. You are advised to rename the templatesource file that the software initially gives you, remove it from the project and to add thenew name to the project. The F9 key attempts to compile and run.

4.2 Using the Visual Studio 2008 IDE to create everything

The following assumes that you are creating a new project and not opening an existingproject as described earlier.

I would recommend that you skip this step until you are more familiar with the languageas the other ways can always be used and because the Visual Studio package is a large pieceof software capable of doing many things and you are offered a number of choices at eachstage and it is important to make the correct choice. However, if you do attempt this nowthen you can proceed as follows.

If you still have the IDE open from the previous subsection then click on File and chooseClose Solution. Otherwise, start the IDE by clicking on msdev latest. We consider nowhow to create a new Empty project called hellow3 containing the C++ file hellow3.cpp.

1. Click on File, select New and then select Project. You are given some choices asto the type of project to create and for this module it will always be a Visual C++General type of project and from the options given you should always choose Empty

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 41–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 42

Project. You need to enter a name (I suggest that you put hellow3). The locationbox refers to the project files and to avoid filling up your H: drive area I suggest thatyou just enter y:\ for the location. Starting msdev latest sets y:\ as your temporaryarea (which is actually on the C: drive). For this module I would recommend that youensure that there is no tick in the box next to “Create directory for solution”. Clickon OK when you are ready.

2. You now need to create hellow3.cpp and add it to the project. Click on File, selectNew and select File. From the options offered the “Categories part” should be Visual

C++ and the installed template to select is C++ File. Create the file that you have donepreviously. You may wish to do this by pasting. If no window is currently open thenstart notepad with the file hellow2.cpp. You can do this from a command promptwindow by typing

notepad hellow2.cpp

Highlight all the lines by moving the mouse to the first character, keep pressing themouse and moving it to the end of the file. Press Ctrl and C to copy the highlightedlines into a buffer. Then make the edit window in Visual Studio the active windowagain and press Ctrl and V to paste the highlighted lines into the window.

3. To have the file name as hellow3.cpp click on File and select the appropriate linesaying Move Source....cpp into project. In the window that appears you canenter the file name as hellow3 provided the type of file says C++ source Files. Theleft hand part of the window should indicate that your project contains hellow3.cpp

in the Sources Files part.

4. You can then compile and run as before by pressing F7 and, if there are no errors,pressing Ctrl and F5 together.

5. As stated previously, it is good practice to select Build and the Clean options whenyou have finished before you exit the IDE.

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 42–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 43

5 A linear equation program – interactive input of the

parameters

Try the following complete program which is concerned with solving a linear equation

ax+ b = 0, which has solution x = − ba, provided a 6= 0,

with the user of the program entering a and b (the cin statement), some checks are madeon the input and then the solution is computed and output. The do–while loop is to enablemany different linear equations to be solved. If you attempting this early on in the termthen it may be a while before all the features used here are covered in the lectures. Nearlyall of the program is connected with the input and output of the data.

#include <iostream>

#include <climits>

using namespace std;

int main()

{

char reply=’y’;

do

{

// .. enter the coefficients of a linear equation a*x+b=0

double a, b, x;

cout << "\nAttempting to solve a*x+b=0" << endl;

cout << "enter a and b with a non-zero: ";

cin >> a >> b;

cout << "a=" << a << " b=" << b << endl;

// .. check that the input was OK

if(!cin.good())

{

cin.clear();

cin.ignore(INT_MAX, ’\n’);

cout << "an error occurred with the input" << endl;

continue;

}

cin.ignore(INT_MAX, ’\n’);

// .. check that a is non-zero

if(a==0)

{

cout << "a=0 --- we do not have a linear equation" << endl;

continue;

}

// .. obtain x and show the result

x=-b/a;

cout << "solution is " << x << endl;

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 43–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 44

// .. ask if another linear equation should be solved

cout << "Do you want to solve another linear equation? (y/n): ";

cin >> reply;

}while(reply==’y’ || reply==’Y’);

return 0;

}

6 Assignment statements and standard mathematical

functions

6.1 A quadratic equation program

A quadratic equation is an equation of the form

ax2 + bx+ c = 0

where a, b and c are given numbers with a 6= 0. It has real solutions (known as the roots ofthe quadratic) given by

−b±√b2 − 4ac

2a

provided b2 − 4ac ≥ 0. The following is a skeleton program which is similar to the linearequations program which uses the above formulae for finding the roots of a quadratic. Theskeleton program is not quite complete. Create the program and add appropriatelines to compute and output the real roots of a quadratic and test it on examples of yourown choice. In the program the <cmath> header makes available functions such as sqrt

which you can use in the form sqrt(d) when d is of type double.

#include <iostream>

#include <climits>

#include <cmath>

using namespace std;

int main()

{

char reply=’y’;

do

{

// .. enter the coefficients of a quadratic and determine the roots

double a, b, c;

cout << "\nAttempting to solve a*x^2+b*x+c=0" << endl;

cout << "enter a, b and c with a non-zero: ";

cin >> a >> b >> c;

cout << "a=" << a << " b=" << b << " c=" << c << endl;

// .. check that the input was OK

if(!cin.good())

{

cin.clear();

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 44–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 45

cin.ignore(INT_MAX, ’\n’);

cout << "an error occurred with the input" << endl;

continue;

}

cin.ignore(INT_MAX, ’\n’);

// .. check that a is non-zero

if(a==0)

{

cout << "a=0 --- we do not have a quadratic" << endl;

continue;

}

double d;

d=b*b-4*a*c;

// .. check that d>=0

if(d<0)

{

cout << "b*b-4*a*c=" << d << endl;

cout << "There are no real roots." << endl;

continue;

}

// ... THE LINES TO COMPUTE AND SHOW THE ROOTS NEED TO GO NEXT

// .. ask if another quadratic is to be considered

cout << "Do you want to solve another quadratic? (y/n): ";

cin >> reply;

}while(reply==’y’ || reply==’Y’);

return 0;

}

As in the linear equations example in section 5, the use of do-while, if and continue

should be covered in the lectures in the first part of Term 1. The statements

if(!cin.good())

{

cin.clear();

cin.ignore(INT_MAX, ’\n’);

cout << "an error occurred with the input" << endl;

continue;

}

are concerned with checking that the input was OK and with clearing errors if they occurred.Here 3 different member functions of cin are used which are good(), clear() and ignore().The part !cin.good() is true when cin.good() is false and this will be the case if at leastone of the 3 items entered is not a number (you should try an invalid input when you run theprogram). If an error does occur then you need to clear the error flag to use cin again andit is best also to ignore any data which may still be waiting to be used. This is achieved herewith the clear() member function and with cin.ignore(INT_MAX, ’\n’) which ignoresup to INT MAX characters in the input buffer or until and end of line character is detected.

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 45–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 46

If there is no data still waiting to be used then the ignore() statement is harmless. If inthe unusual case that there are more than INT MAX characters still in the input buffer thenthe program is likely to fail.

6.2 Computing the angles of a triangle

(x1, y1)

(x2, y2)

(x3, y3)

a

c

b

θc

θa

θb

Let (x1, y1), (x2, y2) and (x3, y3) be 3 points in a plane which give the vertices of a triangle.The side lengths of the triangle are thus

a =√

(x1 − x2)2 + (y1 − y2)2,b =

√(x1 − x3)2 + (y1 − y3)2,

c =√

(x2 − x3)2 + (y2 − y3)2.

The angles of the triangle can be computed using the cosine rule which involves

θa = cos−1(b2 + c2 − a2

2bc

),

θb = cos−1(a2 + c2 − b2

2ac

),

θc = cos−1(a2 + b2 − c2

2ab

).

The following program partially does this. Enter the program and add the relevant lines tocompute lengths a, b and c and the angles θa, θb and θc which in the program are namedas anga, angb and angc respectively. (Please note that the skeleton program given will notcompile until anga, angb and angc have been declared.)

In the program the <cmath> header makes available functions such as acos which youuse in the form acos(x) with a variable x which should be of type double. To get a validanswer with acos(x) you need x to be less than or equal to 1 in magnitude.

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 46–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 47

#include <iostream>

#include <cmath>

using namespace std;

int main()

{

cout << "The angles of a triangles." << endl;

// .. get the 3 vertices

double x1, y1, x2, y2, x3, y3;

cout << "Enter the vertices x1,y1, x2,y2, x3,y3: ";

cin >> x1 >> y1 >> x2 >> y2 >> x3 >> y3;

// .. compute the 3 side lengths a, b and c

// .. YOU NEED STATEMENTS TO DECLARE AND THEN COMPUTE a, b AND c

// .. Use the cosine rule to get the angles anga, angb and angc

// .. YOU NEED STATEMENTS TO DECLARE AND THEN COMPUTE anga, angb AND angc

// .. output the angles in degrees

const double PI=4*atan(1.0);

cout << "The 3 angles are ";

cout << 180*anga/PI << " ";

cout << 180*angb/PI << " ";

cout << 180*angc/PI << endl;

return 0;

}

As test problems you can use the following triangles which are respectively a right angledtriangle (with angles of 90, 45 and 45 degrees) and an equilateral triangle (with anglesof 60, 60 and 60 degrees). In the case of the equalateral triangle you will need to enter0.866025403784439 as one of your 6 numbers.

(0, 0) (1, 0)

(0, 1)

(0, 0) (1, 0)

(12 ,

√3

2 )

√3

2 = 0.866025403784439

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 47–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 48

6.3 Approximations to sinx and cosx

In mathematics it can be shown that if x is in radians then

sin(x) = x− x3

3!+x5

5!− x7

7!+ · · ·

cos(x) = 1− x2

2!+x4

4!− x6

6!+ · · ·

where 3! = 6, 4! = 24, 5! = 120, 6! = 720, 7! = 5040 etc.. We can hence approximate thesefunctions by the functions

p(x) = x− x3

6+

x5

120− x7

5040,

q(x) = 1− x2

2+x4

24− x6

720.

A nearly complete program which computes p(x) and q(x) and does the comparison isshown below. Complete the program by adding the relevant lines and test your programwith x = 0.1, x = 0.2, x = 0.5 and x = 1. In the part that you add you just need to computethe values p(x) and q(x) and store these values in variables called p and q. With x = 1 youshould obtain the following.

x=1 sin(x)=0.841471 p=0.841468 difference=2.73084e-006

x=1 cos(x)=0.540302 q=0.540278 difference=2.45281e-005

#include <iostream>

#include <cmath>

using namespace std;

int main()

{

cout << "A polynomial approx to sin(x) and cos(x)" << endl;

// .. enter x

double x;

cout << "Enter x: ";

cin >> x;

// .. compute the approx to sin(x) and cos(x)

// .. ENTER THE STATEMENTS TO COMPUTE p AND q NEXT

double p, q;

// .. show x, sin(x), p and the difference

// .. show x, cos(x), q and the difference

double s=sin(x);

double c=cos(x);

cout << "x=" << x;

cout << " sin(x)=" << s;

cout << " p=" << p;

cout << " difference=" << s-p << endl;

cout << "x=" << x;

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 48–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 49

cout << " cos(x)=" << c;

cout << " q=" << q;

cout << " difference=" << c-q << endl;

return 0;

}

6.4 Converting mathematical expressions into C++ statements

Try the following program which computes and displays function values for x in the interval[1, 2] of the functions

x, x2, x4, ex,1

1.001− x,

1

(x− 0.99)(2.1− x).

#include <iostream>

#include <iomanip>

#include <cmath>

using namespace std;

int main()

{

// .. a table of function values for several functions

int i;

double x, y2, y4, ye, yr1, yr2;

cout << setw(12) << "x"

<< setw(12) << "x^2"

<< setw(12) << "x^4"

<< setw(12) << "exp(x)"

<< setw(14) << "rational1"

<< setw(12) << "rational2" << endl;

cout << fixed;

for(i=0; i<=10; i++)

{

x=1+0.1*i;

y2=x*x;

y4=y2*y2;

ye=exp(x);

yr1=1/(1.001-x);

yr2=1/((x-0.99)*(2.1-x));

cout << setw(12) << x

<< setw(12) << y2

<< setw(12) << y4

<< setw(12) << ye

<< setw(14) << yr1

<< setw(12) << yr2

<< endl;

}

return 0;

}

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 49–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 50

You should get the following.

x x^2 x^4 exp(x) rational1 rational2

1.000000 1.000000 1.000000 2.718282 1000.000000 90.909091

1.100000 1.210000 1.464100 3.004166 -10.101010 9.090909

1.200000 1.440000 2.073600 3.320117 -5.025126 5.291005

1.300000 1.690000 2.856100 3.669297 -3.344482 4.032258

1.400000 1.960000 3.841600 4.055200 -2.506266 3.484321

1.500000 2.250000 5.062500 4.481689 -2.004008 3.267974

1.600000 2.560000 6.553600 4.953032 -1.669449 3.278689

1.700000 2.890000 8.352100 5.473947 -1.430615 3.521127

1.800000 3.240000 10.497600 6.049647 -1.251564 4.115226

1.900000 3.610000 13.032100 6.685894 -1.112347 5.494505

2.000000 4.000000 16.000000 7.389056 -1.001001 9.900990

Create a similar program which creates

x f1 f2 f3

0.1000 0.9747543404 1.0000561127 -0.0000000000

0.2000 0.9490361294 1.0004064977 -0.0000000020

0.3000 0.9228767260 1.0012517454 -0.0000002658

0.4000 0.8963118146 1.0027253870 -0.0000084001

0.5000 0.8693814182 1.0049188688 -0.0001227086

0.6000 0.8421298475 1.0078972622 -0.0011055171

0.7000 0.8146055788 1.0117093936 -0.0072002200

0.8000 0.7868610573 1.0163945352 -0.0375696877

0.9000 0.7589524215 1.0219869325 -0.1699412348

1.0000 0.7309391472 1.0285189545 -0.7182818285

where f1, f2 and f3 correspond respectively to

f1(x) := 8

(ex − 1− x− x2/2e2x − 1− 2x− 2x2

), f2(x) :=

√1 + x

1 + x/2− x2/8, f3(x) := 1+x6−exp(x6).

6.5 A C++ expression for Gauss’ formula for cos(2π/17)

When the mathematician Gauss (1777–1855) was a teenager he showed that

cos

(2π

17

)=−1 +

√17 +

√34− 2

√17 + 2

√17 + 3

√17−

√34− 2

√17− 2

√34 + 2

√17

16.

See

http://en.wikipedia.org/wiki/Compass_and_straightedge_constructions

for more details.

Create the following program and extend it to verify, to the accuracy of floating pointarithmetic, that the left hand side and the right hand side give the same value.

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 50–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 51

#include <iostream>

#include <iomanip>

#include <cmath>

using namespace std;

int main()

{

double pi=4*atan(1.0);

cout << setprecision(12);

cout << setw(15) << "cos(2*pi/17)=" << cos(2*pi/17) << endl;

// .. extend the program to evaluate the expression

// .. involving many square roots to show that you get the same output

return 0;

}

Hint: I would recommend that you first create and use variables with statements such as

double a, b, c;

a=sqrt(17.0);

b=sqrt(34-2*a);

c=sqrt(34+2*a);

6.6 Cardano’s method for a root of a cubic equation

Sections 5 and section 6.1 considered C++ programs for solving linear equations and quadraticequations. It is also possible to solve cubic equations

x3 + ax2 + bx+ c = 0

involving a method attributed to Cardano (1501–1576). With a, b and c as real numbers therecan be 1, 2 or 3 different real solutions (known as roots) and the following task is concernedwith programming the formula in the Cardano method as given below to determine one realroot.

It is beyond the scope of the C++ module to give a mathematical explanation of themethod and the task is just about attempting to follow the algorithm below which needs anumber of assignment statements and some if–else blocks.

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 51–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 52

Steps in Cardano’s method:

p = −b/3 + a2/9.q = 2a3/27− ab/3 + c.d = q2 − 4p3.If d > 0 then

If q ≤ 0 theny = (−q +

√d)/2.

Elsey = (−q −

√d)/2.

End of If block.u = 3√y.

v = p/u.x = −a/3 + u+ v.

Elser =√p.

x = −a/3.If r > 0 thent = atan2(

√−d,−q).

x = −a/3 + 2r cos(t/3).End of If block.

End of If block.

A skeleton program to start the task, which is similar to the skeleton programs for thelinear and quadratic equations tasks can be as given below. For the part that you need toadd you need to declare all the variables used and you can implement u = 3

√y with the C++

statement

u=cube_root(y);

which uses the function given at the top of the skeleton listing. Also, the statement corre-sponding to t = · · · can be given as

t=atan2(sqrt(-d), -q);

which uses one the functions in <cmath> to determine the angle (in radians) of a point(−q,

√−d).

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 52–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 53

#include <iostream>

#include <iomanip>

#include <climits>

#include <cmath>

using namespace std;

double cube_root(double x)

{

if(x==0) return 0;

if(x>0) return pow(x, 1.0/3);

return -pow(-x, 1.0/3);

}

int main()

{

char reply=’y’;

do

{

// .. enter the coefficients of a cubic and determine the roots

double a, b, c;

cout << "\nAttempting to solve x^3+a*x^2+b*x+c=0" << endl;

cout << "enter a, b and c: ";

cin >> a >> b >> c;

cout << "a=" << a << " b=" << b << " c=" << c << endl;

// .. check that the input was OK

if(!cin.good())

{

cin.clear();

cin.ignore(INT_MAX, ’\n’);

cout << "an error occurred with the input" << endl;

continue;

}

cin.ignore(INT_MAX, ’\n’);

// .. STATEMENTS TO COMPUTE AND SHOW A ROOT NEED TO BE ADDED NEXT

// .. ask if another cubic is to be considered

cout << "Do you want to solve another cubic? (y/n): ";

cin >> reply;

}while(reply==’y’ || reply==’Y’);

return 0;

}

If you manage to add the statements and you wish to check that you have done themcorrectly then when a = 1, b = 2 and c = 3 you should get x = −1.27568220365. As asecond example, the case a = 1, b = −9 and c = 2 should give x = 2.40122230483.

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 53–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 54

7 C++ programming tasks with for loops and if-else

statements

7.1 A compound interest rate program

If you put £x into a savings account with an annual interest rate of r% then after n yearsit is worth

y = x(

1 +r

100

)n.

(This assumes that the interest is only applied at the end of each year.) In the case thatx = 1000 and r = 5 write a program using a for–loop to tabulate n against y for n =0, 1, · · · , 20. You should obtain the following.

0 1000.00

1 1050.00

2 1102.50

3 1157.62

4 1215.51

5 1276.28

6 1340.10

7 1407.10

8 1477.46

9 1551.33

10 1628.89

11 1710.34

12 1795.86

13 1885.65

14 1979.93

15 2078.93

16 2182.87

17 2292.02

18 2406.62

19 2526.95

20 2653.30

You can get the output in this form if you use the header <iomanip> and you outputwith statements of the form

cout << setw(5) << n;

cout << " " << fixed << setprecision(2);

cout << setw(10) << y << endl;

7.2 Comparing doubles and the dangers of using == or != withthis type

Try the following.

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 54–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 55

#include <iostream>

using namespace std;

int main()

{

int i;

double v, w;

for(i=2; i<=200; i++)

{

v=1.0/i;

w=i*v;

if(w!=1)

cout << "with i=" << i << " w is not 1" << endl;

}

return 0;

}

Can you understand the output? In the cases when w is not 1 you may wish to outputw-1.

7.3 Approximately locating roots

The following graph

0 1 2 3 4 5 6 7 8 9 10−4

−3

−2

−1

0

1

2

3

4

5

corresponds to the function

f(x) = 0.1 + cos(3x) + 3 sin(1/(0.1 + (x− 3)2)) + cos(√

11x);

The values of f(x) at points x in 0 ≤ x ≤ 10 can be printed with a program of the followingform.

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 55–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 56

#include <iostream>

#include <iomanip>

#include <cmath>

using namespace std;

int main()

{

int n=500;

double h=10.0/n;

double s11=sqrt(11.0);

for(int i=0; i<n; i++)

{

double x1=i*h;

double x2=x1+h;

double f1=0.1+cos(3*x1)+3*sin(1/(0.1+(x1-3)*(x1-3)) )+cos(s11*x1);

double f2=0.1+cos(3*x2)+3*sin(1/(0.1+(x2-3)*(x2-3)) )+cos(s11*x2);

cout << scientific;

cout << setprecision(5);

cout << "x1, x2, f1, f2=";

cout << setw(12) << x1 << " " << setw(12) << x2 << " ";

cout << setw(15) << f1 << " " << setw(15) << f2 << endl;

}

return 0;

}

If f1 and f2 have opposite signs (i.e. one is positive and one is negative) then f(x) hasa root between x1 and x2. Can you extend this program to show the 14 intervals of width0.02 which each contain one of the roots of f(x)?

You should obtain the following.

x1, x2, f1, f2= 5.80000e-01 6.00000e-01 8.73299e-02 -2.47481e-02

x1, x2, f1, f2= 1.30000e+00 1.32000e+00 -3.13221e-02 9.50082e-02

x1, x2, f1, f2= 2.52000e+00 2.54000e+00 2.51025e-01 -4.10781e-01

x1, x2, f1, f2= 2.78000e+00 2.80000e+00 -2.69046e-02 8.63135e-01

x1, x2, f1, f2= 2.88000e+00 2.90000e+00 2.95098e-01 -6.46894e-01

x1, x2, f1, f2= 3.10000e+00 3.12000e+00 -5.64013e-01 3.93316e-01

x1, x2, f1, f2= 3.22000e+00 3.24000e+00 1.36085e-01 -9.18003e-01

x1, x2, f1, f2= 3.46000e+00 3.48000e+00 -2.18490e-01 4.36197e-01

x1, x2, f1, f2= 4.72000e+00 4.74000e+00 4.21198e-02 -3.97139e-02

x1, x2, f1, f2= 5.30000e+00 5.32000e+00 -3.33179e-02 3.33583e-02

x1, x2, f1, f2= 6.56000e+00 6.58000e+00 3.64417e-02 -2.48639e-02

x1, x2, f1, f2= 7.34000e+00 7.36000e+00 -3.64684e-02 1.10946e-02

x1, x2, f1, f2= 8.60000e+00 8.62000e+00 1.16159e-02 -9.13737e-03

x1, x2, f1, f2= 9.16000e+00 9.18000e+00 -1.19439e-02 1.92612e-03

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 56–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 57

Can you modify the program to create the following output?

1: (x1, x2)= ( 0.580, 0.600) f1= 8.73e-02, f2= -2.47e-02

2: (x1, x2)= ( 1.300, 1.320) f1= -3.13e-02, f2= 9.50e-02

3: (x1, x2)= ( 2.520, 2.540) f1= 2.51e-01, f2= -4.11e-01

4: (x1, x2)= ( 2.780, 2.800) f1= -2.69e-02, f2= 8.63e-01

5: (x1, x2)= ( 2.880, 2.900) f1= 2.95e-01, f2= -6.47e-01

6: (x1, x2)= ( 3.100, 3.120) f1= -5.64e-01, f2= 3.93e-01

7: (x1, x2)= ( 3.220, 3.240) f1= 1.36e-01, f2= -9.18e-01

8: (x1, x2)= ( 3.460, 3.480) f1= -2.18e-01, f2= 4.36e-01

9: (x1, x2)= ( 4.720, 4.740) f1= 4.21e-02, f2= -3.97e-02

10: (x1, x2)= ( 5.300, 5.320) f1= -3.33e-02, f2= 3.34e-02

11: (x1, x2)= ( 6.560, 6.580) f1= 3.64e-02, f2= -2.49e-02

12: (x1, x2)= ( 7.340, 7.360) f1= -3.65e-02, f2= 1.11e-02

13: (x1, x2)= ( 8.600, 8.620) f1= 1.16e-02, f2= -9.14e-03

14: (x1, x2)= ( 9.160, 9.180) f1= -1.19e-02, f2= 1.93e-03

To help you here a statement such as

cout << setprecision(3) << fixed << setw(6) << x1;

outputs x1 in a width of 6 with 3 numbers after the decimal point in a ‘fixed format’. Todisplay f2 in the scientific format as in the above you can use a statement such as thefollowing.

cout << setprecision(2) << scientific << setw(11) << f2;

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 57–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 58

7.4 Generating the factorials

The following computes the first few factorials which are defined as follows.

0! := 1, 1! := 1, 2! := (1)(2) = 2, 3! := (1)(2)(3) = 6,

n! := (1)(2)(3) · · · (n) = n(n− 1)! .

That is n! is the product of the first n natural numbers. You can generate these in a C++program using a for loop as follows.

#include <iostream>

#include <iomanip>

using namespace std;

int main()

{

// .. generate the first few factorials

int i, n=20;

int m;

double dm, v;

// .. m and dm will contain the latest factorial

// .. initialise m and dm;

m=1;

dm=1.0;

for(i=2; i<=n; i++)

{

m=i*m;

dm=i*dm;

v=m;

cout << "i=" << i << " m=" <<m;

cout << " dm=" << dm;

cout << " dm-m=" << dm-m << endl;

if(v!=dm)break;

}

return 0;

}

Try this program. Note that the output is a bit untidy. Replace the 3 lines containing cout

by the following 4 lines.

cout << setprecision(12);

cout << "i=" << setw(3) << i << " m=" << setw(15) << m;

cout << " dm=" << setw(20) << dm;

cout << " dm-m=" << dm-m << endl;

Do you know why the factorials computed using the type double eventually differ from thosecomputed with type int in the last line of the output? Hint: Consider again section 3.4 andyou may wish to see what happens when you add the 3 statements

int a=65536; // this is 2^{16}

cout << "a*a=" << a*a << endl;

cout << "a*a=" << double(a)*double(a) << endl;

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 58–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 59

7.5 Computing sums

for–loops can be used to compute sums. If mathematically we have

s = 1 + 2 + 3 + · · ·+ n =n∑

i=1

i

then we can compute this by successively computing (1+2), then (1+2)+3, then (1+2+3)+4,then etc. until finally (1 + 2 + 3 + · · ·+ n− 1) + n.

A C++ program which does this is as follows.

#include <iostream>

using namespace std;

int main()

{

// .. computing a sum

int i, n=1000;

// .. first initialise s and then add up the terms

double s=0;

for(i=1; i<=n; i++)s=s+i;

cout << "n=" << n << " s=" << s << endl;

return 0;

}

Create and run this program.

Extend this program to compute

1

n2

n∑i=1

i,

1

n3

n∑i=1

i2,

1

n4

n∑i=1

i3

1

n5

n∑i=1

i4

when n = 1000. To get the correct answer in each case you will need to do all the computa-tions in type double. Do you know why it will fail in some cases with our computers if youuse type int throughout?

If you want to check your answers then I obtained

0.5005, 0.333834, 0.2505, 0.2005

which are respectively close to 1/2, 1/3, 1/4 and 1/5.

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 59–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 60

7.6 Determining prime numbers

A whole number n ≥ 2 is a prime numbers if it only divisible by 1 and itself. The primenumber are thus 2, 3, 5, 7, 11, 13, 17, · · · . The purpose of the next task is to write a programwhich extends the following short program in order to show all the prime numbers in therange 2–999.

First try the following program.

#include <iostream>

#include <iomanip>

#include <cmath>

using namespace std;

int check_if_prime(int n)

{

// .. returns 1 if n>=2 and a prime number

// .. returns 0 otherwise

// .. first check if in range or divisible by 2

if(n<=1)return 0;

if(n==2)return 1;

if(n%2==0)return 0;

// .. check for odd number divisors

int i;

double upper=ceil(sqrt(double(n)));

for(i=3; i<=upper; i=i+2)

if(n%i==0)return 0;

// .. no divisors found, hence prime

return 1;

}

int main()

{

// .. check if n=989 and n=997 are prime

int m;

m=check_if_prime(989);

if(m==0)cout << 989 << " is not prime" << endl;

else cout << 989 << " is prime" << endl;

m=check_if_prime(997);

if(m==0)cout << 997 << " is not prime" << endl;

else cout << 997 << " is prime" << endl;

return 0;

}

Next extend or modify the main() function to attempt to create the following outputwhich compactly shows all the prime numbers in the range [2, 1000].

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 60–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 61

2 3 5 7 11 13 17 19 23 29 31 37

41 43 47 53 59 61 67 71 73 79 83 89

97 101 103 107 109 113 127 131 137 139 149 151

157 163 167 173 179 181 191 193 197 199 211 223

227 229 233 239 241 251 257 263 269 271 277 281

283 293 307 311 313 317 331 337 347 349 353 359

367 373 379 383 389 397 401 409 419 421 431 433

439 443 449 457 461 463 467 479 487 491 499 503

509 521 523 541 547 557 563 569 571 577 587 593

599 601 607 613 617 619 631 641 643 647 653 659

661 673 677 683 691 701 709 719 727 733 739 743

751 757 761 769 773 787 797 809 811 821 823 827

829 839 853 857 859 863 877 881 883 887 907 911

919 929 937 941 947 953 967 971 977 983 991 997

From the previous part you will know how many prime numbers are less than 1000. Showthe number of primes less than 1000 and extend the program further to determine and showthe number of primes in each range [1001, 2000], [2001, 3000], · · · , [9001, 10000]. You shouldaim to create output similar to the following.

168 primes in the range 1 to 1000

135 primes in the range 1001 to 2000

127 primes in the range 2001 to 3000

120 primes in the range 3001 to 4000

119 primes in the range 4001 to 5000

114 primes in the range 5001 to 6000

117 primes in the range 6001 to 7000

107 primes in the range 7001 to 8000

110 primes in the range 8001 to 9000

112 primes in the range 9001 to 10000

As a hint in how to do the last part you might note that to count the number of primenumbers in the range [8001, 9000] you can use statements similar to the following.

int j, k;

k=0;

for(j=8000+1; j<=9000; j=j+2)

if(check_if_prime(j))k++;

In the for–loop the part j=j+2 means that j increases by 2 at each stage as we alreadyknow that even numbers are not prime numbers and we do not need to check these.

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 61–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 62

8 Lab tests in Term 1 in previous years

A lab test took place in Nov 2009 when the module had the code MA1990 and a lab testtook place last year when the module had the current code of MA1690. In each case therewere 26 different versions of the test labelled as A–Z and the tests were “open book” in thatstudents could look at their notes and browse the internet but they could not communicatewith anyone else by any means. Before the exam conditions started the students had tofollow some instructions which generated some files that were needed during the test andfor the submission. The set-up and submission instructions are not included here and thusyou will also need to type the starting versions of the file if you wish to attempt one of theversions which is given below in each year. You will need to first get a file for each yearas follows. Get a suitable command window by clicking on an icon which contains cmd andthen in the window type

H:

md h:\cplusplus\labtest_2009

cd h:\cplusplus\labtest_2009

wget -N http://people.brunel.ac.uk/~icstmkw/lab_test_nov2009.h

md h:\cplusplus\labtest_2010

cd h:\cplusplus\labtest_2010

wget -N http://people.brunel.ac.uk/~icstmkw/lab_test_nov2010.h

The lab test which will take place during term 1 this year will not be a repeat of anyprevious test and, at the time of creating these lab instructions, has not been set yet.

8.1 One of the versions in Nov 2009 – version A

Create the following file in the folder h:\cplusplus\labtest_2009 and give it a name ofthe form fo11XYZ9 test1.cpp. with fo11XYZ9 replaced by your actual login id.

#include <iostream>

#include <iomanip>

#include <cstdlib>

#include <cstdio>

#include <cmath>

using namespace std;

#include "lab_test_nov2009.h"

int main()

{

create_backup(__FILE__);

// Q1: output your login id, your 7-digit student number

// and which version of the test you are doing (i.e. A, B, ..., Z)

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 62–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 63

// Q2: a two-column table follows

// Q3: times table 1,..,12 excluding numbers 4, 6 and 8

// Q4: show the contents of the array

const double b[8]={-4.67, 1.63, -3.17, 4.63, -1.09, -3.13, 1.09, -6.77};

// Q5: computations with the array b[]

return 0;

}

In Nov 2009 the students had 80 minutes under exam conditions and in the documentationit was stated that the lab test starts when you receive your questions. Your attendance slipwill be collected at that time and we will record which version you have been allocated. Ifyou have this sheet then you are doing version A.

There are 5 tasks and you should put your answer after the appropriate comment startingwith // Q1:, · · · , // Q5:. The marks allocated to each question are indicated in bold andin brackets on the right hand size of the page and all the marks sum to 20. Partial marksare possible in many cases.

1. Your answer to this part should be after the comment // Q1:.

Put one or more output statements to display your login id., your 7-digit studentnumber and the version of the test that you have been allocated. For example, if youruser-id is fo09xyz4, your number is 0987654 and you are doing version A of the testthen your output could be as follows.

Login id: fo09xyz4, student number 0987654, test version A.

[2 marks]

2. Your answer to this part should be after the comment // Q2:.

Put statements, which involve a for–loop, to create two columns which contain (ui, f(ui)),i = 0, 1, 2, 3, 4, 5, where ui = 0.2i and

v = f(u) =3u+ 8

u− 1.003

The aim is to create a table of the form

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 63–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 64

u v

0.00 -7.9760717846e+00

.... .................

.... .................

.... .................

0.80 -5.1231527094e+01

.... .................

Here .. should be replaced by the actual numbers. The first column should be ina width of 9 with setprecision(2) used. The second column should be in a widthof 21 with setprecision(10) and scientific used to get the output in the requiredformat.

[4 marks]

3. Your answer to this part should be after the comment // Q3:.

Put statements, which involve for–loops, to create the times table from 1 to 12 with4, 6 and 8 missing.

The aim is to create a table of the form

1 2 3 5 7 9 10 11 12

2 4 6 10 14 18 20 22 24

3 . . .. .. .. .. .. ..

5 .. .. .. .. .. .. .. ..

7 .. .. .. .. .. .. .. ..

9 .. .. .. .. .. .. .. ...

10 .. .. .. .. .. ... ... ...

11 .. .. .. .. .. ... ... ...

12 .. .. .. .. ... ... ... ...

Here .. should be replaced by the actual numbers.

[6 marks]

4. Your answer to this part should be after the comment // Q4:.

Put the statement

const double b[8]={-4.67, 1.63, -3.17, 4.63, -1.09, -3.13, 1.09, -6.77};

to create an array with name b and length 8.

Then using an appropriate for–loop add the statements to display the numbers in theform

-4.67

1.63

-3.17

4.63

-1.09

-3.13

1.09

-6.77

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 64–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 65

[3 marks]

5. Your answer to this part should be after the comment // Q5:.

Put appropriate statements which use one or more for–loops to compute and displaythe following sums involving the array with name b given in question 4.

7∑i=0

fabs(b[i])

and7∑

i=0

ceil(b[i]).

The first sum is the sum of the absolute values and the second sum is the sum of thewhole numbers obtained from rounding each value away from zero.

You should output the value for each of the sums computed.

[5 marks]

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 65–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 66

8.2 One of the versions in Nov 2010 – version A

Create the following file in the folder h:\cplusplus\labtest_2010 and give it a name ofthe form fo11XYZ9 test1.cpp with fo11XYZ9 replaced by your actual login id.

#include <iostream>

#include <iomanip>

#include <cstdlib>

#include <cmath>

using namespace std;

#include "lab_test_nov2010.h"

int main()

{

create_backup(__FILE__);

//..Q_1: answer follows

cout << "Q_1 output next" << endl;

//..Q_2: answer follows

cout << "\nQ_2 output next" << endl;

//..Q_3: answer follows

cout << "\nQ_3 output next" << endl;

//..Q_4: answer follows

cout << "\nQ_4 output next" << endl;

//..Q_5: answer follows

cout << "\nQ_5 output next" << endl;

//..Q_6: answer follows

cout << "\nQ_6 output next" << endl;

return 0;

}

In Nov 2010 the students had 80 minutes under exam conditions and in the documentationit was stated that the lab test starts when you receive your questions. Your attendance slipwill be collected at that time and we will record which version of the test you have beenallocated. If you have this sheet then you are doing version A.

1. Your answer to this part should be below the comment Q 1:. [2 marks]

Put one or more output statements to display in this order your login-id, your 7-digitstudent number and the version of the test that you have been allocated. For example,if your user-id is fo10xyz4 your number is 1023456 and you are doing version A ofthe test then your output could be as follows:

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 66–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 67

Login id: fo10xyz4, Student number 1023456, Test Version A.

2. Your answer to this part should be below the comment Q 2:. [6 marks]

Put statements, which involve a for–loop, to create two columns which contain pairsof numbers (pi, f(pi)), i = 0, 1, 2, 3, 4, 5, where pi = 0.2i and

q = f(p) = 1.9 + 2p+ 3p2 +p

p− 1.013.

The aim is to create a table of the form

... ............

0.2 2.1739975400

... ............

... ............

0.8 1.6641314554

... ..............

Here dots (..) should be replaced by the actual numbers. For full marks the firstcolumn should be in a width of 5 with setprecision(1) and fixed used. The secondcolumn should be in a width of 20 with setprecision(10) and fixed used.

3. Your answer to this part should be below the comment Q 3:. [3 marks]

Put statements, which involve for–loops, to create the following times table from 1to 10.

1 2 3 4 5 6 7 8 9 10

2 4 6 8 10 12 14 16 18 20

3 6 9 12 15 18 21 24 27 30

4 8 12 16 20 24 28 32 36 40

5 10 15 20 25 30 35 40 45 50

6 12 18 24 30 36 42 48 54 60

7 14 21 28 35 42 49 56 63 70

8 16 24 32 40 48 56 64 72 80

9 18 27 36 45 54 63 72 81 90

10 20 30 40 50 60 70 80 90 100

4. Your answer to this part should be below the comment Q 4:. [6 marks]

If the numbers in the times table shown in the previous question correspond to percent-ages in an exam then the task in this question is to use appropriate control statementsto create another 10× 10 table with some of the numbers replaced by letters. For thisspecific version of the test you need to arrange that the numbers between 0 and 34(inclusive) are replaced by the letter F and the numbers between 60 and 69 (inclusive)are replaced by the letter B so that the output contains the following.

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 67–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 68

. . . . . . . . . .

F F F F F 36 42 48 54 B

. . . . .. .. .. .. . ..

F F F F 40 48 56 B 72 80

. . . .. .. . .. .. .. ...

Here dots (..) should be replaced by the actual numbers or letters.

5. Your answer to this part should be below the comment Q 5:. [4 marks]

Put the statement

const int a[8]={101, 103, 107, 109, 113, 127, 131, 137};

to create an array with name a and length 8.

By using a set-up containing the lines below, or otherwise, display the entries in a gridwith 2 rows and 4 columns with each number displayed in a width of 5. The possibleset-up to use is as follows.

for(i=0; i<2; i++)

{for(j=4*i; j<4*(i+1); j++)...

...

}

with dots (...) replaced by appropriate statements and i and j will need to bedeclared before they are used. The output to aim to generate is of the following form.

101 103 ... ...

... ... ... 137

6. Your answer to this part should be below the comment Q 6:. [4 marks]

Add statements which compute and display the mean of the first 6 numbers of thearray used in the previous question.

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 68–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 69

9 C++ programming tasks with if, if–else and for

statements

The tasks of this section are concerned with the use of the if, if–else and for statements.

9.1 Generating Fibonacci numbers

The Fibonacci number are 1, 1, 2, 3, 5, 8, 13, · · · which involves each number being the sumof the previous two numbers. Mathematically we have

f1 := 1, f2 := 1, fn+1 = fn−1 + fn, n = 2, 3, · · · .

Appropriately complete the following skeleton program to compute and output the first32 numbers. You need to replace the ... parts by the appropriate statements as the givenskeleton program will not compile.

#include <iostream>

#include <iomanip>

using namespace std;

int main()

{

int fa=1, fb=1;

// .. output the first 2 numbers next

...

for(int n=3; n<=32 ; n++)

{

// .. compute the next number and output

int fc=...

// .. update fa and fb ready for the next case

// .. so that fa, fb, fc are 3 consecutive fibonacci numbers

fa=...

fb=...

}

...

return 0;

}

Below are the numbers that you should get.

1 1 2 3 5 8 13 21

34 55 89 144 233 377 610 987

1597 2584 4181 6765 10946 17711 28657 46368

75025 121393 196418 317811 514229 832040 1346269 2178309

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 69–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 70

9.2 Approximately determining the area under a curve

The following is the graph of the normal distribution function in the interval [−2.5, 2.5].

y = f(x) =1√2π

e−x2/2.

−2.5 −2 −1.5 −1 −0.5 0 0.5 1 1.5 2 2.50

0.05

0.1

0.15

0.2

0.25

0.3

0.35

We can evaluate this function at 200 equally spaced points in (−1, 1) with the followingprogram.

#include <iostream>

#include <iomanip>

#include <cmath>

using namespace std;

int main()

{

int n=200;

double h=2.0/n;

double pi=4*atan(1.0);

double a=1.0/sqrt(2*pi);

for(int k=0; k<n; k++)

{

double x=-1+(k+0.5)*h;

double y=a*exp(-x*x/2);

cout << fixed << setprecision(4);

cout << x << " " << y << endl;

}

return 0;

}

Implement this program.

Modify the program to compute and output the quantity

hn−1∑k=0

f(−1 + (k + 0.5)h), h =2

n,

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 70–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 71

which gives an approximation to the area under the curve. Repeat with n being 400, 800and 1600. You should obtain the following.

n Approx area200 0.6826915086400 0.6826899962800 0.6826896182

1600 0.6826895236

If you have met the normal distribution function in statistics then the area is the probabilitythat an event from a sample is within one standard deviation of the mean when the eventsare assumed to be normally distributed.

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 71–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 72

10 C++ programming tasks involving arrays and for

loops

The tasks of this section are concerned with using arrays together with using the statementsif, if–else and for as in previous sections. Some of the tasks re-visit tasks of previoussections which you can now do with the help of arrays.

10.1 Displaying in reverse order

The following program asks the user to enter a line which is then read and stored in an arrayof type char. Your task is to extend the program so that it displays the characters in reverseorder.

#include <iostream>

#include <iomanip>

#include <cstring>

using namespace std;

int main()

{

// .. ask for a line

char c[256];

cout << "enter a line: ";

cin.getline(c, 255, ’\n’);

int l=strlen(c);

cout << l << " characters entered in: " << c << endl;

// .. now output in reverse order

// .. your statements go next

return 0;

}

If you complete this task then the dialogue and output should be of the following formwhen C++ programming is entered at the prompt.

enter a line: C++ programming

15 characters entered in: C++ programming

In reverse: gnimmargorp ++C

10.2 Generating Fibonacci numbers (again)

The Fibonacci numbers are 1, 1, 2, 3, 5, 8, 13, · · · which involves each number being thesum of the previous two numbers. Mathematically we have

f0 = 1, f1 = 1, fn+1 = fn−1 + fn, n = 1, 2, · · · .

Implement the program using arrays to compute the first 32 of these numbers and then neatlyoutput them with 8 numbers on each line. You should get the output given in section 9.1.

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 72–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 73

10.3 The number of days since 31 December 2010

Consider the following program.

#include <iostream>

int num_of_days(int month, int day);

using namespace std;

int main()

{

// .. 2011 is not a leap year, Feb has 28 days

int num_months[12]={31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

// .. confirm that the 12 values in num_months[] add to 365

int i, k=0;

for(i=0; i<12; i++)k=k+num_months[i];

cout << "The number of days in 2010=" << k << endl;

return 0;

}

Extend the program to request a date in the form

26 09

for the 26th Sep 2010 and which then computes and outputs the number of days since31st December 2010. Thus in the above example it should compute

(31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 26) = 269

You can request and read in the month number and the day of the month with statementsof the form

int month, day;

cout << "Enter the month (1--12) followed by the day of the month: ";

cin >> month >> day;

Modify the program further so that you have a function with the header

int num_of_days(int month, int day);

which takes the month number (1–12) and the day of the month and returns the day of theyear in the range 1–365. You can then use the function with statements of the form

cout << "26 Sep 2011 is the " << num_of_days(9, 26)

<< " day of the year " << endl;

cout << "The number of days from this date until Christmas day is "

<< num_of_days(12, 25)-num_of_days(9, 26)+1 << endl;

By including the header statements

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 73–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 74

#include <fstream>

#include <iomanip>

we may wish to have statements such as the following to create a file with 365 lines whichshows the numbers for each day in 2011.

ofstream fout("alldays_in_2010");

cout << "..creating the file alldays_in_2011" << endl;

for(i=1; i<=12; i++)

for(k=1; k<=num_months[i-1]; k++)

fout << setw(3) << i << setw(3) << k << ": "

<< setw(6) << num_of_days(i, k) << endl;

fout.close();

10.4 The exact amount with the minimum number of coins

Suppose that you have many coins of each of the amounts 1, 2, 5, 10, 20, 50, 100 and 200pence and you wish to pay for something using the minimum number of coins. Write aprogram which requests the amount x in pence (x ≥ 1) and which determines the numberof coins of each type that you need to use. Thus if x = 678 then the output should be of theform

3 200 pence coins

1 50 pence coin

1 20 pence coin

1 5 pence coin

1 2 pence coin

1 1 pence coin

You may wish to organise your program by having an array

int coins[8]={200, 100, 50, 20, 10, 5, 2, 1};

At each stage you need to keep track of the amount remaining before you have all the coinsfor the exact amount. To describe what you have to do in the form of an algorithm let thecoin values be 200 = c0 > c1 > · · · > c7 = 1.

Set r = x.For i = 0, 1, · · · , 7 domi =integer part of r/ciRe-set r ←− r −mici.

Modify the program so that you have a function with the header

void num_of_coins(int amount, int n_coins[]);

which takes the int quantity amount and which determines an int type array of length 8containing the number of each of the coins to use with n_coins[0] being the number of 200pence coins, n_coins[1] being the number of 100 pence coins, etc.. The function is of typevoid which means that it does not return any value in the function call.

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 74–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 75

10.5 Reading a data set and analysing the data

The following program uses arrays to store numbers which are read from the file

prem_table_2010_2011.txt

which is shown below and which is available at the URL

http://people.brunel.ac.uk/~icstmkw/ma1690/prem_table_2010_2011.txt

The file contains all the results in the Premiership in the season 2010/2011. This data wasobtained from the following URL.

http://en.wikipedia.org/wiki/2010-11_Premier_League

year:2010_2011 ARS AST BIR BLB BLP BOL CHE EVE FUL LIV MNC MNU NEW STO SUN TOT WBA WHU WIG WOL

Arsenal 1-2 2-1 0-0 6-0 4-1 3-1 2-1 2-1 1-1 0-0 1-0 0-1 1-0 0-0 2-3 2-3 1-0 3-0 2-0

Aston_Villa 2-4 0-0 4-1 3-2 1-1 0-0 1-0 2-2 1-0 1-0 2-2 1-0 1-1 0-1 1-2 2-1 3-0 1-1 0-1

Birmingham_City 0-3 1-1 2-1 2-0 2-1 1-0 0-2 0-2 0-0 2-2 1-1 0-2 1-0 2-0 1-1 1-3 2-2 0-0 1-1

Blackburn_Rovers 1-2 2-0 1-1 2-2 1-0 1-2 1-0 1-1 3-1 0-1 1-1 0-0 0-2 0-0 0-1 2-0 1-1 2-1 3-0

Blackpool 1-3 1-1 1-2 1-2 4-3 1-3 2-2 2-2 2-1 2-3 2-3 1-1 0-0 1-2 3-1 2-1 1-3 1-3 2-1

Bolton_Wanderers 2-1 3-2 2-2 2-1 2-2 0-4 2-0 0-0 0-1 0-2 2-2 5-1 2-1 1-2 4-2 2-0 3-0 1-1 1-0

Chelsea 2-0 3-3 3-1 2-0 4-0 1-0 1-1 1-0 0-1 2-0 2-1 2-2 2-0 0-3 2-1 6-0 3-0 1-0 2-0

Everton 1-2 2-2 1-1 2-0 5-3 1-1 1-0 2-1 2-0 2-1 3-3 0-1 1-0 2-0 2-1 1-4 2-2 0-0 1-1

Fulham 2-2 1-1 1-1 3-2 3-0 3-0 0-0 0-0 2-5 1-4 2-2 1-0 2-0 0-0 1-2 3-0 1-3 2-0 2-1

Liverpool 1-1 3-0 5-0 2-1 1-2 2-1 2-0 2-2 1-0 3-0 3-1 3-0 2-0 2-2 0-2 1-0 3-0 1-1 0-1

Manchester_City 0-3 4-0 0-0 1-1 1-0 1-0 1-0 1-2 1-1 3-0 0-0 2-1 3-0 5-0 1-0 3-0 2-1 1-0 4-3

Manchester_United 1-0 3-1 5-0 7-1 4-2 1-0 2-1 1-0 2-0 3-2 2-1 3-0 2-1 2-0 2-0 2-2 3-0 2-0 2-1

Newcastle_United 4-4 6-0 2-1 1-2 0-2 1-1 1-1 1-2 0-0 3-1 1-3 0-0 1-2 5-1 1-1 3-3 5-0 2-2 4-1

Stoke_City 3-1 2-1 3-2 1-0 0-1 2-0 1-1 2-0 0-2 2-0 1-1 1-2 4-0 3-2 1-2 1-1 1-1 0-1 3-0

Sunderland 1-1 1-0 2-2 3-0 0-2 1-0 2-4 2-2 0-3 0-2 1-0 0-0 1-1 2-0 1-2 2-3 1-0 4-2 1-3

Tottenham_Hotspur 3-3 2-1 2-1 4-2 1-1 2-1 1-1 1-1 1-0 2-1 0-0 0-0 2-0 3-2 1-1 2-2 0-0 0-1 3-1

West_Bromwich_Albion 2-2 2-1 3-1 1-3 3-2 1-1 1-3 1-0 2-1 2-1 0-2 1-2 3-1 0-3 1-0 1-1 3-3 2-2 1-1

West_Ham_United 0-3 1-2 0-1 1-1 0-0 1-3 1-3 1-1 1-1 3-1 1-3 2-4 1-2 3-0 0-3 1-0 2-2 3-1 2-0

Wigan_Athletic 2-2 1-2 2-1 4-3 0-4 1-1 0-6 1-1 1-1 1-1 0-2 0-4 0-1 2-2 1-1 0-0 1-0 3-2 2-0

Wolverhampton_Wanderers 0-2 1-2 1-0 2-3 4-0 2-3 1-0 0-3 1-1 0-3 2-1 2-1 1-1 2-1 3-2 3-3 3-1 1-1 1-2

In the listing each pair of numbers indicates the results between the teams correspondingto the row and the column.

The following program reads the data, displays the data, and contains functions forsorting. Your task is to add the additional statements which will determine the number ofpoints and goal difference for each team so that a league table can be correctly displayed.In the program the result between team i and j is stored in a[i][2*j] and a[i][2*j+1].If the numbers are equal then the match was a draw and both teams obtained 1 point. Ifthe first number is greater than the second number then team i gets 3 points and team j

gets 0 points. If the first number is less than the second number then team i gets 0 pointsand team j gets 3 points. For the goal difference part the value for team i increases bya[i][2*j]-a[i][2*j+1] whilst the value for team j decreases by this amount.

#include <iostream>

#include <fstream>

#include <sstream>

#include <cstring>

#include <iomanip>

#include <cstdlib>

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 75–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 76

using namespace std;

int order_pint(const void *a, const void *b)

{

// .. criteria for putting pointers to ints in descending order

const int& x=**(const int**)a;

const int& y=**(const int**)b;

return y-x;

}

void int_sort(int n, int b[], int o[])

{

// .. determine the rank order o[] of b[0], ..., b[n-1]

if(n<=0)return;

int i;

int **c=new int*[n];

for(i=0; i<n; i++)c[i]=&b[i];

int *c0=c[0];

qsort(c, n, sizeof(c[0]), order_pint);

for(i=0; i<n; i++)o[i]=c[i]-c0;

delete[] c;

}

void analyse_year(const char fn[], int n)

{

system("y:\\cust_cmd.exe -s1");

int i, j, l;

char teams[22][32];

char dummy[16];

char line[256];

stringstream st;

char abbrev[22][4];

int a[22][42];

// .. read the data from the file into abbrev[], teams[] and a[][]

ifstream in(fn);

if(in==0)

{

cout << "..failed to open " << fn << endl;

exit(0);

}

in.getline(line, 256, ’\n’);

l=strlen(line);

st.clear();

st.str(line);

st >> dummy;

for(i=0; i<n; i++)st >> abbrev[i];

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 76–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 77

for(i=0; i<n; i++)

{

in.getline(line, 256, ’\n’);

l=strlen(line);

for(j=0; j<l; j++)if(line[j]==’-’)line[j]=’ ’;

st.clear();

st.str(line);

st >> teams[i];

for(j=0; j<i; j++) st >> a[i][2*j] >> a[i][2*j+1];

for(j=i+1; j<n; j++)st >> a[i][2*j] >> a[i][2*j+1];

}

in.close();

// .. display to confirm that the read was OK

cout << setw(3) << " ";

for(j=0; j<n; j++)cout << setw(4) << abbrev[j];

cout << endl;

for(i=0; i<n; i++)

{

cout << abbrev[i];

for(j=0; j<i; j++) cout << " " << a[i][2*j] << ’-’ << a[i][2*j+1];

cout << setw(4) << " ";

for(j=i+1; j<n; j++)cout << " " << a[i][2*j] << ’-’ << a[i][2*j+1];

cout << endl;

}

// .. determine the number of points and goal difference for each team

int points[22], gd[22], comb[22];

// .. YOUR CONTRIBUTION NEEDS TO GO NEXT

// .. combine points and goal difference

for(i=0; i<n; i++)comb[i]=1000*points[i]+gd[i];

cout << "\nPoints and goal difference for teams in alphabetical order"

<< endl;

for(i=0; i<n; i++)

cout << setw(3) << points[i] << setw(4) << gd[i]

<< " " << teams[i] << endl;

int o[22];

int_sort(n, comb, o);

cout << "\nPoints and goal difference for teams in points order" << endl;

for(i=0; i<n; i++)

cout << setw(3) << points[o[i]] << setw(4) << gd[o[i]]

<< " " << teams[o[i]] << endl;

}

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 77–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 78

int main()

{

system("y:\\cust_cmd.exe -s1");

analyse_year("prem_table_2010_2011.txt", 20);

return 0;

}

If you do things correctly then you should obtain the following.

Points and goal difference for teams in alphabetical order

68 29 Arsenal

48 -11 Aston_Villa

39 -21 Birmingham_City

43 -13 Blackburn_Rovers

39 -23 Blackpool

46 -4 Bolton_Wanderers

71 37 Chelsea

54 6 Everton

49 6 Fulham

58 14 Liverpool

71 27 Manchester_City

80 41 Manchester_United

46 -1 Newcastle

46 -2 Stoke_City

47 -11 Sunderland

62 9 Tottenham_Hotspur

47 -15 West_Bromwich_Albion

33 -27 West_Ham_United

42 -21 Wigan_Athletic

40 -20 Wolverhampton_Wanderers

Points and goal difference for teams in points order

80 41 Manchester_United

71 37 Chelsea

71 27 Manchester_City

68 29 Arsenal

62 9 Tottenham_Hotspur

58 14 Liverpool

54 6 Everton

49 6 Fulham

48 -11 Aston_Villa

47 -11 Sunderland

47 -15 West_Bromwich_Albion

46 -1 Newcastle

46 -2 Stoke_City

46 -4 Bolton_Wanderers

43 -13 Blackburn_Rovers

42 -21 Wigan_Athletic

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 78–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 79

40 -20 Wolverhampton_Wanderers

39 -21 Birmingham_City

39 -23 Blackpool

33 -27 West_Ham_United

You can also test your program with data from other years provided you first get thedata which can be done, for example, by getting a command window and typing

wget -N http://people.brunel.ac.uk/~icstmkw/ma1690/prem_table_1994_1995.txt

Then in your main() function you should add the statement

analyse_year("prem_table_1994_1995.txt", 22);

Data for all the years has been obtained using the wikipedia site mentioned above andalso the following URLs.

http://uk.eurosport.yahoo.com/football/premier-league/

http://www.pedwards.co.uk/

http://www.statto.com/football/stats/england/premier-league/

On some sites some of the the data may be inaccurate or incomplete in what they showabout the 380 results in all the seasons from 1995-1996 to 2010-2011 and the 462 results inall the seasons from 1992-1993 to 1994-1995 when there were 22 teams although I believethat the league tables presented are probably without errors.

10.6 Testing a random number generator

In the following program the function rand() is used which is available when the header<cstdlib> is included. When this is repeatedly used it generates a sequence of integers inthe range 0 to RAND_MAX which can be used when we want to perform simulations whichneed random data. The size of RAND MAX depends on the compiler that you are using andthe algorithm used to generate the sequence of random integers is also compiler dependentand specifically you will get different results when you run on Windows compared to whenyou run using the linux computer fenrir. However, you can get the source code of theWindows version of the rand() function and this is included in listing below. Create andrun this program.

#include <iostream>

#include <iomanip>

#include <cstdlib>

#include <cmath>

#include <ctime>

#include <climits>

using namespace std;

int HoldRand=0;

const int w_randmax=32767;

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 79–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 80

int windows_rand()

{

// .. equivalent to windows version of rand()

HoldRand = HoldRand * 214013 + 2531011;

int y = HoldRand >> 16;

int z = y & 0x7fff;

return z;

}

const double pi=4*atan(1.0);

double randn()

{

// .. generates pseudo random numbers satisfying a

// .. normal distribution with mean 0 and standard deviation of 1

double w1, w2, x;

w1=double(windows_rand())/w_randmax;

w2=double(windows_rand())/w_randmax;

if(w1==0)x=1e-15;

else x=sqrt(-2*log(w1))*cos(2*pi*w2);

return x;

}

double randu()

{

// .. re-scales to a uniform distribution on (0,1)

return double(1.0+windows_rand())/(w_randmax+2);

}

int main()

{

int i;

cout << "RAND_MAX=" << RAND_MAX << endl;

// .. display rand() and windows_rand() values

srand(0);

cout << left << setw(30) << "stdlib rand version: " << right;

for(i=0; i<6; i++)cout << " " << rand();

cout << endl;

cout << left << setw(30) << "windows_rand rand version: " << right;

HoldRand=0;

for(i=0; i<6; i++)cout << " " << windows_rand();

cout << endl;

return 0;

}

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 80–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 81

On Windows with either g++.exe or cl.exe you should get the following output.

RAND_MAX=32767

stdlib rand version: 38 7719 21238 2437 8855 11797

windows_rand rand version: 38 7719 21238 2437 8855 11797

Extend your program to do the following.

1. The function randu() generates pseudo random numbers uniformly distributed on(0, 1). To test this claim add lines containing the following.

int count1[]={0, 0, 0, 0, 0};

HoldRand=0;

double v;

for(i=0; i<10000000; i++)

{

v=randu();

// .. more lines needed

}

These lines use the function 10 million times. Add the extra lines to count how manyvalues (named as v above) lie in each of the 5 regions (0, 0.2), (0.2, 0.4), (0.4, 0.6),(0.6, 0.8) and (0.8, 1.0) and display the results. Below is what I obtained and youshould aim to generate.

number in (0.0, 0.2) is 2000064

number in (0.2, 0.4) is 1999716

number in (0.4, 0.6) is 1999225

number in (0.6, 0.8) is 2001562

number in (0.8, 1.0) is 1999433

This shows that there are about the same number of random numbers in each of theintervals.

2. The function randn() creates random numbers which satisfy a standard normal dis-tribution. To test this claim add lines containing the following.

HoldRand=0;

int count2[]={0, 0, 0};

for(i=0; i<1000000; i++)

{

v=randn();

// .. more lines needed

}

These lines use the function 1 million times. Add the extra lines to count how manyvalues (named as v above) lie in each of the 3 regions (−1, 1), (−2, 2) and (−3, 3) anddisplay the results. Below is what I obtained and you should aim to generate.

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 81–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 82

..tests with randn()

fraction of numbers in (-1, 1) is 0.683017

fraction of numbers in (-2, 2) is 0.954371

fraction of numbers in (-3, 3) is 0.997279

These numbers indicate the fraction of all the numbers generated which lie within 1,2 and 3 standard deviations of the mean.

3. The function rand() used by C and C++ is criticised for not generating randomnumbers of high quality which are needed in some applications and users which needhigh quality random numbers obtain their random numbers by other methods. Inthe case of the Windows version only 215 = 32768 different values are generated (thenumbers are 0, 1, · · · , RAND MAX). As the numbers depend on HoldRand, which is anint type, and as there are only 232 different possible values it can take this impliesthat the sequence of random numbers repeats itself after 232 or less calls. In fact thefunction repeats after it has been called exactly 232 times. Add the following lines totest this.

HoldRand=0;

for(i=0; i<6; i++)cout << " " << windows_rand();

cout << endl;

time_t t1, t2;

HoldRand=0;

double N=pow(2.0, 32);

time(&t1);

for(double y=0; y<N; y++)(int)windows_rand();

time(&t2);

cout << "after " << N << " calls we have HoldRand=" << HoldRand << endl;

cout << "..time taken=" << t2-t1 << " seconds" << endl;

for(i=0; i<6; i++)cout << " " << windows_rand();

cout << endl;

On various computers that I tried this it took 22, 38 and 52 seconds to do the 4.29×109

function calls. As you should observe, HoldRand is 0 again.

4. The previous task was concerned with the sequence repeating. Add the following linesto count how many times each of the numbers 0, 1, · · · , 32767 = 215 − 1 occurs whenthe random number generator is used 232 times.

int count3[w_randmax+1];

for(i=0; i<=w_randmax; i++)count3[i]=0;

HoldRand=0;

for(double y=0; y<N; y++)

{

int j=windows_rand();

count3[j]++;

}

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 82–

Wed Jan 4 10:20:56 2012 c© M. K. Warby Part A of the C++ lab tasks for ma1690 in 2011/2012 Page 83

Add additional lines to check each count value is 217. (Note that the run time herewill be similar to the previous task.)

– Part A of the C++ lab tasks for ma1690 in 2011/2012- –page 83–

8-1-2012 23:59 c© M. K. Warby C++ Programming labs, Term 2, 2011/2012 Page 84

C++ lab session tasks: Part B, Term 2

The dates for the weeks for Term 2 and beyond are as follows.

Univ Week Number Mo Tu We Th Fr

16 9 10 11 12 13 Jan

17 16 17 18 19 20

18 23 24 25 26 27

19 30 1 2 3 4

20 6 7 8 9 10 Feb

21 13 14 15 16 17

22 20 21 22 23 24 Combined test involving ma1690

23 27 28 29 1 2

24 5 6 7 8 9 Mar

25 12 13 14 15 16

26 19 20 21 22 23

27 26 27 28 29 30 Deadline for ma1690 assignment

28 2 3 4 5 6 Apr

29 9 10 11 12 13

30 16 17 18 19 20

31 23 24 25 26 27 Revision week

32 30 1 2 3 4 Exams

33 7 8 9 10 11 May, Exams

34 14 15 16 17 18 Exams

You will also have a two-hour unseen written examination in the exam period which isadvertised as Mon 30 Apr 2012–Fri 18 May 2012. As partial practice for the final examyou have a written question as part of the combined test which is planned to take place inweek 22.

Whether or not you completed the tasks in part A you are advised to attempt at leastsome of the tasks in part B to help prepare you for the assignment and to generally be closerto the material covered in the lectures. Hence you can immediately try the section 11.1 tasksthen later return to do some of the tasks in section A. If you are short of time then you mayconsider skipping sections 7.6, 10.6 and 10.5. If you are still unsure as to what to attemptand what to skip then please ask at the supervised lab sessions. When you are given theassignment then you start working on that during the lab sessions.

Remember, to learn programming you need to practice and you learn from the struggle toget things working properly. Please also note that any stage you can typically only expect topartially understand something with your depth of understanding improving as you progress.

All the material for this C++ module are contained in the following location.

http://people.brunel.ac.uk/~icstmkw/ma1690/

– C++ Programming labs, Term 2, 2011/2012, 84–

8-1-2012 23:59 c© M. K. Warby C++ Programming labs, Term 2, 2011/2012 Page 85

11 Creating functions: Binomial coefficients and Pas-

cal’s triangle

11.1 A function to compute binomial coefficients and generatingPascal’s triangle

For 0 ≤ k ≤ n the binomial coefficient(n

k

)=

n!

k!(n− k)!=

(n− k + 1)(n− k + 2) · · · (n− 1)n

2 · 3 · · · (k − 1)k.

By definition 0! = 1 and thus the binomial coefficient is 1 if k = 0 and if k > 0 it can becomputed with statements of the form

int v=n-k+1;

for(int i=2; i<=k; i++)v=(n-k+i)*v/i;

By doing the computations in this order the denominator is always a factor of the numeratorin the expression in the loop. Use this, or something similar to this, to create a functionwith the header

int binom(int n, int k);

which returns the binomial coefficient(nk

)and use the function to create Pascal’s triangle.

You should create the following.

1

1 1

1 2 1

1 3 3 1

1 4 6 4 1

1 5 10 10 5 1

1 6 15 20 15 6 1

1 7 21 35 35 21 7 1

1 8 28 56 70 56 28 8 1

1 9 36 84 126 126 84 36 9 1

1 10 45 120 210 252 210 120 45 10 1

1 11 55 165 330 462 462 330 165 55 11 1

Here the (n + 1)th row contains the n + 1 numbers(nk

), k = 0, 1, · · · , n. By having an

output command which sends the appropriate number of spaces at the start of each row canyou output the Pascal’s triangle in the following form?

– C++ Programming labs, Term 2, 2011/2012, 85–

8-1-2012 23:59 c© M. K. Warby C++ Programming labs, Term 2, 2011/2012 Page 86

1

1 1

1 2 1

1 3 3 1

1 4 6 4 1

1 5 10 10 5 1

1 6 15 20 15 6 1

1 7 21 35 35 21 7 1

1 8 28 56 70 56 28 8 1

1 9 36 84 126 126 84 36 9 1

1 10 45 120 210 252 210 120 45 10 1

1 11 55 165 330 462 462 330 165 55 11 1

If you have done the previous program then your output is likely to have been createdby using cout (as this is all that has been covered in term 1) with the output being shownin the default command window. To modify your program to also send to a file namedpascals triangle.txt you can do the following.

(i) Add the following line at the top of your file where the other #include statements arekept such as <iostream>.

#include <fstream>

(ii) In main() before your loop to display the rows of the triangle add the statement

ofstream fout("pascals_triangle.txt");

This declares fout and opens the file with the name given.

(iii) After any statement involving cout repeat the statement with cout replaced by fout.In this way you write the same information to the file as you display with cout.

(iv) Before return 0 in main() add

fout.close();

This is unlikely to be strictly needed as the file will be closed if the program completesproperly but it is good practice to do this.

If you do the above successfully then you should check that the file has been created anddoes have the correct output. (You can do this using any editor, e.g. notepad, or even usingthe editor associated with the IDE.)

11.2 Using arrays to generate Pascal’s triangle

Another way to generate Pascal’s triangle is to use the following identity.(n

0

)= 1,

(n

n

)= 1, and

(n

k

)=

(n− 1

k − 1

)+

(n− 1

k

), k = 1, · · · , n− 1.

That is, apart from the two edge values which are equal to 1, the values on the nth row arethe some of two entries on the (n− 1)th row. To generate the triangle it thus seems naturalto use two-dimensional arrays and have a statement of the form

– C++ Programming labs, Term 2, 2011/2012, 86–

8-1-2012 23:59 c© M. K. Warby C++ Programming labs, Term 2, 2011/2012 Page 87

a[n][k]=a[n-1][k-1]+a[n-1][k];

somewhere in the program. Enter and complete the following program which computesPascal’s triangle in this way.

#include <iostream>

#include <iomanip>

using namespace std;

const int m=12;

void show_triangle(int m, int a[][12]);

void show_triangle(int m, int *c[]);

int main()

{

// .. Pascal’s triangle

int a[m][m];

int n, k;

// .. determine a[][]

// .. ADD YOUR STATEMENTS

cout << "..show the triangle" << endl;

show_triangle(m, a);

// .. create an array of pointers and show the triangle again

int *c[m];

for(n=0; n<m; n++)c[n]=a[n];

cout << "..show the triangle again" << endl;

show_triangle(m, c);

return 0;

}

void show_triangle(int m, int *c[])

{

for(int n=0; n<m; n++)

{

for(int k=0; k<=n; k++)

cout << setw(5) << c[n][k];

cout << endl;

}

}

void show_triangle(int m, int a[][12])

{

for(int n=0; n<m; n++)

{

for(int k=0; k<=n; k++)

cout << setw(5) << a[n][k];

cout << endl;

}

}

– C++ Programming labs, Term 2, 2011/2012, 87–

8-1-2012 23:59 c© M. K. Warby C++ Programming labs, Term 2, 2011/2012 Page 88

12 Locating roots and turning points of functions

We revisit here the problem of finding the 14 roots in [0, 10] of the function

f(x) = 0.1 + cos(3x) + 3 sin(1/(0.1 + (x− 3)2)) + cos(√

11x)

shown in Figure 14 which was first considered in section 6.3, The task now is to createa function which reports the approximate roots and the approximate turning points of afunction using values (xi, yi), i = 0, 1, · · · , n− 1 where x0, · · · , xn−1 are equally spaced andwhere yi is the function value at xi. In this context we have approximately located a root ifwe have found an interval (xi, xi+1) for which

yiyi+1 ≤ 0,

we have approximately located a local minimum if we have found a value for which

yi−1 ≥ yi and yi ≤ yi+1

and we have approximately located a local maximum if we have found a value for which

yi−1 ≤ yi and yi ≥ yi+1.

The function to create which does such tests on the values y0, · · · , yn−1 and which reportsthe properties should have the header statement

void min_max_etc(int n, double x[], double y[]);

An outline of a complete program can then be as follows.

#include <iostream>

#include <iomanip>

#include <cmath>

using namespace std;

double f(double x);

void min_max_etc(int n, double x[], double y[]);

int main()

{

const int n=1000;

double x[n+1], y[n+1];

int i;

// .. create the arrays for function f

for(i=0; i<=n; i++)

{

x[i]=0.01*i;

y[i]=f(x[i]);

}

cout << "\nAnalysis of the function f():" << endl;

– C++ Programming labs, Term 2, 2011/2012, 88–

8-1-2012 23:59 c© M. K. Warby C++ Programming labs, Term 2, 2011/2012 Page 89

min_max_etc(n+1, x, y);

return 0;

}

double f(double x)

{

return 0.1+cos(3*x)+3*sin(1/(0.1+(x-3)*(x-3)) )+cos(sqrt(11.0)*x);

}

void min_max_etc(int n, double x[], double y[])

{

// .. report some properties: change of sign, min and max

cout << "Using " << n << " points from "

<< x[0] << " to " << x[n-1] << endl;

// ..ADD STATEMENTS TO FIND ROOTS, LOCAL MIN, LOCAL MAX

// ..AND GLOBAL MIN AND GLOBAL MAX

}

Part of the output that your program should generate is as follows.

Analysis of the function f():

Using 1001 points from 0 to 10

change of sign in the interval 0.59, 0.60

change of sign in the interval 1.30, 1.31

change of sign in the interval 2.52, 2.53

change of sign in the interval 2.78, 2.79

change of sign in the interval 2.88, 2.89

change of sign in the interval 3.11, 3.12

change of sign in the interval 3.22, 3.23

change of sign in the interval 3.46, 3.47

change of sign in the interval 4.73, 4.74

change of sign in the interval 5.31, 5.32

change of sign in the interval 6.57, 6.58

change of sign in the interval 7.35, 7.36

change of sign in the interval 8.61, 8.62

change of sign in the interval 9.17, 9.18

local maximum close to 0.01, y value= 2.43

local minimum close to 0.96, y value= -1.17

....several lines removed

discrete global maximum at 2.14, 4.56

– C++ Programming labs, Term 2, 2011/2012, 89–

8-1-2012 23:59 c© M. K. Warby C++ Programming labs, Term 2, 2011/2012 Page 90

0 1 2 3 4 5 6 7 8 9 10−4

−3

−2

−1

0

1

2

3

4

5

Figure 14: Graph of f(x) = 0.1 + cos(3x) + 3 sin(1/(0.1 + (x− 3)2)) + cos(√

11x)

– C++ Programming labs, Term 2, 2011/2012, 90–

8-1-2012 23:59 c© M. K. Warby C++ Programming labs, Term 2, 2011/2012 Page 91

13 Computing exp(x) using the Maclaurin expansion

The exponential function which is written as ex and as exp(x) has the Maclaurin expansion

ex = 1 + x+x2

2!+x3

3!+ · · ·+ xn

n!+ · · ·

which converges for all x. By taking n sufficiently large we can compute

1 + x+x2

2!+x3

3!+ · · ·+ xn

n!

to get an accurate approximation of ex. Write a function with a header of the form

double myexp(double x);

which computes this finite sum until n is first such that

|x|n

n!< 10−10.

Note that with a set-up such as

double v=1;

...

for(int n=1; ; n++)

{

v=v*x/n;

...

}

the double variable v will successively contain 1, x, x2/2, x3/6 which are exactly the termsin the Maclaurin expansion. You never need to separately compute n! to do this task.

Compare myexp() with the built-in function exp() which is available with the <cmath>

header by creating a table of the following form.

x exp(x) myexp(x) difference

-5.0 6.737946999085e-003 6.737946996062e-003 3.02301e-012

-4.0 1.831563888873e-002 1.831563887901e-002 9.72000e-012

-3.0 4.978706836786e-002 4.978706837110e-002 -3.23545e-012

-2.0 1.353352832366e-001 1.353352832405e-001 -3.91667e-012

-1.0 3.678794411714e-001 3.678794411722e-001 -7.19702e-013

-0.8 4.493289641172e-001 4.493289641167e-001 4.78839e-013

-0.6 5.488116360940e-001 5.488116360897e-001 4.34341e-012

-0.4 6.703200460356e-001 6.703200460367e-001 -1.01663e-012

-0.2 8.187307530780e-001 8.187307530794e-001 -1.38334e-012

0.0 1.000000000000e+000 1.000000000000e+000 0.00000e+000

0.2 1.221402758160e+000 1.221402758159e+000 1.43974e-012

0.4 1.491824697641e+000 1.491824697640e+000 1.08713e-012

0.6 1.822118800391e+000 1.822118800386e+000 4.76330e-012

0.8 2.225540928492e+000 2.225540928492e+000 5.32907e-013

1.0 2.718281828459e+000 2.718281828458e+000 8.14904e-013

2.0 7.389056098931e+000 7.389056098926e+000 4.78728e-012

3.0 2.008553692319e+001 2.008553692318e+001 4.16378e-012

4.0 5.459815003314e+001 5.459815003313e+001 1.30740e-011

5.0 1.484131591026e+002 1.484131591026e+002 4.23483e-012

– C++ Programming labs, Term 2, 2011/2012, 91–

8-1-2012 23:59 c© M. K. Warby C++ Programming labs, Term 2, 2011/2012 Page 92

To demonstrate function overloading, extend your program by creating another versionof myexp() corresponding to the header

double myexp(double x, int& n, double delta);

where the reference parameter n indicates the first value of n such that

|x|n

n!< |delta|.

With this version you should get the following when delta=10−10.

x exp(x) myexp(x) difference n

-5.0 6.737946999085e-003 6.737946996062e-003 3.02301e-012 29

-3.0 4.978706836786e-002 4.978706837110e-002 -3.23545e-012 22

-1.0 3.678794411714e-001 3.678794411722e-001 -7.19702e-013 14

1.0 2.718281828459e+000 2.718281828458e+000 8.14904e-013 14

3.0 2.008553692319e+001 2.008553692318e+001 4.16378e-012 22

5.0 1.484131591026e+002 1.484131591026e+002 4.23483e-012 29

– C++ Programming labs, Term 2, 2011/2012, 92–

8-1-2012 23:59 c© M. K. Warby C++ Programming labs, Term 2, 2011/2012 Page 93

14 Functions as arguments to other functions

14.1 A bisection method function

The bisection method is a method for computing a root of a continuous function

f : [a, b]→ R

which is such that f(a)f(b) < 0. The method involves successively dividing an interval intotwo parts of equal length and with choosing at each stage the part which brackets the root.

Write a function with the header statement

double bisection(double (*f)(double), double a, double b, double delta);

which does the following.

(∗) It first checks that f(a)f(b) ≤ 0. If this is false then it stops the program with anappropriate error message.

(∗) It next checks that delta>0 and if this is not true delta is set to 0. (The followingalgorithm will stop if delta is 0 with floating arithmetic as a stage will be reachedwhen a, b and the mid-point c used in the algorithm are no longer all different.)

(∗) If this stage is reached then the function should implement the following pseudo codewhere in this description a, b, f and δ corresponds to a, b, f and delta.

Let w = |b− a|.Compute the mid-point c = (a+ b)/2.While w > δ and a < c and c < b

Compute f(c).Set w ← w/2If f(a)f(c) ≤ 0b← c

Elsea← c

Compute the mid-point c = (a+ b)/2.

When this stage is reached the function should return the value c.

Use the function to find the roots of the function considered previously in section 12, i.e.

f(x) = 0.1 + cos(3x) + 3 sin(1/(0.1 + (x− 3)2)) + cos(√

11x)

by choosing as the intervals [a, b] the intervals found by the min_max_etc() functions. Thusan outline of your program can be as follows.

– C++ Programming labs, Term 2, 2011/2012, 93–

8-1-2012 23:59 c© M. K. Warby C++ Programming labs, Term 2, 2011/2012 Page 94

#include <iostream>

#include <iomanip>

#include <cmath>

#include <cstdlib>

using namespace std;

double bisection(double (*f)(double), double a, double b, double delta);

double f(double x)

{

return 0.1+cos(3*x)+3*sin(1/(0.1+(x-3)*(x-3)) )+cos(sqrt(11.0)*x);

}

int main()

{

const int n=1000;

double x[n+1], y[n+1];

int i;

for(i=0; i<=n; i++)

{

x[i]=0.01*i;

y[i]=f(x[i]);

}

double t;

cout << "roots of the function f() follow:" << endl;

for(i=0; i<n-1; i++)

{

if(y[i]*y[i+1]>0)continue;

cout << scientific << setprecision(12);

t=bisection(f, x[i], x[i+1], 0);

cout << "t=" << setw(22) << t << " f(t)="

<< setw(12) << setprecision(2) << f(t) << endl;

}

return 0;

}

double bisection(double (*f)(double), double a, double b, double delta)

{

double c;

// STATEMENTS FOLLOW TO FIND c SUCH THAT f(c)=0 IN [a, b]

// TO AN ACCURACY delta

return c;

}

– C++ Programming labs, Term 2, 2011/2012, 94–

8-1-2012 23:59 c© M. K. Warby C++ Programming labs, Term 2, 2011/2012 Page 95

Your complete program should generate output such as the following.

roots of the function f() follow:

t= 5.955434685046e-01 f(t)= -5.55e-17

t= 1.305030811675e+00 f(t)= -1.33e-15

t= 2.527738290296e+00 f(t)= 1.62e-14

t= 2.780533960898e+00 f(t)= -1.57e-14

t= 2.886469864215e+00 f(t)= -1.18e-14

t= 3.111573935050e+00 f(t)= -3.11e-15

t= 3.222692541994e+00 f(t)= 2.28e-14

t= 3.466531867453e+00 f(t)= 4.50e-15

t= 4.730134497169e+00 f(t)= 2.22e-16

t= 5.310080299062e+00 f(t)= 2.39e-15

t= 6.571809129945e+00 f(t)= 3.00e-15

t= 7.355349459397e+00 f(t)= 0.00e+00

t= 8.611018509134e+00 f(t)= 2.22e-16

t= 9.177241799801e+00 f(t)= -7.77e-16

As the numbers in the last column are close to zero the values that you get may differslightly although if you have done things correctly your numbers should also be very closeto zero. Also note that it depends on what system you are using whether the numbers givenin scientific format has 3 digits in the exponent or 2 digits as in the above output.

14.2 Using the composite mid-point rule

Let f : [a, b]→ R denote a function. The area under the curve of f between a and b is givenby

I =

∫ b

a

f(x) dx

and this can be approximated using the composite mid-point rule which involves the followingapproximation. For n ≥ 1 the approximation is given by

In := hn∑

i=1

f(xi), where xi = a+ (i− 1/2)h and h =b− an

.

Write a function with a header of the form

double mid_point_rule(double (*f)(double x), double a, double b, int n);

which computes this approximation. Also, write a main() program together with the func-tions specified below to test your function mid_point_rule().

f1(x) = x3, with a = 0, b = 2,

f2(x) = x−1/2, with a = 0, b = 1,

f3(x) =1

x, with a = 1, b = 2,

f4(x) =1√2π

exp(−x2/2), with a = −1, b = 1,

f4(x) with a = −2, b = 2,

f4(x) with a = −3, b = 3.

– C++ Programming labs, Term 2, 2011/2012, 95–

8-1-2012 23:59 c© M. K. Warby C++ Programming labs, Term 2, 2011/2012 Page 96

In each case you should test the approximation with n = 8, 16, 32, 64, 128, 256, · · · , 8192.

These are results that I obtained.

f1 f2 f3 f4, [-1,1] f4, [-2,2] f4, [-3,3]

n= 8 3.9687500 1.7864610 0.6926606 0.6839544 0.9567320 0.9978633

n= 16 3.9921875 1.8488567 0.6930252 0.6830048 0.9550611 0.9974522

n= 32 3.9980469 1.8930884 0.6931167 0.6827683 0.9546403 0.9973389

n= 64 3.9995117 1.9243928 0.6931396 0.6827092 0.9545349 0.9973099

n= 128 3.9998779 1.9465353 0.6931453 0.6826944 0.9545085 0.9973026

n= 256 3.9999695 1.9621942 0.6931467 0.6826907 0.9545019 0.9973008

n= 512 3.9999924 1.9732671 0.6931471 0.6826898 0.9545003 0.9973004

n= 1024 3.9999981 1.9810969 0.6931472 0.6826896 0.9544999 0.9973002

n= 2048 3.9999995 1.9866335 0.6931472 0.6826895 0.9544998 0.9973002

n= 4096 3.9999999 1.9905485 0.6931472 0.6826895 0.9544997 0.9973002

n= 8192 4.0000000 1.9933168 0.6931472 0.6826895 0.9544997 0.9973002

You should note that∫ 2

0

x3 dx = 4,

∫ 1

0

x−1/2 dx = 2,

∫ 2

1

1

xdx = ln 2 = 0.6931472

and ∫ ∞−∞

1√2π

exp(−x2/2) dx = 1.

– C++ Programming labs, Term 2, 2011/2012, 96–

8-1-2012 23:59 c© M. K. Warby C++ Programming labs, Term 2, 2011/2012 Page 97

15 Using arrays and some functions from <cstring>

In section 17 starting on page 103 there are some discussion about reading data from files. Asthis exercise is before that section this example has the data in an array within the followingprogram which you can get by typing the following in a command window available by firstclicking the mouse on the icon containing cmd 441. You should first change to the folder youwant the file to be in and then type

wget http://people.brunel.ac.uk/~icstmkw/ma1690/metropolitan_line.cpp

The array s[] has all the links in the Metropolian line from Uxbridge to Aldgate in alpha-betical order where the links are consecutive entries s[2*i] and s[2*i+1].

#include <iostream>

#include <iomanip>

#include <cstring>

#include <cstdlib>

using namespace std;

int main()

{

const char *s[]={

"Baker Street" , "Great Portland Street",

"Barbican" , "Moorgate",

"Eastcote" , "Rayners Lane",

"Euston Square" , "King’s Cross St. Pancras",

"Farringdon" , "Barbican",

"Finchley Road" , "Baker Street",

"Great Portland Street" , "Euston Square",

"Harrow-on-the-Hill" , "Northwick Park",

"Hillingdon" , "Ickenham",

"Ickenham" , "Ruislip",

"King’s Cross St. Pancras" , "Farringdon",

"Liverpool Street" , "Aldgate",

"Moorgate" , "Liverpool Street",

"Northwick Park" , "Preston Road",

"Preston Road" , "Wembley Park",

"Rayners Lane" , "West Harrow",

"Ruislip Manor" , "Eastcote",

"Ruislip" , "Ruislip Manor",

"Uxbridge" , "Hillingdon",

"Wembley Park" , "Finchley Road",

"West Harrow" , "Harrow-on-the-Hill"

};

int ns=sizeof(s)/sizeof(s[0]);

cout << ns/2 << " links" << endl;

int i, j, l, m;

// .. get the length of the longest name as m

m=0;

for(i=0; i<ns/2; i++)

{

– C++ Programming labs, Term 2, 2011/2012, 97–

8-1-2012 23:59 c© M. K. Warby C++ Programming labs, Term 2, 2011/2012 Page 98

l=strlen(s[2*i]);

if(l>m)m=l;

}

// .. find the position of Uxbridge

for(i=0; i<ns/2; i++)

{

if(strcmp(s[2*i], "Uxbridge")==0)

{

j=i;

break;

}

}

// .. start the route from Uxbridge to Aldgate

cout << left << setw(m) << s[2*j] << " -> " << s[2*j+1] << endl;

// ..ADD STATEMENTS WHICH DETERMINES AND OUTPUTS ALL THE STAGES

// ..OF THE ROUTE TO ALDGATE

return 0;

}

In the above program the functions strlen() and strcmp() are available as the header<cstring> is included. strlen() gives the number of characters in a C-string and strcmp()

compares two C-strings and returns 0 when both C-strings are identical. Extend the programso that it creates the following output.

21 links

Uxbridge -> Hillingdon

Hillingdon -> Ickenham

Ickenham -> Ruislip

Ruislip -> Ruislip Manor

Ruislip Manor -> Eastcote

Eastcote -> Rayners Lane

Rayners Lane -> West Harrow

West Harrow -> Harrow-on-the-Hill

Harrow-on-the-Hill -> Northwick Park

Northwick Park -> Preston Road

Preston Road -> Wembley Park

Wembley Park -> Finchley Road

Finchley Road -> Baker Street

Baker Street -> Great Portland Street

Great Portland Street -> Euston Square

Euston Square -> King’s Cross St. Pancras

King’s Cross St. Pancras -> Farringdon

Farringdon -> Barbican

Barbican -> Moorgate

Moorgate -> Liverpool Street

Liverpool Street -> Aldgate

– C++ Programming labs, Term 2, 2011/2012, 98–

8-1-2012 23:59 c© M. K. Warby C++ Programming labs, Term 2, 2011/2012 Page 99

16 Using arrays: A route planning journey

The following table gives the road distances in miles between 11 U.S. cities.

Atla Chic Denv Hous Kans Los_ Minn Miam New_ San_ Seat

Atlanta 0 715 1405 800 805 2185 1135 665 865 2495 2785

Chicago 715 0 1000 1085 525 2020 410 1380 795 2135 2070

Denver 1405 1000 0 1120 600 1025 915 2065 1780 1270 1335

Houston 800 1085 1120 0 795 1550 1230 1190 1635 1930 2450

Kansas 805 525 600 795 0 1625 440 1470 1195 1865 1900

Los_Angeles 2185 2020 1025 1550 1625 0 1935 2740 2800 385 1140

Minneapolis 1135 410 915 1230 440 1935 0 1795 1200 2010 2015

Miami 665 1380 2065 1190 1470 2740 1795 0 1280 3115 3365

New_York 865 795 1780 1635 1195 2800 1200 1280 0 3055 2860

San_Francisco 2495 2135 1270 1930 1865 385 2010 3115 3055 0 810

Seattle 2785 2070 1335 2450 1900 1140 2015 3365 2860 810 0

This file is available at the URL

http://people.brunel.ac.uk/~icstmkw/ma1690/usa_road_distances.txt

You need to get this file or type it yourself to do this task.

A visitor decides to do a circular tour of these n = 11 cities and decides to start and endthe tour in Atlanta, with no other city visited more than once, and wishes to know the routeto take so that circular tour is as short as possible. Determining this route is an example ofa travelling salesman problem.

In the general case of n cities there are n− 1 possible places to travel to from the initialplace, then n− 2 possible places for the next stage, then n− 3 possible places etc. giving

(n− 1)! = (n− 1)(n− 2)(n− 3) · · · (3)(2)

possible circular tours. The number of possible routes hence grows rapidly with n and it isonly possible to solve the problem by considering all possible routes for values of n whichare not too large. Fortunately, for n = 11, (n−1)! = 10! = 3628800 is not too large that thisapproach can be used here. To generate all possible routes you need to be able to generateall permutations (i.e. re-arrangements) of the (n− 1) numbers 0, 1, · · · , n− 2.

The incomplete program given below requires that you obtain the following file

http://people.brunel.ac.uk/~icstmkw/ma1690/next_permutation.h

which contains a function with the header

void next_permutation(int m, int a[]);

This function generates the next permutation in a list of permutations starting with {0, 1, · · · ,m−1}. In the case of m=3 the factorial is 3! = 6 and the permutations are as follows

– C++ Programming labs, Term 2, 2011/2012, 99–

8-1-2012 23:59 c© M. K. Warby C++ Programming labs, Term 2, 2011/2012 Page 100

0 1 2

0 2 1

1 0 2

1 2 0

2 0 1

2 1 0

and each use of the function generates the next set of 3 values.

In the following an array of entries of type string is used to store the names of the11 cities. string is a C++ class which you can be used instead of C-style strings in manysituations. The function set route() creates a route with n+ 1 entries r0, r1, · · · , rn withr0 = rn = 0 corresponding to the place city[0] which is Atlanta in the application. Thefunction distance route() computes the distance associated with a route.

Complete the following skeleton program to find the shortest possible circular route andto show the route.

#include <iostream>

#include <iomanip>

#include <fstream>

#include <string>

#include <cstdlib>

using namespace std;

#include "next_permutation.h"

void read_data(int n, string s[], int d[])

{

// .. read in the 2D array from the file

const char fn[]="usa_road_distances.txt";

ifstream fin(fn);

if(fin==0)

{

cout << "..failed to read file " << fn << endl;

exit(0);

}

char tem[160];

fin.getline(tem, 160, ’\n’);

for(int i=0; i<n; i++)

{

fin >> s[i];

for(int j=0; j<n; j++) fin >> d[n*i+j];

}

fin.close();

}

double factorial(int n)

{

// .. compute the factorial of n

– C++ Programming labs, Term 2, 2011/2012, 100–

8-1-2012 23:59 c© M. K. Warby C++ Programming labs, Term 2, 2011/2012 Page 101

if(n<=1)return 1;

double f=1;

for(int i=2; i<=n; i++)f=i*f;

return f;

}

void set_route(int n, int a[], int r[])

{

// .. convert a permutation a[] into a route r[]

r[0]=0;

for(int i=0; i<n-1; i++)r[i+1]=a[i]+1;

r[n]=0;

}

int distance_route(int n, int r[], int d[])

{

// .. compute the distance associated with the route

// .. r[0]-->r[1]-->r[2]-->...-->r[n]

int i, v;

v=0;

for(i=0; i<n; i++) v=v+d[n*r[i]+r[i+1]];

return v;

}

int main()

{

// .. read the data

const int n=11;

string city[n];

int d[n*n];

read_data(n, city, d);

// .. confirm the data by displaying

int i, j;

for(i=0; i<n; i++)

{

cout << left << setw(15) << city[i] << right;

for(j=0; j<n; j++)cout <<setw(5) << d[n*i+j];

cout << endl;

}

// .. set the first permutation and candidate for the min route

int dmin, a[n-1], rmin[n+1];

for(i=0; i<n-1; i++)a[i]=i;

set_route(n, a, rmin);

dmin=distance_route(n, rmin, d);

int v, r[n+1];

for(double x=1; x<factorial(n-1); x++)

{

– C++ Programming labs, Term 2, 2011/2012, 101–

8-1-2012 23:59 c© M. K. Warby C++ Programming labs, Term 2, 2011/2012 Page 102

next_permutation(n-1, a);

set_route(n, a, r);

v=distance_route(n, r, d);

// ..STATEMENTS TO POSSIBLY UPDATE THE SHORTEST ROUTE FOLLOW

}

// .. STATEMENTS TO SHOW THE SHORTEST ROUTE FOLLOW

return 0;

}

The aim is to show the following.

Number of routes=3628800, shortest route follows:

Atlanta --> Miami 665 665

Miami --> Houston 1190 1855

Houston --> Los_Angeles 1550 3405

Los_Angeles --> San_Francisco 385 3790

San_Francisco --> Seattle 810 4600

Seattle --> Denver 1335 5935

Denver --> Kansas 600 6535

Kansas --> Minneapolis 440 6975

Minneapolis --> Chicago 410 7385

Chicago --> New_York 795 8180

New_York --> Atlanta 865 9045

– C++ Programming labs, Term 2, 2011/2012, 102–

8-1-2012 23:59 c© M. K. Warby C++ Programming labs, Term 2, 2011/2012 Page 103

17 Reading data from files

In some of the previous sections there have been tasks in which you have had to read froma file, e.g. in section 10.5 on page 75 for a problem of determining the league table knowingonly the results of all the matches and in section 16 on page 99 for reading the data forthe route planning task. In this section we consider some more techniques for successfullyreading information from files and, in certain cases, overcoming failures.

The functions defined in this section are available in the file

http://people.brunel.ac.uk/~icstmkw/ma1690/read_utils.h

17.1 Some preliminary tasks

If you need to read from a file (or write to a file) in a program then you need the headerstatement

#include <fstream>

To have a robust program which reads from a file a recommended first step is to first checkthat a file exists and that the data can be read. This task can be done by the followingfunction.

int exists(const char fn[])

{

// .. return 1 if the file fn[] exists

ifstream i(fn, ios::binary);

if(i==0)

{

i.clear();

return 0;

}

i.close();

return 1;

}

Here variable i has type ifstream, which is a class, and clear() and close() aremember functions of this class.

If you are likely to want to read all or most of a file then the next task might be todetermine the size of the file. One way of doing this is to read the file byte-by-byte as far aspossible and to count the number of bytes that can be read. It is actually more efficient todo this by attempting to read many bytes in one go as in the following function.

int filesize(const char fn[])

{

// .. get the file size in bytes

int nr, ns;

const int N=65536;

char c[N];

// .. open the file and read to get the size

if(exists(fn)==0)return -1;

– C++ Programming labs, Term 2, 2011/2012, 103–

8-1-2012 23:59 c© M. K. Warby C++ Programming labs, Term 2, 2011/2012 Page 104

ifstream inp(fn, ios::binary);

ns=0;

do

{

inp.read(c, N);

nr=inp.gcount();

ns=ns+nr;

}while(nr==N);

inp.clear();

inp.close();

return ns;

}

In this case inp is a variable of type ifstream and member functions read() andgcount() have also been used. In the function successive attempts are made to read N

bytes and the first time that less than N bytes can be read indicates that this is as much ascan be read.

17.2 Reading a file byte by byte

The filesize() function indicated how to read the file byte by byte and to read the entirefile into an array of type char we can do the following steps.

(i) First determine the size of the file (e.g. use filesize()).

(ii) Allocate an array of sufficient capacity to read everything.

(iii) Read the entire file into the array.

This can all be put together in the following function f2a().

char* f2a(const char fn[], int& n)

{

// .. read a file into an array

n=filesize(fn);

if(n<0)return NULL;

char *c=new char[n+1];

ifstream inp(fn, ios::binary);

inp.read(c, n);

inp.close();

return c;

}

Here the return value is the pointer to the space allocated to the array storing all thecharacters. Also, the space allocated has been set to n+1 to deal with the possibility thatn is 0 (using delete[] later in a program will fail in such cases if this is not done) and toallow for an extra character to be added (this is useful if we wish to add a NULL characterand treat the array as a C-style string).

After a file has been read you can check if it only contains characters with ASCII codevalues not exceeding 127 with the following function.

– C++ Programming labs, Term 2, 2011/2012, 104–

8-1-2012 23:59 c© M. K. Warby C++ Programming labs, Term 2, 2011/2012 Page 105

int check_less_128(int n, char c[])

{

// .. return 1 if all the n entries in c[] have an ASCII code<=127

unsigned char u;

for(int i=0; i<n; i++)

{

u=(unsigned char)c[i];

if(u>127)return 0;

}

return 1;

}

This is useful to know before attempting to display the contents of the file and it is alsouseful to know if you are attempting to read numbers from a file as such characters are likelyto cause this to fail and determining the reason can sometimes be difficult when the spuriouscharacters appear to be blank when viewed with a text editor. The use of unsigned char

is needed here in order that the integer values are in the range 0–255

Complete the following to determine and how times each of the possible 256 charactersappears in a file.

#include <iostream>

#include <fstream>

#include <cstdio>

using namespace std;

#include "read_utils.h"

int exists(const char fn[]);

int filesize(const char fn[]);

char* f2a(const char fn[], int& n);

int check_less_128(int n, char c[]);

int main()

{

char *c;

int n;

char name[512];

cout << "enter the name of a file: ";

cin >> name;

c=f2a(name, n);

cout << "file " << name << " has " << n << " bytes" << endl;

// .. show the file as a C-style string if it contains appropriate chars

if(check_less_128(n, c)==1 && n>=0)

{

c[n]=0;

cout << c << endl;

}

// ADD STATEMENTS TO DETERMINE HOW MANY TIMES EACH POSSIBLE CHARACTER

// APPEARS IN THE FILE

– C++ Programming labs, Term 2, 2011/2012, 105–

8-1-2012 23:59 c© M. K. Warby C++ Programming labs, Term 2, 2011/2012 Page 106

return 0;

}

For the number of each character which appears in a file I obtained the following for myversion of the file usa road distances.txt which is shown again.

Atla Chic Denv Hous Kans Los_ Minn Miam New_ San_ Seat

Atlanta 0 715 1405 800 805 2185 1135 665 865 2495 2785

Chicago 715 0 1000 1085 525 2020 410 1380 795 2135 2070

Denver 1405 1000 0 1120 600 1025 915 2065 1780 1270 1335

Houston 800 1085 1120 0 795 1550 1230 1190 1635 1930 2450

Kansas 805 525 600 795 0 1625 440 1470 1195 1865 1900

Los_Angeles 2185 2020 1025 1550 1625 0 1935 2740 2800 385 1140

Minneapolis 1135 410 915 1230 440 1935 0 1795 1200 2010 2015

Miami 665 1380 2065 1190 1470 2740 1795 0 1280 3115 3365

New_York 865 795 1780 1635 1195 2800 1200 1280 0 3055 2860

San_Francisco 2495 2135 1270 1930 1865 385 2010 3115 3055 0 810

Seattle 2785 2070 1335 2450 1900 1140 2015 3365 2860 810 0

ASCII char count ASCII char count ASCII char count ASCII char count

10: 12 13: 12 32: 285 48: 0 97

49: 1 80 50: 2 44 51: 3 28 52: 4 18

53: 5 68 54: 6 20 55: 7 20 56: 8 28

57: 9 20 65: A 3 67: C 2 68: D 2

70: F 1 72: H 2 75: K 2 76: L 2

77: M 4 78: N 2 83: S 4 89: Y 1

95: _ 6 97: a 15 99: c 4 101: e 11

103: g 2 104: h 2 105: i 9 107: k 1

108: l 5 109: m 2 110: n 14 111: o 9

112: p 1 114: r 3 115: s 10 116: t 7

117: u 2 118: v 2 119: w 2

In these outputs the distances file has the same number of characters with ASCII codes10 and 13 which indicates that it is likely to have been created on a Microsoft windowssystem as on such systems text lines end with these 2 characters (ASCII code 13, whichis carriage return, followed by ASCII code 10, which is line feed). The most frequentlyoccurring character in the file is the space character which has ASCII code 32.

You can also try the program on the file with the name

r:\c++\dictionary\words

which contains about 0.38 million words and abbreviations etc.. In this case you should getthe following.

ASCII char count ASCII char count ASCII char count ASCII char count

10: 380645 39: ’ 88099 65: A 6797 66: B 7183

67: C 8099 68: D 4450 69: E 3457 70: F 3134

71: G 4581 72: H 4989 73: I 1795 74: J 2284

75: K 3821 76: L 5189 77: M 7833 78: N 2855

79: O 2288 80: P 5465 81: Q 367 82: R 4269

83: S 8639 84: T 4839 85: U 762 86: V 1819

– C++ Programming labs, Term 2, 2011/2012, 106–

8-1-2012 23:59 c© M. K. Warby C++ Programming labs, Term 2, 2011/2012 Page 107

87: W 3126 88: X 165 89: Y 692 90: Z 872

97: a 276283 98: b 58191 99: c 124661 100: d 102382

101: e 362596 102: f 35817 103: g 80086 104: h 84074

105: i 287141 106: j 4859 107: k 31086 108: l 179826

109: m 91954 110: n 230698 111: o 221921 112: p 88319

113: q 5204 114: r 232809 115: s 358234 116: t 208664

117: u 107132 118: v 31317 119: w 24499 120: x 8856

121: y 56602 122: z 16091 197: 2 214: 2

220: 4 224: 6 225: 31 226: 17

228: 37 229: 9 231: 27 232: 128

233: 541 234: 21 235: 4 237: 7

238: 3 239: 5 241: 42 243: 21

244: 19 246: 76 248: 10 250: 2

251: 10 252: 64

In this file there are 380645 lines with the most common letters being s and e. The filecontains some bytes with ASCII codes which are larger than 127 with, for example, the codeof 233 corresponding to the character e.

17.3 Getting all the lines in a file as C-style strings

To manipulate a file line by line it is useful to have all the lines as C-style strings, i.e.each line is an array of characters which is null terminated. This can be achieved with thefollowing function which implements the following steps.

1. Read the file into an array.

2. Determine the number of lines.

3. Allocate space for the pointers to the lines.

4. Set the pointers to the lines.

5. Replace all end of line characters by null characters.

void textfile(const char fn[], char*& c, int& n, int& nl, char**& cl)

{

// .. read in the file fn[] and determine the lines cl[i], i=0,...,nl-1

// .. set default values

nl=0;

cl=NULL;

// .. read the file into c[] and return if this did not work

c=f2a(fn, n);

if(n<=0 || c==NULL)return;

// .. count the lines

int i;

for(i=0; i<n; i++) if(c[i]==10)nl++;

// .. allocate space for the pointers to the lines and possibly set c[n]

– C++ Programming labs, Term 2, 2011/2012, 107–

8-1-2012 23:59 c© M. K. Warby C++ Programming labs, Term 2, 2011/2012 Page 108

cl=new char*[nl+1];

if(c[n-1]!=10) c[n]=0;

// .. indicate where each line starts in array cl[]

cl[0]=c;

nl=1;

for(i=0; i<n-1; i++)

if(c[i]==10)

{

cl[nl]=&c[i+1];

nl++;

}

// .. change end of lines to null characters

for(i=0; i<n; i++)

{

if(c[i]==13)c[i]=0;

if(c[i]==10)c[i]=0;

}

}

You can try this out with the following main() function. Here __FILE__ gives the nameof the file that contains this statement.

#include <iostream>

#include <fstream>

#include <iomanip>

using namespace std;

#include "read_utils.h"

int exists(const char fn[]);

int filesize(const char fn[]);

char* f2a(const char fn[], int& n);

void textfile(const char fn[], char*& c, int& n, int& nl, char**& cl);

int main()

{

// .. read the file as a text file

char *c, **cl;

int n, nl;

textfile(__FILE__, c, n, nl, cl);

// .. show the file line by line

cout << "This file is " << __FILE__ << endl;

for(int i=0; i<nl; i++)cout << cl[i] << endl;

return 0;

}

– C++ Programming labs, Term 2, 2011/2012, 108–

8-1-2012 23:59 c© M. K. Warby C++ Programming labs, Term 2, 2011/2012 Page 109

18 Programs to sort data

18.1 Some explanation about using qsort()

A common task in a program is sorting information, e.g. sorting numbers into ascendingor descending order or sorting words alphabetically. There are efficient functions as partof C++ (and also C) such as qsort() which is available with the header <cstdlib> fordoing this common task which you can use and thus you probably do not need to entermany statements in a program provided your sorting criteria is relatively simple. To usethe function qsort() you do need to know a little about pointers and in particular void*

pointers (actually it is void* and const void* pointers) and pointers to functions. Mostof this complexity is because qsort() does not specify the criteria for determining whenone item must be before another in the final sorted list but instead the user has to write afunction to do this. Also, linked with the previous comment, qsort() does not specify whattype of array is being sorted (e.g. int, double, char*, · · · ) and requires the user to indicatethe size of each item. To be specific, if there are n items to sort of an array a[] and eachitem occupies m bytes then all the entries occupy n×m bytes. (On the PCs in the labs andin the case of 32-bit versions of the software we have 4 for the type int and any pointersuch as char* and we have 8 for the type double. If you use a 64-bit version then some ofthese numbers will be higher.) qsort() needs to know n, m and the array name a, whichis a pointer, which it treats as the generic pointer type void* and which gives the memoryaddress of where the array starts. Before the re-cast to void*, the address of all the itemscan be determined by pointer arithmetic which can be visualised as shown below.

m bytes m bytes m bytes

a a+1 a+2 a+n-1

If your function which specifies the sorting criteria is called compar then a consequence ofthe use of type void* is that when qsort() uses your function it requires that your functionis compatible with the following header statement.

int (*compar)(const void*, const void*);

That is the function takes the addresses of two items to compare and it must return an int

type with a return value of less than 0 meaning that the value at the first argument is beforethe value at the second argument, a return value of greater than 0 meaning that the value atthe first argument is after the value at the second argument and a return value of 0 meansthe two arguments are the same with respect to the sorting criteria. The use of const in thearguments is to ensure that this function only makes a decision about the order of the valuesand cannot alter any of the values. (Actually it is possible to remove the const part whenthe pointer type is changed and thus take care with such operations.) We can illustrate whatis involved in particular cases with some examples.

For putting an int array in ascending order we can have the following.

– C++ Programming labs, Term 2, 2011/2012, 109–

8-1-2012 23:59 c© M. K. Warby C++ Programming labs, Term 2, 2011/2012 Page 110

int ascending_int(const void *xx, const void *yy)

{

const int& x=*(const int*)xx; //re-cast the pointer type

const int& y=*(const int*)yy; //re-cast the pointer type

if(x < y)return -1;

if(x > y)return +1;

return 0;

}

Note as xx and yy are pointers we need to re-cast them consistent with how they willbe used. To avoid having to work with pointers for the decisions they are dereferenced withreference variables x and y being used. The comparison decision can then be made in theusual way with x and y.

If descending order is required then we can have the following.

int descending_int(const void *xx, const void *yy)

{

const int& x=*(const int*)xx; //re-cast the pointer type

const int& y=*(const int*)yy; //re-cast the pointer type

if(x > y)return -1;

if(x < y)return +1;

return 0;

}

If we want to sort an array of type double into ascending or descending order then we cansimilarly have

int ascending_dou(const void *xx, const void *yy)

{

const double& x=*(const double*)xx; //re-cast the pointer type

const double& y=*(const double*)yy; //re-cast the pointer type

if(x < y)return -1;

if(x > y)return +1;

return 0;

}

int descending_dou(const void *xx, const void *yy)

{

const double& x=*(const double*)xx; //re-cast the pointer type

const double& y=*(const double*)yy; //re-cast the pointer type

if(x > y)return -1;

if(x < y)return +1;

return 0;

}

To deal with C-style strings and alphabetical order we can make use of the functionstrcmp() which is available when the header <cstring> is used. The thing to note here isthat the C-style string has a type char* and thus a pointer to this has the type char** andhence for alphabetical sorting we can have the following function.

– C++ Programming labs, Term 2, 2011/2012, 110–

8-1-2012 23:59 c© M. K. Warby C++ Programming labs, Term 2, 2011/2012 Page 111

int alphabetical(const void *xx, const void *yy)

{

const char*& x=*(const char**)xx; //re-cast the pointer type

const char*& y=*(const char**)yy; //re-cast the pointer type

return strcmp(x, y);

}

18.2 Testing qsort() to sort various types

Try the following function which sorts the 10 entries in array a[] into ascending order, the5 entries of b[] into descending order and the 5 C-style strings of c[] into alphabeticalorder.

#include <iostream>

#include <iomanip>

#include <cstring>

#include <cstdlib>

using namespace std;

int ascending_int(const void *xx, const void *yy)

{

const int& x=*(const int*)xx; //re-cast the pointer type

const int& y=*(const int*)yy; //re-cast the pointer type

if(x < y)return -1;

if(x > y)return +1;

return 0;

}

int descending_dou(const void *xx, const void *yy)

{

const double& x=*(const double*)xx; //re-cast the pointer type

const double& y=*(const double*)yy; //re-cast the pointer type

if(x > y)return -1;

if(x < y)return +1;

return 0;

}

int alphabetical(const void *xx, const void *yy)

{

const char*& x=*(const char**)xx; //re-cast the pointer type

const char*& y=*(const char**)yy; //re-cast the pointer type

return strcmp(x, y);

}

template<class T>

void show_array1(int n, T a[], const char t[])

{

cout << n << " items, ";

cout << t << "[]=";

– C++ Programming labs, Term 2, 2011/2012, 111–

8-1-2012 23:59 c© M. K. Warby C++ Programming labs, Term 2, 2011/2012 Page 112

for(int i=0; i<n; i++)cout << " " << a[i];

cout << endl;

}

int main()

{

// .. several tests of qsort()

const int n=10, m=5;

int a[n]={98, 1, -54, 33, 4, 1, -7, 12, 11, 10};

double b[m]={1.618, 3.14, 2.78, 99.1, -4};

char *c[m], cs[m][9]={"Portugal", "Spain", "France", "Italy", "Greece"};

for(int i=0; i<m; i++)c[i]=cs[i];

qsort(a, n, sizeof(a[0]), ascending_int);

show_array1(n, a, "a");

qsort(b, m, sizeof(b[0]), descending_dou);

show_array1(m, b, "b");

qsort(c, m, sizeof(c[0]), alphabetical);

show_array1(m, c, "c");

return 0;

}

The program should produce the following output.

10 items, a[]= -54 -7 1 1 4 10 11 12 33 98

5 items, b[]= 99.1 3.14 2.78 1.618 -4

5 items, c[]= France Greece Italy Portugal Spain

One new feature in this example is the use of the template function show array1() whichbriefly displays the entries in each of the arrays. The compiler generates separate versionsfor each of the types used and hence spares you the task of creating a version which worksfor each different type used.

18.3 Using qsort() to sort C-style strings by the number of vowels

As a test of sorting a large number of C-style strings take the previous program and replacethe statement with textfile() by

textfile("r:\\c++\\dictionary\\words", c, n, nl, cl);

which reads the list with about 0.38 million words. The entries are mostly in a case-insensitivealphabetical order although the list does contain many words ending in ’s and has somenon-ascii characters.

You can count the number of vowel letters, i.e. uppercase and lowercase versions of a, e,i, o and u, with the following function.

– C++ Programming labs, Term 2, 2011/2012, 112–

8-1-2012 23:59 c© M. K. Warby C++ Programming labs, Term 2, 2011/2012 Page 113

int count_vowels(const char s[])

{

// .. count how many vowel letter appear in s[]

int i, j, k, l;

const char v[11]="aeiouAEIOU";

l=strlen(s);

k=0;

for(i=0; i<l; i++)

for(j=0; j<10; j++)

if(s[i]==v[j])

{

k++;

break;

}

return k;

}

Use this function, or otherwise, to sort the names by the number of vowel letters andthen by using strcmp() for 2 words with the same number of vowels. You should show inorder all the words containing 11 or more vowels.

#include <iostream>

#include <fstream>

#include <iomanip>

#include <cstdlib>

#include <cstring>

using namespace std;

#include "read_utils.h"

void textfile(const char fn[], char*& c, int& n, int& nl, char**& cl);

int count_vowels(const char fn[]);

int vowel_compare(const void *x, const void *y);

int main()

{

char *c, **cl;

int n, nl;

char fn[]="r:\\c++\\dictionary\\words";

textfile(fn, c, n, nl, cl);

//STATEMENTS TO USE qsort() AND SHOW THE WORDS WITH THE MOST VOWELS

return 0;

}

//STATEMENTS OF count_vowels() AND vowel_compare() FOLLOW

For information, the following contains some of the output that I obtained.

– C++ Programming labs, Term 2, 2011/2012, 113–

8-1-2012 23:59 c© M. K. Warby C++ Programming labs, Term 2, 2011/2012 Page 114

11 antidisestablishmentarianism

....

11 counterrevolutionaries

11 deinstitutionalization

....

11 overintellectualization

....

11 reinstitutionalization

....

13 Llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch

....

13 ethylenediaminetetraacetate

....

13 hippopotomonstrosesquipedalian

13 honorificabilitudinitatibus

14 floccinaucinihilipilification

16 supercalifragilisticexpialidocious

20 pneumonoultramicroscopicsilicovolcanoconiosis

18.4 Using qsort() to show the most frequent letters

If you did the tasks in section 17.2 which generated the 78 count values shown on page 106 forthe characters in the dictionary then this task is concerned with extending the presentationso as to sort the count values and to show the characters in this order. As a hint, yourprogram might contain the following.

//EARLIER STATEMENTS IN THE FILE

int numbers[256], *pn[256];

unsigned char c1;

int i;

for(i=0; i<256; i++) numbers[i]=0;

for(i=0; i<n; i++)

{

c1=c[i];

numbers[c1]++;

}

// .. create an array of pointers

for(i=0; i<256; i++)pn[i]=&numbers[i];

// .. sort the counts

qsort(pn, 256, sizeof(pn[0]), order_pint);

//STATEMENTS TO NEATLY PRESENT THE COUNT VALUES FOLLOW AND

//STATEMENT TO COMPLETE THE FUNCTION main() FOLLOW

– C++ Programming labs, Term 2, 2011/2012, 114–

8-1-2012 23:59 c© M. K. Warby C++ Programming labs, Term 2, 2011/2012 Page 115

//THE FUNCTION TO CONTROL THE SORTING

int order_pint(const void *xx, const void *yy)

{

const int& x=**(const int**)xx;

const int& y=**(const int**)yy;

return y-x;

}

The aim is to create the following.

Most frequent to least frequent characters

Rank Count ascii Rank Count ascii Rank Count ascii

1: 380645 10 2: 362596 101 e 3: 358234 115 s

4: 287141 105 i 5: 276283 97 a 6: 232809 114 r

7: 230698 110 n 8: 221921 111 o 9: 208664 116 t

10: 179826 108 l 11: 124661 99 c 12: 107132 117 u

13: 102382 100 d 14: 91954 109 m 15: 88319 112 p

16: 88099 39 ’ 17: 84074 104 h 18: 80086 103 g

19: 58191 98 b 20: 56602 121 y 21: 35817 102 f

22: 31317 118 v 23: 31086 107 k 24: 24499 119 w

25: 16091 122 z 26: 8856 120 x 27: 8639 83 S

28: 8099 67 C 29: 7833 77 M 30: 7183 66 B

31: 6797 65 A 32: 5465 80 P 33: 5204 113 q

34: 5189 76 L 35: 4989 72 H 36: 4859 106 j

37: 4839 84 T 38: 4581 71 G 39: 4450 68 D

40: 4269 82 R 41: 3821 75 K 42: 3457 69 E

43: 3134 70 F 44: 3126 87 W 45: 2855 78 N

46: 2288 79 O 47: 2284 74 J 48: 1819 86 V

49: 1795 73 I 50: 872 90 Z 51: 762 85 U

52: 692 89 Y 53: 541 233 54: 367 81 Q

55: 165 88 X 56: 128 232 57: 76 246

58: 64 252 59: 42 241 60: 37 228

61: 31 225 62: 27 231 63: 21 234

64: 21 243 65: 19 244 66: 17 226

67: 10 248 68: 10 251 69: 9 229

70: 7 237 71: 6 224 72: 5 239

73: 4 220 74: 4 235 75: 3 238

76: 2 197 77: 2 214 78: 2 250

Most frequent to least frequent letters as a C-style string.

esiarnotlcudmp’hgbyfvkwzxSCMBAPqLHjTGDRKEFWNOJVIZUYQX

In this dictionary the most frequent letters are e and s and the least frequent lower caseletters are x, q and j.

– C++ Programming labs, Term 2, 2011/2012, 115–

8-1-2012 23:59 c© M. K. Warby C++ Programming labs, Term 2, 2011/2012 Page 116

19 Experiments and tasks related to functions in <ctime>

When a C++ program has the statement

#include <ctime>

you have some types and functions for reporting and manipulating the time. The time itselfis represented as the type time t which corresponds to the 4 byte type int on our systemswith valid values on all systems corresponding to the range

[0, 231 − 1] = [0, 2147483647].

The value 0 corresponds to 00:00:00 1st Jan 1970 GMT. You can test this with the followingshort program which you can try.

#include <iostream>

#include <ctime>

#include <cmath>

using namespace std;

void gmt_and_local(time_t& t, char cgmt[], char cloc[])

{

tm a;

a=*gmtime(&t);

strftime(cgmt, 32, "%a %d %b %H:%M:%S %Y", &a);

a=*localtime(&t);

strftime(cloc, 32, "%a %d %b %H:%M:%S %Y", &a);

}

int main()

{

time_t t;

char cgmt[32], cloc[32];

t=0;

gmt_and_local(t, cgmt, cloc);

cout << cgmt << endl;

cout << cloc << endl;

t=int( pow(2.0, 31)-1 );

gmt_and_local(t, cgmt, cloc);

cout << cgmt << endl;

cout << cgmt << endl;

cout << "approx number of years in this range="

<< double(t)/(365.25*24*60*60) << endl;

return 0;

}

– C++ Programming labs, Term 2, 2011/2012, 116–

8-1-2012 23:59 c© M. K. Warby C++ Programming labs, Term 2, 2011/2012 Page 117

If you run this on the computer fenrir which is running the operating system linux thenyou get the following output.

Thu 1 Jan 00:00:00 1970

Thu 1 Jan 01:00:00 1970

Tue 19 Jan 03:14:07 2038

Tue 19 Jan 03:14:07 2038

approx number of years in this range=68.0497

If you run using Windows the output is as follows.

Thu 1 Jan 00:00:00 1970

Thu 1 Jan 00:00:00 1970

Tue 19 Jan 03:14:07 2038

Tue 19 Jan 03:14:07 2038

approx number of years in this range=68.0497

With type int involving 4 bytes=32 bits the time span is only just over 68 years and weare more than half way through this already. Note that the GMT and local time differ withthe first date on linux but the dates are the same for second date with both platforms. Thelinux values are correct here for the local time on 1st Jan 1970 as during the period 27 Oct1968 to 31 Oct 1971 the UK stayed with British Summer Time (BST) all year.

The type tm in the program above is a structure which has at least the following members.

int tm_sec Seconds [0,60].

int tm_min Minutes [0,59].

int tm_hour Hour [0,23].

int tm_mday Day of month [1,31].

int tm_mon Month of year [0,11].

int tm_year Years since 1900.

int tm_wday Day of week [0,6] (Sunday =0).

int tm_yday Day of year [0,365].

int tm_isdst Daylight Savings flag.

The functions gmtime() and localtime() create this type with respect to GMT and localtime respectively. strftime() creates a a C-style string of the date which is later displayedin the main() function.

The following contains a short program which does the reverse of gmtime() and localtime()

by first setting up such a structure, then uses the function mktime() to create the time t

value. Try this program.

#include <iostream>

#include <ctime>

#include <cmath>

using namespace std;

time_t create_t(int y, int mon, int d, int h, int min, int s)

{

// ..return the time_t values corresponding to the arguments

– C++ Programming labs, Term 2, 2011/2012, 117–

8-1-2012 23:59 c© M. K. Warby C++ Programming labs, Term 2, 2011/2012 Page 118

tm a;

a.tm_sec=s;

a.tm_min=min;

a.tm_hour=h;

a.tm_mday=d; // ..day of the month [1,31]

a.tm_mon=mon-1; // ..month of the year [0,11]

a.tm_year=y-1900;

a.tm_isdst=0;

return mktime(&a);

}

void gmt_and_local(time_t& t, char cgmt[], char cloc[])

{

tm a;

a=*gmtime(&t);

strftime(cgmt, 32, "%a %d %b %H:%M:%S %Y", &a);

a=*localtime(&t);

strftime(cloc, 32, "%a %d %b %H:%M:%S %Y", &a);

}

int main()

{

time_t t;

char cgmt[32], cloc[32];

t=create_t(2011, 10, 29, 23, 0, 0);

gmt_and_local(t, cgmt, cloc);

cout << cgmt << endl;

cout << cloc << endl;

t=create_t(2011, 10, 30, 23, 0, 0);

gmt_and_local(t, cgmt, cloc);

cout << cgmt << endl;

cout << cloc << endl;

return 0;

}

This generates the following output.

Sat 29 Oct 23:00:00 2011

Sun 30 Oct 00:00:00 2011

Sun 30 Oct 23:00:00 2011

Sun 30 Oct 23:00:00 2011

The first 2 lines indicate that there is a one hour difference between the GMT value and thelocal time in the first case but that one day later both are the same. The program also givesa way of determining the day of the week given a date at least for the years 1970–2037 andto ensure that the GMT and local time report the same day we should choose a time whichis not too close to midnight, e.g. we can take 12:00:00 (mid-day) as the time of the day.

– C++ Programming labs, Term 2, 2011/2012, 118–

8-1-2012 23:59 c© M. K. Warby C++ Programming labs, Term 2, 2011/2012 Page 119

We can use bisection to determine precisely when we change from GMT to BST asindicated in the following program.

#include <iostream>

#include <iomanip>

#include <ctime>

#include <cmath>

#include <cstring>

using namespace std;

// ..functions as before

int main()

{

char cloc[32], cgmt[32];

time_t ta, tb, tc;

ta=create_t(2012, 1, 1, 0, 0, 0);

tb=create_t(2012, 7, 1, 0, 0, 0);

do

{

tc=ta+(tb-ta)/2;

gmt_and_local(tc, cgmt, cloc);

if(strcmp(cgmt, cloc)==0)ta=tc;

else tb=tc;

}while(tb-ta>1);

gmt_and_local(ta, cgmt, cloc);

cout << "Change from " << cgmt << " GMT to ";

gmt_and_local(tb, cgmt, cloc);

cout << cloc << " BST" << endl;

return 0;

}

This creates the following output.

Change from Sun 25 Mar 00:59:59 2012 GMT to Sun 25 Mar 02:00:00 2012 BST

Extend the program to determine the precise time when we have changed the clocks orwhen we will change the clocks from 1972 to 2012. Part of the output could be as follows.

Change from Sun 19 Mar 01:59:59 1972 GMT to Sun 19 Mar 03:00:00 1972 BST

Change from Sun 29 Oct 02:59:59 1972 BST to Sun 29 Oct 02:00:00 1972 GMT

Change from Sun 18 Mar 01:59:59 1973 GMT to Sun 18 Mar 03:00:00 1973 BST

Change from Sun 28 Oct 02:59:59 1973 BST to Sun 28 Oct 02:00:00 1973 GMT

..lines removed

Change from Sun 25 Mar 00:59:59 2012 GMT to Sun 25 Mar 02:00:00 2012 BST

Change from Sun 28 Oct 01:59:59 2012 BST to Sun 28 Oct 01:00:00 2012 GMT

– C++ Programming labs, Term 2, 2011/2012, 119–