Go Down

Topic: Functions - return array or multiple variables? (Read 20271 times) previous topic - next topic

kradnz

Hi,  I am new to C and am trying to write a function which accepts no input parameters, but returns either a byte array or two separate byte variables, whatever will work.

Here is an example of what I am talking about:
Code: [Select]

void loop()
{
 byte data[2] = getdat();
}

byte getdat()
{
 byte dat[2];
 dat[0] = 'a';
 dat[1] = 'b';
 return dat;
}


I have tried some variations of declaring the array and get different errors on compile this version yields this tidbit:

In function 'void loop()':
error: array must be initialized with a brace-enclosed initializer In function 'byte getdat()':  

What am I doing wrong here? Is what I am asking even possible?

kradnz

After doing some more searching It seems that functions in C are unable to return arrays  :(. I will try to use  some kind of workaround.

mellis

The usual way to handle this in C is to pass the array into the function and modify it.  The modified values will be retained when the function ends.

Cheater

AFAIK you pass a pointer to the array as a parameter to the function and then just edit it normally inside the function.

nkcelectronics

Quote
AFAIK you pass a pointer to the array as a parameter to the function and then just edit it normally inside the function.

And this is an example of what Cheater is suggesting:

Code: [Select]

void loop()
{
 byte data[2];

 getdat(&data);
}

void getdat(byte *pdata)
{
 pdata[0] = 'a';
 pdata[1] = 'b';
}


Warning: getdat() doesn't know the number of elements in the array data, so it is better to pass it as a second argument while calling getdat().

Or you can define the array as a global variable in setup() and use it everywhere.

C is an extremely powerful language... remember that almost 100% of all Unixes and Linuxes are written with it...

local_dani_21

Thanks for the code, I slowly start to understand the concept of pointers. My gcc-4.2 accepted the code posted by nkcelectronics but gave a warning (incompatible pointer type) during compiling. The program worked well despite the warning.

The Arduino-environment though didn't compile the code nkcelectronics suggested and aborted with an error (cannot convert pointer type), so I had to change the function-call to «getdat(&data[0])» and then it worked perfectly. It seems, as if you have to specificly hand over the address of the first element of the array.

Code that worked in Arduino:

void loop()
{
 byte data[2];

 getdat(&data[0]);
}

void getdat(byte *pdata)
{
 pdata[0] = 'a';
 pdata[1] = 'b';
}

Mike Murdock

That will work.  There's a simpler, and more conventional way to do it:
Code: [Select]
void loop()
{
byte data[2];

getdat(data);
}

void getdat(byte pdata[])
{
pdata[0] = 'a';
pdata[1] = 'b';
}


Either way, the same address gets passed to getdata().  In the function declaration for getdat(), I would use 'byte pdata[]' rather than 'byte *pdata' because I will be referencing pdata as an array rather than a character pointer.  Once again, the way you did it was  equivalent, but saying it's an array makes it a tiny bit more self-documenting.

By the way, if you wanted to change the value of two variables in getdat(), rather than using an array, here's one way to do it:
Code: [Select]
void loop()
{
byte data1;
byte data2;

getdat(&data1,&data2);
}

void getdat(byte *d1,byte *d2)
{
*d1 = 'a';
*d2 = 'b';
}
Personally, I'd use an array, as you did.

Regards,

-Mike

PaulS

You could also declare the function as taking addresses of variables:

Code: [Select]
void getdat(byte &one, byte &two)
{
   one = 1;
   two = 2;
}

Then, call it:

Code: [Select]
byte a=13, b=26;
getdat(a, b);


After the call, a will contain 1, and b will contain 2.

scgtrp

Quote
My gcc-4.2 accepted the code posted by nkcelectronics but gave a warning (incompatible pointer type) during compiling. The program worked well despite the warning.

In C an array IS a pointer. You should be calling getdat(data) rather than   getdat(&data);. The latter will probably "work" but will overwrite some random place in memory which will not be where you intended.

("data" is equivalent to "&data[0]", i.e. the address of the start of the array. "&data" is the address of the address of the start of the array)

tkbyd

a) If your example shows ALL you want to do, you could be really, really "bad" and just use some global variables.

b) If you want one function to return two (or more) numbers to one of a limited number of destinations, you could still use global variables ("bad"), but pass a "which destination" switch to the function....



Calls....

Fill2(0);

Fill2(1);

Function's declaration...

void Fill2(byte bWhichDest)
{
if (bWhichDest==0)
 {
    a=whatever;
    b=whatever;
 }
 else
 {
  c=whatever;
  d=whatever;
 };

Not "good programming"... but would get some jobs done...

Go Up