Initialize struct variable with previous one C [closed] - c

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},
};

Related

How do I implement a struct with two floats in C?

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;

How to add a structure member dynamically in C?

struct point {
int x;
int y;
};
main() {
struct point a;
a.x = 5;
a.y = 10;
printf("%d %d", a.x, a.y);
}
Output:
5 10
Here if I want add a member (int z) int the same structure dynamically.
What is the procedure?
What I have tried:
struct point {
int x;
int y;
};
struct newpoint {
struct point a;
int z;
};
I have tried the above steps, through which we have added a new member and the old structure point to new structure newpoint. But this is not what I want, I want to add the new member the same structure dynamically. I got this question in an interview.
The interviewer that asked you this has set you on a trap.
It's impossible to "dynamically define a struct" in C. It's possible to do "duck-typing in other languages, for example JavaScript, but C structures are compile time definitions and are as static as it gets.

Returning multiple values in header file

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, &params); /* 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.

Initializing structure array inside a structure array

I have a question in initializing my structure array inside a structure array. for example if I have a code as below:
#include <stdio.h>
int main() {
typedef struct {
int a;
int b;
int c;
} FIRST_T;
typedef struct {
int x;
int y;
int z;
FIRST_T *p;
} SECOND_T;
FIRST_T p1[]={{1,2,3},{3,4,5},{6,7,8}};
FIRST_T p2[]={{4,5,6},{7,8,9}};
SECOND_T my_second[]=
{
{1,2,3,p1},
{4,5,6,p2}
};
}
if I have to initialize my first array in second array intialization part itself, then how would I write my typedef of SECOND_T?
like
SECOND_T my_second[]=
{
{1,2,3,{{1,2,3},{4,5,6},{7,8,9}}},
{4,5,6,{{1,1,1},{2,2,2}}}
};
then how should be my SECOND_T?
I am sure I can't define it as:
typedef struct {
int x;
int y;
int z;
FIRST_T p[]; //(I know its a blunder)
} SECOND_T;
Please help.
You can't define a type with unbounded array in C, you have to specify the dimension. So you either do:
typedef strut {
int x;
int y;
int z;
FIRST_T f[SOME_VALUE];
} SECOND_T;
and then initialize SOME_VALUE count of members always, or do it the way you did.
I don't think you can do this, i.e, initialize the FIRST_T inside the initialization of SECOND_T, other than the first way you do it. Think about it, how can the compiler tell how many FIRST_T are there in SECOND_T? The problem here is, you can NOT define an array of flexible size struct statically.
you can't to do like that:
SECOND_T my_second[]=
{
{1,2,3,{{1,2,3},{4,5,6},{7,8,9}}},
{4,5,6,{{1,1,1},{2,2,2}}}
};
with
typedef struct {
int x;
int y;
int z;
FIRST_T p[]; //(I know its a blunder)
} SECOND_T;
becase the compiler don't know how to malloc memory for this struct. if you must do like this, you should define
typedef struct { int x,y,z; FIRST_T p[CONST_VALUE];}SECOND_T;
but I advise you use the first style that you write.
I don't know if I completely capture the question that you have. If it is that you want to avoid to have to declare an auxiliary variable for the pointers in the structure you can use a compound literal as follows:
SECOND_T my_second[] = {
{1,2,3, &(FIRST_T){{1,2,3},{3,4,5},{6,7,8}}},
{4,5,6, &(FIRST_T){{4,5,6},{7,8,9}}}
};
You'd have a compiler that complies to C99 for that.

Casting one C structure into another

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

Resources