Reputation: 143
I am trying to pass array to function (*getcreditcurve). I am expecting function (*getcreditcurve) to return an array. Main function is expected to send several such array to function (*getcreditcurve), pointer function is expected to return a array to main function for different array using the logic given in pointer function (*getcreditcurve). I am not getting error but I don’t get correct value. I expect I+1 to be 3 * 0.0039 = 0.0117 and I+2 to be 4 *0.0060 = 0.0024 however I get following in excel output
'00D4F844 00D4F84C'
Even if I change the print statement to
'print << *(I1+1) << '\t' << *(I2+2) << endl;'
I get following excel out put
-9.26E+61 -9.26E+61
Can somebody help in trouble shooting please? Sorry I went through other post/question in this site but not able to get simplest way to solve this issue. I am going to use this logic to build other projects so simplified the question just to resolve main issue.
#include<iostream>
#include<cmath>
#include<fstream>
typedef double S1[5];
using namespace std;
double *getcreditcurve(double *);
int main()
{
S1 C1 = { 0.0029, 0.0039, 0.0046, 0.0052, 0.0057 };
S1 C2 = { 0.0020, 0.0050, 0.0060, 0.0070, 0.0080 };
typedef double *issuer;
issuer I1 = getcreditcurve(C1);
issuer I2 = getcreditcurve(C2);
ofstream print;
print.open("result1.xls");
print << (I1+1) << '\t' << (I2+2) << endl;
print.close();
return 0;
}
double *getcreditcurve(S1 ptr)
{
const int cp = 5;
typedef double curve[cp];
curve h;
h[0] = 2 * ptr[0];
h[1] = 3 * ptr[1];
h[2] = 4 * ptr[2];
h[3] = 5 * ptr[3];
h[4] = 6 * ptr[4];
return h;
}
Upvotes: 1
Views: 205
Reputation: 27133
It's not possible to return a C array from a function. There are other things you can return, such as std::vector
or std::array
. You should consider redesigning your application around those two instead.
But if you really need to use C arrays in C++, I suggest that instead of trying to return an array from getcreditcurve
, you pass an extra array into getcreditcurve
which will be used to store the result. This is called an output parameter.
void getcreditcurve(double*, double *);
This would solve the "scope" problem. The caller (main
) would then create the array before calling getcreditcurve
and would then pass that to getcreditcurve
. As a result, getcreditcurve
does not have to take responsibility for creating (or destroying) any object.
double I1[5];
getcreditcurve(I1, C1); // will store its result on `I1`.
This might be the easiest option if you really really need to get this working as soon as possible.
If you are willing to make some further changes, you can make a much safer program. The short term goal is to abolish all uses of *
(except to use it for multiplication).
C arrays cannot be passed by value, in particular they cannot be returned. There are other funky things you can do (passing special pointers), but the best thing to do with C arrays is to pass them by reference. In C++, reference-passing behaviour is quite consistent and works well.
// http://stackoverflow.com/questions/31362360/unexpected-value-return-by-array-variable
#include<iostream>
#include<cmath>
#include<fstream>
typedef double S1[5];
using namespace std;
/* In the following declaration, the two parameters
* are taken by reference (note the '&').
* This is almost always the best way to pass arrays.
*
* Also, this is a template where N is automatically
* set to the correct number of parameters. This nice
* automatic behaviour is possible only because the
* array is taken by reference.
*
* Finally, note that the second reference, for 'input',
* has 'const'. This is to emphasize that 'input' is for input,
* that getcreditcurve will not be allowed to modify the input argument.
*/
template<size_t N>
void getcreditcurve(double (&output)[N],const double (&input)[N]);
int main()
{
/* S1 is the type - array of five doubles */
/* Here declare and initialize C1 and C2 as two variables
* of this type */
S1 C1 = { 0.0029, 0.0039, 0.0046, 0.0052, 0.0057 };
S1 C2 = { 0.0020, 0.0050, 0.0060, 0.0070, 0.0080 };
// create the two output arrays first, within main
S1 I1;
S1 I2;
// call getcreditcurve, passing in the output and input arrays
getcreditcurve(I1,C1);
getcreditcurve(I2,C2);
ofstream print;
/* you can't create Excel(.xls) files in C++ easily
* Better to just create a .csv file instead
* csv = comma-separated values
*/
print.open("result1.csv");
print << I1[0] << ',' << I2[3] << endl;
print.close();
return 0;
}
template<size_t N>
void getcreditcurve(double (&output)[N],const double (&input)[N])
{
output[0] = 2 * input[0];
output[1] = 3 * input[1];
output[2] = 4 * input[2];
output[3] = 5 * input[3];
output[4] = 6 * input[4];
}
But seriously, you really should just ditch C arrays entirely. This is C++, not C. Use std::vector<double>
instead.
Upvotes: 0
Reputation: 27133
If you want getcreditcurve
to return an array, then try this:
const int cp = 5;
typedef double curve[cp];
curve getcreditcurve(S1 ptr) {
But that gives an error error: ‘foo’ declared as function returning an array
. Functions can't return C arrays. But the good news is that if you fully embrace C++ you can return std::array
instead.
#include<array>
const int cp = 5;
typedef curve std::array<double,cp>;
curve getcreditcurve(S1 ptr) {
But really, std::vector
is probably much better as you have more flexibility about the size.
#include<vector>
std::vector<double> getcreditcurve(std::vector<double> ptr)
{
std::vector<double> h;
h.push_back(2 * ptr.at(0));
h.push_back(3 * ptr.at(1));
h.push_back(4 * ptr.at(2));
h.push_back(5 * ptr.at(3));
h.push_back(6 * ptr.at(4));
return h;
}
In fact, pretty much all problems with C arrays can be solved by std::vector
. Then, in special situations, you can use std::array
. But focus on std::vector
for now.
Upvotes: 1