returning two variables that have multiple values - c

I am trying to use a function that will calculate values for h and then input these values of h into an equation that will calculate n. This is what my code currently looks like...
int findN(double xI, double xF) {
double h = 0.1;
int n;
do {
printf_s("%8.5f \n", h);
n = ((xF - xI) / h);
h = h / 10;
printf_s("%6d \n", n);
} while (h >= 0.00001);
return n;
}
I know that this function will only return n currently, but as i am new to this i am unsure as to how to also return all the values of h as well as all the values of n... If someone could assist me and show me how to return all the values for n & h, it would be much appreciated.
Thanks.

Typical approach to return multpile values is using arrays and pass its pointer to function:
int f(double *h) {
h[0] = 1.1;
h[1] = 2.2;
}
int main()
{
// create pointer
double *h;
// initialize it with memory block
h = malloc(2*sizeof(double));
// call the function
f(h);
// show output
printf_s("%8.5f \n", h[0]);
printf_s("%8.5f \n", h[1]);
// release memory block
free(h);
return 0;
}
Also same array may be created without memory allocation. It is more simple but arrays exists only until execution is not leave away from function scope where it declared.
int main()
{
// create array
double h[2];
// call the function
f(h);
// show output
printf_s("%8.5f \n", h[0]);
printf_s("%8.5f \n", h[1]);
return 0;
}
And if you can know count of element only during function call you can allocate array in function and return array by pointer and release array at caller.
double* f() {
// create pointer
double *h;
// some size calculations
int size = 1+1;
// initialize it with memory block
h = malloc(size*sizeof(double));
// fill the array
h[0] = 1.1;
h[1] = 2.2;
// return array by pointer
return h;
}
int main()
{
// create pointer
double *h;
// call the function
h = f();
// show output
printf_s("%8.5f \n", h[0]);
printf_s("%8.5f \n", h[1]);
// release memory block
free(h);
return 0;
}

There are many ways to solve this. Another is to return a struct.
Below, findN() returns one object. It just happens that the object contains two members. This approach is suitable when with small objects. With large objects,other approaches should be considered.
typedef struct {
int n;
double h;
} nh;
nh findN(double xI, double xF) {
nh retval;
retval.h = 0.1;
do {
printf_s("%8.5f\n", retval.h);
retval.n = ((xF - xI) / retval.h);
retval.h = retval.h / 10;
printf_s("%6d\n", retval.n);
} while (retval.h >= 0.00001);
return retval;
}
// usage exanple
nh y;
y = findN(1.23, 4.56);
printf_s("h:%8.5f, n:%6d\n", y.h, y.n);

Read into pointers if you want to learn more. But essentially by sending h as a pointer it will return it's value to main.
#include <stdio.h>
int findN(double xI, double xF, double h[]) {
int i = 0;
int n;
h[i] = 0.1;
do {
i++;
printf_s("%8.5f \n", *h);
n = ((xF - xI) / (*h));
h[i] = h[i-1] / 10;
printf_s("%6d \n", n);
} while (h[i] >= 0.00001);
return n;
}
int main()
{
double h[100];
double xI = 1.0, xF = 1.0;
int n;
n = findN(xI, xF, h);
return 0;
}

Read pointers,you will be able to return as many values you want to return,when calling function through main add &h in actual parameters,it means findN(xI,xF,&h) and in declaring the function findN add double *h in formal parameters,that is int findN(double xI,double xF,double *h)...."meaning of * is -value at address of....meaning of & is address of.This will make changes in h globally in this program as the vale is changing in its address.You can return even more values like this using more variables.This is called returning values indirectly.Vote for my answer if its applicable.

The simplest way to handle this is change the function to accept pointers to variables that will accept the values of n and h. Then the function will dereference those pointers to update the relevant variables in the calling function.
void findN(double xI, double xF, int *ret_n, double *ret_h)
{
...
*ret_n = n;
*ret_h = h;
}
Then you can call your function like this:
int n;
double h;
findN(1.2, 3.4, &n, &h);
This method is fine for a relatively small number of parameters. If the number of parameters gets to be too large, you can instead create a struct containing all of the values to be returned either pass in the address of the struct or just return the struct outright.

Related

Find the distance of the closest pair of points ( c )

