I have a couple of questions all relating to the same code. In this code, I am trying to return the value for V, Ug1, Ug2, Vg1, and Vg2 from the "submerged_volume" function. Then, I want to use these values in the "centre_of_buoyancy" function. From that function, I want to return two values: Uc, and Vc. Finally, I want to call these functions using the header file in my main, and use the returned values from the functions for further calculations! I have not included the main body as it just has long calculations, so for the sake of space, here's a summarised version of my code:
#ifndef DATE_H_
#define DATE_H_
double submerged_volume(double L1, double L2, double Lavg, double H) {
//Boat parameters
double V1, V2;
double Ug1, Ug2, Vg1, Vg2; //lengths in U and V direction in relation to gravity
double V; //Submerged volume
//Initialising V, the value to calculate
V = 0;
//Volume Calculations
....
....
return V, Ug1, Ug2, Vg1, Vg2, V1, V2;
}
double centre_of_buoyancy(double Ug1, double Ug2, double Vg1, double Vg2, double V1, double V2);
//Calculations for Uc and Vc
.....
.....
return Uc, Vc;
}
#endif
I understand that this won't work as I can't return multiple variables. My question is, is there some way that I can do this? I'm very new to C and am not sure exactly how to use things like this!
You can define a struct holding those values, and return that from your function. (Check your C reference of choice for documentation of structs.)
BTW, you don't return anything "in a header", you only return something "from a function". And defining a function in a header file is asking for trouble. The idea is to declare the function in the header, and to define it in a source (.c) file.
Since I didn't really understand what you're trying to do, excuse me for using my own example.
Header:
#ifndef POINT_H_
#define POINT_H_
struct point_t
{
int x;
int y;
};
struct point_t move_horizontal( struct point_t point, int offset );
struct point_t move_vertical( struct point_t point, int offset );
#endif
Source:
#include "point.h"
struct point_t move_horizontal( struct point_t point, int offset )
{
point.x += offset;
return point;
}
struct point_t move_vertical( struct point_t point, int offset )
{
point.y += offset;
return point;
}
Main:
#include "point.h"
int main()
{
struct point_t some_point = { 0, 0 };
struct point_t other_point = move_horizontal( some_point, 42 );
return 0;
}
Non-sensical of course, but you might get the idea. Source and Main are two distinct compilation units, both of which include the header to know what they're talking about. The linker then puts them together, adds some runtime support, and generates your binary. (Your C book of choice should really have told you as much.)
There is a way to do this, and it's called struct. With struct, you aggregate data and look at them as a single type. That's very nice, since you can give a name to each part of the data:
struct boat_params
{
double submerged_volume;
double length_in_U1,
length_in_U2,
length_in_V1,
length_in_V2;
/* etc */
};
and then you fill this information and return it:
struct boat_params submerged_volume(double L1, double L2, double Lavg, double H) {
//Boat parameters
struct boat_params params;
//Initialising V, the value to calculate
params.submerged_volume = 0;
//Volume Calculations (params.<fields>)
....
....
return params;
}
It makes sense to create a struct for the arguments of the function too, since they are many and they all look similar (all double). Creating a struct when you have many parameters helps the users of your function (and yourself) stay sane by easily assigning values to the parameters by their name, rather than some arbitrary order.
For example:
struct boat_data
{
double L1, L2; /* of course, give better names */
double Lavg;
double H;
};
struct boat_params submerged_volume(struct boat_data boat);
and the user would do:
struct boat_data boat;
struct boat_params params;
boat.L1 = ...;
boat.L2 = ...;
....
params = submerged_volume(boat); /* look how nice this looks */
Once you learn about pointers, you can make it more efficient by passing pointers rather than copying a bulk of data:
void submerged_volume(struct boat_data *boat, struct boat_param *params);
//Initialising V, the value to calculate
params->submerged_volume = 0;
//Volume Calculations (params-><fields>)
....
....
}
and later:
struct boat_data boat;
struct boat_params params;
boat.L1 = ...;
boat.L2 = ...;
....
submerged_volume(&boat, ¶ms); /* less nice, but efficient and still short */
Typcially you would define the function prototype in the header file and the implementation in the .c file.
As #DevSolar said you could define a struct and return this from the function.
struct Boat
{
double V1, V2;
double Ug1, Ug2, Vg1, Vg2;
};
Alternatively you could pass in arguments by reference and modify the variable directly in memory through pointers.
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I want to have a structure like below:
typedef struct Mystruct
{
double p;
double x_min;
double x_max;
double y_min;
double y_max;
double params[] = {x_min, x_max, y_min, y_max};
};
My target is that the elements of the array params should be populated by { x_min, x_max, y_min, y_max}.
Is there anyway to achieve this structure in c?
In C you cannot do this, instead you could write a function which does the initialization for structure instance.
typedef struct Mystruct
{
double p;
double x_min;
double x_max;
double y_min;
double y_max;
double params[4];
}Mystruct;
Mystruct GetMystruct( double p,
double x_min,
double x_max,
double y_min,
double y_max)
{
Mystruct my = { p, x_min,x_max,y_min,y_max, {x_min,x_max,y_min,y_max} } ;
return my;
}
Then, example :
Mystruct m = GetMystruct( 0.0, 42.1, 42.2, 42.3,42.4 );
If your intent is to have two different views of the same structure members, one by name and one by index, then this can be achieved in most C implementations with:
#include <stdio.h>
typedef struct foo
{
double p;
union
{
struct { double x_min, x_max, y_min, y_max; };
double params[4];
};
} foo;
int main(void)
{
foo x = { 1, 2, 3, 4, 5 };
for (size_t i = 0; i < 4; ++i)
printf("%g\n", x.params[i]);
}
There are some theoretical hazards to this (notably ensuring that the internal struct is not padded), but it will work in normal C implementations, and the hazards can be guarded against. (Checking that the size of the internal struct equals the size of the array will guard against padding. In order to check the size, you will need to give that struct a tag so it has a name.)
This uses a union to make the named members the same as the array elements (not just initialized to be the same, but to actually use the same member), and it uses anonymous struct and union to make the names of the members in the inner aggregates usable as names of members of the outer struct.
It would be possible to share the memory between the XY params and the entries in the array using an union:
typedef struct Mystruct
{
double p;
union {
struct {
double x_min;
double x_max;
double y_min;
double y_max;
};
double params[] = {x_min, x_max, y_min, y_max};
};
This would mean that the xy values would always be the same as the ones in the array
No you can't do that. You can't initialized member inside the declaration of structure. Because structure declaration defines a type not a variable. The way you showed it. Keeping a set of variables which are dependent among themselves. Even if you could why would you do that? Simply have an array.
typedef struct Mystruct
{
double p;
double params[4];
};
Now with this you can do the initialization part yourself. Or if you need both which is less likely you can keep both of them. By that I mean you can keep those 4 variables and keep an array and then while initializing you can explicitly set the content yourself. No way to wrap it like you did. Then you initialze like this
struct MyStruct mystruct = {
10.0,
{ 5, 6, 7, 8 }
};
Also if you want to keep two sets of variable being initialized with the same value you can follow the same method as shown above. But it is really meaningless given that it is nothing other two different variables having same values.
you can define a function inside the struct that initializes /sets the params array to the desired values, with the function containing a self-reference ( self ) to its containing structure. however the values in the params array and will only get 'synchronized' if this function is called ...
an example for this method is in "this" pointer in C (not C++) :
#include <stdio.h>
#include <stdlib.h>
typedef struct MyStruct
{
double p;
double x_min;
double x_max;
double y_min;
double y_max;
double params[4] ;
void (*setParams)();
}MyStruct;
void setParams(MyStruct* self) {
self->params[0]= self->x_min;
self->params[1]= self->x_max;
self->params[2]= self->y_min;
self->params[3]= self->y_max;
}
int main (int argc, char * argv[])
{
MyStruct myStruct = {1.24, 2.0, 4.0, 2.0, 4.0, {0,0,0,0}, NULL };
printf("%f, %f, %f, %f \n", myStruct.params[0], myStruct.params[1], myStruct.params[2], myStruct.params[3] );
setParams(&myStruct);
printf("%f, %f, %f, %f \n", myStruct.params[0], myStruct.params[1], myStruct.params[2], myStruct.params[3] );
return 0;
}
however to 'synchronize' you have to call setParams()
Assuming you want 2 different copies of the same data, simply use common sense:
typedef struct
{
double x_min;
double x_max;
double y_min;
double y_max;
} xy_stuff;
typedef struct
{
double p;
xy_stuff xy;
xy_stuff params;
} Mystruct;
...
Mystruct ms =
{
.p = 1.0,
.xy = {1.0, 2.0, 3.0, 4.0},
.params = {1.0, 2.0, 3.0, 4.0},
};
error: must use "struct" tag to refer to type 'point'
All I want to do is store a coordinate as a struct.
This seems maddeningly simple to do but yet I cannot do it after visiting 20 websites and scouring Kernaghan's book.
What am I missing?
#include <stdio.h>
int main()
{
struct point
{
float x;
float y;
};
point.x = 0.0;
point.y = 1.9;
return 0;
}
You defined a type called struct point, not a variable name using that definition. You'd want to either define an instance of the struct using that type:
struct point mypoint; // In C, you could change mypoint to point, but that gets confusing
or (less common) declare variables with a type of the (possibly anonymous) struct definition by putting the name after the struct definition, before the semi-colon:
struct {
float x;
float y;
} point;
All you've declared is a type named struct point ; you haven't created an object named point to manipulate. You need a separate object definition, either by writing:
struct point {
float x;
float y;
};
struct point pvar;
or
struct point {
float x;
float y;
} pvar;
then you can manipulate the members of the object:
pvar.x = 0.0;
pvar.y = 1.9;
etc.
The "point" in your example is a struct tag, not a variable name. You have declared a type named struct point, but not any variable having that type. Where that declaration is in scope, you can declare variables having that type with the form
struct point my_point;
and then assign to their members as
my_point.x = 0.0;
my_point.y = 1.9;
What you have done, is similar to saying int = 3; This is more like it:
#include<stdio.h>
int main(void) {
struct point {
float x;
float y;
} s;
s.x = 0.0;
s.y = 1.9;
return 0;
}
But you should see compiler warnings, because the code assigns double values to float. It is better not to use the inferior float type unless you are forced to.
You need to have a structure object, ie instantiate the structure.
struct point obj;
obj.x = 0.0;
obj.y = 1.9;
Other options available are
struct point // Note,structure is tagged 'point' which enables multiple instantiations
{
float x;
float y;
}obj;
and
struct // Anonymous structure with one & only one instance possible
{
float x;
float y;
}obj;
and finally a typedef which is also a common practice
typedef struct point
{
float x;
float y;
}point;
point obj;
obj.x = 0.0;
obj.y = 1.9;
For example, I have a C external function that returns a structure. Is it possible to return the structure to Modelica?
struct point{
double x;
double y;
}
struct point return_Struct(double a, double b){
struct point pt;
pt.x = a;
pt.y = b;
return pt;
};
In Modelica,
function structReturn
input Real x;
input Real y;
output ??????;
external"C" ????? = return_Struct(x,y)
annotation (Include="#include <cStructReturn.c>");
end structReturn;
Use a record and pass it by reference. See section 12.9.1.3 Records in the Modelica specification. Note that the record may have a different name in the Modelica tool from what you expect, so pass it through void* and cast it explicitly. Use a library not an included C-file to hide the interface or the code might not compile.
void return_Struct(double a, double b, void* result){
struct point *pt = result;
pt->x = a;
pt->y = b;
};
record R
Real x,y;
end R;
function structReturn
input Real x;
input Real y;
output R r;
external"C" return_Struct(x,y,r)
annotation (Library="cstructreturn");
end structReturn;
But I recommend passing 2 reals as output of the external function and constructing the record in a Modelica wrapper function instead.
function multipleReturn
input Real x;
input Real y;
output Real ox;
output Real oy;
external"C" return_notStruct(x,y,ox,oy)
annotation (Library="cstructreturn");
end multipleReturn;
My application is written in C. I have a module that uses some data from a certain given global structure. I now have to extend the module to optionally work against a different given global structure, which basically provides the same fields (as far as my module is concerned), but under different names.
Here's a car analogy to hopefully make my problem clearer. I've got these two global structures I have no control over.
struct {
unsigned char manufacturer_id;
unsigned short top_speed;
} Car;
struct {
RGB_t color;
unsigned short topSpeed;
unsigned char mfr;
} Automobile;
Let's say my Car Manager module uses information from Automobile. E.g.,
const char *car_manager__get_manufacturer_name(car_manager_t *self)
{
return self->manufacturers[Automobile.mfr];
}
I'd like to extend Car Manager to optionally (perhaps decided by a flag in the car_manager_t instance) use the same information from Car, so the above function would return self->manufacturers[Car.manufacturer_id]. I don't want to duplicate any logic in the module while adding this functionality.
I assume I'll have to put an interface on the access to the global structures. Any suggestions on how to do that?
I would define functions for getting the needed values, and pass pointers to the functions. You could even pass a struct which contains the needed function pointers.
struct Interface {
unsigned char (*manufacturer)(void);
unsigned short (*top_speed)(void);
}
struct Interface CarInterface = {&Car_manufacturer, &Car_top_speed};
struct Interface AutoInterface = {&Auto_manufacturer, &Auto_top_speed};
const char *car_manager__get_manufacturer_name(car_manager_t *self, Interface i)
{
return self->manufacturers[(*i.manufacturer)()];
}
I haven't written any C for a long time; please correct my syntax if necessary!
I don't know exactly what do you need, but note that if you have an union, that contain several structs that begin with the same types, you can access those types equally through all the structs. for example, if you have:
union bla {
struct {
int a;
char b;
float *c;
} s1;
struct {
int r;
char c;
float *j;
short s;
} s2;
int i;
} un;
Then un.s1.a,un.s2.r,un.i are the same, and so on un.s1.c==un.s2.j
Also, consider moving to C++ (and overload functions for your structs)
This is just the first solution that came to my mind, but one way to go about it might be to generalize your module to make it configurable so you can tell it how to look up the fields.
It's been a while since I coded in C, so consider this pseudo code ;)
The two structures:
/* Struct layout 1 */
struct {
float x; /*aka foo*/
float y; /*aka bar*/
float z; /*aka baz*/
} entity_type1;
/* Struct layout 2 */
struct {
float c; /*aka baz*/
float a; /*aka foo*/
float b; /*aka bar*/
} entity_type2;
The module:
struct {
int foo_index;
int bar_index;
int baz_index;
} fields_definition;
/* Private configuration */
fields_definition entity_fields;
/* Private getters */
float foo(void * entity) {
return *(float*)(entity_ptr + entity_fields.foo_index);
}
float bar(void * entity) {
return *(float*)(entity_ptr + entity_fields.bar_index);
}
/* Private setters */
void baz(void * entity, float value) {
*(float*)(entity_ptr + entity_fields.baz_index) = value; /* Legal?? */
}
/* Exported/Public function for setup */
void configure(fields_definition entity_fields_config){
entity_fields = entity_fields_config;
}
/* Normal exported/public function for usage */
void some_operation(void * entity) {
baz(entity, foo(entity) + bar(entity));
}
Usage:
/* Initialize... */
fields_definition for_type1 = {0,4,8};
fields_definition for_type2 = {4,8,0};
configure(for_type2);
/* ... and use */
entity_type2 e;
some_operation(&e);
Setting up the field_definition(s) could also be done by something similar to
entity_type2 t2;
fields_definition for_type2 = {
&(t2.a)-&t2,
&(t2.b)-&t2,
&(t2.c)-&t2
};
(Again, it's been a while, so I don't remember exactly how this would be done.) I believe some compilers have a built in function for getting the field offset in a struct, which would be cleaner but less portable.
I have two identical (but differently named) C structures:
typedef struct {
double x;
double y;
double z;
} CMAcceleration;
typedef struct {
double x;
double y;
double z;
} Vector3d;
Now I want to assign a CMAcceleration variable to a Vector3d variable (copying the whole struct). How can I do this?
I tried the following but get these compiler errors:
vector = acceleration; // "incompatible type"
vector = (Vector3d)acceleration; // "conversion to non-scalar type requested"
Of course I can resort to set all members individually:
vector.x = acceleration.x;
vector.y = acceleration.y;
vector.z = acceleration.z;
but that seems rather inconvenient.
What's the best solution?
That's your only solution (apart from wrapping it into a function):
vector.x = acceleration.x;
vector.y = acceleration.y;
vector.z = acceleration.z;
You could actually cast it, like this (using pointers)
Vector3d *vector = (Vector3d*) &acceleration;
but this is not in the specs and therefore the behaviour depends on the compiler, runtime and the big green space monster.
You could use a pointer to do the typecast;
vector = *((Vector3d *) &acceleration);
memcpy(&vector, &acceleration, sizeof(Vector3d));
Please note that this works only, if the physical layout of the structs in memory are identical. However, as #Oli pointed out, the compiler is not obliged to ensure this!
You use an utility function for that:
void AccelerationToVector( struct CMAcceleration* from, struct Vector3d* to )
{
to->x = from->x;
to->y = from->y;
to->z = from->z;
}
Why dont you use.
typedef CMAcceleration Vector3d;
(instead of creating a whole new structure)
in that case vector = acceleration; compiles just fine.
Another version of the utility function making use of C99:
static inline struct Vector3d AccelerationToVector(struct CMAcceleration In)
{
return (struct Vector3d){In.x, In.y, In.z};
}
With the compiler optimization turned up (e.g., -Os), this should turn into absolutely no object code when invoked.
This is achieved easily through a union:
typedef struct {
double x;
double y;
double z;
} CMAcceleration;
typedef struct {
double x;
double y;
double z;
} Vector3d;
typedef union {
CMAcceleration acceleration;
Vector3d vector;
} view;
int main() {
view v = (view) (Vector3d) {1.0, 2.0, 3.0};
CMAcceleration accel = v.acceleration;
printf("proof: %g %g %g\n", accel.x, accel.y, accel.z);
}
A safe (albeit somewhat convoluted) way to do it would be to use a union:
union { CMAcceleration a, Vector3d v } tmp = { .a = acceleration };
vector = tmp.v;
Values are reinterpreted (since C99) when the accessed member is not the last set one. In this case, we set the acceleration and then we access the vector, so the acceleration is reinterpreted.
This is the way the NSRectToCGRect function is implemented, for example.
You could create a union with pointers that way you avoid copying data.
example :
struct Ocp1SyncHeader
{
aes70::OCP1::OcaUint8 syncVal;
aes70::OCP1::Ocp1Header header;
};
struct convertToOcp1SyncHeader
{
union
{
Ocp1SyncHeader* data;
const uint8_t* src;
};
convertToOcp1SyncHeader& operator=(const uint8_t* rvalue)
{
src = (const uint8_t*)rvalue;
return *this;
}
};
** access like this:
convertToOcp1SyncHeader RecvData;
RecvData = src; // src is your block of data that you want to access
** access members like this :
RecvData.data.header