|
|
View previous topic :: View next topic |
Author |
Message |
JAM2014
Joined: 24 Apr 2014 Posts: 138
|
Returning an array from a function.... |
Posted: Tue Mar 10, 2015 7:25 am |
|
|
Hi All,
I have a function that reads a temperature and humidity sensor. I'd like to return both values, possibly in an array, when the function is called, but I haven't been successful thus far....
Code: |
int16 ReadSensor(void)
{
int16 TH[2] = {0,0};
.
.
.
TH[0] = Humidity;
TH[1] = Temperature;
Return(TH);
}
|
Now, I'm trying to use the function like this:
Code: |
int16 Values[2];
Values = ReadSensor();
fprintf(Console, "Humidity = %ld%%\n\r", Values[0]);
fprintf(Console, "Temperature = %ldC\n\r", Values[1]);
|
But this code won't compile. I've tried many variations, but it either won't compile, or the returned values are incorrect.
Can someone point me to the proper way to pass two variables back from a C function, and then read them?
Thanks,
Jack |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9221 Location: Greensville,Ontario
|
|
Posted: Tue Mar 10, 2015 7:34 am |
|
|
First you MUST post a small, compilable program ! Just displaying 'snippets' doesn't help us help you.
Generally speaking though a function can only return one value.
As far as what it 'looks' like you want, just declare the sensor variables as 'global', then your 'read sensor function' will put the results into a 'common' memory location where in 'main()' can read and display the results.
Unless you're really,really strapped for RAM, I don't any reason to do it the hard way....though it could be done, I suppose.
Jay |
|
|
kWoody_uk
Joined: 29 Jan 2015 Posts: 47 Location: United Kingdom
|
|
Posted: Tue Mar 10, 2015 8:20 am |
|
|
If you make the array static it should work.
Or you could pass the address of the array into the function, and work with it that way.
Keith |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19499
|
|
Posted: Tue Mar 10, 2015 9:15 am |
|
|
As posted it'll never work.
He is declaring the function to return an int16. TH, is the address of the array (but the array won't exist after the function exits - this is the point about declaring it as static), but even if it was static, the code needs to say that he is returning a pointer, not an integer.....
Then there is the inherent problem about this of 'knowing' the size of the returned object.
In C, things like 'sizeof', only work inside the function where a variable is declared. Better to declare a 'structure' outside the function (hence global), containing the array. Declare 'TH' in the function to be a structure of this type, and declare the function to return a pointer to such a structure. Then all the components will actually 'know' what is being passed. So:
Code: |
//Different ways:
Typedef struct {int16 TH[2]} THtype;
THtype * ReadSensor(void)
{
static THtype val;
val.TH[0] = Humidity;
val.TH[1] = Temperature;
return &val;
}
//This then returns a pointer to the physical data stored in
//the static 'val' variable.
//In the main have a variable as:
THtype * rval;
rval=ReadSensor();
temperature = rval->TH[0];
//and the same for humidity
//Or
//With the same typedef
THtype ReadSensor(void)
{
THtype val;
val.TH[0] = Humidity;
val.TH[1] = Temperature;
return val;
}
//This then physically returns the value as a structure of THtype.
THtype rval;
rval=ReadSensor();
temperature=rval.TH[0];
//etc..
//Or
int16 * ReadSensor(void)
{
static int16 TH[2] = {0,0};
.
.
.
TH[0] = Humidity;
TH[1] = Temperature;
Return(TH);
}
//then in the main
int16 * rval;
rval=ReadSensor();
temperature=rval[0];
//and again for humidity
|
I think I've typed these all right, but no guarantees.... |
|
|
RF_Developer
Joined: 07 Feb 2011 Posts: 839
|
|
Posted: Tue Mar 10, 2015 10:20 am |
|
|
If its declared as a non-static local variable, then the variable doesn't exist outside of the function. You can pass a pointer to a local variable as the return value of a function, but the pointer has no meaning outside of the function. This might work in some cases, but don't bet on it.
If the variable is declared as a static local, then it does exist outside of the function (even though technically its out of scope). This means a pointer to it will point to something useful. However, the value pointed to should be considered volatile as it may change, and indeed will every time the function is called. Its okay if you only use values soon after calling the function, but if you expect them to still be there after a few calls... if you do, well, you won't get what you expect.
The way this would often be done is with dynamic memory: malloc a variable of the required type in the function and return a pointer to it. Its then up to the calling code to free the memory at some later stage. However, using dynamic memory on processors with such limited RAM as most PICS is fraught with problems and is rarely successful. In general its best avoided. As yet, I have not used dynamic memory in any of my PIC, or even ARM, code and I don't want to encourage its use. This is why I'm not giving an example of this technique.
I tend to call by reference: pass a pointer to the routine, pointing to a structure, array or union, which the function can fill with the required data. This is something like this. Note, you don't have to pass a pointer to a structure, you can pass a pointer to an array, or even an element of an array as many of the string (strings simply being arrays of char in C) and memory functions do:
Code: |
Typedef struct {int16 TH[2]} THtype;
THtype Temperature;
void ReadSensor(THtype * Val)
{
val->TH[0] = Humidity;
val->TH[1] = Temperature
}
...
ReadSensor(&Temperature);
|
|
|
|
JAM2014
Joined: 24 Apr 2014 Posts: 138
|
|
Posted: Tue Mar 10, 2015 10:50 am |
|
|
Hi Guys,
Thanks for the suggestions! I'm pretty good with electronics, but I'm just beginning to learn the 'C' language, and I want to learn it the "proper" way. I'm in the process of updating a number of projects, originally done in assembler, with CCS 'C' code. This project is now working like a charm.
Thanks,
Jack |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19499
|
|
Posted: Tue Mar 10, 2015 11:29 am |
|
|
I have to say that RF_developer is very right. It's always better to pass the variable 'to' the function, and return the values in this. This is the 'really right' way of doing it, but I was trying to just answer the 'how to return an array' part of the question, and ignoring this.
There is one other way that has been missed, which is to pass by reference.
This can be better for small functions that are 'in-lined'. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|