Forum > Beginners
Dimensioning the Dynamic Arrays
ArtLogi:
Ohh, thx both of you. Now I get what were wrong.. :)
[/quote]
--- Quote from: Leledumbo on January 15, 2016, 06:14:59 pm ---
--- Quote from: ArtLogi on January 15, 2016, 03:12:23 pm ---There seems to be a logic inconsistency in general, since the FPC mixes 1 and 0 based indexing depending on the function. :(
--- End quote ---
There was NEVER 1 based indexing on arrays, only 0 based and up-to-you based ones.
--- End quote ---
I did mean that some functions (all of them what I have used so far) are indexing from 1 and also the basic array what I have understood is indexed from 1. Why the dynamic array do brake this rule Idk, but it seems to me a logical inconsistency and now I need always to try to figure if there is an another part of the system that uses 0 index and not 1 index. :-\
--- Quote from: Leledumbo on January 15, 2016, 06:14:59 pm ---
--- Quote from: ArtLogi on January 15, 2016, 05:03:18 pm ---Thx... I'm still making some mistake on my test code. With comments it works.
--- End quote ---
You call SetLength with as many parameters corresponding to the number of dimensions as well. You only declare `array of string`, hence you can only set its first dimension. If you declare it as `array of array of string` you can set first and second dimension. More dimensions is the same.
--- End quote ---
So is it possible to make an array that is truly dynamic in both ways not just one (the dimensions)? I assume there is some way that is widely used to do it, but tbh I don't understand these extended datatypes in pascal yet, much confusing to figure out the do and do nots in those.
--- Quote from: Leledumbo on January 15, 2016, 06:14:59 pm ---
--- Quote from: ArtLogi on January 15, 2016, 05:03:18 pm ---Also adding function call below leads to error? What I understood it should be a part of RTLs System unit.
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---DynArrayDim(arry)it should return integer, but it doesn't matter if I pipe the result to integer variable or try to use it inside the writeln command, compiler still gives an error "DynArrayDim not found" or something on those lines.
I'm a bit confused.
--- End quote ---
Works fine:
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---uses typinfo; type tintdynarr = array of array of integer; var a: tintdynarr;begin writeln(dynarraydim(typeinfo(a))); // displays 2end. Please read the description in documentation before calling any function, it clearly states the parameter is a type info of a dynamic array.
--- End quote ---
I did read the documentation, unfortunately that type just doesn't say anything to me and I assumed it translates to put your "variable name here" and in general trying to crack the basics through these nonexistent FPC documentation is pain, fortunately I have old Delphi 1&2 book and somewhere is TB6 book (misplaced atm.). Those unfortunately end where I start what comes to basic manipulation of data, jumping to other tasks like printing, database applications and GUI programming (TP5..7 book were pretty good though, but it is misplaced atm.).
molly:
--- Quote from: ArtLogi on January 15, 2016, 06:49:03 pm ---I did mean that some functions (all of them what I have used so far) are indexing from 1 and also the basic array what I have understood is indexed from 1. Why the dynamic array do brake this rule Idk, but it seems to me a logical inconsistency and now I need always to try to figure if there is an another part of the system that uses 0 index and not 1 index. :-\
--- End quote ---
Uhm, no idea where you got that notion from, but depending on what you meant, you are a bit off.
_You_ determine with which index a static array starts. If you declare static array with 1 as starting index, then it is you at fault (Me for instance always use zero based arrays).
Are you perhaps mixing pascal strings with dynamic arrays ? e.g. in a Pascal string the length of the string is usually stored in the zero'th index
Maybe this is able to help you further?
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---program arrayplay; {$MODE OBJFPC}{$H+} procedure PlayWithDynamicArrays;var // Declare variable with 1 dimension OneDimension : array of integer; // Declare variable with 2 dimensions TwoDimensions : array of array of integer; // Declare variable with 3 dimensions ThreeDimensions : array of array of array of integer; // declare some index variables to acces individual items inside array i,j,k : integer;begin // ================= // Initialize arrays // ================= // Initialize 1 dimensional array (5 items) SetLength(OneDimension, 5); // Initialize 2 dimensional array (5*4 = 20 items) SetLength(TwoDimensions, 5, 4); // Initialize 3 dimensional array (5*4*3 = 60 items) SetLength(ThreeDimensions, 5, 4, 3); // ========================= // Display array information // ========================= // Display size of array // --------------------- // Note that when using function SizeOf() on dynamic arrays that this // function will actually return the size of an individual item from the // array, expressed in bytes. // It will not return the actual bytes occupied by the complete array. WriteLn; WriteLn('SizeOf(integer) = ', SizeOf(Integer) , ' bytes'); WriteLn('SizeOf(OneDimension) = ', SizeOf(OneDimension) , ' bytes'); WriteLn('SizeOf(TwoDimensions) = ', SizeOf(TwoDimensions) , ' bytes'); WriteLn('SizeOf(ThreeDimensions) = ', SizeOf(ThreeDimensions) , ' bytes'); // Display size of dimensions and individual items // ----------------------------------------------- // Note that it doesn't matter which and how many indices are used: the size // in bytes will be the same for each entry/dimension in the array. WriteLn; WriteLn('SizeOf(OneDimension[1]) = ', SizeOf(OneDimension[1]) , ' bytes'); WriteLn('SizeOf(TwoDimensions[1]) = ', SizeOf(TwoDimensions[1]) , ' bytes'); WriteLn('SizeOf(TwoDimensions[1,1]) = ', SizeOf(TwoDimensions[1,1]) , ' bytes'); WriteLn('SizeOf(ThreeDimensions[1]) = ', SizeOf(ThreeDimensions[1]) , ' bytes'); WriteLn('SizeOf(ThreeDimensions[1,1]) = ', SizeOf(ThreeDimensions[1,1]) , ' bytes'); WriteLn('SizeOf(ThreeDimensions[1,1,1]) = ', SizeOf(ThreeDimensions[1,1,1]), ' bytes'); // Determine/display length of array // --------------------------------- // Note that only the length of the first dimension of the array is being // displayed here WriteLn; WriteLn('Length(OneDimension) = ', Length(OneDimension) , ' items'); WriteLn('Length(TwoDimensions) = ', Length(TwoDimensions) , ' items'); WriteLn('Length(ThreeDimensions) = ', Length(ThreeDimensions), ' items'); // Determine/display length of dimensions of array // ----------------------------------------------- // Note that the dimensions of the array are taken into account here. // // Note2 that it is not valid to invoke function Length() on a individual // item inside the array, as function Length() only operates on arrays. // // So, Length(ThreeDimensions[1,1,1]) will result in a type mismatch -> an // indidividual item is an integer and its size is determined by SizeOf (see // also code above). (unless, of course, an individual item in the array is // also an array itself). WriteLn; WriteLn('Length(OneDimension) = ', Length(OneDimension) , ' items'); WriteLn('Length(TwoDimensions[1]) = ', Length(TwoDimensions[1]) , ' items'); WriteLn('Length(ThreeDimensions[1,1]) = ', Length(ThreeDimensions[1,1]), ' items'); // ================================================ // Determine "range" of arrray (e.g. valid indices) // ================================================ // Note that this will only determine the range of the first dimension WriteLn; WriteLn('Low(OneDimension) = ', Low(OneDimension)); WriteLn('High(OneDimension) = ', High(OneDimension)); WriteLn('Low(TwoDimensions) = ', Low(TwoDimensions)); WriteLn('High(TwoDimensions) = ', High(TwoDimensions)); WriteLn('Low(ThreeDimensions) = ', Low(ThreeDimensions)); WriteLn('High(ThreeDimensions) = ', High(ThreeDimensions)); // Determine the range of other dimensions (where applicable) // ---------------------------------------------------------- WriteLn; WriteLn('Low(OneDimension) = ', Low(OneDimension)); WriteLn('High(OneDimension) = ', High(OneDimension)); WriteLn('Low(TwoDimensions[1]) = ', Low(TwoDimensions[1])); WriteLn('High(TwoDimensions[1]) = ', High(TwoDimensions[1])); WriteLn('Low(ThreeDimensions[1,1]) = ', Low(ThreeDimensions[1,1])); WriteLn('High(ThreeDimensions[1,1]) = ', High(ThreeDimensions[1,1])); // ================================= // Intialize arrays with some values // ================================= // Set values for 1 dimensional array for i := Low(OneDimension) to High(OneDimension) do OneDimension[i] := i; // Set values for 2 dimensional array for i := Low(TwoDimensions) to High(TwoDimensions) do for j := Low(TwoDimensions[i]) to High(TwoDimensions[i]) do TwoDimensions[i,j] := i*j; // Set values for 3 dimensional array for i := Low(ThreeDimensions) to High(ThreeDimensions) do for j := Low(ThreeDimensions[i]) to High(ThreeDimensions[i]) do for k := Low(ThreeDimensions[i,j]) to High(ThreeDimensions[i,j]) do ThreeDimensions[i,j,k] := i*j*k; // =============================== // Display values stored in arrays // =============================== // Display 1 dimensional array values WriteLn; WriteLn('Values inside one dimensional array:'); for i := Low(OneDimension) to High(OneDimension) do WriteLn('Item[', i, '] := ', OneDimension[i]); // Display 2 dimensional array values WriteLn; WriteLn('Values inside two dimensional array:'); for i := Low(TwoDimensions) to High(TwoDimensions) do for j := Low(TwoDimensions[i]) to High(TwoDimensions[i]) do WriteLn('Item[', i, ',' , j, '] := ', TwoDimensions[i, j]); // Display 3 dimensional array values WriteLn; WriteLn('Values inside three dimensional array:'); for i := Low(TwoDimensions) to High(TwoDimensions) do for j := Low(TwoDimensions[i]) to High(TwoDimensions[i]) do for k := Low(ThreeDimensions[i,j]) to High(ThreeDimensions[i,j]) do WriteLn('Item[', i, ',' , j, ',' , k, '] := ', ThreeDimensions[i,j,k]); // ========================================== // Clear Arrays (e.g. release used resources) // ========================================== SetLength(OneDimension, 0); SetLength(TwoDimensions, 0, 0); SetLength(ThreeDimensions, 0, 0, 0);end; Procedure PlayWithStaticArray;Var OneDimension : array[15..30] of Word; i : Integer;begin // ========================================== // Display size of array (expressed in bytes) // ========================================== // Note that with a static declared array, function SizeOf() will return the // number of bytes actually occupied. // // This is different when applied to dynamic arrays, which will return // the size of an individual item inside the array instead. This is because // function SizeOf() determines these sizes at compile time, not runtime. WriteLn; WriteLn('SizeOf(Word) = ', SizeOf(Word) , ' bytes'); WriteLn('SizeOf(OneDimension) = ', SizeOf(OneDimension) , ' bytes'); // Display size of a single item in array // -------------------------------------- WriteLn; WriteLn('SizeOf(OneDimension[15]) = ', SizeOf(OneDimension[15]) , ' bytes'); // Determine length of array // ------------------------- // Note that the length of the first dimension is determined. WriteLn; WriteLn('Length(OneDimension) = ', Length(OneDimension), ' items'); // ======================== // determine range of array // ======================== WriteLn('Low(OneDimension) = ', Low(OneDimension)); WriteLn('High(OneDimension) = ', High(OneDimension)); // ================================ // Intialize array with some values // ================================ // Set values for 1 dimensional array for i := Low(OneDimension) to High(OneDimension) do OneDimension[i] := i; // ======================= // Display values in array // ======================= // Display 1 dimensional array values WriteLn; WriteLn('Values inside one dimensional array:'); for i := Low(OneDimension) to High(OneDimension) do WriteLn('Item[', i, '] := ', OneDimension[i]);end; procedure PassAlong(AnArray: Array of Integer);var i: Integer;begin // Display length of array WriteLn; WriteLn('Length(AnArray) = ', Length(AnArray), ' items'); // Display range of array WriteLn; WriteLn('Low(AnArray) = ', Low(AnArray)); WriteLn('High(AnArray) = ', High(AnArray)); // display array values WriteLn; WriteLn('Array values are:'); For i := Low(AnArray) to High(AnArray) do WriteLn('Item[', i, '] := ', AnArray[i]);end; Procedure PassAlongStaticArray;var AnArray : array[200..205] of Integer; i : Integer;begin // Display length of array WriteLn; WriteLn('Length(AnArray) = ', Length(AnArray), ' items'); // Display range of array WriteLn; WriteLn('Low(AnArray) = ', Low(AnArray)); WriteLn('High(AnArray) = ', High(AnArray)); // fill array with values For i := Low(AnArray) to High(AnArray) do AnArray[i] := i; // display array values WriteLn; WriteLn('Array values are:'); For i := Low(AnArray) to High(AnArray) do WriteLn('Item[', i, '] := ', AnArray[i]); // Pass along the array to another function/procedure // Note the different numbers used for index) WriteLn; WriteLn('Passing the array to another function/procedure'); WriteLn('Note the difference in index values used'); PassAlong(AnArray);end; begin WriteLn('===================================='); WriteLn('Playing with arrays'); WriteLn('===================================='); WriteLn; WriteLn('--------------'); WriteLn('Dynamic arrays'); WriteLn('--------------'); PlayWithDynamicArrays; WriteLn; WriteLn('------------'); WriteLn('Static array'); WriteLn('------------'); PlayWithStaticArray; WriteLn; WriteLn('-------------'); WriteLn('Pass an array'); WriteLn('-------------'); PassAlongStaticArray; WriteLn; WriteLn('===================================='); WriteLn('done'); WriteLn('====================================');end.
edit: source: rectified some (wrong) comments, removed some typo's
edit2: extended comments, (hopefully) removed all typo's and added extra example passing an array to a procedure.
ArtLogi:
Well that ;D I call spoonfeeding. Thank you, I must go through it and test compile it.
PS. That is (with the first quick skimming) so good that it might be really helpfull and extend the information value of this fpc wiki article considerably:
http://wiki.freepascal.org/Dynamic_array
PPS. It would fit also as a example program in FPC console IDE.. It is really good.
FTurtle:
I would like to remind that dynamic arrays may be non-rectangular.
Example:
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---program project1; type TArr2D = array of array of Integer; procedure FillArr2D(Arr: TArr2D);var i, j: Integer;begin for i:=Low(Arr) to High(Arr) do for j:=Low(Arr[i]) to High(Arr[i]) do Arr[i][j] := i*10 + j;end; procedure ShowArr2D(Arr: TArr2D);var i, j: Integer;begin for i:=Low(Arr) to High(Arr) do begin Write('Arr[', i, ']: '); for j:=Low(Arr[i]) to High(Arr[i]) do Write(Arr[i][j]:2, ' '); WriteLn; end;end; procedure Pause;begin WriteLn; //WriteLn('Press Enter to continue...'); Write('...'); ReadLn; WriteLn;end; var Arr2D: TArr2D;begin SetLength(Arr2D, 5, 3); // resize on two dimensions WriteLn('Rectangular dynamic array after resizing:'); WriteLn('-----------------------------------------'); ShowArr2D(Arr2D); Pause; FillArr2D(Arr2D); WriteLn('Rectangular dynamic array after filling:'); WriteLn('-----------------------------------------'); ShowArr2D(Arr2D); Pause; SetLength(Arr2D, 10); // resize on one dimension WriteLn('Non-rectangular dynamic array after resizing on first dimension:'); WriteLn('----------------------------------------------------------------'); ShowArr2D(Arr2D); Pause; SetLength(Arr2D[0], 9); SetLength(Arr2D[1], 7); SetLength(Arr2D[2], 6); SetLength(Arr2D[3], 9); SetLength(Arr2D[4], 5); SetLength(Arr2D[5], 8); SetLength(Arr2D[6], 5); SetLength(Arr2D[7], 3); SetLength(Arr2D[8], 1); SetLength(Arr2D[9], 7); WriteLn('Non-rectangular dynamic array after individual resizing on second dimension:'); WriteLn('----------------------------------------------------------------------------'); ShowArr2D(Arr2D); Pause; FillArr2D(Arr2D); WriteLn('Non-rectangular dynamic array after filling:'); WriteLn('--------------------------------------------'); ShowArr2D(Arr2D); Pause;end.
molly:
--- Quote from: FTurtle on January 16, 2016, 08:07:09 am ---I would like to remind that dynamic arrays may be non-rectangular.
Example:
--- End quote ---
That's a very nice complementary example FTurtle. Thank you, as indeed i didn't handle those inside my example
TBH, sometimes using different dim'ed arrays makes my head hurt :-[
Since you was passing an array, i extended my original posted example with showing how that works with a static array (effectively turning it into a dynamic array from the called procedure/function 's point of view).
--- Quote from: ArtLogi on January 15, 2016, 09:08:29 pm ---Well that ;D I call spoonfeeding. Thank you, I must go through it and test compile it.
--- End quote ---
Hmz, in that case i must have done something terribly wrong ::)
On the other hand, you still have to apply things to your own situation ;)
But seriously, i did see that there was lacking some examples on existing tutors/wiki pages (it is however discussed on these forums, but i understand it is sometimes hard to find).
--- Quote ---PS. That is (with the first quick skimming) so good that it might be really helpfull and extend the information value of this fpc wiki article considerably:
--- End quote ---
Thank you for having such confidence in my posted example.
Unfortunately, i'm currently a bit occupied. (as in: it's on my to do list. As many other things FPC/lazarus related i might add).
The article you referred to (thanks for the link) has some really strange references which leads to an even more stranger tutorial not effectively handling the topic of dynamic arrays and multiple dimensions (or i must have overlooked something).
In that regards, my example is a bit strange as it doesn't really fit in any of the topics about arrays as the example handles multiple topics in one go.
--- Quote ---PPS. It would fit also as a example program in FPC console IDE.. It is really good.
--- End quote ---
I've adjusted my initial example, and removed some typo's (hopefully all of them now), extended the comments and added an example showing the aspect of what happens when you pass a static array to another procedure/function.
Feel free to do whatever one sees fit to do with my example (preferably remove errors :P )
Actually, the whole point of the example (as also shown by FTurtle) is to always be careful with making assumptions about dynamic arrays and use the low(), high() and length() functions to determine the index-range and size of a dimension in the array (unless you are sure they are static for your situation -> but then, why use dynamic arrays to begin with...).
Have fun, and please have a good look at FTurtles example as well.
Navigation
[0] Message Index
[#] Next page
[*] Previous page