Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Returning an array from a function 3

Status
Not open for further replies.

aaadetos

Programmer
Nov 21, 2004
54
US
Hi..I have a function which is to return an array...I probably need to pass the array as a reference or pointer; but I don't fully understand these. Asides from the fact that the code which I'll post below probably returns only a value, and not an array, I get error c2664 at 2 lines(as indicated in code); but these 2 lines call perfectly compiled functions, so I cannot even "return the array" without addressing the errors. I'd appreciate any tips on this.

Here's the code:
Code:
double Integrals(void)	
{	double alpha[20],beta[20];
	for (int t=1;t<21;t++)
	{
		double j0[20],j1[20],H0[20],H1[20],p[20],Ip[20];

		double bessj0(double x[20]);	
		double bessj1(double x[20]);
		int t = 1;

		alpha[t] = beta[t] = 2*t*PI;	// t = 1
		p[t] = sqrt(pow(alpha[t],2.0)+pow(beta[t],2.0))
			+sqrt(pow(alpha[t],2.0)+pow(beta[t],2.0));

		j0[t] = bessj0(p[t]);//ERROR C2664! :'bessj0':cannot convert parameter 1 from 'double, to 'double[]'
		j1[t] = bessj1(p[t]);]);//ERROR C2664! :'bessj1':cannot convert parameter 1 from 'double, to 'double[]'


		H0[t] = sum0(p[t]);
		H1[t] = sum1(p[t]);

		
		Ip[t] = ((PI*p[t])/2) * ((2*p[t]*j0[t]) + (((PI*p[t])/2) * ((H0[t]*j1[t])-(H1[t]*j0[t]))) - j1[t]);

		return Ip[20];
	//}
}
}

I know the reason for the errors: bessj0 and bessj1 don't return arrays in the 1st place!!

Code:
double bessj0(double x[20])			
//Returns the Bessel function j0(x) for any real x. 
{
	//CKuchukDlg MyClas;	
	//MyClas.m_fWellRad = x;
	/*	Specify definition of 'x' at point of usage..
		in Ip() and unbounded.cpp,for instance.	*/ 

	double ax[20],z[20],xx[20],y[20],ans1[20],ans2[20],j0[20];

	if ((ax[20]=fabs(x[20]))<8.0)		//Direct rational function fit
	{
		y[20]=x[20]*x[20];
		ans1[20]=57568490574.0+y[20]*(-13362590354.0+y[20]*(651619640.7
			+y[20]*(-11214424.18+y[20]*(77392.33017+y[20]*(-184.9052456)))));
		ans2[20]=57568490411.0+y[20]*(1029532985.0+y[20]*(9494680.718
			+y[20]*(59272.64853+y[20]*(267.8532712+y[20]*1.0))));
		j0[20]=ans1[20]/ans2[20];
	}
	else
	{
		z[20]=8.0/ax[20];
		y[20]=z[20]*z[20];
		xx[20]=ax[20]-0.785398164;
		ans1[20]=1.0+y[20]*(-0.1098628627e-2+y[20]*(0.2734510407e-4
			+y[20]*(-0.2073370639e-5+y[20]*0.2093387211e-6)));
		ans2[20]=-0.1562499995e-1+y[20]*(0.1430488765e-3
			+y[20]*(-0.6911147651e-5+y[20]*(0.7621095161e-6
			-y[20]*0.934945152e-7)));
		j0[20]=sqrt(0.636619772/ax[20])*(cos(xx[20])*ans1[20]-z[20]*sin(xx[20])*ans2[20]);
	}
	return j0[20];//THIS DOESN'T RETURN AN ARRAY! HOW CAN I RETURN AN ARRAY??
}
But I don't know how to write the code to return arrays. I'd really appreciate anyone's help. Thanks a lot.
 
If you want to return an array, you need to pass it as a parameter when you call the function.

So
Code:
void bessj0 ( double x[20], double j0[20] ) {
  // your code here, without a local array called j0
}

> j0[t] = bessj0(p[t]);
You call (and get the answer) using
Code:
bessj0(p,j0);


Code:
    for (int t=1;t<21;t++)
    {
        int t = 1;
Two things wrong here
1. arrays run from index 0, not index 1
So the correct loop is [tt]for ( int t = 0 ; t < 20 ; t++ )[/tt]
2. The [tt]int t = 1;[/tt] shadows the value of t being used for the loop.

I rather suspect that the loop should be in the bessj0() function, because code like this
[tt]if ((ax[20]=fabs(x[20]))<8.0)[/tt]
doesn't mean apply this to all 20 elements of the array.

--
 
You could also put the array in a struct or dynamically allocate the array and manually delete it later, but the best option is generally to pass it as a parameter, as salem said.
 
Thanks a lot, Salem, for your most valuable tip. It was right on the button. Thanks Timmaay3141 and cpjust also for concurring and making further suggestions. Personally, I find references and pointers messy and wouldn't use them unless I absolutely need to. Someone needs to do something about that! [don't mind me::[pipe]]

