Action! › and› BBS Express! PRO› Tutorial›› by› Thomas M. Johnson ››› Available from ›› Villa Video's Bargain Cellar › (414) 265-5149 › ExpressNet Node X11 ››Action! is copyright of ACS, OSS, ICD.›BBS Express! PRO is copyright Orion›Micro Systems.› ›This tutorial is copyright Thomas M.›Johnson.››This tutorial can be distributed under›the following conditions:› 1) It is free.› 2) All of the above› information is intact.››--------------------------------------››Well, as you probably noticed in the›last file that POINTERs and records›aren't all that usefull by themselves.›In fact, I decided not to include›a sample program about records because›I couldn't think of a good example.››But, when you mix POINTERs and ›records you get alot of power. You›may have tried to make a ARRAY of›records. This is illegal in Action!›But, if you use POINTERs to accomplish›this it will work.››Also, you cannot have a ARRAY as a›field in a record. Since strings are›just CHAR ARRAYs, you can't, for›example, associate a name with other›information about a person. Again,›POINTERs make this possible too.››Even more, you can't have ARRAYs of›strings. You guessed it, POINTERs to›the rescue again. I will be covering›all of these in this lesson. You›don't have to fully understand records›and POINTERs to use the concepts I am›introducing. You can just copy the›routines, etc. and modify them for›whatever use you have in mind. But,›a good understanding of POINTERs will›allow you to even more powerful things›in Action!››First, how do you make an ARRAY of›records in Action!? First you have›to decide what your record will look›like.›› TYPE employee=[CARD ssnumber1› BYTE ssnumber2› CARD ssnumber3› BYTE department,› salary ]››Now we have to count up the total›number of bytes in the record. CARDs›and INTs take up 2 bytes and BYTEs›take up 1. So, here we have 2 CARDs›and 3 BYTEs for a total of 7.›› DEFINE size = "7"››We have to decide how many records we›want to hold. Our company is kind of›small, we only have 6 employees. So,›6 employees each taking up 7 bytes.›We have to reserve 42 bytes of memory›to hold our information because›6*7=42.›› BYTE ARRAY company(42)››Now its time to make that POINTER I›have been talking about.›› employee POINTER info ››'employee' is the type of record that›the POINTER will point to. 'info' is›the name of the POINTER.››Lastly, you need an equation to›figure out where in memory this really›is. This equation is the same one we›will use for all advanced record and›POINTER manipulations.›› info = company + (counter * size)››That's it!››info - The name we gave our POINTER›company - The ARRAY we used to reserve› memory.›counter - This is the record number› we wish to look at. Since› we have 6 employees this› will be a number from 0 to› 5. This can be a constant› like 3 or a variable like› in a FOR loop.›size - The number of bytes in a› record in our DEFINE line.››Ok, so how do you use it? Easy...›If we want to enter employee number›3's information.›› info = company + ( 3 * size)› info.ssnumber1 = 392› info.ssnumber2 = 80› info.ssnumber3 = 4593› info.department = 3› info.salary = 7››And if employee #2 got a raise to›paycode #10›› info = company + ( 4 * size)› info.salary = 10› ›If you want to print employee #0's›social security number:›› info = company + ( 0 * size)› PrintC( info.ssnumber1)› Print("-")› PrintB( info.ssnumber2)› Print("-")› PrintCE( info.ssnumber3)››The numbers in the record can be used›just like any other variable.›› info.department = 4 * 5››Or whatever. Here is a little picture›that I hope will help you to see what›is going on. In case you didn't know,›when you declare a ARRAY in Action!,›the ARRAY name is actually a POINTER›to where the ARRAY is in memory.›So, let's say our ARRAY starts at›memory location 16000. Also, I'll›use - to represent bytes. So a CARD›would have 2 bytes, --.›› TYPE employee=[CARD ssnumber1› BYTE ssnumber2› CARD ssnumber3› BYTE department,› salary ]››record 0 record 1 record 2›-- - -- - -|-- - -- - -|-- - -- - -|›^›|›16000››To get record 1 we use this formula:›› info = company + ( 1 * size)››Sticking in the numbers:› › info = 16000 + ( 1 * 7)› info = 16007››So, we move our pointer over 7 bytes›to location 16007.››record 0 record 1 record 2›-- - -- - -|-- - -- - -|-- - -- - -|› ^› |› 16007››To get record 2:› › info = 16000 + ( 2 * 7)› info = 16014››So, we move our pointer over 14 bytes›from location 16000 to 16014››record 0 record 1 record 2›-- - -- - -|-- - -- - -|-- - -- - -|› ^› |› 16014››But records can't contain strings. So›POINTERs must be used again to trick›Action!››What if you wrote a game where there›are multiple levels. When the first›player dies, the second player takes›over, right where he left off. Well,›you have to keep track of the players›score, level and name. The score and›level are easy with records, but the›name? We'd use this:›› TYPE record = [BYTE level › CARD score› BYTE name]››Why only 1 BYTE for the name? This›is just the first BYTE of the players›name. We'll save more space for it›in a second. Count up the bytes ›without the name BYTE. 1 BYTE and›1 CARD = 3 bytes›› DEFINE offset = "3"››We'll save 20 bytes for the name. So›add the length of the name and the›offset value for the size.›› DEFINE size = "23"››How many players maximum can play our›game? We'll just say 8. So,›8 * 23 = 184›› BYTE ARRAY players(184)››Now we need 2 POINTERs. One like›normal, and 1 to point to the name.›› record POINTER active_player›› CHAR POINTER his_name››The first POINTER we use just like›we have been before.›› active_player = players + (count * size)››But to get the name we use:› › his_name = active_player + offset››That's it! We'll so some assignments›to record number 4.›› active_player = players + (4 * size)› his_name = active_player + offset›› active_player.level=1› active_player.score=0› InputS(his_name)››Now lets output player 6.›› active_player = players + (6 * size)› his_name = active_player + offset›› Print("Level: ")› PrintBE(active_player.level)› Print("Score: ")› PrintCE(active_player.score)› Print("Name: ")› PrintE(his_name)››Ok, the last situation like these›is if you need an ARRAY of different›size strings. Let's say a you need›a program to keep track of your›customers first name, lastname and›the last date the ordered from you.›We'll say the date is of the form›mm/dd/yy.››How big to we want each field?››field size in bytes›---------------------------------››firstname 11›lastname 14›date 9››Try to declare your sizes 1 bigger›because strings go from 0 to 1 less›than their size. This is needed›because, remember, the 0th byte is the›length of the string.››There are no records involved this›construct. Here we just use›POINTERs to get around. The first›DEFINE always starts at 0.›› DEFINE firstname = "0"››If you want to the firstname to be›11 bytes, the lastname must start›at the 12th byte. 0 + 12 = 12›› DEFINE lastname = "12"››If the lastname is 14 bytes long the›date must start 15 bytes later than›the lastname. This means the 27 byte›overall. 12 + 15 = 27›› DEFINE date = "27"››The total size is 27 + 9 = 36›› DEFINE size = "36"››How many customers do you have? Let's›just say 100. 100 * 27 = 2700›› BYTE ARRAY data(2700)››Since we don't have a record only ›characters, our POINTER is just: ›› CHAR POINTER ptr››The POINTER is just like normal›› ptr = data + (counter * size)››Once again, that's it! For customer›#53:› › ptr = data + (53 * size)›› Print("First name: ")› InputS(ptr + firstname)› › Print("Last name: ")› InputS(ptr + lastname)›› Print("Last order date: ")› InputS(ptr + date)››APROG12.002 is a full featured phone›book based on this last subject.››