Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How do you pass a variable size array into a function

Status
Not open for further replies.

xwb

Programmer
Jul 11, 2002
6,828
GB
I'm translating some legacy stuff from another language to Delphi/Pascal. It has several arrays of variable sizes. I can't figure out how the function is declared.

Codewise, I have
Code:
type
   CustomTable = record
      m_kind: integer;
      m_value: integer;
      m_name: array[1..16] of char;
   end;

   {                               ,-- how do I do this bit}
   function DBAdd (in_defn: array [] of CustomTable,
      in_numEntries: integer);
There are arrays of size 7 to 90. It isn't very efficient to pass in an array of size 90 every time so I'm not sure what to do. I can't use a singly linked list as the later routines access the definition by index.
 
So is it Delphi or Pascal? That matters for the answer to your question, as well as what the proper forum is for your question.

I'm waiting for the white paper entitled "Finding Employment in the Era of Occupational Irrelevancy
 
Hi

Not in old fashion Pascal.
Code:
  [b]type[/b]
    CustomTable[teal]=[/teal][b]record[/b]
      m_kind[teal]:[/teal][maroon]Integer[/maroon][teal];[/teal]
      m_value[teal]:[/teal][maroon]Integer[/maroon][teal];[/teal]
      m_name[teal]:[/teal][b]array[/b][teal][[/teal][purple]1[/purple][teal]..[/teal][purple]16[/purple][teal]][/teal] [b]of[/b] [maroon]Char[/maroon][teal];[/teal]
    [b]end[/b][teal];[/teal]

  [b]var[/b]
    arr[teal]:[/teal][b]array[/b] [b]of[/b] CustomTable[teal];[/teal]   [gray]{ for method 1 }[/gray]
    tab1[teal],[/teal]tab2[teal],[/teal]tab3[teal]:[/teal]CustomTable[teal];[/teal] [gray]{ for method 2 }[/gray]

  [b]procedure[/b] [COLOR=darkgoldenrod]DBAdd[/color][teal]([/teal]in_defn[teal]:[/teal][b]array[/b] [b]of[/b] CustomTable[teal];[/teal]in_numEntries[teal]:[/teal][maroon]Integer[/maroon][teal]);[/teal]
    [b]var[/b] i[teal]:[/teal][maroon]Integer[/maroon][teal];[/teal]
  [b]begin[/b]
    [b]Writeln[/b][teal]([/teal][green][i]'I got '[/i][/green][teal],[/teal][COLOR=darkgoldenrod]Length[/color][teal]([/teal]in_defn[teal]),[/teal][green][i]' in_defn :'[/i][/green][teal]);[/teal]
    [b]for[/b] i[teal]:=[/teal][purple]0[/purple] [b]to[/b] [COLOR=darkgoldenrod]Length[/color][teal]([/teal]in_defn[teal])-[/teal][purple]1[/purple] [b]do[/b]
      [b]Writeln[/b][teal]([/teal][green][i]' - '[/i][/green][teal],[/teal]i[teal],[/teal][green][i]' : '[/i][/green][teal],[/teal]in_defn[teal][[/teal]i[teal]].[/teal]m_value[teal]);[/teal]
    [b]Writeln[/b][teal]([/teal][green][i]'And in_numEntries : '[/i][/green][teal],[/teal]in_numEntries[teal]);[/teal]
  [b]end[/b][teal];[/teal]

[b]begin[/b]
[gray]{ method 1 }[/gray]
  [COLOR=darkgoldenrod]SetLength[/color][teal]([/teal]arr[teal],[/teal][purple]3[/purple][teal]);[/teal]
  arr[teal][[/teal][purple]0[/purple][teal]].[/teal]m_value[teal]:=[/teal][purple]42[/purple][teal];[/teal]
  arr[teal][[/teal][purple]1[/purple][teal]].[/teal]m_value[teal]:=[/teal][purple]43[/purple][teal];[/teal]
  arr[teal][[/teal][purple]2[/purple][teal]].[/teal]m_value[teal]:=[/teal][purple]44[/purple][teal];[/teal]

  [COLOR=darkgoldenrod]DBAdd[/color][teal]([/teal]arr[teal],[/teal][purple]2010[/purple][teal]);[/teal]