My function which returns Ip[] is as follows:
Code:
void Integrals(double Ip[20])	
{	double alpha[20],beta[20];
	for (int t=0;t<20;t++)
	{
		double j0[20],j1[20],H0[20],H1[20],p[20];

		void bessj0(double x[20],double j0[20]);	
		void bessj1(double x[20],double j1[20]);
		//int t = 1;


		alpha[t] = beta[t] = 2*t*PI;	// t = 1
		p[t] = sqrt(pow(alpha[t],2.0)+pow(beta[t],2.0))
			+sqrt(pow(alpha[t],2.0)+pow(beta[t],2.0));

		bessj0(p,j0);
		bessj1(p,j1);


		H0[t] = sum0(p[t]);//WATCH THIS
		H1[t] = sum1(p[t]);//WATCH THIS

		Ip[t] = ((PI*p[t])/2) * ((2*p[t]*j0[t]) + (((PI*p[t])/2) * ((H0[t]*j1[t])-(H1[t]*j0[t]))) - j1[t]);

	//	return 0;//Ip[20];
	//}
}
}

Why would this compile without any error or warning, when my struve functions H0 and H1 are written like above? Why didn't H0[t] and H1[t] return any errors? like the function that returns Bessel functions?

Code:
double sum0(double x)	//using the power series expansion, till the 11th power
{
	double H0;
	H0 = x - (pow(x,3)/9) + (pow(x,5)/(9*25)) - (pow(x,7)/(9*25*49))
		+ (pow(x,9)/(9*25*49*81)) - (pow(x,11)/(9*25*49*81*121));

	return H0;
}
 
What is the advantage of writing codes B or C over A?

Code:
//Code A
void Integrals(double Ip[20])
{    
....    
for( i=0; i<20; ++i ) // SIZE KNOWN 
Ip[i] = what ever;
}

// Code B
void Integrals(double *Ip)
{    ....    
for( i=0; i<20; ++i ) // SIZE KNOWN
Ip[i] = what ever;
}

//Code C
void Integrals(double *Ip, int nSize)
{    
     ....    
for( i=0; i<nSize; ++i ) // SIZE UNKNOWN        
Ip[i] = what ever;
}
 
A and B are the same, as is
Code:
void Integrals(double Ip[])
The size specified in the left-most array position of arrays in function prototypes is optional.

void Integrals(double *Ip, int nSize)
is the far superior implementation since you can use if for any array you have.

--
 
See also std::valarray template (for numeric computation;):
Code:
#include <valarray>
typedef valarray<double> Array;

double f(Array &a)
{
   int n = a.size();
   Array w1(n), w2(n); // Working storage:
...
   for (int i = 0; i < 0; ++i)
   {
      w1[i] = a[i]*i;
...
      w2.resize(n+n,0);
...
   }
   return w2.sum();
}
Indexing operator for valarrays is a very effective one (like intrinsic *(p+i);). What's dynamics, clarity and robustness!..
 
Hi..I don't understand why I get error 2664 at the line in the code below. The function definition is as shown below this, viz:

Code:
void dimpress(double* &pD,int nSize)
{
		double tdim[1],dimrw[1],dimpress[20],gwk[20],rwD;
		double tD,rD = 0.0;
		float Lw=0,rw=0;
		int K=0;
		void Time(double tStart, double tStop, double *time, int ntime);
		double tStart = 1e-3;
		double tStop = 1e5;
		int ntime = 100;

		CKuchukDlg MyClass;
		MyClass.m_fHLength = Lw;
		MyClass.m_fWellRad = rw;
		MyClass.m_iSLayer = K;
	
		Stfst = new Stehfest(nSize);	
		Time(tStart,tStop,time,ntime);//ERROR C2664: 'Time', cannot convert parameter 3 from 'long(_cdecl*)(long*) to double*
		
		for(int i=0;i<ntime;i++)
		{
			for(int t=0;t<nSize;t++)
			{
		        tdim[K] = (0.0002637*kh_md[K])/(por[K]*visc_cp[K]*ct_psi[K]*pow(Lw,2));
		        tD += tdim[K];

		dimrw[K] = (rw/(2*Lw))*(1+sqrt(kh_md[K]/kv_md[K]));//for the transversely isotropic medium
		rwD += dimrw[K];

		Stfst -> SetLaplacePoints(tD);

		void gwkfinal(double *gwk, int nSize);
		
		gwkfinal(gwk,20);	
		
		s= 2*t*PI;

	        pD[t] = (2.0*gwk[t]*rwD)/s;	//equation (2)

		dimpress[t] = Stfst -> InverseTransform(pD,tD);
			}
        	}

}
The function definition for 'Time', is:
Code:
void Time(double tStart, double tStop, double *time, int ntime)
{
	time[0]=tStart;

	double delta = pow(tStop/tStart,1/(ntime-1));
	for (int i=1;i<ntime;i++)
	{
		time[i]=time[i-1]*delta;	
	}
}
Thank you!

 
> Time(tStart,tStop,time,ntime);//ERROR C2664: 'Time', cannot convert parameter 3 from 'long(_cdecl*)(long*) to double*
You don't have a local variable
Code:
double *time;

Though you probably want
Code:
double time; Time(tStart,tStop,&time,ntime);

So instead, it tried to use the global function time() in it's place (namely passing a pointer to a function)

--
 
Thanks. I actually renamed the 3rd variable -time, since time is the name of a function defined in the Ctime or time.h header. The function prototype for it looks like time_t time( time_t *timer) where time_t is a typedef'd long which therefore make the prototype look like long time( long*) timer.

Renaming the variable, "time_hr" in all appropriate places got rid of the error.

Thanks again.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top