Passing and returning arrays
BlitzMax Forums/BlitzMax Programming/Passing and returning arrays
| ||
Hi, so far in BMax I haven't used arrays much (I have plenty in other languages) but now I'm wondering what the various syntaxs are for the following: 1) passing an array into a function. i.e. how to call the function and how to declare the function. I assume an array will be passed as a variable automatically without me having to put "var" after it? 2) returning a new array from a function. i.e. is this even possible, like say I declare an array of a certain size (or no size?) and I call a function and assign the return value, which is an array, to the array that I declared. Maybe I should just stick to TLists ;-) Thanks for any help. |
| ||
To pass an array:function passAnArray(myArray:float[]) local theSizeIWant:int = 3 if myArray.length <> theSizeIWant then return end if end function To return an array: function returnArray:float[]() local retArray:float[3] return retArray end function of course float is just the datatype, can be whatever. |
| ||
Thanks Alex. seem to have figured it out:Function ArrayFiddler:String[](In$[]) Local out$[] return out End Function Local myarray$[] myarray = ArrayFiddler(myarray) Now I know I could just modify the In array in the function and because it's passed as a var (isn't it?) it would remain modified after the function, but my function is pretty complex and it's easier to make a new array and pass that out. Anyway another question arise. Will BMax garbage collection handle this line: myarray = ArrayFiddler(myarray) properly because the original myarray is now being overwritten, all the strings in the original one need to be freed and so does the original array. Will that be done? I hope so... |
| ||
some test code that shows arrays ARE passed as var (of course). Interestingly the compiler lets you redundantly write var after the array in the function parameters...Strict Local test$[2] test[0] = "hello" fiddle(test) Print test[0] Function fiddle(in$[]) in[0] = "goodbye" End Function |
| ||
...because the original myarray is now being overwritten Blitzmax handles arrays as special objects from what I understand. You aren't really 'overwriting' it technically. You're just changing what myarray points to. So the original array no longer has a reference to it...and therefore gets garbage collected. |
| ||
Thanks. yep thought so. It handles them as objects but we can't as developers (i.e. no Extending allow, shame). I just bunged this round the function call: GCCollect Local old = GCMemAlloced() myarray = ArrayFiddler(myarray) GCCollect Notify old + " " + GCMemAlloced() And it's the same, which confirms it. |
| ||
Maybe I should just stick to TLists Well yes TLists are designed for games in mind really aren't they? But if you have data that doesn't change arrays are certainly faster. |
| ||
TLists are just more OOP I feel and less techie and better for changing data for sure you are right. |
| ||
Interestingly the compiler lets you redundantly write var after the array in the function parameters... Not quite redundant...Local test[10] Print test.length ResizeMe1(test, 20) Print test.length ResizeMe2(test, 30) Print test.length End Function ResizeMe1(array[], size) array = array[..size] End Function Function ResizeMe2(array[] Var, size) array = array[..size] End Function |
| ||
Yan: What the hell! so you can change the contents of array slots without var but not the size, well that is worth knowing. Thanks. |
| ||
Very old post, but yan's intervention is wrong and might lead to false statement : Arrays are NOT passed by reference ! It looks like it because when we pass an array as argument to a function, the handle of the array in the argument also hold the pointer to the original data. So the data can be modified, but not the variable itself. It's Like using "const SomeType MyVariable" in C -> the reference object can't be modified (whyle its content can be). Which leads to the false statement seen above : Function ResizeMe1(array[], size) array = array[..size] End Function This function does nothing but creating a "NEW" array of a new size. Slicing an array ALWAYS create a NEW array, it doesn't affect the original. And as long as it's not returned in any way, it will be garbage collected, and nothing more. So it does not affect the variable "array[]" passed as argument as it's missing the "Var" keyword. -> So, the only conclusion is : The content of the array can be modified when passing an array (else it would make no sense to send an array ^^), but slicing an array will ALWAYS create a "New" array. It doesn't modify the original. Function ResizeMe2(array[] Var, size) array = array[..size] End Function While, this works because the "Var" keywords specifies that the "array[]" variable is a reference. So, whenever its allocation is modified, the original variable is affected to And by the way, we HAVE TO pass a "variable" for this to work. For example, passing an array returned by a function will just fail at compile time (because it's not a variable). Function Gen:Object[](size:Int) Return New Object[size]; End Function Function Slice(a:Object[] Var,newSize:Int) a = a[..newSize] End Function Slice(gen(10), 20); This won't work because it's missing a valid "variable reference". ---------------------------------------------------------------- Just imagine you have a letter to send, but you're very bad in grammar you send it to your friend to get it corrected. He makes the correction and send it back to you. You can send the letter (or copy it to get a clean sheet) That's what happens when you use "Var" -> you really send the paper. Now, imagine you've got a mail to send ... You send a copy to your friend he modifies it and send it back to you So, there is actually 3 copies of the mail - the original - the copy you sent - the copy he sent back. If you want to send the mail, you'll have to send the last one, because the original is still full of errors. And THAT's what happens when you don't use the "Var" keyword :) ---------------------------------------------------------------- I Hope I'm clear enough for thoose who got there for any reason. |
| ||
Ahem...Yan was not saying that arrays are passed by reference. He(she?) was making the same point you are; correcting Grey Alien's assumption. |
| ||
That's true, but the fact the original post is ten years ago and nobody corrected the Grey Alien's assumption, makes me feel like he didn't noticed it either (and if he did, it should have been corrected). But whatever, his point is useless without further explanation, and that's probably what led Grey alien to a bad conclusion. As a map is nothing without its scale, an example is useless without comments. That's maybe weird to come and suggest a modification to an old (and probably useless) topic, but what has been said is about the basis of the programmation. Anyone who would take it as is will come to great trouble and might even never understand why. I think that's important enough to just let a small message to prevent (potential) future users. |