[epsf,html,12pt,a4]article C at_work.gif (Under Construction...) [1]#1 [2]#1#2 [1]"#1" --- htmlonly [1]"#1" - htmlonly http://www.eeng.dcu.ie/7Emcmullin/swe1/swe1root ../../swe1root/swe1root/labels.pl Software Engineering 1: Laboratory Exercises Barry McMullin Last Modified: 30th April 1996 Note that this complete document is available in LaTexswe1labs.tex and plain ASCIIswe1labs.txt forms, to allow downloading and offline browsing. Introduction This document is one component of the hypermedia documentation for the course Software Engineering 1 ../swe1root/swe1root.html. It presents detailed instructions and background information for the laboratory sessions. In general, the notes for particular lab exercises will be added to this document on an ongoing basis during the academic year, with each new exercise being made available a few days before the first section of the class is due to do it. General Comments on Lab Work The CAE laboratory itself should be used both for the scheduled laboratory exercises, and also for private study: the primary way of studying software engineering is to do it! The laboratory exercises are crucial to this course: you should learn more from the time you spend in the laboratory than from lectures and tutorials combined. Each student attends one three-hour scheduled lab session every two weeks. You should aim to spend at least three further hours of private study time in the lab over the same period. The scheduled lab sessions are deliberately structured so that each student has a separate PC; however, for private study you may find it easier to get at a machine, and also more effective, to work together with one or two othersprovided that you spend time discussing what is happening, and taking turns at actually operating the PC. For the first lab session you are required to bring along a new, unused, copybook or notebook to be used as your lab logbook. However, in contrast to most other laboratory subject, this logbook will not be used to hold formal lab reports. Instead, you will maintain the logbook just with your own personal notes; but these personal notes will serve as the basis for writing separate formal reports, which will actually be submitted (and archived) electronically. This will be explained in more detail during the lab sessions. You should consult the Software Engineering 1: Laboratory Report Guidelines http://www.eeng.dcu.ie/7Emcmullin/swe1/rptfmt/rptfmt.html for advice on how to prepare lab reports, and the criteria which will be used in marking them. Session 1: Week 1/2 This first several lab sessions are concerned simply with introducing general purpose hardware and software tools which will be used in the remainder of the course. Given that you are reading these notes, you have successfully completed the first phase of the exercise! Stop at this point and read back over what you have written in your logbook. Make sure you have a reasonably complete record of what you have done so far (so that, if necessary, you could redo it without further guidance). In particular you should have some record of: The rules http://www.eeng.dcu.ie/eenghome/caerule/caerule.html and timetable http://www.eeng.dcu.ie/eenghome/caetime/caetime.html applying to users of the CAE laboratory. The component physical parts of the PCstheir names and functions. The procedure for booting up a PC. In particular you should have carefully read the notice http://www.eeng.dcu.ie/eenghome/aup.txt regarding acceptable use of the School's computer facilities. How to format a new diskette from the MS-DOS command level. How to check the integrity of a diskette from the MS-DOS command level. How to initialise a diskette as a Netscape Configuration diskette from the MS-DOS command level. How to start up the MS-Windows environment. How to use the MS-Windows online Help facility, including searching and using hypertext links. How to start up the MS-Windows introductory tutorial. How to move, minimize, maximize, and otherwise resize windows. How to launch applications. How to start Netscape, and use hypermedia links. How does navigating with Netscape differ from using MS-Windows Help? If your logbook fails to mention any of these things, take time now to make some additional notes. At this stage you have created and are using a Netscape Configuration Diskette. You should always insert this diskette before starting up a Netscape session. IMPORTANT: Do not remove it again until your Netscape session is over, and the diskette light has gone off. This configuration diskette will hold personal information about your use of Netscape. For example, you can record a bookmark file, identifying nodes that you have visited, making it easy to revisit them. For now, we want to configure Netscape to know your name and email addressso that, if you originate email from within Netscape, you will automatically be identified as the author.You will not be able to receive email for the time being. That will be dealt with in subsequent lab sessions. Follow these steps, within Netscape: Drop down the Options menu. Select Preferences. Select the Mail and News tab. Fill in the fields labelled Your Name and Your Email. Your email address will be something like astudent@ugmail.eeng.dcu.ie, but instead of astudent you have a username consisting of your first initial followed by your surname, up to a maximum of 8 characters in total. Do not use any spaces or punctuation, and keep it all in lower case. Select OK. Now, find out (using Netscape) as much as you can about the Electronic Mailing List facility operated by the School of Electronic Engineering. In particular, read the information about the SOFTENG1-95 http://www.eeng.dcu.ie/7Emajordom/softeng1-95.info.html list. Check out the archives http://www.eeng.dcu.ie/7Emajordom/hmarchives. Finally: compose a short message (one paragraph) which summarises your opinion of this course (Software Engineering 1) so far. Mail this message to SOFTENG1-95@mjmail.eeng.dcu.ie mailto:softeng1-95@mjmail.eeng.dcu.ie.If you enter this address manually, omit the quotation marks. But, in this particular case, you can just click on the address and Netscape should bring up a mail composition window, already addressed to the correct address, and with your name and return address automatically recorded. Check the archives http://www.eeng.dcu.ie/7Emajordom/hmarchives again to see that your message has been archived successfully. Note that, due to a defect in Netscape you may have to clear the caches, before your message will become visible in the index. To do this, drop down the Options menu, and select Preferences again. Select the Cache and Network tab. Click on Clear Memory Cache Now. You will be asked to verify thisclick on OK. Similarly, clear the disk cache. Click on OK again to exit the Preferences dialog. The archive index will be automatically reloaded and is now guaranteed to be up to date. If your message is still not showing up, then something has gone wrong. If your message is now visiblecongratulations: you have successfully completed the first lab exercise!And your message is nowimmediately - accessible to the entire world wide Internet community! Session 2: Week 3/4/5 Background This session introduces the tools you need to create and manipulate text files on the PC. Text files are just textual documents. You might compose a letter or message and save it on diskette in a text file. Subsequently you might edit it to correct mistakes or add more information. You might copy it from one diskette to another for backup purposes (in case one diskette gets damaged or lost). You might print it out or email it. You might delete it off your diskette when you no longer have any use for it. We will be dealing with very basic so-called ASCII text documents. ASCII (American Standard Code for Information Interchange) is a standardised way of expressing text in electronic (binary) form. It essentially specifies a way of encoding each possible character as an 8-digit binary number, or byte. ASCII supports the lower and upper case alphabetic characters (a to z and A to Z), the digit characters 0 to 9, a variety of punctuation characters such as ; : . ? ( ) [ ] etc., and finally a collection of special characters such as + * etc. ASCII provides roughly the same capability for representing text as used to be available with an old fashioned typewriter. ASCII does not support more advanced or complicated kinds of text such as accented characters, mathematical symbols, underlining, bolding, varying sized characters, etc. As such, ASCII might be regarded as pretty primitive. The great advantage of ASCII is that it really is a standard. ASCII encoded text files can be read and printed on virtually any computer system, and can be successfully transmitted through any email system. ASCII is a sort of Lowest Common Denominator of text file formats. We will use ASCII files in this course for preparing lab reports, and for preparing program files (in the programming language). programs will, in effect, be ASCII files, and will be manipulated with the same tools as we manipulate any other ASCII files. Managing Text: Using PFE We will create and manipulate text files using an application called the Programmer's File Editor or PFE for short. PFE will allow you to enter text for a new file, save it on your diskette, edit it again, save it again, print it, and so on. You will find PFE in the Tools group in Program Manager. Start it up now. Once it is started up, you might want to move and resize both its window and the Netscape window so that they do not overlap too much, and you can see both easily. Explore and experiment with the use of PFE for a while. Have a look at the various menus. Read through the online help. Try out the buttons on the button bar to see what (if any) effect they have. Now carry out the following exercise: Create a new text editing window.Select New on the File menu. Type up a couple of paragraphs of text on any subject of your choice. Save the file on your diskette, under the name TESTING.TXT.Select Save on the File menu. This will bring up a file selection dialog. On this you need to specify a disk driveA: for the disketteand the file name. Exit from PFE. Start up PFE afresh. Create a text editing window for the file TESTING.TXT.Select Open on the File menu. This will bring up a file selection dialog again. Make some modifications to the file. In particular, insert a line at the top with your own name, and today's date.This will serve to identify your particular file when you come to print it out in the next step. Save the file again. Note carefully that, while you are editing the file within PFE, this is only changing a copy of the file loaded into main memory. This is a kind of semiconductor memory, which is completely volatilethe information will be lost is there is a power failure or the machine is otherwise reset. The copy of the file on your diskette is not being modified. To update the diskette copy, you must save the file from within PFE. It is very important to get into the habit of saving early and often. Print your file out.Select Print on the File menu. As everybody will be trying to print at more or less the same time, you needn't wait until it is physically printed, but continue on with the exercise. Exit from PFE again. At this point you should be satisfied that, using PFE you know how to create, save, re-edit, and print, ASCII text files. Managing Files: Using File Manager PFE is adequate for basic creation and manipulation of text files. However, for more general management of disks and filesformatting diskettes, organising files into directories, copying files, deleting files etc.you need a different tool, File Manager. File Manager has the further advantage that it can operate on all kinds of filesnot just text files. This isn't much of an issue in this course yet, but will become one in the near future. You will find File Manager in the Main group in Program Manager. Start it up now. Once it is started up, you might want to move and resize both its window and the Netscape window so that they do not overlap too much, and you can see both easily. Explore and experiment with the use of File Manager for a while. Have a look at the various menus. Read through the online help - particularly the section called What is File Manager? Now carry out the following exercise: Create a new directory at the topmost level on disk drive D: with any name you wish (for example, your own forename or surname etc.).If you manage this successfully, you should be able to see the new directory listed by File Managerfor example as D:MYDIR or whatever. Try to establish what, if any restrictions apply to naming a directoryeither by experiment or by reading the help. Delete the directory again. Create a directory at the topmost level on your diskette (drive A:) with the name TMP. Move the file TESTING.TXT from the topmost level of your diskette into the directory TMP. Create a new directory on disk drive D: called MISC. Copy the file TESTING.TXT from directory TMP on your diskette into the MISC directory.To achieve this you need two (sub-)windows open in File Managerone showing the contents of A:TMP, the other showing D:MISC. Then just drag the file TESTING.TXT across. Note how, when you drag a file, File Manager moves the file if both the starting and ending point are on the same disk, but copies the file when they are on different disks. Delete the whole directory MISC from drive D: (including the file TESTING.TXT which it contains). Exit from File Manager. At this point you should be satisfied that you know how to use File Manager to examine what directories and files are on a disk, to create and delete directories, and to move, copy, and delete files. Managing email: Using Eudora Light You have already seen, in session 1, how you can use Netscape to send email messages to one of the mailing lists archived on the School web site, and how to read these messages. However, Netscape does not support accessing or receiving personal email. To receive and manage email, in a general way, we will use the Eudora Light application. Eudora allows email to be prepared and sent; it allows you to download email from your personal email-box on the School server; and it allows you to manage and organise you own archives of email messages you have received. Like Netscape the effective use of Eudora relies on using a configuration diskette where Eudora will store specific information relating to your email account, and will also store your received email messages. You can use a single diskette as both the Netscape and Eudora configuration diskette. A notice, detailing how to set up and use a Eudora diskette was posted to the Local-Notices mailing list within the past few weeks. Find that message now in the web archives http://www.eeng.dcu.ie/7Emajordom/hmarchives. In fact, look for all messages referring to Eudora Light (also known as Freeware Eudora). Read these messages carefully. You will find Eudora in the Internet group in Program Manager. Start it up now, and configure it, as described in the message on Local-Notices. Explore and experiment with the use of Eudora for a while. Have a look at the various menus. Start up the viewer for the online manual (also in the Internet program group). Browse through it (there will not be time to read it in detail). The demonstrator will tell you the assigned password for your account. Verify that Eudora can check for mail received into your mailbox. Try sending yourself email. Try exchanging email messages with the person beside you. Send a message with the following text: to the address majordomo@mjmail.eeng.dcu.ie. See what messages you receive back. You must now change your account password to one of your own choosing. Choosing a good password is not easyit must be both hard for anyone (or any machine!) to guess, yet be easy to remember. Briefly, your password should be 8 characters long, use a mix of both upper and lower case letters (which are considered to be distinct in passwords), some digits, and some special or punctuation characters. You may not use the space character in a password. Read through this online advice on choosing Good Passwords http://www.alw.nih.gov/Security/Docs/passwd.html. When you have made up a satisfactory new password, which you are sure you will be able to remember, use the Change Password option on the Special menu in Eudora to actually change the password. Note that this may fail for a variety of reasonsfor example, if you type in the old password wrongly, or the new password is too short, or does not have a mix of both upper and lower case, or does not have any non alphabetics. If the password changing fails, the old password will remain in effect, so just go through the procedure again. When you have succeeded in changing your password, check again that your email access is still OK by sending yourself another test message and seeing that you can receive it. You should change your password again at least once every term or soand immediately if you have any reason to suspect that it may have been compromised. Finally, using Eudora, compose a short message (one paragraph), summarising your experience of this lab exercise, and mail it to SOFTENG1-95@mjmail.eeng.dcu.ie . That completes the exercise; you can now shut down all applications, take out your diskette, exit Windows, and power down the PC. Session 3: Week 6/7: Introducing C Preparation From this session onward it is essential that you study the notes for the session carefully in advance. The lab exercises are getting increasingly extensive and demanding. You will not be able to study the notes for first time and carry out the required exercises within three hours. Background In this session you will attempt, for the first time, to develop an actual program. You will be using the language. This is a so-called high-level language, so you will need to translate the program into the low-level or machine language that the Central Processing Unit (CPU) can actually directly execute. You translate the program using a tool called a compiler. There are a wide variety of compilers available for PCs, each with their own particular strengths and weaknesses. We will be using DJGPP http://www.delorie.com/djgpp which is a version of the GNU C Compiler or gcc for short. This is very widely used both on PCs and Unix platforms. It has the further advantage that it is free! , and other languages closely related to it, are the de facto industry standard programming languages for most general purpose applications. is a very sophisticated language in certain ways. This makes it a powerful programming tool for the experienced software engineer. It also makes it a very dangerous and difficult tool for beginners. Therefore, in the first instance, you will be insulated from the full complexities of the language by a specially developed device called safe-c. This is, in effect, a package of pre-written building blocks (or functions as they are called in ), together with a few other ancillary elements. For the time being, the distinction between safe-c and proper will not be apparent. But later on in the course, we will begin to uncover exactly the role that safe-c is playing, and separate it from standard . Finally, this session is also the first to require you to prepare a formal lab report. Before going any further, please read carefully through the Laboratory Report Guidelines http://www.eeng.dcu.ie/7Emcmullin/swe1/rptfmt/rptfmt.html, paying particular attention to the marking scheme. This is the format, and marking scheme, that will be used in the lab exams by which this course will be assessed. Now is your opportunity to practise writing reports according to the required format, and doing it in the lab, under the same conditions as will prevail in the exams. Think of every lab session from now on as a mock exam. Reports from these mock exams will be reviewed during lectures, to give an indication of what approximate mark could be expected for it. You will get the maximum benefit from this if you practise marking your report, according to the guidelines, yourself. You must write the report as you go along in the lab session. Start now, by using File Manager to create a working directory called softeng1 in the root directory of drive D:. Use PFE to create a file called report.txt in this directory. Insert into this the required header text for the report, as specified in the guidelines. Keep PFE running, with a subwindow open for this file, throughout the lab session, so that you can add to it as you go along. Remember to save back to disk every time you add any significant amount of textotherwise you run the risk of losing this text completely if, for example, there is a power failure in the lab. At the end of the session you will be required to finish the report and submit it by email. Allow 15 minutes at the end of the session to do this. Specifically, even if you have not completed the assigned exercises, stop working on them and submit the report anyway. In the lab exams, only the report is markedso if the report is not submitted you will get zero marks! Note that, because this particular lab session is very straightforward and is largely concerned with introducing some new tools and procedures it has relatively little technical content: you should therefore be easily able to score over 80+ in your report for this session. If you can't achieve that then it indicates that you are not keeping pace with the course. Exercise 1: Hello World! (60) Here is the minimal Hello World program already discussed in the lectures: Use PFE to create a file called hello.c in the directory D:softeng1 containing the program listed above. Start up the MS-DOS Prompt application. MS-DOS Prompt (or DOS for short) is a command line interpreter. That is, it allows you to type in textual commands which it then tries to carry out. This is an alternative style of user interaction, compared to the graphical style of using the mouse to point and click in order to get things to happen. This textual type interaction will be more convenient for many of the interactions involved in developing programs. On some PCs in the CAE lab DOS is configured to run full-screen. This means you can no longer see the windows for other applications such as Netscape and PFE. This is quite inconvenient. If this happens, press Alt-Enter (i.e. hold down the Alt key and press Enter). This will make DOS run in a window instead. Under MS-DOS Prompt you will have, at any given time, a default disk drive and default directory on that drive. This simply means that if you refer to a file, without explicitly stating what disk drive or directory it is located in, then DOS will assume it is on the default drive and in the default directory. The DOS prompt will indicate the current default drive and directory. We are going to be working with files on drive D: and in directory softeng1, so it will be convenient to make these the defaults. To change the default drive, simply type in the desired drive letter followed by a colon, and press Enter. The prompt should change to reflect the new default. Try changing to drive A: and back to drive D: now to see this happened. To change the default directory (on the default drive) use the cd command (short for Change Directory): Note the leading backslash character here. This character is used to separate drive specifiers from directory names, and directory names from subdirectory or file names etc. In this particular case, the signals that tmp is in the top-level or root directory of the current drive. If the were omitted, DOS would think that tmp was intended as the name of a sub-directory of the current directory (whatever that might be). Experiment with changing the current directory to make sure that you understand its operation fully. You can only change to directories that exist. You can, of course, check what directories (and files) exist using File Manager. Alternatively you can use the dir command in DOS. You can get help on DOS commands by using the help command. Its operation is pretty self explanatory. Experiment with it now. Note that case is not significant in DOS command, directory, file, or drive namesso, for example, CD has the same effect as cd etc. Make D:softeng1 your current drive and directory. Use dir to check that the file hello.c is present there. You can use the command type in DOS to type the contents of a text file on the screen. Try this now to check that hello.c does indeed contain what you expect. Compile your program by giving the command: scc is part of the safe-c package. It invokes the compiler in the appropriate way to ensure that the safe-c components get automatically combined with your program. The program should compile without any problemsif you have entered it correctly. But if any problems are encountered try to figure out what is going wrong and fix them. If you get stuck, seek help from the demonstrator. Check (using File Manager or the dir command in DOS) what files now exist in your directory. There should be a new file called hello.exe. This is the executable filethe file containing the binary instruction codes that the CPU can directly execute. Make a note of the size of this file in your report. To execute the program under DOS you simply give its name as a command: In fact, it is enough to just say hello as the command name - DOS will automatically search for a file with that name and the .exe extension. Check that the file executes as you expected. If it does not, try to figure out why, and fix it. Again, if you get stuck, ask for help from the demonstrator. If all has executed correctly, then congratulationsyou have just entered, compiled, and tested your first program. Make a directory called lab3 in the root directory of your diskette. Copy the file hello.c into this directory. There is no need to copy the file hello.exe onto your disketteexplain why in your report. Exercise 2: Branching out! (40) Here is the program insult.c introduced in the lectures: Using this as a basis, or template, develop (plan, code, test, correct) a program called sport.c which will behave as follows: Display a suitable welcome/identification message. Ask the user to type in his or her favourite sport. If the topic is Tennis, display the message Tennis? I used to play Cricket!. If the topic is anything else, display the message What a silly game! instead. Finally display some suitable closing message. Conclusion That completes the exercise. As previously explained, the formal lab report, which you have prepared during the session, must now be submitted by email. Carry out the following procedure to submit your report. You need to allow at least the last 15 minutes of the lab session for this. Read quickly back through the report, correcting obvious errors, and possibly adding some brief concluding remarks. Close the PFE subwindow. Using File Manager, make a copy of the report file in the directory lab3 on your diskette. This gives you a permanent copy of the report as a precaution against it somehow getting lost or corrupted in the mail system. Using Eudora, bring up a new message window to prepare to email the report. Fill in the To: field as: Its a good idea to also include yourself as an additional recipient (in the Cc: field) so that you get positive feedback that the message successfully went into the mail system. Fill in the subject of the message as simply Session 3 Report. To include the report file in the message, drop down the Message menu and select Attach File. This will bring up a file selection dialog. Select the file where you have saved the report (D:softeng1report.txt). BEWARE: Eudora has several possible mechanisms for attaching files to a message, depending on the type of data in the file (e.g. whether it is simply ASCII text, or some kind of word processing format or whatever). Only one of them will work correctly for your lab reports. If you get this wrong in the lab exam, the report will not be correctly submitted and you will score zero. The correct mechanism in this particular case is for Eudora to simply include the text from the file as part of the text of the message. It will do this if the button on the message window marked TEXT->DOC is out or deselected. Check this now, and make sure the button is in the correct state.You may find it convenient to make this the default for Eudora. Drop down the Special menu and select Settings. Scroll down through the categories and select Attachments. Put a cross in the box marked Put text attachments in body of message. Now, whenever you bring up a new message window, the TEXT->DOC button will be deselected by default. Press Send to send the message. If you have included yourself as an additional recipient, then you should receive a copy back. Wait about 30 seconds and then check this. This submitted report should be automatically archived on the school Web site, under the archives for the softeng1-95-reports mailing list. However, this will only happen after the report has been previewed and approved by the moderator, which should normally be within a couple of hours. You should make a point of checking whether your report appears correctly in the archives in due course. If not, do not submit it again. First, post a message on the softeng1-95 list, querying what has happened. Session 4: Week 8/9: Quiz Time Introduction This session is concerned with developing and reinforcing the basic tools of programming already introduced. The session does not involve any significant new concepts, but merely requires that you apply the techniques you have already learned in slightly more elaborate ways. You are again required to write a formal lab report, and submit it by email, in exactly the same format and manner as in session 3. This session also again involves creating, editing and storing files on your PC (in suitable directories), and compiling source files to produce executable files. If you are unsure of any aspect of doing these things, please review the session 3 notessession3 again. The relevant instructions will not be repeated here. This session has two exercises. In the first you are give a program and told what it ought to do. You are then asked to test whether the program behaves as specified; and, if not, to correct any defects you can identify. In the second exercise you are asked to develop a more ambitious program, based on the given program. Exercise 1: Correction (60) Consider the program mquiz0.c ../src/mquiz0.c. This should prompt for the user's name; then print Hello followed by the user's name; then repeatedly ask the user what the best album of all time is, unless and until the answer Dark Side of the Moon is given. Test whether this program behaves as specified.Note that, once you are viewing the program file in Netscape, you can use the Save as... option on the File menu of Netscape to save a copy of the program in some suitably named file on your PC. If not, identify and correct any defects. Carefully record each such defect, and your correction, in your formal report. Exercise 2: Enhancement (40) The program mquiz0 will keep on repeating the question unless and until the user is inspired to give the correct answer. Develop an enhanced version of this program, called mquiz1. This should behave in the same way as mquiz0, except that, if the user gives a wrong answer, the program should then ask whether the user wants to try again. If the user indicates that he or she does not want to continue then the program should exit (remarking Good idea - `cos you don't know much about music, do you?). Session 5: Week 10/11: Ever Decreasing Circles... Introduction This session introduces the use of two new safe-c data typesintegertype and floatingpointtype. A data type is a format for storing and manipulating some particular kind of information in a program. So far we have used just two data types: stringtype and booleantype. stringtype allows the input, output, and comparison of arbitrary strings of ASCII characters. The length of the string is variable, up to a certain maximum length. The only manipulations allowed (so far) on objects of stringtype rely on using functions (or subprograms) provided by the safe-c module: putstring() : Allows a string to be be displayed in the MS-DOS window in which the program is running. getstring() : Allows a string to be read in from the keyboard. stringequal() : Allows two strings to be compared. Generates a return value which is of booleantype. This will be TRUE if the two strings are exactly identical, and FALSE otherwise. booleantype has only two possible values (TRUE and FALSE) and is useful in controlling if and while statements. Values of booleantype can be manipulated with the following operators: In more detail, the meaning of these operators is as follows: Boolean AND: Denoted by a double ampersand (with no space between them). Takes two operands. If both operands are TRUE it evaluates as TRUE; otherwise it evaluates as FALSE. Boolean OR: Denoted by a double vertical bar "" (with no space between them). Takes two operands. If either operand is TRUE it evaluates as TRUE; otherwise it evaluates as FALSE. Boolean NOT: Denoted by an exclamation mark !. Takes one operand. If the operand is TRUE it evaluates as FALSE; if the operand is FALSE it evaluates as TRUE. Test for equality: Denoted by a double equal sign == (with no space between them). Takes two operands. If both operands have the same boolean value it evaluates as TRUE; otherwise it evaluates as FALSE. This operator can be applied to operands of certain types other than booleantype, but its result is always of booleantype. When the operands are of booleantype it is equivalent to the negation of the boolean XOR (Exclusive OR) operator. Assignment: Denoted by a single equal sign =. Takes two operands. The left hand operand must be a variable. The value of the right hand operand is copied into, or assigned to, the variable named as the left hand operand.The assignment operator also technically generates an evaluation result, just as any of the other operators do. This evaluation result will be the value of the right hand operandi.e. the same value as is stored in the variable named as the left hand operand. This allows an assignment operation to be nested within a more complex expression. That is sometimes useful, but its use is beyond the scope of the current session. The two new data types introduced in this session are both used to represent, store, and manipulate numbers. integertype can represent only whole numbers (positive and negative); floatingpointtype can represent fractional, or rational, numbers (positive or negative), using a form of scientific notation. The most basic operation or manipulation that can be performed with these data types is to assign a value to a variable of that type. This uses the same assignment operator as for booleantype. For example: Note, incidentally, that the assignment operator cannot be used with objects of stringtype. Thus, it would quite wrong to say something like: If you need to do something like that, use the function assignstring instead: Both the numerical data types allow the four normal arithmetic operations: These operators all accept two operands, and evaluate with a result which is of the same data type as the operands. Note carefully that when you divide two values of integertype the result is just the quotient and will still be of integertype. Any remainder will be discarded. Thus, for example 5/3 would evaluate as 1. You can use the special remainder operator, denoted by , to separately calculate the remainder part of an integertype division if you like. So 53 evaluates as the remainder after dividing 5 by 3, which is to say 2. The remainder operator is not applicable to floatingpointtype (for obvious reasons?). These numerical data types also allow various comparison operations: All of these comparison operators yield a result of booleantype. The detailed way that integertype and floatingpointtype are represented internally will not be discussed here, except to say that they both rely on a binary notation, because this matches best the actual physical nature of the computer's memory system. Functions are provided to convert between values of these binary numerical data types and stringtypewhich indirectly allows input and output of these numbers (using getstring() and putstring()). All the data types and functions introduced here are specific to the safe-c module and you will not find them discussed in standard texts. However, all the operators (arithmetic, boolean, assignment, comparison) are part of the language definition and will be covered in the textbooks. More detailed information on these new data types, and the facilities available for using them, is provided in the safe-c User Guide ../safe-c. You are again required to write a formal lab report in this session, and submit it by email, in exactly the same format and manner as in sessions 3 and 4. This session also again involves creating, editing and storing files on your PC (in suitable directories), and compiling source files to produce executable files. If you are unsure of any aspect of doing these things, please review the session 3 notessession3 again. The relevant instructions will not be repeated here. The overall format of this session is very similar to session 4. It has two exercises. In the first you are given a program and told what it ought to do. You are then asked to test whether the program behaves as specified; and, if not, to correct any defects you can identify. In the second exercise you are asked to develop a more ambitious program, based on the given program. Exercise 1: Correction (50) Consider the program circle0.c ../src/circle0.c. This should prompt for the user's name; then print Hello followed by the user's name; then ask the user to enter the radius of a circle (in m); the program should then calculate and print out the circumference and area of the circle.The circumference is given by the mathematical formula ; the area by the formula . The program is very poorly laid out and formatted. Reformat it in a way that makes it easier to read and understand.Note again that, once you are viewing the program file in Netscape, you can use the Save as... option on the File menu of Netscape to save a copy of the program in some suitably named file on your PC. Correct any obvious mistakes. Of course, you should note what changes your make, and include a copy of the reformatted program, in your formal report. Now test whether the program behaves as specified. If not, identify and correct any defects. Carefully record each such defect, and your correction, in your formal report. Exercise 2: Enhancement (50) The program circle0 calculates the circumference and area of just one circle. Develop an enhanced version of this program, called circle1. This should behave in the same way as circle0, except that it should repeat the sequence (of requesting a radius, then calculating and printing out the circumference and area) exactly five times. Each time the prompt should change (so the first time it should say Enter radius 1:, the second time Enter radius 2 and so forth). Session 6: Week 12/13: Lab Examination 1 Please see the General Examination Instructions http://www.eeng.dcu.ie/7Emcmullin/swe1/95-96/exams/general, which includes links to all the specific examination exercises for the different sections of the class. Session 7: Week 14/15: Functional Decomposition Introduction This session is concerned with practical experimentation with the facilities for breaking down a program into smaller, more manageable, pieces called functions. The standard library makes available a large range of standard mathematical functions. These include standard trigonometrical functions, sin(), cos() and tan(). These three functions each accept one argument (of floatingpointtype) and return a result (also of floatingpointtype). The argument must be an angle measured in radians. Often it is more convenient to work with angles measured in degrees instead. The ultimate objective of this session is for you to write your own trigonometric functions (exploiting the existing standard functions) which will accept arguments in degrees rather than radians. However, we shall get there through a series of smaller steps. Before this session it is essential that you review and understand the very basic example programs, already introduced in the lectures, which illustrate functional decomposition. These are: sum0.chttp://www.eeng.dcu.ie/7Emcmullin/swe1/src/sum0.c: This program prompts for two numbers, adds them, and prints out the sum. It does not use functional decomposition at all. sum1.chttp://www.eeng.dcu.ie/7Emcmullin/swe1/src/sum1.c: This is a modified version of sum0.c in which a new function has been defined, called getfloatingpoint() which combines the effects of the standard safe-c functions getstring() and stringtofloatingpoint(). This illustrates how to define a function which has to pass back, or return, some information to the place which it was called from; and how to use, or access, that information at the calling site. sum2.chttp://www.eeng.dcu.ie/7Emcmullin/swe1/src/sum2.c: This is a further modified version, in which a second new function has been defined, putfloatingpoint() which combines the effects of floatingpointtostring() and putstring(). This illustrates how to define a function where some information has to be passed from the calling site, into a function, and how that information can be accessed within the function. The session is divided into five separate exercises. Each of these builds on the previous one. It is important that you read through the instructions for all the exercises, in advance of the lab session. None of the exercises is very complex in itself, and you should be able to complete all five in the time available. However, it is more important to fully complete as many of the exercises as possible than to make an incomplete attempt at them all. So, it is essential that you take the exercises in the order given, and do not attempt to go on to a following exercise until you have fully completed its precursor. Each exercise involves developing a program. Note carefully that develop here means writing, compiling (with no errors or warnings), and testing. The tests should exercise a reasonable range of behaviour before you consider them complete. The report must specify exactly (including actual numerical values, where relevant) what tests you carried out, what results you expected, and what results the program generated. If the actual results are not exactly the same as the results you expected, you must comment on this. Exercise 1: The sin() Function (20) Develop a program, called trig1.c, which will prompt for an angle value (in radians), and print out the sine of that angle. Where appropriate, this program should use the functions getfloatingpoint() and putfloatingpoint() defined in the example program sum2.c http://www.eeng.dcu.ie/7Emcmullin/swe1/src/sum2.c. You can simply cut and past the relevant section of that program into your own program. This program does not involve defining any additional new functions of your own. Exercise 2: Angle Conversion (20) Modify trig1.c as follows, renaming it as trig2.c. trig2.c should prompt for an angle in degrees. It should then calculate the corresponding angle in radians, using the equation: where and denote the angle expressed in degrees and radians respectively. Having converted the angle to radians, it should then calculate, and print out, the sine (this behaviour is unchanged from trig1.c). The degrees conversion calculation should be carried out directly by suitable statement(s) within the main() function. That is, this program again does not involve defining any additional new functions of your own. Exercise 3: Function Definition (20) Modify trig2.c as follows, renaming it as trig3.c. trig3.c should behave exactly as trig2.c. However, instead of carrying out the angle conversion directly within the main() function, main() should invoke or call a new function, called degtorad(), to do this conversion. This should accept a single argument, of floatingpointtype, representing an angle in degrees. It should return a result, also of floatingpointtype, being the corresponding angle in radians. Of course, you have to provide the definition of this new function. Exercise 4: Refinement (20) Modify trig3.c as follows, renaming it as trig4.c. trig4.c should behave exactly as both trig3.c and trig2.c. However, instead of calling degtorad() and then calling sin(), main() should simply call a single new function, called degsin(). This should accept a single argument, of floatingpointtype, representing an angle in degrees. It should return a result, also of floatingpointtype, being the sine of this angle. Again, you have to provide the definition of this new function. It should use the function degtorad() which you have already written. Exercise 5: Finale (20) Modify trig4.c as follows, renaming it as trig5.c. trig5.c should prompt for an angle in degrees, and then print out the sine, cosine and tangent of this angle. The main() function should be structured to invoke functions called degcos() and degtan() to calculate the cosine and tangent respectively. You will have to add definitions for these functions, similarly to the definition of degsin(). Hints When defining a new function, you need to first prepare an adequate specification. This will consist of answers, expressed in plain English, to the following questions: What will it be called? function names, like variable names, consist of a sequence of characters, including upper and lower case alphabetics, the digits 0 through 9, and the underscore character . The name should always begin with an alphabetic. Names can be as long as you wish, but anything much longer than 20 characters becomes unwieldy and error-prone and should usually be avoided. All function names must be unique within a given program. Most programmers use only lower case alphabetics in function and variable names (i.e., no capitals). However, this is only a convention, and is not a compulsory part of the language definition. Names of functions are usually chosen based on verbs because they do something - whereas names of variables tend to be based on nouns (they just are). It is important to think carefully about the names of both functions and variables in a program. While the compiler really doesn't care (as long as the names are unique) these choices can make a big difference to how easy or difficult it is for another human being to understand how the program is intended to operate. What (if any) information will be passed in from the calling site? Many functions can behave differently based on certain information passed into them by their calling function. For example, the standard function putstring() is able to print out any string on the screen. Which particular string it will print out on any particular occasion is specified by the calling sitethe invocation specifies a particular string to be passed into the function. The specification of the information to be passed into a function will thus determine the layout of its argument list. The argument list states how many arguments the function will accept, what types they must be, and what names will be used within the body of the function to refer to these arguments. What (if any) information will be passed back to the calling site? Many functions generate a result of some sort, which must be made accessible to its calling site, after the function has finished execution. In the special case of objects of stringtype, this can be achieved by the calling site passing in a string variable to the function; any changes which the function makes to this string, will still be visible, after the function terminates, at the calling site. This is called passing by reference, and is the mechanism used, for example, by the getstring function. However, this does not work for information of other types. Thus, for example, if a variable of integertype is passed into a function, all that really happens is that a copy of this variable is made available to the function. Any changes which the function makes to that value are lost when the function exits. This is called passing by value. In this case, the idea of passing in a variable for a function to modify cannot be used to allow a function to pass information back to its calling site. In that case, you should use the return value mechanism. If you place a return statement in your function then, when that statement is executed, the function will immediately terminate, and the specified value will be made available at the calling site, in the position where the function was invoked. This is the mechanism used, for example, by the stringfloatingpoint function. Typically, this return value is assigned to a variable at the calling site, so that it can be stored for use in subsequent statements. The return mechanism cannot be used to pass back values of stringtype. In that case, you must use the passing by reference mechanism, where a string variable, belonging to the calling site, is passed into the function as an argument, and modified by it. The specification of the information to be passed back from a function may thus lead to the specification of additional arguments (passing by reference), or to the specification of a return type (or, possibly, both). What will the function actually do? That is, having stated what, if any, information if passed in, and what, if any, information is passed back, you need to state, in plain English, what the effect of the function is supposed to be. The idea of defining a new function usually arises in the context of some higher level function which you are already writing. Essentially, you want to defer coding some more detailed activity or calculation. This is called top-down design, and is a typical strategy for all forms of engineering design, not just software. So, for the time being, you just want to put in a call to a function, which, at some later stage, you will define in detail. The coding of this function call will, implicitly, at least, answer all of the questions we have just raised. Having answered these questions, you should then enter the skeleton definition of the function: You then go back and fill in the slots. For example, suppose we decide to define a function called foo, which will accept one argument of floatingpoint type, and generate no return value, we can immediately make out the following skeleton: You need to minimally provide this skeleton, just to allow an invocation of the function to even be compiled properly. You may well temporarily put in a dummy body to the functioncalled a stubjust to allow you to test out the higher level invocation. But, eventually, you must come back and fill in the body of the function definition with the actual statements which will make it, upon invocation, carry out the activities specified for it. Session 8: Week 16/17: Projectiles Problem Specification The purpose of this exercise is to calculate the theoretical trajectory of a projectile in a constant gravitational field. In other words, we want to calculate the path followed by, say, a ball thrown in the air. We are going to make some simplifications. We will work in just two dimensions (i.e. as if we are looking exactly side on at the path of the ball). We will also neglect air resistance, and will treat the projectile as a point mass. This allows a simple analysis of the motion of the projectile, using newtonian theory. In our two dimensional ( and ) coordinate system, will denote horizontal position, and will denote vertical position. The initial value of will be taken as zero. A zero value will correspond to the projectile being on the ground. The initial value of will be some positive value (in effect, the height of the person throwing the ball). will denote the horizontal component of velocity, and the vertical component. We will assume that both and are initially positive. Similarly, and will be the components of acceleration. The initial information provided for a particular run of the program will be the initial height () and initial velocity components ( and ) of the projectile. These values will be assigned to suitable variables. You can either code values directly into the program (in which case you will have to change the program, and recompile, every time you want to try different values) or you can have the program prompt for and read in values when it starts running. The output from the program will be a print out on the screen of the numerical values of and at successive, small, intervals of time. The program should terminate when becomes zero again (i.e. the projectile falls back to earth). This print out may be captured into a text file and a graph plotted of versus (one way of doing this is described in detail in the Hintshints8 section below). Informally, the motion of the projectile is pretty simple: it moves steadily to the right (positive direction), simultaneously going up for a while (positive direction), and then coming down again to land.Technically, under the various idealizing assumptions we have made, it can be shown that the trajectory will be parabolic. Formally, at each time step, the new co-ordinate can be calculated as: where (approximately): In words, if the velocity in the direction is , then, in a time , the projectile will move a distance of multiplied by ; and the new position is the old position plus this movement. This calculation would be exact if were constant; if is changing (as it will be in our case) then the calculation will still be approximately correct, as long as is smallnamely small enough that the percentage change in in that time is negligible. Of course, you can only estimate this once you have some idea of how quickly will be changing... The new co-ordinate may be calculated similarly. Now, in principle, both and could also be simultaneously changing, and have to be recalculated, at each time step. But since we are neglecting air resistance, and since gravity works straight down, there will be zero acceleration in the direction ( is zero), so that will actually remain constant, equal to its initial value. There will be acceleration in the direction however, of value , where is the acceleration due to gravity at the surface of the earth (about 9.81 meters per second per second). This is negative because our co-ordinate is positive in the upward direction and gravity works downward (last time I checked anyway...). This acceleration in the direction will be constant (since is not changing). Thus, the new at each time step can be calculated as follows: where: That is, the change in the (vertical) component of speed is simply the (vertical) acceleration multiplied by the time it acts over; and the new speed is simply the old speed plus this change.This change will be negative, because is negative; to put that another way, what goes up must come down! You should test your program carefully. Explain, in your report, what tests you carry out, how the program behaves, and whether it has passed such tests. Hints The main() Function Your main() function should declare variables to represent the values of all the relevant quantities. Think carefully about naming these variablesnote, for example, that variable names cannot involve subscripts, or greek characters. Think carefully about the type of each variable: is it to be used to represent a numerical value? If so, will that value be strictly integral, or may it have a fractional part? The overall structure of your main() function will consist of some initialisation (assigning initial values to appropriate variables), followed by a while loop which carries out the repeated calculations of the new and co-ordinate values. This loop should continue just so long as the value is greater than zero. The repetition, or iteration, in your program should be achieved using a while statement. It might be a good idea to start off with a highly simplified version of the main() function, having only a variable to represent and which just (for example) decrements the value by a fixed amount each iteration. This would allow you to check, at this early stage, that you have correctly implemented the while loop and that it terminates when appropriate. Functional Decomposition Try to use functional decomposition to break your program into smaller, more manageable pieces. This will make it easier to write, test, and debug. Where appropriate, consider using the functions getfloatingpoint() and putfloatingpoint() defined in the example program sum2.c http://www.eeng.dcu.ie/7Emcmullin/swe1/src/sum2.c. You can simply cut and past the relevant section of that program into your own program. Define a new function of your own, which deals with printing out the results, for one cycle of your calculations. This can then be simply called or invoked from within the while loop of your main() functionwhich should make the main() function shorter and easier to follow. Note that this function will have to accept two arguments (being the current values for the and co-ordinates). Command Line Redirection If you want to plot a graph of the trajectory calculated by your program, you will need to capture the program output in a file, rather than having it simply displayed on the screen. Perhaps the simplest way of arranging for a program to route its output to a file (or, indeed, to take its input from a file), is to use so-called command line redirection. Suppose your program is in a file called foobar.c. After successful compilation, you will have a executable file called foobar.exe. Normally you would execute this simply by giving the name foobar as a command. However, if you want to use command line redirection, you would give a command somewhat like this instead: The serves as the input redirection character in an MS-DOS command line. The effect is that the input for foobar will no longer be taken from the keyboard, but from this file instead. Similarly, the character in an MS-DOS command provides for output redirection, to direct output to a file instead of the screen. With any given command invocation you can choose to use no redirection at all (as we have been doing up to now), or to use input redirection only, or output redirection only, or both together. Plotting a Graph Sometimes you may find it useful to view the output of a program in the form of a graph. There are a variety of ways of doing this. One simple way is using a utility program, provided on the PC's in the CAE Lab, called graph. This program should be run as a full-screen MS-DOS application. To do this, first open an MS-DOS window by double clicking on the relevant icon in Program Manager. Then make this window take over the full screen by pressing Alt-Enter (i.e. press and hold the Alt key while you press the Enter key also). If your program's output has been stored in a file called out.txt, you can then see a graph of this simply by giving the following command: Note that graph expects each line of its input file to contain just two numbers. The first is taken as the x co-ordinate, and the second as the y co-ordinate, of a single point to be plotted. graph will automatically scale the axes in order to fit in all the data points. You can exit from the graph program by pressing the Esc key. You can make the MS-DOS application revert from full-screen to a window by pressing Alt-Enter again. Session 9: Week 18/19: Encryption Exercise 1: The Caesar Cipher (50) Encryption is the process of disguising a message or text so that its meaning will not be apparent to anyone who may intercept it, accidentally or otherwise. In this exercise you will work with a very simple encryption procedure. This is called a substitution cipher, in which each letter of the original message (the plaintext) is replaced by a different letter to generate the coded message (the ciphertext). To simplify matters further, we will restrict our plaintext to use only the upper case letters A to Z, together with the space and newline characters; furthermore, space and newline characters will be left unchanged by the encryption. In each case, the replacement letter will be a fixed number of letters later in the alphabet compared to the original letter (and wrapping around back to A again after Z, as necessary). The number of letters to count forward will be called the encryption key. Thus, with a key of 3, we would replace A by D, B by E and so on, with, finally, W being replaced by Z, X by A, Y by B and Z by C. This simple kind of cipher is sometimes called a Caesar Cipher after Julius Caesar, who is said to have used it for secure battlefield messages. To implement a Caesar cipher with a program, note that, when accessing individual characters in , what you are really dealing with are numeric codes for the characters. As such, you can do any normal arithmetic (addition, subtraction etc.) and comparison (greater-than, less-than etc.) operations on them. The relationship between the characters, as displayed on your screen or in your editor, and the numeric codes accessed within your program is strictly arbitrary. It is not specified by the language standard. It is thus open to anyone developing a compiler to adopt any character numbering scheme they like; you cannot reliably assume that the numbering scheme in effect for one compiler will be the same as for another. Strictly, you need to check the documentation for your particular compiler to find out what the numbering scheme is. However: there is one particular numbering scheme which is the most widely used, and to which most compilers conform (including DJGPP): this is the so-called ASCII scheme.If you really want to know, ASCII is an acronym for American Standard Code for Information Interchange. In ASCII, the upper case letters A to Z have consecutive numeric codes from 65 to 90. Thus, given a particular key value (a number from 1 to 25) simple addition will encypher a letter as requiredexcept that if the sum is greater than 90 you must wrap around to the start of the alphabet again by subtracting 26. You are required to develop a program which will input a series of lines of characters, and encode them with a Caesar cipher; as each line of plaintext is input, the corresponding line of ciphertext should be output. It is up to you to devise a mechanism whereby the user can indicate that all lines have been input, and to implement the program in such a way that it will then terminate. The key for the encoding should be hard coded into your program (as opposed to be being read in at run time). Thus, changing the key will involve modifying the source program and recompiling. You may find it handy to be able to run your program on an input file (and producing an output file) rather than working only with the keyboard and screen. Use command line redirectionredirection to achieve this. Exercise 2: Crytanalysis (20) Now think about the problem of cryptanalysis: that is, suppose you are the enemy and have intercepted a transmission known to have been encyphered with a Caesar cipher. How would you set about trying to decipher it? You may wish to challenge a colleague in the class to see who can decipher the other's ciphertext message most quickly. Record your conclusions in your report. Exercise 3: The Vigenere Cipher (30) Finally develop a program to implement the somewhat more sophisticated Vigenere cipher, invented in the 16th century by Blaise de Vigenere. This has the same basic idea as the Caesar cipher, but the key no longer stays the same throughout the message: instead it follows some periodic cycle. A Vigenere key is thus not a single number but a sequence of some fixed lengthsay 10, 3, 25, which would mean the first letter should be shifted by 10, the second by 3, the third by 25, and then back to 10 again etc. Session 10: Week 20/21: Letter Frequencies In a world where there are code makers there will, inevitably, also be code breakers. One of the simplest tools in the armoury of a code breaker is a program to count the relative frequency of each letter appearing in the cyphertext. For any given language there will be a characteristic distribution of letter frequencies in the uncoded message (the plaintext). The most commonly used letter in English is e, by a wide margin; t is in second place, with a and o nearly tied for third; i, n and r are also very commonly used. If we know that a coded message uses any kind of simple substitution cypher (such as the Caesar cypher we saw previously) then a simple count of the relative frequencies will allow us to make a fairly good guess as to the letters which have substituted for the most common english letters. Often this would be enough to allow the remaining substitutions to be easily guessed. Of course, real cyphers are much more sophisticated and harder to break than this (how would you tackle a Vigenerevigenere cypher for example?). But letter frequency counts still form an essential tool for code breaking, albeit in conjunction with many other techniques. Try to develop the programs for this session without using safe-c. You should use standard library http://www.eeng.dcu.ie/7Emcmullin/swe1/stdlib functions declared in stdio.h for doing input and outputfor example, use getchar() for reading in the input file and use printf() for printing out results. Use functions declared in ctype.h for testing (or possibly altering) the characteristics of character code data (e.g. distinguishing alphabetic from non-alphabetic characters; or changing between upper and lower case etc.). Exercise 1: Counting A! (30) Your first task in this session is to write a program which will read a file, and count how many times the character A (or a) occurs. The program should ignore the distinction between upper and lower case, and should ignore all characters other than A (and a). When the file has been completely read, the program should output the total number of A characters found. Redirectionredirection should be used to cause the program to read the appropriate file via stdin. As usual, you should test your program carefully, and document any problems etc. in your report. Exercise 2: More Counting... (30) Now enhance your program to count how many times each separate alphabetic character occurs. Again, it should ignore distinctions between upper and lower case, and should ignore all non-alphabetic characters. So it should generate 26 distinct count values, one for each letter of the alphabet, and not counting non-alphabetic characters at all. Note that you can use a single array, with 26 elements (where the elements are of type int, say), to hold all the counts. You will need to think carefully about how to access the correct position or slot in this array to get the correct count for any given letter found in the file. When the file has been completely read, the program should output a table showing the count for each of the letters A to Z. Again, you should test your program carefully, and document any problems etc. in your report. Exercise 3: Statistics (20) Next you are required to enhance the program further so that it will also calculate the total number of all alphabetic characters read, and output, for each character, both the actual number of times it occurred, and the percentage this represents of the total number of alphabetic characters encountered. Again, test and document the program carefully. Exercise 4: Plotting a Histogram (20) Finally: develop a further version of the program, which, instead of outputing the relative frequencies as numbers, outputs a histogram. This will be made up of lines of varying width (made up of asterisk characters) one line for each letter, from A to Z. The letter with the most occurrences should be scaled to give a line with, say, 60 *'s. Then the lines for all the others should be shorter in proportion. The display might look somewhat as follows: and so on. Note that histograms would normally be plotted with the independent variable oriented vertically, whereas I have described an horizontal orientation here. If you have time, try to alter your program again, to yield a histogram with a vertical orientation (this is a substantially more challenging task). Session 11: Week 22/23: Simulating an RC Circuit The program(s) developed in this session must not use any facilities of the safe-c librarythey must rely on the facilities of the Standard C Library http://www.eeng.dcu.ie/7Emcmullin/swe1/stdlib instead. Consider the following schematic diagram of a simple RC circuit: The capacitor is assumed to be initially charged up to some voltage denoted v(0), corresponding to a charge level of: The switch is closed at time t = 0. The capacitor then discharges by causing a current to flow through the resistor. Denote the instantaneous signals in the system as follows: : The instantaneous charge on the capacitor at time t. : the instantaneous voltage across the capacitor at time t. : the instantaneous current discharging from the capacitor through the resistor, at time t. Suppose that, at some time t, the value of q(t) is known. It then follows that the following values may be calculated: Consider now what happens over a small interval of time, which I shall denote . If this interval is small enough we can take the current to be approximately constant over this interval. Thus, the change in the value of q over this interval can be approximated by: and the value of q at the end of the interval can be calculated (approximately) as: Since we now know the value of q, one time step later, we can now repeat all the calculations to calculate the values of v, i and q one time step later also and thus calculate how much q will change by over one further time step. And so on. By repeating this procedure, one can calculate the state of the circuit (at least approximately) into the indefinite future, once we know the state at some initial time. In fact, this basic method is so powerful that it can be extended to (approximately) predict the time behaviour of arbitrarily complex electronic circuits under arbitrary stimulation and such simulations are a crucial tool in the design of all modern electronic circuits. Exercise 1: Basic Simulation Program (60) Develop a program which will simulate the behaviour of a simple RC circuit, in the sense of providing predictions of how the charge on the capacitor will vary over time. The program should prompt for and read in values for the following parameters from the user: : Resistance (in ). : Capacitance (in F). : Initial value of q (in C). : The duration (in s) of one time step. (In practise, choose to be a small fraction less than 1 sayof the circuit time constant, which will be given by .) : The value of t at which the program should stop. When the program is executed, it should print one line on the screen for each time step. Each line should show the time and the calculated value for q(t) at that time. Exercise 2: Enhanced Simulation Program (40) Now enhance your program in the following ways. Instead of automatically prompting for the required parameter values, the program should offer the user a choice of reading the values from the keyboard or from a file (which would have been prepared in advance). When the user opts for reading from the keyboard, the program should prompt for, and read the parameters just as before. Where the users opts for a file, the program should prompt for the file name, and then read the parameter values from the file (without issuing any prompts). If the program encounters any difficulty reading the parameters from the specified file, it should offer the user a choice between giving up, or respecifying the file to read from, or reverting to reading the parameters from the keyboard. Once the program has successfully got a set of parameter values, it should offer the user a choice between output to the screen, or output to a file. Again, in the former case, the program should continue as before; but in the latter case, it should prompt for the name of the file to output the results to. Session 12: Week 24/25: Exploring Pointers Note that in this exercise you are not required to generate any new programs of your ownthough you may wish to modify the programs you are given. This exercise is concerned with exploring the use of pointers in . Specifically, you will examine programs where pointer variables are created using pointer data types. Thus, for example: declares a variable, i, of type int; whereas the declaration: declares that i is a variable of type pointer to int or (int *). That is, i itself does not hold an int value, but the thing it points at does. Note that you can happily declare variables which point at other pointer variables. Thus: declares that i is a variable of type pointer to pointer to int. The value of i is a pointer; the thing it points at is now another pointer variable; but the thing this points at is an int. And so on! A pointer value can be produced using the address-of operator, denoted with the ampersand character . Thus, the following code fragment might make sense: The net effect is that ptr now points at a. You can display a pointer value using the p format specification with printf(): With our particular computer platform, addresses can be thought of as binary numbers with 32 bits. By convention, they are displayed by printf() in hexadecimal, or base-16, notation (where the digits 0 to 9 as used as normal, but the letters A through F are used to represent the base-16 digits for the numbers 10 to 15). So a typical result from executing the printf() above might be something like: The 0x prefix is a standard C notation for showing that a number is in hex; this is then followed by 8 hex digits (since one hex digit represents a number between 0 and 15, it is equivalent to 4 binary digits; so a 32 bit number is equivalent to 8 hex digits). In any case, your only use for looking at pointer values will be to assess whether or not different pointer values are equaland you can do that without knowing any of the details of interpreting hex notation. A pointer value is dereferenced with the dereference or indirection operator, denoted with the asterisk character, *. A dereferenced pointer may be used anywhere a variable name can be used. Thus, normally, a variable name evaluates as the value of a variable; so a dereferenced pointer normally evaluates as the value of the thing pointed at. But a variable name can also be used in an assignment, in which case its value is altered (overwritten); similarly, a dereferenced pointer can be used in an assignment, and the value of the thing pointed at will be changed. Note very carefully that, whenever you are dealing with a pointer variable, you must be very clear about whether it is its own value that is being referred to, or the value of the thing pointed at; these are generally very different things (they are usually even of different types, never mind values). A simple use of dereferencing is this: In this simple fragment, there are two variables of type int, and one of type pointer to int. The variable ptr is given the value i, so it points at i; i is given the value 25; so when j is given the value 2 + *ptr, this means 2 plus the value of the thing ptr is pointing at and this evaluates as 27; finally, *ptr, which is to say i, is given the value j + 2 which is to say 29. Take a copy of the file ptr0.c../src/ptr0.c. This is a basic test program for investigating the idea of pointers. Note that this program (and all the other programs introduced in this session) is totally contrived. It does not do anything useful whatsoever. It is intended purely as a vehicle for you to experiment with pointer variables and pointer operations. First analyse the program by hand, and predict what you think the outcome will be. Record this analysis in your report. Then execute it and test your predictions. Add extra printf() statements as you deem necessary in order to check the values of variables at different stages during execution. If the results differ from your predictions then test more carefully until you can explain the discrepancies. Note your results in your report. Repeat the procedure described above for the file ptr1.c../src/ptr1.c. Now consider the file ptrnet.c../src/ptrnet.c. The is again a contrived program. It does not do anything useful. It merely serves to illustrate some further ideas on the use of pointers. To understand this example you will first need some elementary understanding of structures. Only the basic ideas will be introduced here. For more detailed information consult a textbook. The idea of a structure in is that you can group a number of distinct data items, of distinct types, together into one unit. That collection of data items can then (for some purposes at least) be manipulated as a unit. In particular, having once described the format or shape of the unit, one can declare, in a single step, structured variables which have separate slots for all the constituent parts or members. Look at this simple example: struct is a keyword which introduces the declaration of structured variables. This is followed by braces which enclose a detailed description of the members of each structured variable. Finally come the names of the actual variablesfive of them in this case. The effect of this declaration is to create five variables, each of which has two distinct members, one called age the other called IQ. To access these members we use the dot operator, thus: and so on. But we can also, to a limited extent, manipulate a structured variable as a wholefor example, by assignment: This would assign the values of the members of john to each of the corresponding members of henry in turn. Thus, it would be exactly equivalent to: So far, so good. It should be clear that structures might be useful whenever you have information that naturally divides into groups or units with a certain similarity. This next point is that, if you are using structures at all, it is often handy to be able to declare structured variables (or function parameters for that matter), having a given shape (i.e. a given set of members) in several different places in your program. Now you can certainly do this in the obvious way by simply repeating the detailed declaration of all the members in each different place. But it would be nicer if the compiler could let you declare the shape once, and then refer back to it later. And, fortunately, it doesactually in a couple of different ways. But I will just show one: This time I have put an identifier (person) immediately after the struct keyword, and before the left brace. This does not create a structured variable called person. Instead, person acts as a tag or identifier for this particular shape of structured variable. Once I have given this declaration, then, at any subsequent point in the program, I can use simply struct person as a shorthand for the full declaration. So I could write, for example: This would then create variables barry, john and mary with the same shape as before. Then somewhere later on (or inside some other function) I might write: Be clear on the advantage of adding an identifier, such as person to a particular shape of structure: it just saves having to re-enter the detailed description of the shape in several different parts of a program. One slight difficulty might be evident here: in reading a program one can easily become confused between identifiers such as henry, which refer to actual variables, and person which simply identifies an abstract shape for variables which might get declared at some stage. It would be ridiculous, for example, to try to refer to person.age because there is no such variable as person. Rather, person simply provides a name for a template from which variables might be created. Once you get used to using structures this should not cause any problem. Once you see the keyword struct you will expect to see it followed either by a left brace or a name for a particular shape of structure. But when you are just starting off, it may be a good idea to adopt some kind of systematic identifier conventioni.e. to choose your identifiers so as to clearly distinguish between those that refer to actual variables and those that simply refer to an abstract shape. One simple convention that I sometimes use is to append s (for structure) to the end of any identifier that refers to a structure shape. So I would actually use the identifier persons. But note carefully that is only a convention: it has no significance for the compiler at allit is purely a device to remind a reader of what's going on. OK, now we can declare a structure shape, and give it an identifier; we can declare variables or parameters of that shape; and we can access the members of such variables. We now join these ideas up with the idea of a pointer. Roughly speaking, we can embed, within a structured variable, a pointer member that points at something else. In particular, we can embed a member that can point to another structured variable of the same type or shape. And once we can do that, we can create indefinitely large networks of structured variables that are linked together by pointers. This turns out to be an immensely powerful programming ideawhich, regretfully, we shall not be able to pursue properly in this introductory course. For now, you simply have to take it on faith that this idea is potentially useful. The question for us is simply what language features we need to use to do it. At this stage, look again at the example program ptrnet.c../src/ptrnet.c. This first introduces the declaration of the structure shape called buckets: This says, simply, that any structure of this shape will have three members, called black, white and quantity. The quantity member is simply of type int; but black and white are pointers to (other?) structures of the same shape. Of course, they do not automatically point at any particular other structures: but they potentially can, if suitable assignments are made. Four actual variables of this structured type or shape are then declared: Each of these will have the three separate members already described. They have been declared outside of any function so they are visible and accessible to all functions. The rest of the program then involves setting up particular linkages between these structures (via the black and white members) and using these linkages to indirectly access various members in different ways. I repeat that none of this achieves any useful purpose: the only purpose of the exercise is for you to test whether you have a sufficient grasp of what's going on to be able to accurately predict what members will be accessed in each case. There is one final facility of you need to understand in order to to this: the so-called arrow operator. Consider this fragmentary program: In this program there is a structured variable called barry, and a pointer variable called p. For the purposes of the example, p is made to point at barry, and then the age member of barry is indirectly accessed via p. This is done with the construction (*p).age. That is, p is first dereferenced using the * operator; this yields the thing p points at (namely barry), and the dot operator is then used to access the age member of this structure. The parentheses around *p are necessary here because the dot operator takes precedence over dereferencing by default. So if I simply write *p.age, the compiler thinks I want to first take the age member of p and then dereference that. Now, since p isn't even a structured variable, and therefore has no members at all (never mind a particular one called age) this cannot make sense, and the compiler would simply generate an error. But in more complicated cases the compiler might not even diagnose the error effectively. Anyway, the point is that if you are starting with a pointer, and you want to get at a member of the object being pointed at by that pointer, then you must use something like (*p).age. This is moderately convoluted; worse still, it turns out that this kind of operation or access is actually needed very commonly in programs that operate on complicated data structures. The language therefore provides a single operator, the arrow operator, which combines the effects of dereferencing and accessing a member of the structure thus accessed. It is written like this: But try to get clear that p->age is simply shorthand for (*p).age: if you ever find the arrow operator confusing, then try replacing it by the longhand version, with an explicit dereferencing and explicit dot operator. Now, with all that in mind (!) let's return to the final part of the exercise, and the program ptrnet.c../src/ptrnet.c. First try to draw out on paper the relationships between the structures n0, n1, n2 and n3 immediately after execution of the statement at line 77 (the invocation of the function redconnections()). Do this by analysing the program manually, not by executing it. The diagram should show graphically what each pointer member of each structure is pointing at. Next attempt to predict the values of the quantity members of each structure immediately after execution of the statement at line 78 (the first invocation of the function massage()). Check your predictions by executing the program (you'll have to add some printf() statements to print out the values you are interested in). Explain any discrepancies. Note that I really do mean thatdo not go any further unless and until you can explain all discrepancies between your predictions and the actual results. Now draw a new diagram showing the relationships between the structures immediately after execution of the statement at line 79 (the invocation of the function blueconnections()). Repeat this diagram one last time for the situation immediately after execution of the statement at line 80 (the invocation of the function yellowconnections()). Finally, predict the values of the quantity members of each structure immediately after execution of the statement at line 81 (the second invocation of the function massage()). As before, check your predictions by executing the program, and explain any discrepancies. Copyright This Hypermedia Document is copyrighted, 1994--1996, by Barry McMullinhttp://www.eeng.dcu.ie/7Emcmullin/home.html. Permission is hereby granted to access, copy, or store this work, in whole or in part, for purposes of individual private study only. The work may not be accessed or copied, in whole or in part, for commercial purposes, except with the prior written permission of the author. Listing 1: mquiz0.c Listing 2: circle0.c Listing 3: ptr0.c Listing 4: ptr1.c Listing 4: ptrnet.c