#include <stdio.h>
#include <math.h>
typedef struct
{
int x,y;
}point;
double distance(point p1[], point p2[], int i)
{
double d = sqrt((pow(p2[i+1].x-p1[i].x,2)) + (pow(p2[i+1].y-p1[i].y,2)));
return d;
}
int main()
{
int size,i;
double d;
printf("Enter number of point: ");
scanf("%d",&size);
point p[size];
for(i=0;i<size;i++)
{
printf("Enter point %d: ",i+1);
scanf("%d,%d",&p[i].x,&p[i].y);
}
d = distance(p[0].x,p[0].y,0);
for(i=0;i<size-1;i++)
{
if( d > distance(p[i+1].x,p[i+1].y,i))
{
d = distance(p[i+1].x,p[i+1].y,i);
}
}
printf("Closest pair distance = %.4lf",d);
}
I have been trying to finish this homework for a while and I'm not sure on how to fix this.
The output supposed to look like this:
This is what I got:
First, I think your distance function should get two points, and not two points arrays. you also don't need to pass the index. this way your function will only do what it should do: calculate the Euclidean distance.
double distance(point p1, point p2)
{
double d = sqrt(pow(p2.x-p1.x,2) + pow(p2.y-p1.y,2));
return d;
}
Second, in your main function, do you want to check only the distance between consecutive points or between any point? I think you want the second option but decide for yourself:
first option:
for(i=0;i<size-1;i++)
{
if( d > distance(p[i],p[i+1]))
{
d = distance(p[i],p[i+1]);
}
}
second option:
for(i=0;i<size-1;i++)
{
for (j=i+1;j<size;j++)
{
if( d > distance(p[i],p[j]))
{
d = distance(p[i],p[j]);
}
}
}
notice I set j=i+1 because first, i don't want to calculate distance(p[i],p[i]) because that will always be 0 and that is the minimal value distance can return. secondly it's sufficient to test only for j>i values because distance(p[i],p[j])==distance(p[j],p[i])
I hope that cover everything
I have done some changes. Read the comments marked with // CHANGE HERE to understand the changes.
#include <stdio.h>
#include <math.h>
#include <float.h>
#include <stdlib.h>
typedef struct
{
// CHANGE HERE: double instead of int
double x, y;
} point;
// CHANGE HERE: just accept two points whose distance needs to be calculated
double distance(point p1, point p2)
{
return sqrt((pow(p1.x - p2.x, 2)) + (pow(p1.y - p2.y, 2)));
}
int main()
{
int size, i, j;
double d;
printf("Enter number of points: ");
scanf("%d", &size);
// CHANGE HERE: use malloc for variable sized arrays
point* p = malloc(size * sizeof(point));
for (i = 0; i < size; i++)
{
// CHANGE HERE: read double instead of int
printf("Enter point %d: ", i + 1);
scanf("%lf,%lf", &p[i].x, &p[i].y);
}
// CHANGE HERE: store a high value by default
d = DBL_MAX;
for (i = 0; i < size - 1; i++)
{
// CHANGE HERE: to get the exact pair of points with closest distance
// you need to compare the distance of each point with the rest
for (j = i + 1; j < size; j++)
{
// CHANGE HERE: pass previous and current point to distance
double dist = distance(p[i], p[j]);
if (d > dist)
{
d = dist;
}
}
}
printf("Closest pair distance = %.4lf", d);
// CHANGE HERE: don't forget to free malloc()ed memory
free(p);
return 0;
}
As mentioned by #tstanisl, you can also use hypot function present in math.h, like:
double distance(point p1, point p2)
{
return hypot(p1.x - p2.x, p1.y - p2.y);
}

Python C Extension

I am having issues returning a 2D array from a C extension back to Python. When I allocate memory using malloc the returned data is rubbish. When I just initialise an array like sol_matrix[nt][nvar] the returned data is as expected.
#include <Python.h>
#include <numpy/arrayobject.h>
#include <math.h>
#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
// function to be solved by Euler solver
double func (double xt, double y){
double y_temp = pow(xt, 2);
y = y_temp;
return y;
}
static PyObject* C_Euler(double h, double xn)
{
double y_temp, dydx; //temps required for solver
double y_sav = 0; //temp required for solver
double xt = 0; //starting value for xt
int nvar = 2; //number of variables (including time)
int nt = xn/h; //timesteps
double y = 0; //y starting value
//double sol_matrix[nt][nvar]; //works fine
double **sol_matrix = malloc(nt * sizeof(double*)); //doesn't work
for (int i=0; i<nt; ++i){
sol_matrix[i] = malloc (nvar * sizeof(double));
}
int i=0;
//solution loop - Euler method.
while (i < nt){
sol_matrix[i][0]=xt;
sol_matrix[i][1]=y_sav;
dydx = func(xt, y);
y_temp = y_sav + h*dydx;
xt = xt+h;
y_sav=y_temp;
i=i+1;
}
npy_intp dims[2];
dims[0] = nt;
dims[1] = 2;
//Create Python object to copy solution array into, get pointer to
//beginning of array, memcpy the data from the C colution matrix
//to the Python object.
PyObject *newarray = PyArray_SimpleNew(2, dims, NPY_DOUBLE);
double *p = (double *) PyArray_DATA(newarray);
memcpy(p, sol_matrix, sizeof(double)*(nt*nvar));
// return array to Python
return newarray;
}
static PyObject* Euler(PyObject* self, PyObject* args)
{
double h, xn;
if (!PyArg_ParseTuple(args, "dd", &h, &xn)){
return NULL;
}
return Py_BuildValue("O", C_Euler(h,xn));
}
Could you provide any guidance on where I am going wrong?
Thank you.
The data in sol_matrix is not in contiguous memory, it's in nt separately allocated arrays. Therefore the line
memcpy(p, sol_matrix, sizeof(double)*(nt*nvar));
is not going to work.
I'm not a big fan of pointer-to-pointer arrays so believe your best option is to allocate sol_matrix as one big chunk:
double *sol_matrix = malloc(nt*nvar * sizeof(double));
This does mean you can't do 2D indexing so will need to do
// OLD: sol_matrix[i][0]=xt;
sol_matrix[i*nvar + 0] = xt;
In contrast
double sol_matrix[nt][nvar]; //works fine
is a single big chunk of memory so the copy works fine.