[gray]{ method 2 }[/gray]
  tab1[teal].[/teal]m_value[teal]:=[/teal][purple]52[/purple][teal];[/teal]
  tab2[teal].[/teal]m_value[teal]:=[/teal][purple]53[/purple][teal];[/teal]
  tab3[teal].[/teal]m_value[teal]:=[/teal][purple]54[/purple][teal];[/teal]

  [COLOR=darkgoldenrod]DBAdd[/color][teal]([[/teal]tab1[teal],[/teal]tab2[teal],[/teal]tab3[teal]],[/teal][purple]2011[/purple][teal]);[/teal]
[b]end[/b][teal].[/teal]
Tested with FreePascal and Kylix.

Feherke.
 
Glen9999 - I've just been told by management that it has to be in Pascal. Since I had Delphi installed on my machine and it has a Pascal-ish compiler, I decided to use it. Then I got stuck.

feherke - thanks. I'll try that.
 
xwb: True Pascal is much different than Delphi. Case in point is what Feherke posted. It's a great Delphi answer (FreePascal and Kylix are both Delphi variants), but fails in true Pascal (e.g. Borland/Turbo Pascal and equivalents). Hence, it's necessary to know which is the case.

I'm waiting for the white paper entitled "Finding Employment in the Era of Occupational Irrelevancy
 
