C programming, doing multiple calculations in one function - c

Is it possible to create a function and do multiple calculations in that function, then create another function to print out the results of the calculations... I know a function can only return one value.

There are several ways to return multiple values. One way is to "package" them as a struct:
typedef struct
{
int x;
float y;
} Result;
Result add2( int x1, int x2, float y1, float y2)
{
Result r;
r.x = x1 + x2;
r.y = y1 + y2;
return r;
}
Another way to do it is to use parameters as your outputs:
void add2( int x1, int x2, float y1, float y2, int* x, float* y)
{
*x = x1 + x2;
*y = y1 + y2;
}
You could also do combinations of these.

One return value is for wimps! Simply define the function as
struct retval { int i; double d; size_t z; } func(void);
(replacing the contents of the struct and the parameters as applicable).
Be careful when doing this, though. In spite of what I said up top, in general there is no need for multiple returns.

You can create a struct with all the things ​​you are interested in, alloc it on heap, edit it inside a function, return the same struct that you have edited and at the end free the memory.
Alternatively, you can also pass the pointer and at the end free the memory.
Example:
typedef struct date_test {
int year;
int month;
int day;
} Date;
With this you create a structure that will contain 3 int values: year, month and day.
Alloc it on heap and check for errors:
Date *test = malloc(sizeof(Date));
if (test == NULL) {
perror("Malloc");
exit(EXIT_FAILURE);
}
Edit it inside a function and return the struct, example:
Date* test_f(Date* test)
{
test->year = 2017;
test->month = 05;
test->day = 29;
return test;
}
Then free the allocated memory:
free(test);

Related

Function Pointer with void* return and void* parameters

I wrote a function pointer that has all void* so that it can be used for any numeric value
int
float
double.
But it is working only for the int addition function
For float and double addition functions, it throws compile time error.
Why is that so ?
If you uncomment the last two printf lines, you would receive error
#include<stdio.h>
int int_add(int x, int y) {
return x + y;
}
float float_add(float x, float y) {
return x + y;
}
double double_add(double x, double y) {
return x + y;
}
void* do_operation(void* (*op)(void*, void*), void* x, void* y) {
return op(x, y);
}
void main(void) {
printf("Sum= %d\n",(int*) do_operation(int_add, 1, 2));
/*printf("Sum= %f\n",(float*) do_operation(float_add, 1.20, 2.50));*/
/*printf("Sum= %lf\n",(double*) do_operation(double_add, 1.20, 2.50));*/
}
void * is a pointer type. You're not passing pointers, you're passing values, so that's not going to compile. It accidentally "works" for int because pointers themselves are represented as integers by most C compilers.
If you pass pointers to int, float, and double instead of the int, float, and double themselves, you will avoid that compiler error. You'd also need to change int_add and friends to take pointers, and you'd have to make sure you dereferenced the pointers before using them. You'll also have to return pointers, which means you'll have to malloc some memory on the heap, because the stack memory assigned to your local variables will be invalid once your function exits. You'll then have to free it all later... in the end, this is going to result in something considerably more complicated than the problem it appears you are trying to solve.
I have to ask why you are trying to do this? C is really not the best language for this type of pattern. I'd suggest just calling the int_add, float_add, etc. functions directly instead of trying to abstract them in this way.
So as per #charles-srstka suggestion I rewrote the code and then it worked as I wanted
#include<stdio.h>
#include<stdlib.h>
int* int_add(int *x, int *y) {
int *c = (int *)malloc(sizeof(int));
*c = *(int*)x + *(int*)y;
return c;
}
float* float_add(float *x, float *y) {
float *c = (float*)malloc(sizeof(float));
*c = *(float*)x + *(float*)y;
return c;
}
void* do_operation(void* (*op)(void*, void*), void* x, void* y) {
return op(x, y);
}
void main(void) {
int a = 1;
int b = 2;
int *c;
c = do_operation(int_add, &a, &b);
printf("%d\n",*c);
free(c);
float x = 1.1;
float y = 2.2;
float *z;
z = do_operation(float_add, &x, &y);
printf("%f\n",*z);
free(z);
}

