# Thread: Function returning multiple data

1. ## Function returning multiple data

Hi Team,

I am about to write a function and it will return 8 arrays. I have previously only written functions that return 1 array.

Is it possible to do the below or am I doing this wrong? I do not know another way of doing this.

Many Thanks,

Rocketman46.

Code:
```int function(int data)
{

// do some calculations

return array1;
return array2;
return array3;
return array4;
return array5;
return array6;
return array7;
return array8;
}```

2. Functions cannot return arrays as it is simply against the language rules. What they can do is to return a pointer to some element (typically the first) in the array.

Perhaps you should be dealing with a 2D array (or for dynamic arrays: an array of pointers, or a pointer to a pointer), or with a struct of arrays (or for dynamic arrays: struct of pointers).

I will do some more reading and come back with my solution.

4. Just to be clear, a function can only return one thing. Ideas on how to get multiple values back from a function are discussed here: Question 20.1

Also, if you declare an array with automatic storage duration locally in your function, returning it (or more precisely, returning a pointer to its first element) will not work, since the data will cease to exist when the function ends.

5. OK i can modify my functions to pass one parameter. But i would like to pass five parameters. I can make my code more compact if data() can return for example data2, data3, data4, data5. But i know this is not correct in C. I can do this if I replicate raw_data() ..... raw_data5() etc but I do not want to do this.

Is the best way to write data()....data5() and raw_data()....raw_data5().

Sorry in advance for my misunderstanding.

Code:
```int data(int)
{

// Do some calculations

return int data1;
//return int data2;
//return int data3;
//return int data4;
//return int data5;
}```
Code:
```void raw_data(int)
{
results[3]=data(0x00); // fault data
results[2]=data(0x00); // MSB result byte
results[1]=data(0x00); // 2nd result byte
results[0]=data(0x00); // LSB result byte

// Repeat the above block another 4 times for data2...data5

}```

6. Just to be clear, you want to pass a value to a function, and have up to five arrays be updated based on that value - right?
And if so, the values in each of the arrays will differ from one another?

Using a structure to hold all of your arrays (as already suggested by laserlight) would be one solution:

Code:
```struct data_t
{
int data_1[3];
int data_2[3];
int data_3[3];
/* etc */
};

struct data_t function(int action)
{
struct data_t data;

/* use "action" in your calculations */

data.data_1[0] = /* */;
data.data_1[1] = /* */;
data.data_1[2] = /* */;

/* repeat for "data.data_2", "data.data_3", etc */

return data;
}```
To make things more efficient, you could pass a pointer to a struct and update that rather than return a struct from the function:

Code:
`void function(int action, struct data_t *data)`
That is one possible solution. There are others, as well.

Also, if you tell us what you want to accomplish, rather than how you want to accomplish it, we might be able to suggest better alternatives.

7. Thank you for taking the time to look at my problem.

OK so added below are four functions. The first two are the original that only return one variable and work correctly. The second two functions are wrongly modified to return multiple variables.

The problem I have is spi_transfer_byte() can only return one variable not multiple and secondly get_raw_results() can only receive one data type from spi_transfer_byte().

I can now understand the logic of using a structure because all the results at the bottom of spi_transfer_byte() can be uploaded to the structure so this gets over the one return type, and get_raw_results() can access multiple data in the structure - I think I understand this, but when the spi_transfer_byte() is finished does the structure lose its data and go out of scope?. My problem now is where do I put this structure. Because both of the below functions are in different .c files. Would I create a third .c file to add my structure.

If all of the above is correct, would you use pointers to access the structures.

Code:
```// spi.c
// original code

byte byte_in = 0;
byte bit = 0;
byte result = 0;

for (bit = 0x80; bit; bit >>= 1) {

PORTA |= BV(SPI_MOSI); // HIGH
}
else{
PORTA &= ~BV(SPI_MOSI); // LOW
}

_delay_us(4);

PORTE |= BV(SPI_CLK);      // CLK_High

if (PINA & (1<<SPI_MISO))
byte_in |= bit;

_delay_us(4);

PORTE &= ~BV(SPI_CLK);      // CLK_low
}
return byte_in;
}
// raw_data.c
// original code

void get_raw_results(long base_address, int channel_number, unsigned char results[4]) {

results[3]=spi_transfer_byte(0x00); // fault data
results[2]=spi_transfer_byte(0x00); // MSB result byte
results[1]=spi_transfer_byte(0x00); // 2nd result byte
results[0]=spi_transfer_byte(0x00); // LSB result byte

}```
Code:
```// spi.c
// modified code

byte bit = 0;
byte byte_in_1, byte_in_2,
byte_in_3, byte_in_4,
byte_in_5, byte_in_6,
byte_in_7 = 0;

for (bit = 0x80; bit; bit >>= 1) {

PORTA |= BV(SPI_MOSI); // HIGH
}
else{
PORTA &= ~BV(SPI_MOSI); // LOW
}

_delay_us(2);

PORTE |= BV(SPI_CLK);      // CLK_High

if (PINA & (1<<SPI_MISO_PT100_SP11))
byte_in_1 |= bit;

if (PINA & (1<<SPI_MISO_PT100_SP12))
byte_in_2 |= bit;

if (PINA & (1<<SPI_MISO_PT100_SP13))
byte_in_3 |= bit;

if (PINA & (1<<SPI_MISO_PT100_SP14))
byte_in_4 |= bit;

if (PINA & (1<<SPI_MISO_PT100_SP15))
byte_in_5 |= bit;

if (PINA & (1<<SPI_MISO_PT100_SP16))
byte_in_6 |= bit;

if (PINA & (1<<SPI_MISO_PT100_SP17))
byte_in_7 |= bit;

_delay_us(2);

PORTE &= ~BV(SPI_CLK);      // CLK_low
}
return byte_in_1;
return byte_in_2;
return byte_in_3;
return byte_in_4;
return byte_in_5;
return byte_in_6;
return byte_in_7;
}
// raw_data.c
// modified code

void get_raw_results(long base_address, int channel_number, unsigned char results[4]) {

results[3]=spi_transfer_byte(0x00); // fault data
results[2]=spi_transfer_byte(0x00); // MSB result byte
results[1]=spi_transfer_byte(0x00); // 2nd result byte
results[0]=spi_transfer_byte(0x00); // LSB result byte
/*
results[3]=spi_transfer_byte(0x00); // fault data
results[2]=spi_transfer_byte(0x00); // MSB result byte
results[1]=spi_transfer_byte(0x00); // 2nd result byte
results[0]=spi_transfer_byte(0x00); // LSB result byte

results[3]=spi_transfer_byte(0x00); // fault data
results[2]=spi_transfer_byte(0x00); // MSB result byte
results[1]=spi_transfer_byte(0x00); // 2nd result byte
results[0]=spi_transfer_byte(0x00); // LSB result byte

// etc

// etc
*/