How do I implement a struct with two floats in C? - 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;

Related

Initialize struct variable with previous one C [closed]

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

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.

Structure with more than one member per data type

Could someone explain what exactly it means to have a structure that has more than one member for a data type ?
struct {
int x, y;
};
This is just a contracted form of
struct {
int x;
int y;
};
meaning that the struct has a member x and a member y that are both of type int, and can both be accessed as myObject.x or myObject.y, for instance.
It is equivalent to:
struct {
int x;
int y;
};
This is covered in all text books on C and C++, It is a bit meaningless as the struct has not been given a name

Warning when using anonymous structures in a 4D matrix type

I'm trying to define a 4-d matrix type in C (for use in the iOS/ObjC environment) that is encapsulated (so not a bare array), and that can be accessed using indexed values or via named struct members. This is my attempt:
typedef union {
float m[16];
struct {
struct {
float x;
float y;
float z;
float w;
} x;
struct {
float x;
float y;
float z;
float w;
} y;
struct {
float x;
float y;
float z;
float w;
} z;
struct {
float x;
float y;
float z;
float w;
} w;
}; // warning here "Declaration does not declare anything"
} Matrix4;
This works, but I get a warning due to the anonymous (unnamed) struct. I obviously don't want to name that container struct as it only serves to hold the four inner structs.
This page implies that I should be able to do this?
http://gcc.gnu.org/onlinedocs/gcc/Unnamed-Fields.html#Unnamed-Fields
It seems to actually work, so is this wrong, or if not, how should I get rid of the warning?
I'm using LLVM GCC 4.2.
Thanks for any insight or suggestions.
Anonymous structs and unions are now allowed (as of C11). Your worries will eventually go away as you migrate to a newer compiler. In GCC, add -std=c1x.

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