C assign some values of one struct to another

I am having a problem with my code. I am attempting to get some of the values from one of my structs to assign to another. Everything I find on here is about assigning the whole struct to the other.
What I am after is a drone is selected from an array of 10 drones and the details in the struct is assigned to a new member of the delivery_info struct so it can be formatted on the screen in a table.
Currently is not assigning the values from the drone struct to the delivery as intended
I have attached what I have at the moment.
void drone_delivery(Delivery *delivery_info, Drone *drones, float x1, float x2, float y1, float y2, int total, float item_weight, int*totalD){
totalD = realloc(totalD, sizeof(delivery_info) * (*totalD+1));
float cDistance = sqrt((pow(x2-x1,2) ) + (pow(y2-y1,2)));
printf("%4.2f\n", cDistance);
int i;
for ( i = 0; i < total; i++)
if (drones[i].maxDist >= cDistance && drones[i].loadCapacity >= item_weight) {
delivery_info[i].droneNumber = drones[i].droneNumber;
strcpy(drones[i].droneName, delivery_info[i].droneName);
delivery_info[i].maxDist = drones[i].maxDist;
delivery_info[i].loadCapacity = drones[i].loadCapacity;
delivery_info[i].x1=x1;
delivery_info[i].y1=y1;
delivery_info[i].x2= x2;
delivery_info[i].y2 = y2;
}
print_delivery_info(delivery_info[i]);
*totalD+=1;
}

to write a function that tests whether a Point is in a Rectangle