Trying to create a line with a function and then print it with another function

guys. I'm a beginner and have to create a function that returns a line of output type Line from inputs y intercept and slope, and create another function that prints it. When I run the functions, it mostly prints right, but x prints as 0.00. I need it to print as an x variable because I will later be making a function that finds the intercept of two lines.
Here's the create function:
Line createLine (double m, double b) {
Line y;
double x;
y.m = m;
y.b = b;
//y = y.m * x + y.b; get an error saying the types dont match so I stopped using this
return y;
The print function:
void displayLine (Line a){
double x;
printf("y = %lf * %lf + %lf\n", a.m, x, a.b);
And the struct:
typedef struct line_struct{
double m;
double b;
} Line;
I also have a point struct if it matters.
You're assuming the variable x will get printed as the output, but the way you've desired won't work. The x is an identifier name and hence, it can't be used to print its name itself.
Thus, you don't need to use any other stuff here at all. Just simply print x in the printf() statement and you're done.
Also, note that, as per of your requirement, we've used int datatype here rather than using double, the double is only required when you need to show a very large floating point value which can't be held by the float itself.
You may try this way to achieve:
#include <stdio.h>
struct line_struct {
int m;
int b;
} Line;
Line createLine(int m, int b) {
Line y;
y.m = m;
y.b = b;
return y; // returning the initialized struct to the function correctly
}
void displayLine (Line a){
printf("y = %dx + %d\n", a.m, a.b); // displaying a simple 'x'
}
int main(void) {
Line l;
l.b = 3;
l.m = 4;
displayLine(l);
return 0;
}
This will give you the desired output:
y = 4x + 3
If all you want is to print the line y = 4x + 3, you don't need a variable called x at all. This will suffice:
printf("y = %lf x + %lf\n", a.m, a.b);
I think the error is in the createLine function.
I hope it works this way.
Line createLine (double m, double b) {
Line y;
double x;
y.m = m*x;
y.b = b;
return y;
}

Assigning value calculated through pthread

I have a function that calculates an integral like this:
/* Complete this function to perform the trapezoidal rule using pthreads. */
void *compute_using_pthreads(void *inputs)
{
double integral;
int k;
threadParams *args = (threadParams *) inputs;
float a = args->a;
float b = args->b;
int n = args->n;
float h = args->h;
integral = (f(a) + f(b))/2.0;
for (k = 1; k <= n-1; k++) {
integral += f(a+k*h);
}
integral = integral*h;
printf("Solution computed using pthreads = %f \n", integral);
}
It's called within main like this:
int i;
for(i = 0; i < NUM_THREADs; i++) {
trapThread = (threadParams *) malloc(sizeof(threadParams));
trapThread->a = a;
trapThread->b = b;
trapThread->n = n;
trapThread->h = (b - a) / (float) n;
if (pthread_create(&slaveThread[i], NULL, *compute_using_pthreads, (void *) trapThread) != 0) {
printf("Looks like something went wrong..\n");
return -1;
}
}
My problem is, since I am running 4 threads, the results string Solution computed using pthreads = is printed four times.
My question is, how do I, within main, call compute_using_pthreads and save its return data into a double variable?
Add another variable res to the struct threadParams and store the result in it.
integral = integral*h;
args->res = integral;
Now, from main(), you'll be able to read this integral calculated by each thread.
Currently, you have no identifier to the access malloc'ed memory since you are using the same variable trapThread. Instead, use an array or malloc'ed list of pointers so that you'll be able to access it later.
Obviously your main thread will have to wait for the other threads to complete i.e. if it exits then the whole process will die.

Returning an array of structs from a function - C programming

So I'm trying to write a function that will return an array of several values. At the moment, it is running correctly but only outputting the final calculated value. How would I make it so the output includes all calculated values?
My code looks like this:
//Practice to output an array of structs
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
struct boat_params {
double V, Uc, Vc;
};
struct boat_params submerged_volume(double L1, double L2, double Lavg, double H) {
struct boat_params volume;
double V_sub, Uc_sub, Vc_sub;
V_sub = 0;
//Boat description
double C, delta;
double theta, theta_rad, theta_min, theta_min2, theta_lim, theta_lim2, theta_lim_deg;
double Ug1, Ug2, Vg1, Vg2, V1, V2;
double pi;
pi = 4*atan(1);
C = sqrt(L1*L1 + L2*L2);
delta = acos(L1/C);
theta_lim = asin(H/L1);
theta_lim_deg = (theta_lim/pi) * 180.0;
theta_min = asin(H/C) - delta;
theta_min2 = 0;
//Calculating the submerged volume and centre of gravity for each different angle
for (theta = 0; theta <= 10; theta ++) {
//**Note: I've taken out the actual calculations of V_sub, Uc_sub, and Vc_sub for brevity**
volume.V = V_sub;
volume.Uc = Uc_sub;
volume.Vc = Vc_sub;
}
return volume;
}
int main () {
double L1, L2, Lavg, H;
struct boat_params volume;
L1 = 17.6;
L2 = 3;
Lavg = 4;
H = 4.5;
volume = submerged_volume(L1, L2, Lavg, H);
printf("V = %lf\nUc = %lf\nVc = %lf\n", volume.V, volume.Uc, volume.Vc);
return 0;
}
I can get it to correctly output the last calculated value (for theta = 10) but that's the only value I'm getting. How would I calculate V_sub, Uc_sub, and Vc_sub for each theta value? and output each value. I'm assuming this means turning the struct into an array and filling each element of the array with values of the struct for that theta but I don't know how to do this!
I really appreciate any help and thank you in advance.
Also: If possible I'd like to avoid pointers but understand this may not be possible! I'm still very new and not good at using them!
You are quite right, you will need to have an array for that. If the number of elements in the array is constant, you could also create a struct that contains exactly that number elements, but please don't do that.
To operate on arrays you will - unfortunately - need pointers. A very common way to do this in C is not to return a pointer, but pass a 'result' pointer in. This means that it will be up to the user of the function to allocate space and free it, he can also use the syntax for arrays. In your code it seems that the number of values is constant, this makes the aforementioned solution possible. Alternatively you could allocate space on the heap (using malloc) and return a pointer, but that means the user needs to free memory he never allocated, counter intuitive and might result in memory leaks if he forgets to do so. Consider the following solution:
void submerged_volume(double L1, double L2, double Lavg, double H, struct boat_params *result) {
// your calculations here
for (theta = 0; theta <= 10; theta ++) {
(result+theta)->V = V_sub;
(result+theta)->Uc = Uc_sub;
(result+theta)->Vc = Vc_sub;
}
}
// somewhere in your code where you want to use your function
struct boat_params values[11];
unsigned char i = 0;
submerged_values(/* parameters */, values);
for (; i <= 10; ++i) {
printf("V = %lf\nUc = %lf\nVc = %lf\n", values[i].V, values[i].Uc, values[i].Vc);
}
Try this, just add your logic to the loop and maths:
#include <stdio.h>
#include <stdlib.h>
#define ARRSIZE 100
typedef struct boat_params {
double V, Uc, Vc;
} Volume;
struct boat_params submerged_volume(double L1, double L2, double Lavg, double H, Volume *volumes[]) {
double theta;
int i = 0; /* only example, change as needed */
Volume *p;
for (theta = 0; theta <= 10; theta ++) {
p = malloc(sizeof(* p));
if (p == NULL) {
printf("malloc failed to allocate a new space");
exit(0);
}
p->V = 1; //V_sub;
p->Uc = 2; //Uc_sub;
p->Vc = 3; //Vc_sub;
volumes[i] = p;
i++;
}
}
int main () {
double L1, L2, Lavg, H;
L1 = 17.6;
L2 = 3;
Lavg = 4;
H = 4.5;
Volume *volumes[ARRSIZE];
submerged_volume(L1, L2, Lavg, H, volumes);
printf("V = %lf\nUc = %lf\nVc = %lf\n", volumes[0]->V, volumes[0]->Uc, volumes[0]->Vc); /* first element for example */
return 0;
}
If you don't know the size of the volumes array in advance, you should consider using linked list.

Resources