I tried feherke's example with the GNU Pascal compiler which is probably more conservative than FreePascal.
With GNU Pascal you cannot declare in the main program
Code:
arr:array of CustomTable;   { for method 1 }
because you get the error:
error: syntax error before `of'

Only the first feherke's method works (with modifications):
Code:
[COLOR=#804040][b]program[/b][/color] arrays;
  [COLOR=#804040][b]const[/b][/color]
    Nmax = [COLOR=#ff00ff]90[/color];
  [COLOR=#804040][b]type[/b][/color]
    CustomTable=[COLOR=#804040][b]record[/b][/color]
      m_kind:[COLOR=#2e8b57][b]Integer[/b][/color];
      m_value:[COLOR=#2e8b57][b]Integer[/b][/color];
      m_name:[COLOR=#2e8b57][b]array[/b][/color][[COLOR=#ff00ff]1[/color]..[COLOR=#ff00ff]16[/color]] [COLOR=#804040][b]of[/b][/color] [COLOR=#2e8b57][b]Char[/b][/color];
    [COLOR=#804040][b]end[/b][/color];

  [COLOR=#804040][b]var[/b][/color]
    arr:[COLOR=#2e8b57][b]array[/b][/color] [[COLOR=#ff00ff]1[/color]..Nmax] [COLOR=#804040][b]of[/b][/color] CustomTable;   [COLOR=#0000ff]{ for method 1 }[/color]

  [COLOR=#804040][b]procedure[/b][/color] DBAdd(in_defn:[COLOR=#2e8b57][b]array[/b][/color] [COLOR=#804040][b]of[/b][/color] CustomTable;in_numEntries:[COLOR=#2e8b57][b]Integer[/b][/color]);
    [COLOR=#804040][b]var[/b][/color] i:[COLOR=#2e8b57][b]Integer[/b][/color];
  [COLOR=#804040][b]begin[/b][/color]
    [COLOR=#008080]writeln[/color]([COLOR=#ff00ff]'Lower index of in_defn  = '[/color], [COLOR=#008080]low[/color](in_defn));
    [COLOR=#008080]writeln[/color]([COLOR=#ff00ff]'Upper index of in_defn  = '[/color], [COLOR=#008080]high[/color](in_defn));
    [COLOR=#008080]writeln[/color]([COLOR=#ff00ff]'in_numEntries           = '[/color],in_numEntries);
    [COLOR=#804040][b]for[/b][/color] i:=[COLOR=#008080]low[/color](in_defn) [COLOR=#804040][b]to[/b][/color] in_numEntries[COLOR=#ff00ff]-1[/color] [COLOR=#804040][b]do[/b][/color]
      [COLOR=#008080]writeln[/color]([COLOR=#ff00ff]' - '[/color],i,[COLOR=#ff00ff]' : '[/color],in_defn[i].m_value);
  [COLOR=#804040][b]end[/b][/color];

[COLOR=#804040][b]begin[/b][/color]
  [COLOR=#0000ff]{ method 1 }[/color]
  arr[[COLOR=#ff00ff]1[/color]].m_value:=[COLOR=#ff00ff]42[/color];
  arr[[COLOR=#ff00ff]2[/color]].m_value:=[COLOR=#ff00ff]43[/color];
  arr[[COLOR=#ff00ff]3[/color]].m_value:=[COLOR=#ff00ff]44[/color];

  [COLOR=#008080]writeln[/color]([COLOR=#ff00ff]'Lower index of arr  = '[/color], [COLOR=#008080]low[/color](arr));
  [COLOR=#008080]writeln[/color]([COLOR=#ff00ff]'Upper index of arr  = '[/color], [COLOR=#008080]high[/color](arr));
  [COLOR=#008080]writeln[/color];

  [COLOR=#0000ff](* Calling the procedure *)[/color]
  DBAdd(arr,[COLOR=#ff00ff]3[/color]);
[COLOR=#804040][b]end[/b][/color].
Code:
$ gpc arrays.pas -o arrays

Roman@DANKA-PC ~/pascal
$ arrays
Lower index of arr  = 1
Upper index of arr  = 90

Lower index of in_defn  = 0
Upper index of in_defn  = 89
in_numEntries           = 3
 - 0 : 42
 - 1 : 43
 - 2 : 44
 
Thanks mikrom. The only problem I'm trying to avoid having to create a whole load of arrays of the same size.
 
xwb said:
I'm trying to avoid having to create a whole load of arrays of the same size
You don't need to use arrays of the same size. You can pass to the procedure arrays of several sizes which fits your needs - see this:
First I pass to the same procedure an array of 3 elements and then an array of 5 elements:
Code:
[COLOR=#804040][b]program[/b][/color] arrays2;
  [COLOR=#804040][b]type[/b][/color]
    CustomTable=[COLOR=#804040][b]record[/b][/color]
      m_kind:[COLOR=#2e8b57][b]Integer[/b][/color];
      m_value:[COLOR=#2e8b57][b]Integer[/b][/color];
      m_name:[COLOR=#2e8b57][b]array[/b][/color][[COLOR=#ff00ff]1[/color]..[COLOR=#ff00ff]16[/color]] [COLOR=#804040][b]of[/b][/color] [COLOR=#2e8b57][b]Char[/b][/color];
    [COLOR=#804040][b]end[/b][/color];

  [COLOR=#804040][b]var[/b][/color]
    arr1:[COLOR=#2e8b57][b]array[/b][/color] [[COLOR=#ff00ff]1[/color]..[COLOR=#ff00ff]3[/color]] [COLOR=#804040][b]of[/b][/color] CustomTable;
    arr2:[COLOR=#2e8b57][b]array[/b][/color] [[COLOR=#ff00ff]1[/color]..[COLOR=#ff00ff]5[/color]] [COLOR=#804040][b]of[/b][/color] CustomTable;

  [COLOR=#804040][b]procedure[/b][/color] DBAdd(in_defn:[COLOR=#2e8b57][b]array[/b][/color] [COLOR=#804040][b]of[/b][/color] CustomTable);
    [COLOR=#804040][b]var[/b][/color] i:[COLOR=#2e8b57][b]Integer[/b][/color];
  [COLOR=#804040][b]begin[/b][/color]
    [COLOR=#008080]writeln[/color]([COLOR=#ff00ff]'Lower index of in_defn   = '[/color], [COLOR=#008080]low[/color](in_defn));
    [COLOR=#008080]writeln[/color]([COLOR=#ff00ff]'Upper index of in_defn   = '[/color], [COLOR=#008080]high[/color](in_defn));
    [COLOR=#008080]writeln[/color]([COLOR=#ff00ff]'Number of array elements = '[/color], [COLOR=#008080]high[/color](in_defn)+[COLOR=#ff00ff]1[/color]);
    [COLOR=#804040][b]for[/b][/color] i:=[COLOR=#008080]low[/color](in_defn) [COLOR=#804040][b]to[/b][/color] [COLOR=#008080]high[/color](in_defn) [COLOR=#804040][b]do[/b][/color]
      [COLOR=#008080]writeln[/color]([COLOR=#ff00ff]' - '[/color],i,[COLOR=#ff00ff]' : '[/color],in_defn[i].m_value);
  [COLOR=#804040][b]end[/b][/color];

[COLOR=#804040][b]begin[/b][/color]
  [COLOR=#0000ff](*--- 3 elements array ---*)[/color]
  arr1[[COLOR=#ff00ff]1[/color]].m_value:=[COLOR=#ff00ff]42[/color];
  arr1[[COLOR=#ff00ff]2[/color]].m_value:=[COLOR=#ff00ff]43[/color];
  arr1[[COLOR=#ff00ff]3[/color]].m_value:=[COLOR=#ff00ff]44[/color];

  [COLOR=#008080]writeln[/color]([COLOR=#ff00ff]'Lower index of arr  = '[/color], [COLOR=#008080]low[/color](arr1));
  [COLOR=#008080]writeln[/color]([COLOR=#ff00ff]'Upper index of arr  = '[/color], [COLOR=#008080]high[/color](arr1));
  [COLOR=#008080]writeln[/color];
  DBAdd(arr1);
  [COLOR=#008080]writeln[/color]([COLOR=#ff00ff]'--------------------------------'[/color]);
  [COLOR=#0000ff](*--- 5 elements array ---*)[/color]
  arr2[[COLOR=#ff00ff]1[/color]].m_value:=[COLOR=#ff00ff]10[/color];
  arr2[[COLOR=#ff00ff]2[/color]].m_value:=[COLOR=#ff00ff]20[/color];
  arr2[[COLOR=#ff00ff]3[/color]].m_value:=[COLOR=#ff00ff]30[/color];
  arr2[[COLOR=#ff00ff]4[/color]].m_value:=[COLOR=#ff00ff]40[/color];
  arr2[[COLOR=#ff00ff]5[/color]].m_value:=[COLOR=#ff00ff]50[/color];
  [COLOR=#008080]writeln[/color]([COLOR=#ff00ff]'Lower index of arr  = '[/color], [COLOR=#008080]low[/color](arr2));
  [COLOR=#008080]writeln[/color]([COLOR=#ff00ff]'Upper index of arr  = '[/color], [COLOR=#008080]high[/color](arr2));
  [COLOR=#008080]writeln[/color];
  DBAdd(arr2);
[COLOR=#804040][b]end[/b][/color].
Output:
Code:
$ gpc arrays2.pas -o arrays2

$ arrays2
Lower index of arr  = 1
Upper index of arr  = 3

Lower index of in_defn   = 0
Upper index of in_defn   = 2
Number of array elements = 3
 - 0 : 42
 - 1 : 43
 - 2 : 44
--------------------------------
Lower index of arr  = 1
Upper index of arr  = 5

Lower index of in_defn   = 0
Upper index of in_defn   = 4
Number of array elements = 5
 - 0 : 10
 - 1 : 20
 - 2 : 30
 - 3 : 40
 - 4 : 50
 
Thanks for the tips - it is Delphi. The boss doesn't know the difference between Delphi and Pascal.
 
I thought that FreePascal is closer to Turbo-,Borland-Pascal and Delphi and GNU Pascal is closer to the "Standard Pascal". But I'm not sure if there is an standard for Pascal :)

IMHO, FreePascal seems to be more advanced than GNU Pascal.
 
Hi

Regarding old fashion Pascal, you could use pointer :
Code:
  [b]type[/b]
    CustomTable[teal]=[/teal][b]record[/b]
      m_kind[teal]:[/teal][maroon]Integer[/maroon][teal];[/teal]
      m_value[teal]:[/teal][maroon]Integer[/maroon][teal];[/teal]
      m_name[teal]:[/teal][b]array[/b][teal][[/teal][purple]1[/purple][teal]..[/teal][purple]16[/purple][teal]][/teal] [b]of[/b] [maroon]Char[/maroon][teal];[/teal]
    [b]end[/b][teal];[/teal]
    tarrayofCustomTable[teal]=[/teal][b]array[/b] [teal][[/teal][purple]0[/purple][teal]..[/teal][purple]0[/purple][teal]][/teal] [b]of[/b] CustomTable[teal];[/teal]
    parrayofCustomTable[teal]=^[/teal]tarrayofCustomTable[teal];[/teal]

  [b]var[/b]
    arr[teal]:[/teal]parrayofCustomTable[teal];[/teal]
    nr[teal],[/teal]i[teal]:[/teal][maroon]Integer[/maroon][teal];[/teal]

  [b]procedure[/b] [COLOR=darkgoldenrod]DBAdd[/color][teal]([/teal]in_defn[teal]:[/teal]parrayofCustomTable[teal];[/teal]in_numEntries[teal]:[/teal][maroon]Integer[/maroon][teal]);[/teal]
    [b]var[/b] i[teal]:[/teal][maroon]Integer[/maroon][teal];[/teal]
  [b]begin[/b]
    [b]Writeln[/b][teal]([/teal][green][i]'I got '[/i][/green][teal],[/teal]in_numEntries[teal],[/teal][green][i]' in_defn : '[/i][/green][teal]);[/teal]
    [b]for[/b] i[teal]:=[/teal][purple]0[/purple] [b]to[/b] in_numEntries[teal]-[/teal][purple]1[/purple] [b]do[/b]
      [b]Writeln[/b][teal]([/teal][green][i]' - '[/i][/green][teal],[/teal]i[teal],[/teal][green][i]' : '[/i][/green][teal],[/teal]in_defn[teal]^[[/teal]i[teal]].[/teal]m_value[teal]);[/teal]
  [b]end[/b][teal];[/teal]

[b]begin[/b]
  Randomize[teal];[/teal]

  nr[teal]:=[/teal][purple]3[/purple][teal];[/teal]

  [b]if[/b] MaxAvail[teal]<[/teal][COLOR=darkgoldenrod]SizeOf[/color][teal]([/teal]CustomTable[teal])*[/teal]nr [b]then[/b] [b]begin[/b]
    [b]Writeln[/b][teal]([/teal][green][i]'Not enough memory'[/i][/green][teal]);[/teal]
    Halt[teal];[/teal]
  [b]end[/b][teal];[/teal]

  [COLOR=darkgoldenrod]GetMem[/color][teal]([/teal]arr[teal],[/teal][COLOR=darkgoldenrod]SizeOf[/color][teal]([/teal]CustomTable[teal])*[/teal]nr[teal]);[/teal]

  [b]for[/b] i[teal]:=[/teal][purple]0[/purple] [b]to[/b] nr[teal]-[/teal][purple]1[/purple] [b]do[/b]
    arr[teal]^[[/teal]i[teal]].[/teal]m_value[teal]:=[/teal][COLOR=darkgoldenrod]Random[/color][teal]([/teal][purple]100[/purple][teal]);[/teal]

  [COLOR=darkgoldenrod]DBAdd[/color][teal]([/teal]arr[teal],[/teal]nr[teal]);[/teal]

  [COLOR=darkgoldenrod]FreeMem[/color][teal]([/teal]arr[teal],[/teal][COLOR=darkgoldenrod]SizeOf[/color][teal]([/teal]CustomTable[teal])*[/teal]nr[teal]);[/teal]
[b]end[/b][teal].[/teal]
Tested with Turbo Pascal.

Feherke.
 
xwb said:
Thanks for the tips - it is Delphi. The boss doesn't know the difference between Delphi and Pascal.

For future reference, Delphi questions go here. forum102 While you got a number of responses here, it will benefit you to post there, as you will have more people familiar with Delphi looking in there than you will here.

mikrom said:
I thought that FreePascal is closer to Turbo-,Borland-Pascal and Delphi and GNU Pascal is closer to the "Standard Pascal". But I'm not sure if there is an standard for Pascal

The de-facto standard essentially got written by Borland through their compilers (BP/TP, earlier Delphi(<v5), and later Delphi), simply because of market acceptance and the fact that there wasn't much effort put forth from the so-called standard bearers. That's born out in that the Pascal creator even admitted Borland to have the standard.

So in most conversations, the other compilers are put up against those two. As I remember FreePascal, it is made more to Delphi standards than BP standards, though you can set it to work with either (with a few caveats, since they left 16-bitdom a long time ago).

Truthfully, if anyone uses a semi-modern compiler, the question of "Delphi or Pascal" is moot. But there are enough people using different/older stuff for whatever reason (through VMs or boot disks or the like because of equipment, old software, etc) that it is still a worthy question to ask.

I'm waiting for the white paper entitled "Finding Employment in the Era of Occupational Irrelevancy
 
For what it's worth, in old-fashioned turbo-pascal I used to define a template array of enormous length as a 'type', and then pass a pointer to the genuine array, and type-cast it using my template array-type. Dreadful, BAD style, I know, but I've always had a soft-spot for leaving all my pointers untyped and type-casting, and in my defence, no one ever taught me proper style.
 
lonehill said:
I used to define a template array of enormous length as a 'type', and then pass a pointer to the genuine array, and type-cast it using my template array-type
That is what I used to do in the late 70s when Pascal was just a popular teaching language. Just remember that I had no end of problems with parameter passing because of the strong typing.
 
breathes sigh of relief that it's not just me who indulges/indulged in this sort of practice, blushes, and admits to rather liking the old days of weak typing...
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top