the question is as follows:
write and test a program with the following features.
Firstly, defines a new structured type called Point, is represented with floats for the x and y values
. Also, define a new structured type called Rectangle, which has sides parallel to the x-axis and yaxis, allowing you to represent the rectangle with the bottom_left and top_right Points.
Next write a function that computes and returns the area of a Rectangle, based upon the Rectangle parameter passed into the function.
Avoid pass by value, ensure the function exhibits pass by reference behaviour
Ensure the function returns the appropriate type of data
Next write a function that tests whether a Point is in a Rectangle. This function should take in two parameters by reference, the Point and the Rectangle to test. The function must return an integer value of one if the point is inside the rectangle, otherwise it should return zero. Write a main function, with appropriate local variables as test data to then use on the two functions above
#include <stdio.h>
struct Point
{
float x;
float y;
};
struct Rectangle
{
struct Point lb; // left below point
struct Point ru; // right upper point
};
float getArea(struct Rectangle r)
{
return (r.ru.x - r.lb.x)*(r.ru.y - r.lb.y);
}
void setValue(struct Point* p, float x, float y)
{
p->x = x;
p->y = y;
}
void setValueP(struct Rectangle* r, struct Point* lb, struct Point* ru)
{
r->lb = *lb;
r->ru = *ru;
}
void setValueR(struct Rectangle* r, float x1, float y1, float x2, float y2)
{
r->lb.x = x1;
r->lb.y = y1;
r->ru.x = x2;
r->ru.y = y2;
}
int contains(struct Rectangle r, struct Point p)
{
if((p.x > r.lb.x && p.x && p.x < r.ru.x) && (p.y > r.lb.y && p.y && p.y < r.ru.y))
return 1;
return 0;
}
int main()
{
struct Rectangle r;
setValueR(&r, 1, 2, 6, 8);
printf("%f\n", getArea(r));
struct Point p1;
setValue(&p1, 4, 5);
struct Point p2;
setValue(&p2, 4, 1);
if(contains(r, p1))
printf("inside the Rectangle\n");
else
printf("outside the Rectangle\n");
if(contains(r, p2))
printf("inside the Rectangle\n");
else
printf("outside the Rectangle\n");
}
Make sure you compile c++, those errors look like c++ code compiling with c compiler
i need it to be a c programming code, could you please help me?
The C language does not have 'reference' parameters and does not have 'classes' and does not have the concept of 'this'.
The code needs to be changed to not use references not classes nor 'this'.
You could start with changing:
struct Point
{
float x;
float y;
Point(float x, float y) : x(x), y(y)
{}
Point()
{}
};
to this:
struct Point
{
float x;
float y;
};
Then, need to include the 'struct' modifier when referencing 'Point' as there is no 'Point' class but there is a 'Point' struct.
So change this:
struct Rectangle
{
Point lb; // left below point
Point ru; // right upper point
...
to this:
struct Rectangle
{
struct Point lb; // left below point
struct Point ru; // right upper point
};
The setValue() function is using references for the parameters and using the C++ 'this' to indicate the current object:
void setValue(Point& lb, Point& ru)
{
this->lb = lb;
this->ru = ru;
}
However, C does not have the 'this' nor 'references'. To write it for C, use:
void setValue( struct rectangle *pRect, struct Point *pLB, struct Point *pRU)
{
pRect->lb.x = pLB->x;
pRect->lb.y = pLB->y;
pRect->ru.x = pRU->x;
pRect->ru.y = pRU->y;
} // end function: setValue
similar considerations pertain for the rest of the posted code.

How to inherit structure in a plain C

I am working in a plain C (embedded project, little memory) and I have a structure
typedef struct
{
int x;
int y;
int z;
float angle;
float angle1;
float angle2;
} Kind1;
There are cases when I need all fields, and there are cases when I need x, y and angle only.
In C++ I would create a base class with these 3 fields, would inherit from it another class with additional 3 fields and would instantiate one or another per need. How can I emulate this behaviour in plain C?
I know that I can make something like
typedef struct
{
int x;
int y;
float angle;
} Kind1;
typedef struct
{
Kind1 basedata;
int z;
float angle2;
float angle3;
} Kind2;
but then I cannot pass pointer to Kind2 where a pointer to Kind1 is requested.
I know that it is possible to typecast and offset the pointer, I just wonder if there is a better, safer way.
I know that it is possible to typecast and offset the pointer
Not necessarily:
void foo(Kind1*);
struct Kind2
{
Kind1 basedata;
int z;
float angle2;
float angle3;
}
//...
Kind2 k;
foo(&(k.basedata));
You can do it much like you would in C++:
struct Kind1
{
int x;
int y;
float angle;
}
struct Kind2
{
int z;
float angle2;
float angle3;
}
struct Kind
{
Kind1 k1;
Kind2 k2;
}
It's not possible in plain C, the language has no such features. However, you could simplify the typecasts and offsets with pre-processor macros.
Examples below assume these definitions.
struct base { char c; } *a_base;
struct sub { struct base b; int i; } *a_sub;
Your "example" is in fact the (simplest) proper solution.
but then I cannot pass pointer to Kind2 where a pointer to Kind1 is requested.
Yes you can. The following is from the C11 standard but previous revisions had the same guarantees[citation needed].
n1570 6.7.1.1.15
... A pointer to a structure object, suitably converted, points to its initial member (or if that member is a bit-field, then to the unit in which it resides), and vice versa. There may be unnamed padding within a structure object, but not at its beginning.
Therefore (struct base*)a_sub == &a_sub->b and ((struct base*)a_sub)->c == a_sub->b.c
So as long as your "super-struct" is the first member of your "sub-struct" you can treat one as the other when accessing by reference. Basically don't do this.
void copy(struct base *from, struct base *to)
{
*to = *from; // Oops, you just lost half your object.
}
In the case of limited memory, preserve sanity by declaring two different structs:
struct Kind1
{
int x;
int y;
float angle;
}
struct Kind2
{
int x;
int y;
int z;
float angle;
float angle2;
float angle3;
}
I once had to work code which used a union and preprocessor #defines to make the code look more readable. However, this quickly leads to madness. If the two structures are actually handled as a subclass, then rearranging the fields is the least evil:
struct Kind1
{
int x;
int y;
float angle;
}
struct Kind2
{
int x;
int y;
float angle;
// extended data:
int z;
float angle2;
float angle3;
}
as long as they are carefully used with casting. If anything goes wrong though, there really ought to be debug version namechecking to prove it all is done correctly.
struct Kind1
{
char variant[6]; // initialized to "kind1"
int x;
int y;
float angle;
}
struct Kind2
{
char variant[6]; // initialized to "kind2"
int x;
int y;
float angle;
// extended data:
int z;
float angle2;
float angle3;
}
function_expecting_kind2 (struct kind2 *p)
{
if (strcmp (p->variant, "kind2"))
error ("function expecting kind2 got '%s' instead", p->variant);
...
}
One way that I can think of which will save not more than 2*sizeof(float) bytes.
struct Kind2
{
int z;
float angle2;
float angle3;
}
struct Kind1
{
int x;
int y;
float angle;
struct Kind2 *k2;
}
here the whole saving will be based on how much memory the pointer eats.
Init the pointer only if it is needed.

How to return two values from a function? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
returning multiple values from a function
Suppose i have passed two values to a function iCalculate(int x, int y) and this iCalculate returns two values. Those are as follows:-
(x*y)
(x/y)
Now how should i return the above two values at the same time with the same function?
My Approach was:-
int* iCalculate(int x,int y){
int temp[2];
temp[0] = x*y;
temp[1] = x/y;
return temp;
}
returning the address of the first element of a local array has undefined behavior(at least dereferencing it later is).
You may use output parameters, that is, pass two pointers, and set the values inside
void Calculate(int x, int y, int* prod, int* quot)
{
*prod = x*y;
*quot = x/y;
}
usage:
int x = 10,y = 2, prod, quot;
Calculate(x, y, &prod, &quot)
Another thing you could do is pack your data into a struct
typedef struct
{
int prod;
int quot;
} product_and_quot;
product_and_quot Calculate(int x, int y)
{
product_and_quot p = {x*y, x/y};
return p;
}
That won't work, since you're returning a pointer to a temporary array, which will stop existing at function return time.
Instead, define
typedef struct { int first, second; } IntPair;
and return an object of that type.
(This is what the standard library functions div and ldiv do, except that they call the type differently.)
Your approach is wrong, temp is out of scope/ not longer exist when functon iCalculate exit. So you must not return the address of temp. That would be address of out of scope/ no longer exist variable. Accessing that address means undefined behaviour.
You can use this approach:
void iCalculate(int x,int y,int *mult,int *divi){
*mult = x*y;
*divi = x/y;
}
or you can use another approach:
typedef struct{
int mul, divi;
} TResult;
TResult iCalculate(int x,int y){
TResult res;
res.mul = x*y;
res.divi = x/y;
return res;
}
or :
void iCalculate(int x,int y,TResult *res){
res->mul = x*y;
res->divi = x/y;
}
I suggest the first approach. I think it is too silly to create a new struct definition only to wrap 2 unrelated value together.
The way you did is wrong since int temp[2] disappears once the function returns, so the caller has a "dangling" pointer. You have to add static. Another way, likely better, is to let the caller pass where it wants the result be store e.g.
void iCalc(int x, int y, int *rp, int *rq)
{
// check if rp and rq are NULL, if so, returns
*rp = x*y;
*rq = x/y; // y != 0, and this will truncate of course.
}
and the caller will do something like
int res[2];
iCalc(x, y, res, res+1);
or similar.
Your approach was not so wrong you can return the address of the table like this :
int *iCalculate(int x,int y){
int *temp=malloc(sizeof(int)*2);
temp[0]=x*y;
temp[1]=x/y;
return temp;
}
dont forget to free the memory :
int *result;
result=iCalculate(10,7);
printf("%d %d\n",result[0],result[1]);
free(result);

Resources