Recent

Author Topic: Can you make passed array elements (without specified size) start at 1?  (Read 6098 times)

Pi

  • Jr. Member
  • **
  • Posts: 75
In my program, I have in one procedure an array starting at 1.

eg. the_variable: array[1..THE_MAX] of this_type;

So the array elements are 1,2,3 etc.

When I pass that array to another function, which doesn't specifiy the size of the array,

ie:
function the_function(the_array: array of this_type): integer;
begin
end;

The array elements go 0,1,2...

Can I make the arrays in both cases start at 1 and go to the max? I suppose another way would be to change the calling function and have them start at 0, but I'd rather for both to start at 1 and go to max.
« Last Edit: March 29, 2016, 09:26:40 pm by Pi »
Lazarus version 0.9.30.4 + Lazarus 32 bit 1.2.6

skalogryz

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2770
    • havefunsoft.com
the only way to do that is declare a type:
Code: [Select]
TThis_typeArray= array[1..THE_MAX] of this_type

and use the type for the a parameter
Code: [Select]
function the_function(const a:  TThis_typeArray)
or
Code: [Select]
function the_function(var a:  TThis_typeArray)

molly

  • Hero Member
  • *****
  • Posts: 2330
Quote
So the array elements are 1,2,3 etc.
I think you meant array indexes


Quote
Can I make the arrays in both cases start at 1 and go to the max?
No, not as you suggested (see also skalogryz's answer)

Quote
I suppose another way would be to change the calling function and have them start at 0, but I'd rather for both to start at 1 and go to max.

This is the normal way of doing things.
Code: [Select]
procedure Test(MyArray: array of this_Type);
var
  i: integer;
begin
  For i := Low(MyArray) to High(MyArray) do
  begin
    // do someything here
  end;
end;

As an alternative, you can make all your arrays start at index zero, but simply don't use the zero index.
Code: [Select]
var
the_variable: array[0..THE_MAX] of this_type;

procedure Test(MyArray: array of this_Type);
var
  i: integer;
begin
  For i := Succ(Low(MyArray)) to High(MyArray) do
  begin
    // do someything here but now we 'skip' index 0
  end;
end;

Pi

  • Jr. Member
  • **
  • Posts: 75
Thanks everyone. I've decided to change the calling function so that too starts at 0 instead of 1 (array 0..max-1)). It seems like probably the best way, and the same 'index' (/element nr) will refer to the same item everywhere (so it makes checks of array positions/indexes a bit easier). I think it might also make the calling function more flexible (possibly more efficient?) by not referring to a fixed max (so might use less memory if called with less than the absolute max?). Though I thought arrays starting at 0 were more of a C (and other language - eg. Python) style thing than Pascal.
« Last Edit: March 29, 2016, 10:32:37 pm by Pi »
Lazarus version 0.9.30.4 + Lazarus 32 bit 1.2.6

CuriousKit

  • Jr. Member
  • **
  • Posts: 81
It's always been the convention to start indices at 0, mostly due to pointer arithmetic, whether internally or otherwise.  When you have to exchange between one and the other, and you can't make the system consistent (often due to display purposes, since end users don't like seeing "0th"), it's best to just cut your losses and add or subtract 1 to your index variable where needed.
Free Pascal Compiler Developer and Freelance Programmer

engkin

  • Hero Member
  • *****
  • Posts: 3112
the only way to do that is ....

Absolutely not the only way, as absolute could be used to refer to the same array but with an index that starts at 1:
Code: Pascal  [Select][+][-]
  1. function the_function(the_array: array of this_type): integer;
  2. type
  3.   TStart1Array = array[1..1] of this_type;
  4. var
  5.   LStart1Arr: TStart1Array absolute the_array;
  6.   i: integer;
  7. begin
  8.   for i := 1 to Length(the_array) do
  9.     WriteLn(LStart1Arr[i]);
  10. end;
  11.  

skalogryz

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2770
    • havefunsoft.com
Absolutely not the only way, as absolute could be used to refer to the same array but with an index that starts at 1:
but you're still declaring the TStart1Array type ;)


engkin

  • Hero Member
  • *****
  • Posts: 3112
Absolutely not the only way, as absolute could be used to refer to the same array but with an index that starts at 1:
but you're still declaring the TStart1Array type ;)

Different declaration and different usageO:-)

skalogryz

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2770
    • havefunsoft.com
Different declaration and different usageO:-)
...risking to fail range-check  :-\

engkin

  • Hero Member
  • *****
  • Posts: 3112
Different declaration and different usageO:-)
...risking to fail range-check  :-\

You are right, it was meant to show another possible solution. Not a good one. Still half of the range checking problem could be solved with:
Code: Pascal  [Select][+][-]
  1.   TStart1Array = array[1..High(Integer) div SizeOf(this_type)] of this_type;

Thaddy

  • Hero Member
  • *****
  • Posts: 19438
  • Glad to be alive.
Re: Can you make passed array elements (without specified size) start at 1?
« Reply #10 on: March 30, 2016, 10:47:53 am »
Though I thought arrays starting at 0 were more of a C (and other language - eg. Python) style thing than Pascal.

Don't confuse Pascal with BASIC. Even the late Bob Zale (the creator of TurboBasic and PowerBasic and a personal friend when he was still alive) lamented the stupidity of indexes starting at 1, because is is logically wrong. He also pointed out that he didn't like pascal string indexes starting at one, btw. Visionary! ;)
« Last Edit: March 30, 2016, 10:52:06 am by Thaddy »
Any "programmer" that knows only one programming language is not a programmer

 

TinyPortal © 2005-2018